Skip to content

Commit 8779700

Browse files
authored
Fix CNS Program iptables for delegated IPAM (#1499)
* rebase * rebase * rebase * adding snat iptables rules using coreos lib * fix iptables cmd not running * docs * added conflist back * change chain name from SWIFT to SWIFT-POSTROUTING * update go.mod * split internalapi into linux and windows * add imports * fix iptables programming login * fix iptables programming logic * change program iptables rules logic
1 parent 8b5e167 commit 8779700

File tree

8 files changed

+114
-61
lines changed

8 files changed

+114
-61
lines changed

azure-ipam/azilium.conflist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
"log-file": "/var/log/cilium-cni.log"
1212
}
1313
]
14-
}
14+
}

cns/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ COPY . .
1010
RUN CGO_ENABLED=0 go build -a -o /usr/local/bin/azure-cns -ldflags "-X main.version="$VERSION" -X "$CNS_AI_PATH"="$CNS_AI_ID"" -gcflags="-dwarflocationlists=true" cns/service/*.go
1111
RUN CGO_ENABLED=0 go build -a -o /usr/local/bin/azure-vnet-telemetry -ldflags "-X main.version="$VERSION"" -gcflags="-dwarflocationlists=true" cni/telemetry/service/*.go
1212

13-
FROM scratch
13+
FROM mcr.microsoft.com/cbl-mariner/base/core:2.0
14+
RUN tdnf install -y iptables
1415
COPY --from=builder /etc/passwd /etc/passwd
1516
COPY --from=builder /etc/group /etc/group
1617
COPY --from=builder /usr/local/bin/azure-cns \

cns/restserver/internalapi.go

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"context"
99
"encoding/json"
1010
"fmt"
11-
"net"
1211
"net/http"
1312
"net/http/httptest"
1413
"reflect"
@@ -21,8 +20,6 @@ import (
2120
"github.com/Azure/azure-container-networking/cns/types"
2221
"github.com/Azure/azure-container-networking/common"
2322
"github.com/Azure/azure-container-networking/crd/nodenetworkconfig/api/v1alpha"
24-
"github.com/Azure/azure-container-networking/iptables"
25-
"github.com/Azure/azure-container-networking/network/networkutils"
2623
"github.com/pkg/errors"
2724
)
2825

@@ -364,64 +361,11 @@ func (service *HTTPRestService) CreateOrUpdateNetworkContainerInternal(req *cns.
364361
}
365362

366363
if service.Options[common.OptProgramSNATIPTables] == true {
367-
returnCode, returnMessage = service.programSNATIPTableRules(req)
364+
returnCode, returnMessage = service.programSNATRules(req)
368365
if returnCode != 0 {
369366
logger.Errorf(returnMessage)
370367
}
371368
}
372369

373370
return returnCode
374371
}
375-
376-
// nolint
377-
func (service *HTTPRestService) programSNATIPTableRules(req *cns.CreateNetworkContainerRequest) (types.ResponseCode, string) {
378-
service.Lock()
379-
defer service.Unlock()
380-
381-
if service.programmedIPtables { // check if iptables has already been programmed
382-
logger.Printf("[Azure CNS] SNAT IPTables rules already programmed")
383-
return types.Success, ""
384-
}
385-
386-
ncPrimaryIP, ncIPNet, _ := net.ParseCIDR(req.IPConfiguration.IPSubnet.IPAddress + "/" + fmt.Sprintf("%d", req.IPConfiguration.IPSubnet.PrefixLength))
387-
388-
azureDNSUDPMatch := fmt.Sprintf(" -m addrtype ! --dst-type local -s %s -d %s -p %s --dport %d", ncIPNet.String(), networkutils.AzureDNS, iptables.UDP, iptables.DNSPort)
389-
azureDNSTCPMatch := fmt.Sprintf(" -m addrtype ! --dst-type local -s %s -d %s -p %s --dport %d", ncIPNet.String(), networkutils.AzureDNS, iptables.TCP, iptables.DNSPort)
390-
azureIMDSMatch := fmt.Sprintf(" -m addrtype ! --dst-type local -s %s -d %s -p %s --dport %d", ncIPNet.String(), networkutils.AzureIMDS, iptables.TCP, iptables.HTTPPort)
391-
392-
snatPrimaryIPJump := fmt.Sprintf("%s --to %s", iptables.Snat, ncPrimaryIP)
393-
// we need to snat IMDS traffic to node IP, this sets up snat '--to'
394-
snatHostIPJump := fmt.Sprintf("%s --to %s", iptables.Snat, req.HostPrimaryIP)
395-
396-
// Check if iptables rules exist already
397-
if iptables.RuleExists(iptables.V4, iptables.Nat, iptables.Postrouting, "", iptables.Swift) &&
398-
iptables.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureDNSUDPMatch, snatPrimaryIPJump) &&
399-
iptables.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureDNSTCPMatch, snatPrimaryIPJump) &&
400-
iptables.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureIMDSMatch, snatHostIPJump) {
401-
402-
logger.Printf("[Azure CNS] SNAT IPTables rules already programmed")
403-
service.programmedIPtables = true
404-
return types.Success, ""
405-
}
406-
407-
cmds := []iptables.IPTableEntry{
408-
iptables.GetCreateChainCmd(iptables.V4, iptables.Nat, iptables.Swift),
409-
iptables.GetAppendIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Postrouting, "", iptables.Swift),
410-
// add a snat rules to primary NC IP for DNS
411-
iptables.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureDNSUDPMatch, snatPrimaryIPJump),
412-
iptables.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureDNSTCPMatch, snatPrimaryIPJump),
413-
// add a snat rule to node IP for IMDS http traffic
414-
iptables.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureIMDSMatch, snatHostIPJump),
415-
}
416-
417-
logger.Printf("Adding iptable rules...")
418-
for _, cmd := range cmds {
419-
err := iptables.RunCmd(cmd.Version, cmd.Params)
420-
if err != nil {
421-
return types.FailedToRunIPTableCmd, "failed to run iptable cmd: " + err.Error()
422-
}
423-
logger.Printf("Successfully run iptables rule %v", cmd)
424-
}
425-
426-
return types.Success, ""
427-
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package restserver
2+
3+
import (
4+
"fmt"
5+
"net"
6+
"strconv"
7+
8+
"github.com/Azure/azure-container-networking/cns"
9+
"github.com/Azure/azure-container-networking/cns/logger"
10+
"github.com/Azure/azure-container-networking/cns/types"
11+
"github.com/Azure/azure-container-networking/iptables"
12+
"github.com/Azure/azure-container-networking/network/networkutils"
13+
goiptables "github.com/coreos/go-iptables/iptables"
14+
)
15+
16+
const SWIFT = "SWIFT-POSTROUTING"
17+
18+
// nolint
19+
func (service *HTTPRestService) programSNATRules(req *cns.CreateNetworkContainerRequest) (types.ResponseCode, string) {
20+
service.Lock()
21+
defer service.Unlock()
22+
23+
// 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()
26+
if err != nil {
27+
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to create iptables interface : %v", err)
28+
}
29+
30+
chainExist, err := ipt.ChainExists(iptables.Nat, SWIFT)
31+
if err != nil {
32+
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to check for existence of SWIFT chain: %v", err)
33+
}
34+
if !chainExist { // create and append chain if it doesn't exist
35+
logger.Printf("[Azure CNS] Creating SWIFT Chain ...")
36+
err = ipt.NewChain(iptables.Nat, SWIFT)
37+
if err != nil {
38+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to create SWIFT chain : " + err.Error()
39+
}
40+
logger.Printf("[Azure CNS] Append SWIFT Chain to POSTROUTING ...")
41+
err = ipt.Append(iptables.Nat, iptables.Postrouting, "-j", SWIFT)
42+
if err != nil {
43+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to append SWIFT chain : " + err.Error()
44+
}
45+
}
46+
47+
postroutingToSwiftJumpexist, err := ipt.Exists(iptables.Nat, iptables.Postrouting, "-j", SWIFT)
48+
if err != nil {
49+
return types.UnexpectedError, fmt.Sprintf("[Azure CNS] Error. Failed to check for existence of POSTROUTING to SWIFT chain jump: %v", err)
50+
}
51+
if !postroutingToSwiftJumpexist {
52+
logger.Printf("[Azure CNS] Append SWIFT Chain to POSTROUTING ...")
53+
err = ipt.Append(iptables.Nat, iptables.Postrouting, "-j", SWIFT)
54+
if err != nil {
55+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to append SWIFT chain : " + err.Error()
56+
}
57+
}
58+
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())
66+
if err != nil {
67+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to inset SNAT UDP rule : " + err.Error()
68+
}
69+
}
70+
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())
78+
if err != nil {
79+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to insert SNAT TCP rule : " + err.Error()
80+
}
81+
}
82+
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)
90+
if err != nil {
91+
return types.FailedToRunIPTableCmd, "[Azure CNS] failed to insert SNAT IMDS rule : " + err.Error()
92+
}
93+
}
94+
return types.Success, ""
95+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package restserver
2+
3+
import (
4+
"github.com/Azure/azure-container-networking/cns"
5+
"github.com/Azure/azure-container-networking/cns/types"
6+
)
7+
8+
// nolint
9+
func (service *HTTPRestService) programSNATRules(req *cns.CreateNetworkContainerRequest) (types.ResponseCode, string) {
10+
return types.Success, ""
11+
}

cns/restserver/restserver.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ type HTTPRestService struct {
5858
state *httpRestServiceState
5959
podsPendingIPAssignment *bounded.TimedSet
6060
sync.RWMutex
61-
dncPartitionKey string
62-
programmedIPtables bool
61+
dncPartitionKey string
6362
}
6463

6564
type GetHTTPServiceDataResponse struct {

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ require (
5555
github.com/beorn7/perks v1.0.1 // indirect
5656
github.com/cespare/xxhash/v2 v2.1.2 // indirect
5757
github.com/containerd/cgroups v1.0.1 // indirect
58+
github.com/coreos/go-iptables v0.6.0
5859
github.com/davecgh/go-spew v1.1.1 // indirect
5960
github.com/docker/docker v20.10.8+incompatible // indirect
6061
github.com/docker/go-connections v0.4.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
241241
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
242242
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
243243
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
244+
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
245+
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
244246
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
245247
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
246248
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=

0 commit comments

Comments
 (0)