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
}
func ensureIngressRulesDeleted(cfgs map[string]ingressservices.Config, nfr linuxfw.NetfilterRunner) error {
for serviceName, cfg := range cfgs {
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)
}
}
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 {
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
@ -2055,10 +2063,3 @@ func snatRule(t *nftables.Table, ch *nftables.Chain, src, dst netip.Addr, 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
}