Skip to content

Commit

Permalink
Add environment option to disable installation of SNAT
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Brockbank committed Jun 28, 2018
1 parent f649a86 commit cb1fc9b
Showing 1 changed file with 34 additions and 3 deletions.
37 changes: 34 additions & 3 deletions pkg/networkutils/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ package networkutils

import (
"net"
"os"
"strconv"
"strings"
"syscall"

Expand Down Expand Up @@ -42,6 +44,11 @@ const (
fromPodRulePriority = 1536

mainRoutingTable = 254

// This environment is used to specify whether an external NAT gateway will be used to provide SNAT of
// secondary ENI IP addresses. If set to "true", the SNAT iptables rule and off-VPC ip rule will not
// be installed and will be removed if they are already installed.
envExternalSNAT = "AWS_VPC_K8S_CNI_EXTERNALSNAT"
)

// NetworkAPIs defines the host level and the eni level network related operations
Expand All @@ -67,17 +74,18 @@ func isDuplicateRuleAdd(err error) bool {
return strings.Contains(err.Error(), "File exists")
}

// SetupNodeNetwork performs node level network configuration
// SetupHostNetwork performs node level network configuration
// TODO : implement ip rule not to 10.0.0.0/16(vpc'subnet) table main priority 1024
func (os *linuxNetwork) SetupHostNetwork(vpcCIDR *net.IPNet, primaryAddr *net.IP) error {

externalSNAT := useExternalSNAT()
hostRule := os.netLink.NewRule()
hostRule.Dst = vpcCIDR
hostRule.Table = mainRoutingTable
hostRule.Priority = hostRulePriority
hostRule.Invert = true

// if this is a restart, cleanup previous rule first
// If this is a restart, cleanup previous rule first
err := os.netLink.RuleDel(hostRule)
if err != nil && !containsNoSuchRule(err) {
log.Errorf("Failed to cleanup old host IP rule: %v", err)
Expand Down Expand Up @@ -105,12 +113,20 @@ func (os *linuxNetwork) SetupHostNetwork(vpcCIDR *net.IPNet, primaryAddr *net.IP
return errors.Wrapf(err, "host network setup: failed to add POSTROUTING rule for primary address %s", primaryAddr)
}

if !exists {
if !exists && !externalSNAT {
// We are handling SNAT on-node, so include the iptables SNAT POSTROUTING rule.
err = ipt.Append("nat", "POSTROUTING", natCmd...)

if err != nil {
return errors.Wrapf(err, "host network setup: failed to append POSTROUTING rule for primary address %s", primaryAddr)
}
} else if exists && externalSNAT {
// We are not handling SNAT on-node, so delete the existing iptables SNAT POSTROUTING rule.
err = ipt.Delete("nat", "POSTROUTING", natCmd...)

if err != nil {
return errors.Wrapf(err, "host network setup: failed to delete POSTROUTING rule for primary address %s", primaryAddr)
}
}

return nil
Expand All @@ -123,6 +139,21 @@ func containsNoSuchRule(err error) bool {
return false
}

// useExternalSNAT returns whether SNAT of secondary ENI IPs should be handled with an external
// NAT gateway rather than on node. Failure to parse the setting will result in a log and the
// setting will be disabled.
func useExternalSNAT() bool {
if externalSNATStr := os.Getenv(envExternalSNAT); externalSNATStr != "" {
externalSNAT, err := strconv.ParseBool(externalSNATStr)
if err != nil {
log.Error("Failed to parse "+envExternalSNAT, err.Error())
return false
}
return externalSNAT
}
return false
}

// LinkByMac returns linux netlink based on interface MAC
func LinkByMac(mac string, netLink netlinkwrapper.NetLink) (netlink.Link, error) {
links, err := netLink.LinkList()
Expand Down

0 comments on commit cb1fc9b

Please sign in to comment.