Skip to content

Commit dff950b

Browse files
authored
cni-server: clear iptables mark before doing masquerade (#2919)
1 parent d043a2d commit dff950b

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

pkg/daemon/gateway_linux.go

+31-20
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const (
4343
Postrouting = "POSTROUTING"
4444
OvnPrerouting = "OVN-PREROUTING"
4545
OvnPostrouting = "OVN-POSTROUTING"
46+
OvnMasquerade = "OVN-MASQUERADE"
4647
OvnNatOutGoingPolicy = "OVN-NAT-POLICY"
4748
OvnNatOutGoingPolicySubnet = "OVN-NAT-PSUBNET-"
4849
)
@@ -513,24 +514,27 @@ func (c *Controller) setIptables() error {
513514
// mark packets from pod to service
514515
{Table: NAT, Chain: OvnPrerouting, Rule: strings.Fields(`-i ovn0 -m set --match-set ovn40subnets src -m set --match-set ovn40services dst -j MARK --set-xmark 0x4000/0x4000`)},
515516
// nat packets marked by kube-proxy or kube-ovn
516-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x4000/0x4000 -j MASQUERADE`)},
517+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x4000/0x4000 -j ` + OvnMasquerade)},
517518
// nat service traffic
518-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m set --match-set ovn40subnets src -m set --match-set ovn40subnets dst -j MASQUERADE`)},
519+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m set --match-set ovn40subnets src -m set --match-set ovn40subnets dst -j ` + OvnMasquerade)},
519520
// do not nat node port service traffic with external traffic policy set to local
520521
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x80000/0x80000 -m set --match-set ovn40subnets-distributed-gw dst -j RETURN`)},
521522
// nat node port service traffic with external traffic policy set to local for subnets with centralized gateway
522-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x80000/0x80000 -j MASQUERADE`)},
523+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x80000/0x80000 -j ` + OvnMasquerade)},
523524
// do not nat reply packets in direct routing
524525
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -j RETURN`)},
525526
// do not nat route traffic
526527
{Table: NAT, Chain: OvnPostrouting, 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`)},
527-
// nat outgoing
528528
// nat outgoing policy rules
529529
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(fmt.Sprintf(`-m set --match-set ovn40subnets-nat-policy src -m set ! --match-set ovn40subnets dst -j %s`, OvnNatOutGoingPolicy))},
530-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(fmt.Sprintf(`-m mark --mark %s -j MASQUERADE`, OnOutGoingNatMark))},
530+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(fmt.Sprintf(`-m mark --mark %s -j %s`, OnOutGoingNatMark, OvnMasquerade))},
531531
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(fmt.Sprintf(`-m mark --mark %s -j RETURN`, OnOutGoingForwardMark))},
532532
// default nat outgoing rules
533-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m set --match-set ovn40subnets-nat src -m set ! --match-set ovn40subnets dst -j MASQUERADE`)},
533+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m set --match-set ovn40subnets-nat src -m set ! --match-set ovn40subnets dst -j ` + OvnMasquerade)},
534+
// clear mark
535+
{Table: NAT, Chain: OvnMasquerade, Rule: strings.Fields(`-j MARK --set-xmark 0x0/0xffffffff`)},
536+
// do masquerade
537+
{Table: NAT, Chain: OvnMasquerade, Rule: strings.Fields(`-j MASQUERADE`)},
534538
// Input Accept
535539
{Table: "filter", Chain: "INPUT", Rule: strings.Fields(`-m set --match-set ovn40subnets src -j ACCEPT`)},
536540
{Table: "filter", Chain: "INPUT", Rule: strings.Fields(`-m set --match-set ovn40subnets dst -j ACCEPT`)},
@@ -548,23 +552,26 @@ func (c *Controller) setIptables() error {
548552
// mark packets from pod to service
549553
{Table: NAT, Chain: OvnPrerouting, Rule: strings.Fields(`-i ovn0 -m set --match-set ovn60subnets src -m set --match-set ovn60services dst -j MARK --set-xmark 0x4000/0x4000`)},
550554
// nat packets marked by kube-proxy or kube-ovn
551-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x4000/0x4000 -j MASQUERADE`)},
555+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x4000/0x4000 -j ` + OvnMasquerade)},
552556
// nat service traffic
553-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m set --match-set ovn60subnets src -m set --match-set ovn60subnets dst -j MASQUERADE`)},
557+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m set --match-set ovn60subnets src -m set --match-set ovn60subnets dst -j ` + OvnMasquerade)},
554558
// do not nat node port service traffic with external traffic policy set to local
555559
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x80000/0x80000 -m set --match-set ovn60subnets-distributed-gw dst -j RETURN`)},
556560
// nat node port service traffic with external traffic policy set to local for subnets with centralized gateway
557-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x80000/0x80000 -j MASQUERADE`)},
561+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m mark --mark 0x80000/0x80000 -j ` + OvnMasquerade)},
558562
// do not nat reply packets in direct routing
559563
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -j RETURN`)},
560564
// do not nat route traffic
561565
{Table: NAT, Chain: OvnPostrouting, 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`)},
562-
// nat outgoing
563566
// nat outgoing policy rules
564567
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(fmt.Sprintf(`-m set --match-set ovn60subnets-nat-policy src -m set ! --match-set ovn60subnets dst -j %s`, OvnNatOutGoingPolicy))},
565-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(fmt.Sprintf(`-m mark --mark %s -j MASQUERADE`, OnOutGoingNatMark))},
568+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(fmt.Sprintf(`-m mark --mark %s -j %s`, OnOutGoingNatMark, OvnMasquerade))},
566569
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(fmt.Sprintf(`-m mark --mark %s -j RETURN`, OnOutGoingForwardMark))},
567-
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m set --match-set ovn60subnets-nat src -m set ! --match-set ovn60subnets dst -j MASQUERADE`)},
570+
{Table: NAT, Chain: OvnPostrouting, Rule: strings.Fields(`-m set --match-set ovn60subnets-nat src -m set ! --match-set ovn60subnets dst -j ` + OvnMasquerade)},
571+
// clear mark
572+
{Table: NAT, Chain: OvnMasquerade, Rule: strings.Fields(`-j MARK --set-xmark 0x0/0xffffffff`)},
573+
// do masquerade
574+
{Table: NAT, Chain: OvnMasquerade, Rule: strings.Fields(`-j MASQUERADE`)},
568575
// Input Accept
569576
{Table: "filter", Chain: "INPUT", Rule: strings.Fields(`-m set --match-set ovn60subnets src -j ACCEPT`)},
570577
{Table: "filter", Chain: "INPUT", Rule: strings.Fields(`-m set --match-set ovn60subnets dst -j ACCEPT`)},
@@ -682,23 +689,23 @@ func (c *Controller) setIptables() error {
682689
}
683690
}
684691

685-
var natPreroutingRules, natPostroutingRules []util.IPTableRule
692+
var natPreroutingRules, natPostroutingRules, ovnMasqueradeRules []util.IPTableRule
686693
for _, rule := range iptablesRules {
687694
if rule.Table == NAT {
695+
if c.k8siptables[protocol].HasRandomFully() && rule.Rule[len(rule.Rule)-1] == "MASQUERADE" {
696+
rule.Rule = append(rule.Rule, "--random-fully")
697+
}
698+
688699
switch rule.Chain {
689700
case OvnPrerouting:
690701
natPreroutingRules = append(natPreroutingRules, rule)
691702
continue
692703
case OvnPostrouting:
693-
if util.ContainsString(rule.Rule, "MASQUERADE") && c.k8siptables[protocol].HasRandomFully() {
694-
// https://github.com/kubeovn/kube-ovn/issues/2641
695-
// Work around Linux kernel bug that sometimes causes multiple flows to
696-
// get mapped to the same IP:PORT and consequently some suffer packet
697-
// drops.
698-
rule.Rule = append(rule.Rule, "--random-fully")
699-
}
700704
natPostroutingRules = append(natPostroutingRules, rule)
701705
continue
706+
case OvnMasquerade:
707+
ovnMasqueradeRules = append(ovnMasqueradeRules, rule)
708+
continue
702709
}
703710
}
704711

@@ -733,6 +740,10 @@ func (c *Controller) setIptables() error {
733740
klog.Errorf("failed to update chain %s/%s: %v", NAT, OvnPrerouting)
734741
return err
735742
}
743+
if err = c.updateIptablesChain(ipt, NAT, OvnMasquerade, "", ovnMasqueradeRules); err != nil {
744+
klog.Errorf("failed to update chain %s/%s: %v", NAT, OvnMasquerade)
745+
return err
746+
}
736747
if err = c.updateIptablesChain(ipt, NAT, OvnPostrouting, Postrouting, natPostroutingRules); err != nil {
737748
klog.Errorf("failed to update chain %s/%s: %v", NAT, OvnPostrouting)
738749
return err

0 commit comments

Comments
 (0)