Skip to content

Commit

Permalink
do not nat packets for incoming traffic when
Browse files Browse the repository at this point in the history
service externalTrafficPolicy is Local
  • Loading branch information
zhangzujian committed May 24, 2022
1 parent bbb8a69 commit 96f232d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
8 changes: 6 additions & 2 deletions dist/images/uninstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ if [ -n "$1" ]; then
fi
fi

iptables -t nat -D POSTROUTING -m mark --mark 0x80000/0x80000 -j RETURN
iptables -t nat -D POSTROUTING -m set ! --match-set ovn40subnets src -m set ! --match-set ovn40other-node src -m set --match-set ovn40subnets-nat dst -j RETURN
iptables -t nat -D POSTROUTING -m set --match-set ovn40subnets-nat src -m set ! --match-set ovn40subnets dst -j MASQUERADE
ip6tables -t nat -D KUBE-NODE-PORT -p tcp -m set --match-set KUBE-NODE-PORT-LOCAL-TCP dst -j MARK --set-xmark 0x80000/0x80000
ip6tables -t nat -D KUBE-NODE-PORT -p udp -m set --match-set KUBE-NODE-PORT-LOCAL-UDP dst -j MARK --set-xmark 0x80000/0x80000
iptables -t mangle -D PREROUTING -i ovn0 -m set --match-set ovn40subnets src -m set --match-set ovn40services dst -j MARK --set-xmark 0x4000/0x4000
iptables -t filter -D INPUT -m set --match-set ovn40subnets dst -j ACCEPT
iptables -t filter -D INPUT -m set --match-set ovn40subnets src -j ACCEPT
Expand All @@ -47,8 +49,10 @@ ipset destroy ovn40local-pod-ip-nat
ipset destroy ovn40other-node
ipset destroy ovn40services

ip6tables -t nat -D POSTROUTING -m mark --mark 0x80000/0x80000 -j RETURN
ip6tables -t nat -D POSTROUTING -m set ! --match-set ovn60subnets src -m set ! --match-set ovn60other-node src -m set --match-set ovn60subnets-nat dst -j RETURN
ip6tables -t nat -D POSTROUTING -m set --match-set ovn60subnets-nat src -m set ! --match-set ovn60subnets dst -j MASQUERADE
ip6tables -t nat -D KUBE-NODE-PORT -p tcp -m set --match-set KUBE-6-NODE-PORT-LOCAL-TCP dst -j MARK --set-xmark 0x80000/0x80000
ip6tables -t nat -D KUBE-NODE-PORT -p udp -m set --match-set KUBE-6-NODE-PORT-LOCAL-UDP dst -j MARK --set-xmark 0x80000/0x80000
ip6tables -t mangle -D PREROUTING -i ovn0 -m set --match-set ovn60subnets src -m set --match-set ovn60services dst -j MARK --set-xmark 0x4000/0x4000
ip6tables -t filter -D INPUT -m set --match-set ovn60subnets dst -j ACCEPT
ip6tables -t filter -D INPUT -m set --match-set ovn60subnets src -j ACCEPT
Expand Down
56 changes: 51 additions & 5 deletions pkg/daemon/gateway_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ func (c *Controller) setIptables() error {
}

v4Rules = []util.IPTableRule{
// do not nat node port service traffic with external traffic policy set to local
{Table: "nat", Chain: "POSTROUTING", Rule: strings.Fields(`-m mark --mark 0x80000/0x80000 -j RETURN`)},
// do not nat route traffic
{Table: "nat", Chain: "POSTROUTING", Rule: strings.Fields(`-m set ! --match-set ovn40subnets src -m set ! --match-set ovn40other-node src -m set --match-set ovn40subnets-nat dst -j RETURN`)},
// nat outgoing
Expand All @@ -330,6 +332,8 @@ func (c *Controller) setIptables() error {
{Table: "filter", Chain: "OUTPUT", Rule: strings.Fields(`-p udp -m udp --dport 6081 -j MARK --set-xmark 0x0`)},
}
v6Rules = []util.IPTableRule{
// do not nat node port service traffic with external traffic policy set to local
{Table: "nat", Chain: "POSTROUTING", Rule: strings.Fields(`-m mark --mark 0x80000/0x80000 -j RETURN`)},
// do not nat route traffic
{Table: "nat", Chain: "POSTROUTING", Rule: strings.Fields(`-m set ! --match-set ovn60subnets src -m set ! --match-set ovn60other-node src -m set --match-set ovn60subnets-nat dst -j RETURN`)},
// nat outgoing
Expand Down Expand Up @@ -368,14 +372,19 @@ func (c *Controller) setIptables() error {
return err
}

var matchset string
var kubeProxyIpsetProtocol, matchset string
var abandonedRules, iptablesRules []util.IPTableRule
if protocol == kubeovnv1.ProtocolIPv4 {
iptablesRules, abandonedRules = v4Rules, v4AbandonedRules
matchset = "ovn40subnets"
} else {
iptablesRules, abandonedRules = v6Rules, v6AbandonedRules
matchset = "ovn60subnets"
kubeProxyIpsetProtocol, matchset = "6-", "ovn60subnets"
}

kubeProxyIpsets := map[string]string{
"tcp": fmt.Sprintf("KUBE-%sNODE-PORT-LOCAL-TCP", kubeProxyIpsetProtocol),
"udp": fmt.Sprintf("KUBE-%sNODE-PORT-LOCAL-UDP", kubeProxyIpsetProtocol),
}

if nodeIP := nodeIPs[protocol]; nodeIP != "" {
Expand All @@ -384,10 +393,33 @@ func (c *Controller) setIptables() error {
)

rules := make([]util.IPTableRule, len(iptablesRules)+2)
copy(rules[1:3], iptablesRules[:2])
copy(rules[1:4], iptablesRules[:3])
rules[0] = util.IPTableRule{Table: "nat", Chain: "POSTROUTING", Rule: strings.Fields(fmt.Sprintf(`! -s %s -m mark --mark 0x4000/0x4000 -j MASQUERADE`, nodeIP))}
rules[3] = util.IPTableRule{Table: "nat", Chain: "POSTROUTING", Rule: strings.Fields(fmt.Sprintf(`! -s %s -m set ! --match-set %s src -m set --match-set %s dst -j MASQUERADE`, nodeIP, matchset, matchset))}
copy(rules[4:], iptablesRules[2:])
rules[4] = util.IPTableRule{Table: "nat", Chain: "POSTROUTING", Rule: strings.Fields(fmt.Sprintf(`! -s %s -m set ! --match-set %s src -m set --match-set %s dst -j MASQUERADE`, nodeIP, matchset, matchset))}
copy(rules[5:], iptablesRules[3:])

chainExists, err := c.iptables[protocol].ChainExists("nat", "KUBE-NODE-PORT")
if err != nil {
klog.Errorf("failed to check existence of chain KUBE-NODE-PORT in nat table: %v", err)
return err
}
if chainExists {
nodePortRules := make([]util.IPTableRule, 0, len(kubeProxyIpsets))
for protocol, ipset := range kubeProxyIpsets {
ipsetExists, err := ipsetExists(ipset)
if err != nil {
klog.Error("failed to check existence of ipset %s: %v", ipset, err)
return err
}
if !ipsetExists {
klog.Warningf("ipset %s does not exist", ipset)
continue
}
nodePortRules = append(nodePortRules, util.IPTableRule{Table: "nat", Chain: "KUBE-NODE-PORT", Rule: strings.Fields(fmt.Sprintf("-p %s -m set --match-set %s dst -j MARK --set-xmark 0x80000/0x80000", protocol, ipset))})
}
rules = append(nodePortRules, rules...)
}

iptablesRules = rules
}

Expand Down Expand Up @@ -776,3 +808,17 @@ func getIptablesRuleNum(table, chain, rule, dstNatIp string) (string, error) {
}
return num, nil
}

func ipsetExists(name string) (bool, error) {
result, err := netlink.IpsetListAll()
if err != nil {
return false, fmt.Errorf("failed to list ipsets: %v", err)
}

for _, ipset := range result {
if ipset.SetName == name {
return true, nil
}
}
return false, nil
}

0 comments on commit 96f232d

Please sign in to comment.