@@ -43,6 +43,7 @@ const (
43
43
Postrouting = "POSTROUTING"
44
44
OvnPrerouting = "OVN-PREROUTING"
45
45
OvnPostrouting = "OVN-POSTROUTING"
46
+ OvnNodePort = "OVN-NODE-PORT"
46
47
OvnNatOutGoingPolicy = "OVN-NAT-POLICY"
47
48
OvnNatOutGoingPolicySubnet = "OVN-NAT-PSUBNET-"
48
49
)
@@ -420,18 +421,36 @@ func (c *Controller) createIptablesRule(ipt *iptables.IPTables, rule util.IPTabl
420
421
return nil
421
422
}
422
423
423
- func (c * Controller ) updateIptablesChain (ipt * iptables.IPTables , table , chain , parent string , rules []util.IPTableRule ) error {
424
+ // ensure the iptables chain exists
425
+ func (c * Controller ) createIptablesChain (ipt * iptables.IPTables , table , chain string ) error {
426
+ if chain == "" {
427
+ return nil
428
+ }
429
+
424
430
ok , err := ipt .ChainExists (table , chain )
425
431
if err != nil {
426
432
klog .Errorf ("failed to check existence of iptables chain %s in table %s: %v" , chain , table , err )
427
433
return err
428
434
}
429
- if ! ok {
430
- if err = ipt .NewChain (table , chain ); err != nil {
431
- klog .Errorf ("failed to create iptables chain %s in table %s: %v" , chain , table , err )
432
- return err
433
- }
434
- klog .Infof ("created iptables chain %s in table %s" , chain , table )
435
+ if ok {
436
+ return nil
437
+ }
438
+
439
+ if err = ipt .NewChain (table , chain ); err != nil {
440
+ klog .Errorf ("failed to create iptables chain %s in table %s: %v" , chain , table , err )
441
+ return err
442
+ }
443
+
444
+ klog .Infof ("created iptables chain %s in table %s" , chain , table )
445
+ return nil
446
+ }
447
+
448
+ func (c * Controller ) updateIptablesChain (ipt * iptables.IPTables , table , chain , parent string , rules []util.IPTableRule ) error {
449
+ if err := c .createIptablesChain (ipt , table , chain ); err != nil {
450
+ return err
451
+ }
452
+ if err := c .createIptablesChain (ipt , table , parent ); err != nil {
453
+ return err
435
454
}
436
455
if parent != "" {
437
456
comment := fmt .Sprintf ("kube-ovn %s rules" , strings .ToLower (parent ))
@@ -440,7 +459,7 @@ func (c *Controller) updateIptablesChain(ipt *iptables.IPTables, table, chain, p
440
459
Chain : parent ,
441
460
Rule : []string {"-m" , "comment" , "--comment" , comment , "-j" , chain },
442
461
}
443
- if err = c .createIptablesRule (ipt , rule ); err != nil {
462
+ if err : = c .createIptablesRule (ipt , rule ); err != nil {
444
463
klog .Errorf ("failed to create iptables rule: %v" , err )
445
464
return err
446
465
}
@@ -512,14 +531,12 @@ func (c *Controller) setIptables() error {
512
531
v4Rules = []util.IPTableRule {
513
532
// mark packets from pod to service
514
533
{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` )},
515
- // nat packets marked by kube-proxy or kube-ovn
516
- {Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m mark --mark 0x4000/0x4000 -j MASQUERADE` )},
534
+ // packets marked by kube-proxy or kube-ovn will be SNATed later by kube-proxy
535
+ {Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m mark --mark 0x4000/0x4000 -j RETURN` )},
536
+ // handle node port with external traffic policy set to Local
537
+ {Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m mark --mark 0x80000/0x80000 -j ` + OvnNodePort )},
517
538
// nat service traffic
518
539
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m set --match-set ovn40subnets src -m set --match-set ovn40subnets dst -j MASQUERADE` )},
519
- // do not nat node port service traffic with external traffic policy set to local
520
- {Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m mark --mark 0x80000/0x80000 -m set --match-set ovn40subnets-distributed-gw dst -j RETURN` )},
521
- // 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
540
// do not nat reply packets in direct routing
524
541
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -j RETURN` )},
525
542
// do not nat route traffic
@@ -531,6 +548,12 @@ func (c *Controller) setIptables() error {
531
548
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (fmt .Sprintf (`-m mark --mark %s -j RETURN` , OnOutGoingForwardMark ))},
532
549
// default nat outgoing rules
533
550
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m set --match-set ovn40subnets-nat src -m set ! --match-set ovn40subnets dst -j MASQUERADE` )},
551
+ // clear mark
552
+ {Table : NAT , Chain : OvnNodePort , Rule : strings .Fields (`-j MARK --set-xmark 0x80000/0x0` )},
553
+ // do not nat node port service traffic with external traffic policy set to Local
554
+ {Table : NAT , Chain : OvnNodePort , Rule : strings .Fields (`-m set --match-set ovn40subnets-distributed-gw dst -j ACCEPT` )},
555
+ // nat node port service traffic with external traffic policy set to Local for subnets with centralized gateway
556
+ {Table : NAT , Chain : OvnNodePort , Rule : strings .Fields (`-j MASQUERADE` )},
534
557
// Input Accept
535
558
{Table : "filter" , Chain : "INPUT" , Rule : strings .Fields (`-m set --match-set ovn40subnets src -j ACCEPT` )},
536
559
{Table : "filter" , Chain : "INPUT" , Rule : strings .Fields (`-m set --match-set ovn40subnets dst -j ACCEPT` )},
@@ -547,14 +570,12 @@ func (c *Controller) setIptables() error {
547
570
v6Rules = []util.IPTableRule {
548
571
// mark packets from pod to service
549
572
{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` )},
550
- // nat packets marked by kube-proxy or kube-ovn
551
- {Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m mark --mark 0x4000/0x4000 -j MASQUERADE` )},
573
+ // packets marked by kube-proxy or kube-ovn will be SNATed later by kube-proxy
574
+ {Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m mark --mark 0x4000/0x4000 -j RETURN` )},
575
+ // handle node port with external traffic policy set to Local
576
+ {Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m mark --mark 0x80000/0x80000 -j ` + OvnNodePort )},
552
577
// nat service traffic
553
578
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m set --match-set ovn60subnets src -m set --match-set ovn60subnets dst -j MASQUERADE` )},
554
- // do not nat node port service traffic with external traffic policy set to local
555
- {Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m mark --mark 0x80000/0x80000 -m set --match-set ovn60subnets-distributed-gw dst -j RETURN` )},
556
- // 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` )},
558
579
// do not nat reply packets in direct routing
559
580
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-p tcp -m tcp --tcp-flags SYN NONE -m conntrack --ctstate NEW -j RETURN` )},
560
581
// do not nat route traffic
@@ -565,6 +586,12 @@ func (c *Controller) setIptables() error {
565
586
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (fmt .Sprintf (`-m mark --mark %s -j MASQUERADE` , OnOutGoingNatMark ))},
566
587
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (fmt .Sprintf (`-m mark --mark %s -j RETURN` , OnOutGoingForwardMark ))},
567
588
{Table : NAT , Chain : OvnPostrouting , Rule : strings .Fields (`-m set --match-set ovn60subnets-nat src -m set ! --match-set ovn60subnets dst -j MASQUERADE` )},
589
+ // clear mark
590
+ {Table : NAT , Chain : OvnNodePort , Rule : strings .Fields (`-j MARK --set-xmark 0x80000/0x0` )},
591
+ // do not nat node port service traffic with external traffic policy set to Local
592
+ {Table : NAT , Chain : OvnNodePort , Rule : strings .Fields (`-m set --match-set ovn60subnets-distributed-gw dst -j ACCEPT` )},
593
+ // nat node port service traffic with external traffic policy set to Local for subnets with centralized gateway
594
+ {Table : NAT , Chain : OvnNodePort , Rule : strings .Fields (`-j MASQUERADE` )},
568
595
// Input Accept
569
596
{Table : "filter" , Chain : "INPUT" , Rule : strings .Fields (`-m set --match-set ovn60subnets src -j ACCEPT` )},
570
597
{Table : "filter" , Chain : "INPUT" , Rule : strings .Fields (`-m set --match-set ovn60subnets dst -j ACCEPT` )},
@@ -682,7 +709,7 @@ func (c *Controller) setIptables() error {
682
709
}
683
710
}
684
711
685
- var natPreroutingRules , natPostroutingRules []util.IPTableRule
712
+ var natPreroutingRules , natPostroutingRules , ovnNodePortRules []util.IPTableRule
686
713
for _ , rule := range iptablesRules {
687
714
if rule .Table == NAT {
688
715
switch rule .Chain {
@@ -699,6 +726,12 @@ func (c *Controller) setIptables() error {
699
726
}
700
727
natPostroutingRules = append (natPostroutingRules , rule )
701
728
continue
729
+ case OvnNodePort :
730
+ if c .k8siptables [protocol ].HasRandomFully () && rule .Rule [len (rule .Rule )- 1 ] == "MASQUERADE" {
731
+ rule .Rule = append (rule .Rule , "--random-fully" )
732
+ }
733
+ ovnNodePortRules = append (ovnNodePortRules , rule )
734
+ continue
702
735
}
703
736
}
704
737
@@ -733,6 +766,10 @@ func (c *Controller) setIptables() error {
733
766
klog .Errorf ("failed to update chain %s/%s: %v" , NAT , OvnPrerouting )
734
767
return err
735
768
}
769
+ if err = c .updateIptablesChain (ipt , NAT , OvnNodePort , OvnPostrouting , ovnNodePortRules ); err != nil {
770
+ klog .Errorf ("failed to update chain %s/%s: %v" , NAT , OvnNodePort )
771
+ return err
772
+ }
736
773
if err = c .updateIptablesChain (ipt , NAT , OvnPostrouting , Postrouting , natPostroutingRules ); err != nil {
737
774
klog .Errorf ("failed to update chain %s/%s: %v" , NAT , OvnPostrouting )
738
775
return err
0 commit comments