@@ -152,6 +152,7 @@ type NetworkAPIs interface {
152
152
SetupENINetwork (eniIP string , mac string , deviceNumber int , subnetCIDR string ) error
153
153
// UpdateHostIptablesRules updates the nat table iptables rules on the host
154
154
UpdateHostIptablesRules (vpcCIDRs []string , primaryMAC string , primaryAddr * net.IP , v4Enabled bool , v6Enabled bool ) error
155
+ CleanUpStaleAWSChains (v4Enabled , v6Enabled bool ) error
155
156
UseExternalSNAT () bool
156
157
GetExcludeSNATCIDRs () []string
157
158
GetExternalServiceCIDRs () []string
@@ -375,6 +376,51 @@ func (n *linuxNetwork) UpdateHostIptablesRules(vpcCIDRs []string, primaryMAC str
375
376
return n .updateHostIptablesRules (vpcCIDRs , primaryMAC , primaryAddr , v4Enabled , v6Enabled )
376
377
}
377
378
379
+ func (n * linuxNetwork ) CleanUpStaleAWSChains (v4Enabled , v6Enabled bool ) error {
380
+ ipProtocol := iptables .ProtocolIPv4
381
+ if v6Enabled {
382
+ ipProtocol = iptables .ProtocolIPv6
383
+ }
384
+
385
+ ipt , err := n .newIptables (ipProtocol )
386
+ if err != nil {
387
+ return errors .Wrap (err , "stale chain cleanup: failed to create iptables" )
388
+ }
389
+
390
+ exists , err := ipt .ChainExists ("nat" , "AWS-SNAT-CHAIN-1" )
391
+ if err != nil {
392
+ return errors .Wrap (err , "stale chain cleanup: failed to check if AWS-SNAT-CHAIN-1 exists" )
393
+ }
394
+
395
+ if exists {
396
+ existingChains , err := ipt .ListChains ("nat" )
397
+ if err != nil {
398
+ return errors .Wrap (err , "stale chain cleanup: failed to list iptables nat chains" )
399
+ }
400
+
401
+ for _ , chain := range existingChains {
402
+ if ! strings .HasPrefix (chain , "AWS-CONNMARK-CHAIN" ) && ! strings .HasPrefix (chain , "AWS-SNAT-CHAIN" ) {
403
+ continue
404
+ }
405
+ parsedChain := strings .Split (chain , "-" )
406
+ chainNum , err := strconv .Atoi (parsedChain [len (parsedChain )- 1 ])
407
+ if err != nil {
408
+ return errors .Wrap (err , "stale chain cleanup: failed to convert string to int" )
409
+ }
410
+ // Chains 1 --> x (0 indexed) will be stale
411
+ if chainNum > 0 {
412
+ // No need to clear the chain since computeStaleIptablesRules cleans up all rules already
413
+ log .Infof ("Deleting stale chain: %s" , chain )
414
+ err := ipt .DeleteChain ("nat" , chain )
415
+ if err != nil {
416
+ return errors .Wrapf (err , "stale chain cleanup: failed to delete chain %s" , chain )
417
+ }
418
+ }
419
+ }
420
+ }
421
+ return nil
422
+ }
423
+
378
424
func (n * linuxNetwork ) updateHostIptablesRules (vpcCIDRs []string , primaryMAC string , primaryAddr * net.IP , v4Enabled bool ,
379
425
v6Enabled bool ) error {
380
426
primaryIntf , err := findPrimaryInterfaceName (primaryMAC )
@@ -434,15 +480,13 @@ func (n *linuxNetwork) buildIptablesSNATRules(vpcCIDRs []string, primaryAddr *ne
434
480
log .Debugf ("Total CIDRs to program - %d" , len (allCIDRs ))
435
481
// build IPTABLES chain for SNAT of non-VPC outbound traffic and excluded CIDRs
436
482
var chains []string
437
- for i := 0 ; i <= len (allCIDRs ); i ++ {
438
- chain := fmt .Sprintf ("AWS-SNAT-CHAIN-%d" , i )
439
- log .Debugf ("Setup Host Network: iptables -N %s -t nat" , chain )
440
- if err := ipt .NewChain ("nat" , chain ); err != nil && ! containChainExistErr (err ) {
441
- log .Errorf ("ipt.NewChain error for chain [%s]: %v" , chain , err )
442
- return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to add chain" )
443
- }
444
- chains = append (chains , chain )
483
+ chain := "AWS-SNAT-CHAIN-0"
484
+ log .Debugf ("Setup Host Network: iptables -N %s -t nat" , chain )
485
+ if err := ipt .NewChain ("nat" , chain ); err != nil && ! containChainExistErr (err ) {
486
+ log .Errorf ("ipt.NewChain error for chain [%s]: %v" , chain , err )
487
+ return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to add chain" )
445
488
}
489
+ chains = append (chains , chain )
446
490
447
491
// build SNAT rules for outbound non-VPC traffic
448
492
var iptableRules []iptablesRule
@@ -456,23 +500,20 @@ func (n *linuxNetwork) buildIptablesSNATRules(vpcCIDRs []string, primaryAddr *ne
456
500
"-m" , "comment" , "--comment" , "AWS SNAT CHAIN" , "-j" , "AWS-SNAT-CHAIN-0" ,
457
501
}})
458
502
459
- for i , cidr := range allCIDRs {
460
- curChain := chains [i ]
461
- curName := fmt .Sprintf ("[%d] AWS-SNAT-CHAIN" , i )
462
- nextChain := chains [i + 1 ]
503
+ for _ , cidr := range allCIDRs {
463
504
comment := "AWS SNAT CHAIN"
464
505
if cidr .isExclusion {
465
506
comment += " EXCLUSION"
466
507
}
467
- log .Debugf ("Setup Host Network: iptables -A %s ! -d %s -t nat -j %s" , curChain , cidr , nextChain )
508
+ log .Debugf ("Setup Host Network: iptables -A %s -d %s -t nat -j %s" , chain , cidr , "RETURN" )
468
509
469
510
iptableRules = append (iptableRules , iptablesRule {
470
- name : curName ,
511
+ name : chain ,
471
512
shouldExist : ! n .useExternalSNAT ,
472
513
table : "nat" ,
473
- chain : curChain ,
514
+ chain : chain ,
474
515
rule : []string {
475
- "!" , " -d" , cidr .cidr , "-m" , "comment" , "--comment" , comment , "-j" , nextChain ,
516
+ "-d" , cidr .cidr , "-m" , "comment" , "--comment" , comment , "-j" , "RETURN" ,
476
517
}})
477
518
}
478
519
@@ -494,22 +535,21 @@ func (n *linuxNetwork) buildIptablesSNATRules(vpcCIDRs []string, primaryAddr *ne
494
535
}
495
536
}
496
537
497
- lastChain := chains [len (chains )- 1 ]
498
- iptableRules = append (iptableRules , iptablesRule {
499
- name : "last SNAT rule for non-VPC outbound traffic" ,
500
- shouldExist : ! n .useExternalSNAT ,
501
- table : "nat" ,
502
- chain : lastChain ,
503
- rule : snatRule ,
504
- })
505
-
506
538
snatStaleRules , err := computeStaleIptablesRules (ipt , "nat" , "AWS-SNAT-CHAIN" , iptableRules , chains )
507
539
if err != nil {
508
540
return []iptablesRule {}, err
509
541
}
510
542
511
543
iptableRules = append (iptableRules , snatStaleRules ... )
512
544
545
+ iptableRules = append (iptableRules , iptablesRule {
546
+ name : "last SNAT rule for non-VPC outbound traffic" ,
547
+ shouldExist : ! n .useExternalSNAT ,
548
+ table : "nat" ,
549
+ chain : chain ,
550
+ rule : snatRule ,
551
+ })
552
+
513
553
iptableRules = append (iptableRules , iptablesRule {
514
554
name : "connmark for primary ENI" ,
515
555
shouldExist : n .nodePortSupportEnabled ,
@@ -556,16 +596,15 @@ func (n *linuxNetwork) buildIptablesConnmarkRules(vpcCIDRs []string, ipt iptable
556
596
excludeCIDRs := sets .NewString (n .excludeSNATCIDRs ... )
557
597
558
598
log .Debugf ("Total CIDRs to exempt from connmark rules - %d" , len (allCIDRs ))
599
+
559
600
var chains []string
560
- for i := 0 ; i <= len (allCIDRs ); i ++ {
561
- chain := fmt .Sprintf ("AWS-CONNMARK-CHAIN-%d" , i )
562
- log .Debugf ("Setup Host Network: iptables -N %s -t nat" , chain )
563
- if err := ipt .NewChain ("nat" , chain ); err != nil && ! containChainExistErr (err ) {
564
- log .Errorf ("ipt.NewChain error for chain [%s]: %v" , chain , err )
565
- return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to add chain" )
566
- }
567
- chains = append (chains , chain )
601
+ chain := "AWS-CONNMARK-CHAIN-0"
602
+ log .Debugf ("Setup Host Network: iptables -N %s -t nat" , chain )
603
+ if err := ipt .NewChain ("nat" , chain ); err != nil && ! containChainExistErr (err ) {
604
+ log .Errorf ("ipt.NewChain error for chain [%s]: %v" , chain , err )
605
+ return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to add chain" )
568
606
}
607
+ chains = append (chains , chain )
569
608
570
609
var iptableRules []iptablesRule
571
610
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 )
@@ -590,37 +629,23 @@ func (n *linuxNetwork) buildIptablesConnmarkRules(vpcCIDRs []string, ipt iptable
590
629
"-j" , "AWS-CONNMARK-CHAIN-0" ,
591
630
}})
592
631
593
- for i , cidr := range allCIDRs {
594
- curChain := chains [i ]
595
- curName := fmt .Sprintf ("[%d] AWS-SNAT-CHAIN" , i )
596
- nextChain := chains [i + 1 ]
632
+ for _ , cidr := range allCIDRs {
597
633
comment := "AWS CONNMARK CHAIN, VPC CIDR"
598
634
if excludeCIDRs .Has (cidr ) {
599
635
comment = "AWS CONNMARK CHAIN, EXCLUDED CIDR"
600
636
}
601
- log .Debugf ("Setup Host Network: iptables -A %s ! -d %s -t nat -j %s" , curChain , cidr , nextChain )
637
+ log .Debugf ("Setup Host Network: iptables -A %s -d %s -t nat -j %s" , chain , cidr , "RETURN" )
602
638
603
639
iptableRules = append (iptableRules , iptablesRule {
604
- name : curName ,
640
+ name : chain ,
605
641
shouldExist : ! n .useExternalSNAT ,
606
642
table : "nat" ,
607
- chain : curChain ,
643
+ chain : chain ,
608
644
rule : []string {
609
- "!" , " -d" , cidr , "-m" , "comment" , "--comment" , comment , "-j" , nextChain ,
645
+ "-d" , cidr , "-m" , "comment" , "--comment" , comment , "-j" , "RETURN" ,
610
646
}})
611
647
}
612
648
613
- iptableRules = append (iptableRules , iptablesRule {
614
- name : "connmark rule for external outbound traffic" ,
615
- shouldExist : ! n .useExternalSNAT ,
616
- table : "nat" ,
617
- chain : chains [len (chains )- 1 ],
618
- rule : []string {
619
- "-m" , "comment" , "--comment" , "AWS, CONNMARK" , "-j" , "CONNMARK" ,
620
- "--set-xmark" , fmt .Sprintf ("%#x/%#x" , n .mainENIMark , n .mainENIMark ),
621
- },
622
- })
623
-
624
649
// Force delete existing restore mark rule so that the subsequent rule gets added to the end
625
650
iptableRules = append (iptableRules , iptablesRule {
626
651
name : "connmark to fwmark copy" ,
@@ -652,14 +677,24 @@ func (n *linuxNetwork) buildIptablesConnmarkRules(vpcCIDRs []string, ipt iptable
652
677
}
653
678
iptableRules = append (iptableRules , connmarkStaleRules ... )
654
679
680
+ iptableRules = append (iptableRules , iptablesRule {
681
+ name : "connmark rule for external outbound traffic" ,
682
+ shouldExist : ! n .useExternalSNAT ,
683
+ table : "nat" ,
684
+ chain : chain ,
685
+ rule : []string {
686
+ "-m" , "comment" , "--comment" , "AWS, CONNMARK" , "-j" , "CONNMARK" ,
687
+ "--set-xmark" , fmt .Sprintf ("%#x/%#x" , n .mainENIMark , n .mainENIMark ),
688
+ },
689
+ })
690
+
655
691
log .Debugf ("iptableRules: %v" , iptableRules )
656
692
return iptableRules , nil
657
693
}
658
694
659
695
func (n * linuxNetwork ) updateIptablesRules (iptableRules []iptablesRule , ipt iptableswrapper.IPTablesIface ) error {
660
696
for _ , rule := range iptableRules {
661
697
log .Debugf ("execute iptable rule : %s" , rule .name )
662
-
663
698
exists , err := ipt .Exists (rule .table , rule .chain , rule .rule ... )
664
699
log .Debugf ("rule %v exists %v, err %v" , rule , exists , err )
665
700
if err != nil {
@@ -668,10 +703,19 @@ func (n *linuxNetwork) updateIptablesRules(iptableRules []iptablesRule, ipt ipta
668
703
}
669
704
670
705
if ! exists && rule .shouldExist {
671
- err = ipt .Append (rule .table , rule .chain , rule .rule ... )
672
- if err != nil {
673
- log .Errorf ("host network setup: failed to add %v, %v" , rule , err )
674
- return errors .Wrapf (err , "host network setup: failed to add %v" , rule )
706
+ if rule .name == "AWS-CONNMARK-CHAIN-0" || rule .name == "AWS-SNAT-CHAIN-0" {
707
+ // All CIDR rules must go before the SNAT/Mark rule
708
+ err = ipt .Insert (rule .table , rule .chain , 1 , rule .rule ... )
709
+ if err != nil {
710
+ log .Errorf ("host network setup: failed to insert %v, %v" , rule , err )
711
+ return errors .Wrapf (err , "host network setup: failed to add %v" , rule )
712
+ }
713
+ } else {
714
+ err = ipt .Append (rule .table , rule .chain , rule .rule ... )
715
+ if err != nil {
716
+ log .Errorf ("host network setup: failed to add %v, %v" , rule , err )
717
+ return errors .Wrapf (err , "host network setup: failed to add %v" , rule )
718
+ }
675
719
}
676
720
} else if exists && ! rule .shouldExist {
677
721
err = ipt .Delete (rule .table , rule .chain , rule .rule ... )
@@ -726,7 +770,7 @@ func computeStaleIptablesRules(ipt iptableswrapper.IPTablesIface, table, chainPr
726
770
return []iptablesRule {}, errors .Wrapf (err , "host network setup: failed to list rules from table %s with chain prefix %s" , table , chainPrefix )
727
771
}
728
772
activeChains := sets .NewString (chains ... )
729
- log .Debugf ("Setup Host Network: computing stale iptables rules for %s table with chain prefix %s" )
773
+ log .Debugf ("Setup Host Network: computing stale iptables rules for %s table with chain prefix %s" , table , chainPrefix )
730
774
for _ , staleRule := range existingRules {
731
775
if len (staleRule .rule ) == 0 && activeChains .Has (staleRule .chain ) {
732
776
log .Debugf ("Setup Host Network: active chain found: %s" , staleRule .chain )
0 commit comments