This commit is contained in:
Irbe Krumina 2025-04-30 13:44:47 +01:00
parent e9ef402d70
commit 65c6dfc0e5
3 changed files with 72 additions and 12 deletions

View File

@ -247,6 +247,7 @@ func ensureIngressRulesAdded(cfgs map[string]ingressservices.Config, nfr linuxfw
} }
return nil return nil
} }
func ensureIngressRulesDeleted(cfgs map[string]ingressservices.Config, nfr linuxfw.NetfilterRunner) error { func ensureIngressRulesDeleted(cfgs map[string]ingressservices.Config, nfr linuxfw.NetfilterRunner) error {
for serviceName, cfg := range cfgs { for serviceName, cfg := range cfgs {
f := func(svcName string, vipIP, clusterIP netip.Addr) error { f := func(svcName string, vipIP, clusterIP netip.Addr) error {

View File

@ -243,3 +243,61 @@ func protoFromString(s string) (uint8, error) {
return 0, fmt.Errorf("unrecognized protocol: %q", s) return 0, fmt.Errorf("unrecognized protocol: %q", s)
} }
} }
func (n *nftablesRunner) EnsureDNATRuleForSvc(svc string, origDst, dst netip.Addr) error {
t, ch, err := n.ensurePreroutingChain(origDst)
if err != nil {
return fmt.Errorf("error ensuring chain for %s: %w", svc, err)
}
meta := svcRuleMeta(svc, origDst, dst)
rule, err := n.findRuleByMetadata(t, ch, meta)
if err != nil {
return fmt.Errorf("error looking up rule: %w", err)
}
if rule != nil {
return nil
}
rule = dnatRuleForChain(t, ch, origDst, dst, meta)
n.conn.InsertRule(rule)
return n.conn.Flush()
}
func (n *nftablesRunner) DeleteDNATRuleForSvc(svcName string, origDst, dst netip.Addr) error {
table, err := n.getNFTByAddr(origDst)
if err != nil {
return fmt.Errorf("error setting up nftables for IP family of %s: %w", origDst, err)
}
t, err := getTableIfExists(n.conn, table.Proto, "nat")
if err != nil {
return fmt.Errorf("error checking if nat table exists: %w", err)
}
if t == nil {
return nil
}
ch, err := getChainFromTable(n.conn, t, "PREROUTING")
if errors.Is(err, errorChainNotFound{tableName: "nat", chainName: "PREROUTING"}) {
return nil
}
if err != nil {
return fmt.Errorf("error checking if chain PREROUTING exists: %w", err)
}
meta := svcRuleMeta(svcName, origDst, dst)
rule, err := n.findRuleByMetadata(t, ch, meta)
if err != nil {
return fmt.Errorf("error checking if rule exists: %w", err)
}
if rule == nil {
return nil
}
if err := n.conn.DelRule(rule); err != nil {
return fmt.Errorf("error deleting rule: %w", err)
}
return n.conn.Flush()
}
// svcRuleMeta generates metadata for a rule.
// This metadata can then be used to find the rule.
// https://github.com/google/nftables/issues/48
func svcRuleMeta(svcName string, origDst, dst netip.Addr) []byte {
return []byte(fmt.Sprintf("svc:%s,VIP:%s,ClusterIP:%s", svcName, origDst.String(), dst.String()))
}

View File

@ -107,6 +107,12 @@ func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error {
if err != nil { if err != nil {
return err 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 var daddrOffset, fam, dadderLen uint32
if origDst.Is4() { if origDst.Is4() {
daddrOffset = 16 daddrOffset = 16
@ -117,9 +123,9 @@ func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error {
dadderLen = 16 dadderLen = 16
fam = unix.NFPROTO_IPV6 fam = unix.NFPROTO_IPV6
} }
dnatRule := &nftables.Rule{ rule := &nftables.Rule{
Table: nat, Table: t,
Chain: preroutingCh, Chain: ch,
Exprs: []expr.Any{ Exprs: []expr.Any{
&expr.Payload{ &expr.Payload{
DestRegister: 1, DestRegister: 1,
@ -143,8 +149,10 @@ func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error {
}, },
}, },
} }
n.conn.InsertRule(dnatRule) if len(meta) > 0 {
return n.conn.Flush() rule.UserData = meta
}
return rule
} }
// DNATWithLoadBalancer currently just forwards all traffic destined for origDst // DNATWithLoadBalancer currently just forwards all traffic destined for origDst
@ -2055,10 +2063,3 @@ func snatRule(t *nftables.Table, ch *nftables.Chain, src, dst netip.Addr, meta [
UserData: meta, UserData: meta,
} }
} }
func (nfr *nftablesRunner) EnsureDNATRuleForSvc(svcName string, origDst, dst netip.Addr) error {
return nil
}
func (nfr *nftablesRunner) DeleteDNATRuleForSvc(svcName string, origDst, dst netip.Addr) error {
return nil
}