@@ -407,6 +407,10 @@ func (n *linuxNetwork) updateHostIptablesRules(vpcCIDRs []string, primaryMAC str
407
407
if err := n .updateIptablesRules (iptablesConnmarkRules , ipt ); err != nil {
408
408
return err
409
409
}
410
+ err = n .cleanOldNatChains (ipt )
411
+ if err != nil {
412
+ return err
413
+ }
410
414
}
411
415
return nil
412
416
}
@@ -429,15 +433,13 @@ func (n *linuxNetwork) buildIptablesSNATRules(vpcCIDRs []string, primaryAddr *ne
429
433
log .Debugf ("Total CIDRs to program - %d" , len (allCIDRs ))
430
434
// build IPTABLES chain for SNAT of non-VPC outbound traffic and excluded CIDRs
431
435
var chains []string
432
- for i := 0 ; i <= len (allCIDRs ); i ++ {
433
- chain := fmt .Sprintf ("AWS-SNAT-CHAIN-%d" , i )
434
- log .Debugf ("Setup Host Network: iptables -N %s -t nat" , chain )
435
- if err := ipt .NewChain ("nat" , chain ); err != nil && ! containChainExistErr (err ) {
436
- log .Errorf ("ipt.NewChain error for chain [%s]: %v" , chain , err )
437
- return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to add chain" )
438
- }
439
- chains = append (chains , chain )
436
+ chain := "AWS-SNAT-CHAIN-0"
437
+ log .Debugf ("Setup Host Network: iptables -N %s -t nat" , chain )
438
+ if err := ipt .NewChain ("nat" , chain ); err != nil && ! containChainExistErr (err ) {
439
+ log .Errorf ("ipt.NewChain error for chain [%s]: %v" , chain , err )
440
+ return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to add chain" )
440
441
}
442
+ chains = append (chains , chain )
441
443
442
444
// build SNAT rules for outbound non-VPC traffic
443
445
var iptableRules []iptablesRule
@@ -451,23 +453,22 @@ func (n *linuxNetwork) buildIptablesSNATRules(vpcCIDRs []string, primaryAddr *ne
451
453
"-m" , "comment" , "--comment" , "AWS SNAT CHAIN" , "-j" , "AWS-SNAT-CHAIN-0" ,
452
454
}})
453
455
454
- for i , cidr := range allCIDRs {
455
- curChain := chains [i ]
456
- curName := fmt .Sprintf ("[%d] AWS-SNAT-CHAIN" , i )
457
- nextChain := chains [i + 1 ]
456
+ for _ , cidr := range allCIDRs {
457
+ curChain := "AWS-SNAT-CHAIN-0"
458
+ curName := "AWS-SNAT-CHAIN-0"
458
459
comment := "AWS SNAT CHAIN"
459
460
if cidr .isExclusion {
460
461
comment += " EXCLUSION"
461
462
}
462
- log .Debugf ("Setup Host Network: iptables -A %s ! -d %s -t nat -j %s" , curChain , cidr , nextChain )
463
+ log .Debugf ("Setup Host Network: iptables -A %s -d %s -t nat -j %s" , "AWS-SNAT-CHAIN-0" , cidr , "RETURN" )
463
464
464
465
iptableRules = append (iptableRules , iptablesRule {
465
466
name : curName ,
466
467
shouldExist : ! n .useExternalSNAT ,
467
468
table : "nat" ,
468
469
chain : curChain ,
469
470
rule : []string {
470
- "!" , " -d" , cidr .cidr , "-m" , "comment" , "--comment" , comment , "-j" , nextChain ,
471
+ "-d" , cidr .cidr , "-m" , "comment" , "--comment" , comment , "-j" , "RETURN" ,
471
472
}})
472
473
}
473
474
@@ -489,22 +490,31 @@ func (n *linuxNetwork) buildIptablesSNATRules(vpcCIDRs []string, primaryAddr *ne
489
490
}
490
491
}
491
492
492
- lastChain := chains [len (chains )- 1 ]
493
- iptableRules = append (iptableRules , iptablesRule {
494
- name : "last SNAT rule for non-VPC outbound traffic" ,
495
- shouldExist : ! n .useExternalSNAT ,
496
- table : "nat" ,
497
- chain : lastChain ,
498
- rule : snatRule ,
499
- })
500
-
501
493
snatStaleRules , err := computeStaleIptablesRules (ipt , "nat" , "AWS-SNAT-CHAIN" , iptableRules , chains )
502
494
if err != nil {
503
495
return []iptablesRule {}, err
504
496
}
505
497
506
498
iptableRules = append (iptableRules , snatStaleRules ... )
507
499
500
+ // Force delete the SNAT rule as we want this to be the last rule of the AWS-SNAT-CHAIN-0 chain
501
+ iptableRules = append (iptableRules , iptablesRule {
502
+ name : "last SNAT rule for non-VPC outbound traffic" ,
503
+ shouldExist : false ,
504
+ table : "nat" ,
505
+ chain : "AWS-SNAT-CHAIN-0" ,
506
+ rule : snatRule ,
507
+ })
508
+
509
+ // Force add the SNAT rule back so it is the last rule of the AWS-SNAT-CHAIN-0 chain
510
+ iptableRules = append (iptableRules , iptablesRule {
511
+ name : "last SNAT rule for non-VPC outbound traffic" ,
512
+ shouldExist : ! n .useExternalSNAT ,
513
+ table : "nat" ,
514
+ chain : "AWS-SNAT-CHAIN-0" ,
515
+ rule : snatRule ,
516
+ })
517
+
508
518
iptableRules = append (iptableRules , iptablesRule {
509
519
name : "connmark for primary ENI" ,
510
520
shouldExist : n .nodePortSupportEnabled ,
@@ -551,16 +561,15 @@ func (n *linuxNetwork) buildIptablesConnmarkRules(vpcCIDRs []string, ipt iptable
551
561
excludeCIDRs := sets .NewString (n .excludeSNATCIDRs ... )
552
562
553
563
log .Debugf ("Total CIDRs to exempt from connmark rules - %d" , len (allCIDRs ))
564
+
554
565
var chains []string
555
- for i := 0 ; i <= len (allCIDRs ); i ++ {
556
- chain := fmt .Sprintf ("AWS-CONNMARK-CHAIN-%d" , i )
557
- log .Debugf ("Setup Host Network: iptables -N %s -t nat" , chain )
558
- if err := ipt .NewChain ("nat" , chain ); err != nil && ! containChainExistErr (err ) {
559
- log .Errorf ("ipt.NewChain error for chain [%s]: %v" , chain , err )
560
- return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to add chain" )
561
- }
562
- chains = append (chains , chain )
566
+ chain := "AWS-CONNMARK-CHAIN-0"
567
+ log .Debugf ("Setup Host Network: iptables -N %s -t nat" , chain )
568
+ if err := ipt .NewChain ("nat" , chain ); err != nil && ! containChainExistErr (err ) {
569
+ log .Errorf ("ipt.NewChain error for chain [%s]: %v" , chain , err )
570
+ return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to add chain" )
563
571
}
572
+ chains = append (chains , chain )
564
573
565
574
var iptableRules []iptablesRule
566
575
log .Debugf ("Setup Host Network: iptables -t nat -A PREROUTING -i %s+ -m comment --comment \" AWS, outbound connections\" -j AWS-CONNMARK-CHAIN-0" , n .vethPrefix )
@@ -585,37 +594,25 @@ func (n *linuxNetwork) buildIptablesConnmarkRules(vpcCIDRs []string, ipt iptable
585
594
"-j" , "AWS-CONNMARK-CHAIN-0" ,
586
595
}})
587
596
588
- for i , cidr := range allCIDRs {
589
- curChain := chains [i ]
590
- curName := fmt .Sprintf ("[%d] AWS-SNAT-CHAIN" , i )
591
- nextChain := chains [i + 1 ]
597
+ for _ , cidr := range allCIDRs {
598
+ curChain := "AWS-CONNMARK-CHAIN-0"
599
+ curName := "AWS-CONNMARK-CHAIN-0"
592
600
comment := "AWS CONNMARK CHAIN, VPC CIDR"
593
601
if excludeCIDRs .Has (cidr ) {
594
602
comment = "AWS CONNMARK CHAIN, EXCLUDED CIDR"
595
603
}
596
- log .Debugf ("Setup Host Network: iptables -A %s ! -d %s -t nat -j %s" , curChain , cidr , nextChain )
604
+ log .Debugf ("Setup Host Network: iptables -A %s -d %s -t nat -j %s" , "AWS-CONNMARK-CHAIN-0" , cidr , "RETURN" )
597
605
598
606
iptableRules = append (iptableRules , iptablesRule {
599
607
name : curName ,
600
608
shouldExist : ! n .useExternalSNAT ,
601
609
table : "nat" ,
602
610
chain : curChain ,
603
611
rule : []string {
604
- "!" , " -d" , cidr , "-m" , "comment" , "--comment" , comment , "-j" , nextChain ,
612
+ "-d" , cidr , "-m" , "comment" , "--comment" , comment , "-j" , "RETURN" ,
605
613
}})
606
614
}
607
615
608
- iptableRules = append (iptableRules , iptablesRule {
609
- name : "connmark rule for external outbound traffic" ,
610
- shouldExist : ! n .useExternalSNAT ,
611
- table : "nat" ,
612
- chain : chains [len (chains )- 1 ],
613
- rule : []string {
614
- "-m" , "comment" , "--comment" , "AWS, CONNMARK" , "-j" , "CONNMARK" ,
615
- "--set-xmark" , fmt .Sprintf ("%#x/%#x" , n .mainENIMark , n .mainENIMark ),
616
- },
617
- })
618
-
619
616
// Force delete existing restore mark rule so that the subsequent rule gets added to the end
620
617
iptableRules = append (iptableRules , iptablesRule {
621
618
name : "connmark to fwmark copy" ,
@@ -647,14 +644,37 @@ func (n *linuxNetwork) buildIptablesConnmarkRules(vpcCIDRs []string, ipt iptable
647
644
}
648
645
iptableRules = append (iptableRules , connmarkStaleRules ... )
649
646
647
+ // Force delete the CONNMARK rule as we want this to be the last rule of the AWS-CONNMARK-CHAIN-0 chain
648
+ iptableRules = append (iptableRules , iptablesRule {
649
+ name : "connmark rule for external outbound traffic" ,
650
+ shouldExist : false ,
651
+ table : "nat" ,
652
+ chain : "AWS-CONNMARK-CHAIN-0" ,
653
+ rule : []string {
654
+ "-m" , "comment" , "--comment" , "AWS, CONNMARK" , "-j" , "CONNMARK" ,
655
+ "--set-xmark" , fmt .Sprintf ("%#x/%#x" , n .mainENIMark , n .mainENIMark ),
656
+ },
657
+ })
658
+
659
+ // Force add the CONNMARK rule as we want this to be the last rule of the AWS-CONNMARK-CHAIN-0 chain
660
+ iptableRules = append (iptableRules , iptablesRule {
661
+ name : "connmark rule for external outbound traffic" ,
662
+ shouldExist : ! n .useExternalSNAT ,
663
+ table : "nat" ,
664
+ chain : "AWS-CONNMARK-CHAIN-0" ,
665
+ rule : []string {
666
+ "-m" , "comment" , "--comment" , "AWS, CONNMARK" , "-j" , "CONNMARK" ,
667
+ "--set-xmark" , fmt .Sprintf ("%#x/%#x" , n .mainENIMark , n .mainENIMark ),
668
+ },
669
+ })
670
+
650
671
log .Debugf ("iptableRules: %v" , iptableRules )
651
672
return iptableRules , nil
652
673
}
653
674
654
675
func (n * linuxNetwork ) updateIptablesRules (iptableRules []iptablesRule , ipt iptableswrapper.IPTablesIface ) error {
655
676
for _ , rule := range iptableRules {
656
677
log .Debugf ("execute iptable rule : %s" , rule .name )
657
-
658
678
exists , err := ipt .Exists (rule .table , rule .chain , rule .rule ... )
659
679
log .Debugf ("rule %v exists %v, err %v" , rule , exists , err )
660
680
if err != nil {
@@ -714,14 +734,38 @@ func listCurrentIptablesRules(ipt iptableswrapper.IPTablesIface, table, chainPre
714
734
return toClear , nil
715
735
}
716
736
737
+ func (n * linuxNetwork ) cleanOldNatChains (ipt iptableswrapper.IPTablesIface ) error {
738
+ existingChains , err := ipt .ListChains ("nat" )
739
+ if err != nil {
740
+ return errors .Wrapf (err , "host network setup: failed to list iptables %s chains" , "nat" )
741
+ }
742
+ for _ , chain := range existingChains {
743
+ if ! strings .HasPrefix (chain , "AWS-CONNMARK-CHAIN" ) && ! strings .HasPrefix (chain , "AWS-SNAT-CHAIN" ) {
744
+ continue
745
+ }
746
+ parsedChain := strings .Split (chain , "-" )
747
+ num , err := strconv .Atoi (parsedChain [len (parsedChain )- 1 ])
748
+ if err == nil {
749
+ if num == 0 {
750
+ continue
751
+ }
752
+ err = ipt .DeleteChain ("nat" , chain )
753
+ if err != nil {
754
+ return errors .Wrapf (err , "Failed to delete chain %s" , chain )
755
+ }
756
+ }
757
+ }
758
+ return nil
759
+ }
760
+
717
761
func computeStaleIptablesRules (ipt iptableswrapper.IPTablesIface , table , chainPrefix string , newRules []iptablesRule , chains []string ) ([]iptablesRule , error ) {
718
762
var staleRules []iptablesRule
719
763
existingRules , err := listCurrentIptablesRules (ipt , table , chainPrefix )
720
764
if err != nil {
721
765
return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to list rules from table %s with chain prefix %s" , table , chainPrefix )
722
766
}
723
767
activeChains := sets .NewString (chains ... )
724
- log .Debugf ("Setup Host Network: computing stale iptables rules for %s table with chain prefix %s" )
768
+ log .Debugf ("Setup Host Network: computing stale iptables rules for %s table with chain prefix %s" , table , chainPrefix )
725
769
for _ , staleRule := range existingRules {
726
770
if len (staleRule .rule ) == 0 && activeChains .Has (staleRule .chain ) {
727
771
log .Debugf ("Setup Host Network: active chain found: %s" , staleRule .chain )
0 commit comments