@@ -11,18 +11,28 @@ import (
1111 "github.com/Azure/azure-container-networking/iptables"
1212 "github.com/Azure/azure-container-networking/network/networkutils"
1313 goiptables "github.com/coreos/go-iptables/iptables"
14+ "github.com/pkg/errors"
1415)
1516
1617const SWIFT = "SWIFT-POSTROUTING"
1718
19+ type IPtablesProvider struct {}
20+
21+ func (c * IPtablesProvider ) GetIPTables () (iptablesClient , error ) {
22+ client , err := goiptables .New ()
23+ return client , errors .Wrap (err , "failed to get iptables client" )
24+ }
25+
1826// nolint
1927func (service * HTTPRestService ) programSNATRules (req * cns.CreateNetworkContainerRequest ) (types.ResponseCode , string ) {
2028 service .Lock ()
2129 defer service .Unlock ()
2230
2331 // Parse primary ip and ipnet from nnc
24- ncPrimaryIP , ncIPNet , _ := net .ParseCIDR (req .IPConfiguration .IPSubnet .IPAddress + "/" + fmt .Sprintf ("%d" , req .IPConfiguration .IPSubnet .PrefixLength ))
25- ipt , err := goiptables .New ()
32+ // in podsubnet case, ncPrimaryIP is the pod subnet's primary ip
33+ // in vnet scale case, ncPrimaryIP is the node's ip
34+ ncPrimaryIP , _ , _ := net .ParseCIDR (req .IPConfiguration .IPSubnet .IPAddress + "/" + fmt .Sprintf ("%d" , req .IPConfiguration .IPSubnet .PrefixLength ))
35+ ipt , err := service .iptables .GetIPTables ()
2636 if err != nil {
2737 return types .UnexpectedError , fmt .Sprintf ("[Azure CNS] Error. Failed to create iptables interface : %v" , err )
2838 }
@@ -56,41 +66,51 @@ func (service *HTTPRestService) programSNATRules(req *cns.CreateNetworkContainer
5666 }
5767 }
5868
59- snatUDPRuleexist , err := ipt .Exists (iptables .Nat , SWIFT , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , ncIPNet .String (), "-d" , networkutils .AzureDNS , "-p" , iptables .UDP , "--dport" , strconv .Itoa (iptables .DNSPort ), "-j" , iptables .Snat , "--to" , ncPrimaryIP .String ())
60- if err != nil {
61- return types .UnexpectedError , fmt .Sprintf ("[Azure CNS] Error. Failed to check for existence of SNAT UDP rule : %v" , err )
62- }
63- if ! snatUDPRuleexist {
64- logger .Printf ("[Azure CNS] Inserting SNAT UDP rule ..." )
65- err = ipt .Insert (iptables .Nat , SWIFT , 1 , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , ncIPNet .String (), "-d" , networkutils .AzureDNS , "-p" , iptables .UDP , "--dport" , strconv .Itoa (iptables .DNSPort ), "-j" , iptables .Snat , "--to" , ncPrimaryIP .String ())
69+ // use any secondary ip + the nnc prefix length to get an iptables rule to allow dns and imds traffic from the pods
70+ for _ , v := range req .SecondaryIPConfigs {
71+ // put the ip address in standard cidr form (where we zero out the parts that are not relevant)
72+ _ , podSubnet , _ := net .ParseCIDR (v .IPAddress + "/" + fmt .Sprintf ("%d" , req .IPConfiguration .IPSubnet .PrefixLength ))
73+
74+ snatUDPRuleExists , err := ipt .Exists (iptables .Nat , SWIFT , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , podSubnet .String (), "-d" , networkutils .AzureDNS , "-p" , iptables .UDP , "--dport" , strconv .Itoa (iptables .DNSPort ), "-j" , iptables .Snat , "--to" , ncPrimaryIP .String ())
6675 if err != nil {
67- return types .FailedToRunIPTableCmd , "[Azure CNS] failed to inset SNAT UDP rule : " + err .Error ()
76+ return types .UnexpectedError , fmt .Sprintf ("[Azure CNS] Error. Failed to check for existence of pod SNAT UDP rule : %v" , err )
77+ }
78+ if ! snatUDPRuleExists {
79+ logger .Printf ("[Azure CNS] Inserting pod SNAT UDP rule ..." )
80+ err = ipt .Insert (iptables .Nat , SWIFT , 1 , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , podSubnet .String (), "-d" , networkutils .AzureDNS , "-p" , iptables .UDP , "--dport" , strconv .Itoa (iptables .DNSPort ), "-j" , iptables .Snat , "--to" , ncPrimaryIP .String ())
81+ if err != nil {
82+ return types .FailedToRunIPTableCmd , "[Azure CNS] failed to insert pod SNAT UDP rule : " + err .Error ()
83+ }
6884 }
69- }
7085
71- snatTCPRuleexist , err := ipt .Exists (iptables .Nat , SWIFT , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , ncIPNet .String (), "-d" , networkutils .AzureDNS , "-p" , iptables .TCP , "--dport" , strconv .Itoa (iptables .DNSPort ), "-j" , iptables .Snat , "--to" , ncPrimaryIP .String ())
72- if err != nil {
73- return types .UnexpectedError , fmt .Sprintf ("[Azure CNS] Error. Failed to check for existence of SNAT TCP rule : %v" , err )
74- }
75- if ! snatTCPRuleexist {
76- logger .Printf ("[Azure CNS] Inserting SNAT TCP rule ..." )
77- err = ipt .Insert (iptables .Nat , SWIFT , 1 , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , ncIPNet .String (), "-d" , networkutils .AzureDNS , "-p" , iptables .TCP , "--dport" , strconv .Itoa (iptables .DNSPort ), "-j" , iptables .Snat , "--to" , ncPrimaryIP .String ())
86+ snatPodTCPRuleExists , err := ipt .Exists (iptables .Nat , SWIFT , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , podSubnet .String (), "-d" , networkutils .AzureDNS , "-p" , iptables .TCP , "--dport" , strconv .Itoa (iptables .DNSPort ), "-j" , iptables .Snat , "--to" , ncPrimaryIP .String ())
7887 if err != nil {
79- return types .FailedToRunIPTableCmd , "[Azure CNS] failed to insert SNAT TCP rule : " + err .Error ()
88+ return types .UnexpectedError , fmt .Sprintf ("[Azure CNS] Error. Failed to check for existence of pod SNAT TCP rule : %v" , err )
89+ }
90+ if ! snatPodTCPRuleExists {
91+ logger .Printf ("[Azure CNS] Inserting pod SNAT TCP rule ..." )
92+ err = ipt .Insert (iptables .Nat , SWIFT , 1 , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , podSubnet .String (), "-d" , networkutils .AzureDNS , "-p" , iptables .TCP , "--dport" , strconv .Itoa (iptables .DNSPort ), "-j" , iptables .Snat , "--to" , ncPrimaryIP .String ())
93+ if err != nil {
94+ return types .FailedToRunIPTableCmd , "[Azure CNS] failed to insert pod SNAT TCP rule : " + err .Error ()
95+ }
8096 }
81- }
8297
83- snatIMDSRuleexist , err := ipt .Exists (iptables .Nat , SWIFT , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , ncIPNet .String (), "-d" , networkutils .AzureIMDS , "-p" , iptables .TCP , "--dport" , strconv .Itoa (iptables .HTTPPort ), "-j" , iptables .Snat , "--to" , req .HostPrimaryIP )
84- if err != nil {
85- return types .UnexpectedError , fmt .Sprintf ("[Azure CNS] Error. Failed to check for existence of SNAT IMDS rule : %v" , err )
86- }
87- if ! snatIMDSRuleexist {
88- logger .Printf ("[Azure CNS] Inserting SNAT IMDS rule ..." )
89- err = ipt .Insert (iptables .Nat , SWIFT , 1 , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , ncIPNet .String (), "-d" , networkutils .AzureIMDS , "-p" , iptables .TCP , "--dport" , strconv .Itoa (iptables .HTTPPort ), "-j" , iptables .Snat , "--to" , req .HostPrimaryIP )
98+ snatIMDSRuleexist , err := ipt .Exists (iptables .Nat , SWIFT , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , podSubnet .String (), "-d" , networkutils .AzureIMDS , "-p" , iptables .TCP , "--dport" , strconv .Itoa (iptables .HTTPPort ), "-j" , iptables .Snat , "--to" , req .HostPrimaryIP )
9099 if err != nil {
91- return types .FailedToRunIPTableCmd , "[Azure CNS] failed to insert SNAT IMDS rule : " + err .Error ()
100+ return types .UnexpectedError , fmt .Sprintf ("[Azure CNS] Error. Failed to check for existence of pod SNAT IMDS rule : %v" , err )
101+ }
102+ if ! snatIMDSRuleexist {
103+ logger .Printf ("[Azure CNS] Inserting pod SNAT IMDS rule ..." )
104+ err = ipt .Insert (iptables .Nat , SWIFT , 1 , "-m" , "addrtype" , "!" , "--dst-type" , "local" , "-s" , podSubnet .String (), "-d" , networkutils .AzureIMDS , "-p" , iptables .TCP , "--dport" , strconv .Itoa (iptables .HTTPPort ), "-j" , iptables .Snat , "--to" , req .HostPrimaryIP )
105+ if err != nil {
106+ return types .FailedToRunIPTableCmd , "[Azure CNS] failed to insert pod SNAT IMDS rule : " + err .Error ()
107+ }
92108 }
109+
110+ // we only need to run this code once as the iptable rule applies to all secondary ip configs in the same subnet
111+ break
93112 }
113+
94114 return types .Success , ""
95115}
96116
0 commit comments