Skip to content

Commit

Permalink
Add MTU to the plugin config
Browse files Browse the repository at this point in the history
  • Loading branch information
Claes Mogren committed Oct 24, 2019
1 parent 9cc2a27 commit 3e13f7c
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 44 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,18 @@ is not used, and the maximum number of ENIs is always equal to the maximum numbe

---

`AWS_VPC_K8S_CNI_LOGLEVEL`

Type: String

Default: `DEBUG`

Valid Values: `trace`, `debug`, `info`, `warn`, `error`, `critical` or `off`. (Not case sensitive)

Specifies the loglevel for ipamd.

---

`AWS_VPC_K8S_CNI_LOG_FILE`

Type: String
Expand Down Expand Up @@ -298,7 +310,7 @@ on `:61678/metrics`.

Type: String

Default: `eni`
Default: `veth`

Specifies the veth prefix used to generate the host-side veth device name for the CNI. The prefix can be at most 4 characters long.

Expand Down
3 changes: 2 additions & 1 deletion misc/10-aws.conflist
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
{
"name": "aws-cni",
"type": "aws-cni",
"vethPrefix": "__VETHPREFIX__"
"vethPrefix": "__VETHPREFIX__",
"mtu": "__MTU__"
},
{
"type": "portmap",
Expand Down
22 changes: 18 additions & 4 deletions pkg/networkutils/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func New() NetworkAPIs {
typeOfSNAT: typeOfSNAT(),
nodePortSupportEnabled: nodePortSupportEnabled(),
mainENIMark: getConnmark(),
mtu: GetEthernetMTU(),
mtu: GetEthernetMTU(""),

netLink: netlinkwrapper.NewNetLink(),
ns: nswrapper.NewNS(),
Expand Down Expand Up @@ -247,6 +247,16 @@ func (n *linuxNetwork) SetupHostNetwork(vpcCIDR *net.IPNet, vpcCIDRs []*string,
}
}

if n.mtu != maximumMTU {
link, err := LinkByMac(primaryMAC, n.netLink, retryLinkByMacInterval)
if err != nil {
return errors.Wrapf(err, "setupHostNetwork: failed to find the link primary ENI with MAC address %s", primaryMAC)
}
if err = n.netLink.LinkSetMTU(link, n.mtu); err != nil {
return errors.Wrapf(err, "setupHostNetwork: failed to set MTU to %d for %s", n.mtu, primaryIntf)
}
}

// If node port support is enabled, add a rule that will force force marked traffic out of the main ENI. We then
// add iptables rules below that will mark traffic that needs this special treatment. In particular NodePort
// traffic always comes in via the main ENI but response traffic would go out of the pod's assigned ENI if we
Expand Down Expand Up @@ -936,9 +946,13 @@ func (n *linuxNetwork) UpdateRuleListBySrc(ruleList []netlink.Rule, src net.IPNe
return nil
}

// GetEthernetMTU gets the MTU setting from AWS_VPC_ENI_MTU, or defaults to 9001 if not set.
func GetEthernetMTU() int {
if envMTUValue := os.Getenv(envMTU); envMTUValue != "" {
// GetEthernetMTU gets the MTU setting from AWS_VPC_ENI_MTU if set, or takes the passed in string. Defaults to 9001 if not set.
func GetEthernetMTU(envMTUValue string) int {
inputStr, found := os.LookupEnv(envMTU)
if found {
envMTUValue = inputStr
}
if envMTUValue != "" {
mtu, err := strconv.Atoi(envMTUValue)
if err != nil {
log.Errorf("Failed to parse %s will use %d: %v", envMTU, maximumMTU, err.Error())
Expand Down
17 changes: 11 additions & 6 deletions pkg/networkutils/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ func TestSetupHostNetworkNodePortDisabled(t *testing.T) {

ln := &linuxNetwork{
mainENIMark: 0x80,

netLink: mockNetLink,
ns: mockNS,
mtu: testMTU,
netLink: mockNetLink,
ns: mockNS,
newIptables: func() (iptablesIface, error) {
return mockIptables, nil
},
Expand Down Expand Up @@ -267,6 +267,7 @@ func TestSetupHostNetworkNodePortEnabled(t *testing.T) {
useExternalSNAT: true,
nodePortSupportEnabled: true,
mainENIMark: defaultConnmark,
mtu: testMTU,

netLink: mockNetLink,
ns: mockNS,
Expand Down Expand Up @@ -316,17 +317,17 @@ func TestSetupHostNetworkNodePortEnabled(t *testing.T) {

func TestLoadMTUFromEnvTooLow(t *testing.T) {
_ = os.Setenv(envMTU, "1")
assert.Equal(t, GetEthernetMTU(), minimumMTU)
assert.Equal(t, GetEthernetMTU(""), minimumMTU)
}

func TestLoadMTUFromEnv1500(t *testing.T) {
_ = os.Setenv(envMTU, "1500")
assert.Equal(t, GetEthernetMTU(), 1500)
assert.Equal(t, GetEthernetMTU(""), 1500)
}

func TestLoadMTUFromEnvTooHigh(t *testing.T) {
_ = os.Setenv(envMTU, "65536")
assert.Equal(t, GetEthernetMTU(), maximumMTU)
assert.Equal(t, GetEthernetMTU(""), maximumMTU)
}

func TestLoadExcludeSNATCIDRsFromEnv(t *testing.T) {
Expand All @@ -347,6 +348,7 @@ func TestSetupHostNetworkWithExcludeSNATCIDRs(t *testing.T) {
excludeSNATCIDRs: []string{"10.12.0.0/16", "10.13.0.0/16"},
nodePortSupportEnabled: true,
mainENIMark: defaultConnmark,
mtu: testMTU,

netLink: mockNetLink,
ns: mockNS,
Expand Down Expand Up @@ -398,6 +400,7 @@ func TestSetupHostNetworkCleansUpStaleSNATRules(t *testing.T) {
excludeSNATCIDRs: nil,
nodePortSupportEnabled: true,
mainENIMark: defaultConnmark,
mtu: testMTU,

netLink: mockNetLink,
ns: mockNS,
Expand Down Expand Up @@ -457,6 +460,7 @@ func TestSetupHostNetworkExcludedSNATCIDRsIdempotent(t *testing.T) {
excludeSNATCIDRs: []string{"10.12.0.0/16", "10.13.0.0/16"},
nodePortSupportEnabled: true,
mainENIMark: defaultConnmark,
mtu: testMTU,

netLink: mockNetLink,
ns: mockNS,
Expand Down Expand Up @@ -515,6 +519,7 @@ func TestSetupHostNetworkMultipleCIDRs(t *testing.T) {
useExternalSNAT: true,
nodePortSupportEnabled: true,
mainENIMark: defaultConnmark,
mtu: testMTU,

netLink: mockNetLink,
ns: mockNS,
Expand Down
14 changes: 13 additions & 1 deletion plugins/routed-eni/cni.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"os"
"runtime"

"github.com/aws/amazon-vpc-cni-k8s/pkg/networkutils"

"golang.org/x/net/context"
"google.golang.org/grpc"

Expand Down Expand Up @@ -67,6 +69,9 @@ type NetConf struct {
// veth device name. It should be no more than four characters, and
// defaults to 'eni'.
VethPrefix string `json:"vethPrefix"`

// MTU for eth0
Mtu string `json:"mtu"`
}

// K8sArgs is the valid CNI_ARGS used for Kubernetes
Expand Down Expand Up @@ -121,6 +126,13 @@ func add(args *skel.CmdArgs, cniTypes typeswrapper.CNITYPES, grpcClient grpcwrap
return errors.New("conf.VethPrefix can be at most 4 characters long")
}

// MTU
if conf.Mtu == "" {
log.Debug("MTU not set, defaulting to 9001")
conf.Mtu = "9001"
}
mtu := networkutils.GetEthernetMTU(conf.Mtu)

cniVersion := conf.CNIVersion

// Set up a connection to the ipamD server.
Expand Down Expand Up @@ -175,7 +187,7 @@ func add(args *skel.CmdArgs, cniTypes typeswrapper.CNITYPES, grpcClient grpcwrap
// Note: the maximum length for linux interface name is 15
hostVethName := generateHostVethName(conf.VethPrefix, string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME))

err = driverClient.SetupNS(hostVethName, args.IfName, args.Netns, addr, int(r.DeviceNumber), r.VPCcidrs, r.UseExternalSNAT)
err = driverClient.SetupNS(hostVethName, args.IfName, args.Netns, addr, int(r.DeviceNumber), r.VPCcidrs, r.UseExternalSNAT, mtu)

if err != nil {
log.Errorf("Failed SetupPodNetwork for pod %s namespace %s container %s: %v",
Expand Down
24 changes: 10 additions & 14 deletions plugins/routed-eni/cni_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,8 @@ func setup(t *testing.T) (*gomock.Controller,
mock_driver.NewMockNetworkAPIs(ctrl)
}

type RPCCONN interface {
Close() error
}

type rpcConn struct{}

func NewRPCCONN() RPCCONN {
return &rpcConn{}
}

func (*rpcConn) Close() error {
return nil
}
Expand Down Expand Up @@ -101,11 +93,12 @@ func TestCmdAdd(t *testing.T) {
}

mocksNetwork.EXPECT().SetupNS(gomock.Any(), cmdArgs.IfName, cmdArgs.Netns,
addr, int(addNetworkReply.DeviceNumber), gomock.Any(), gomock.Any()).Return(nil)
addr, int(addNetworkReply.DeviceNumber), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)

mocksTypes.EXPECT().PrintResult(gomock.Any(), gomock.Any()).Return(nil)

add(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
err := add(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
assert.Nil(t, err)
}

func TestCmdAddNetworkErr(t *testing.T) {
Expand Down Expand Up @@ -169,7 +162,7 @@ func TestCmdAddErrSetupPodNetwork(t *testing.T) {
}

mocksNetwork.EXPECT().SetupNS(gomock.Any(), cmdArgs.IfName, cmdArgs.Netns,
addr, int(addNetworkReply.DeviceNumber), gomock.Any(), gomock.Any()).Return(errors.New("error on SetupPodNetwork"))
addr, int(addNetworkReply.DeviceNumber), gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error on SetupPodNetwork"))

// when SetupPodNetwork fails, expect to return IP back to datastore
delNetworkReply := &rpc.DelNetworkReply{Success: true, IPv4Addr: ipAddr, DeviceNumber: devNum}
Expand Down Expand Up @@ -213,7 +206,8 @@ func TestCmdDel(t *testing.T) {

mocksNetwork.EXPECT().TeardownNS(addr, int(delNetworkReply.DeviceNumber)).Return(nil)

del(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
err := del(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
assert.Nil(t, err)
}

func TestCmdDelErrDelNetwork(t *testing.T) {
Expand Down Expand Up @@ -242,7 +236,8 @@ func TestCmdDelErrDelNetwork(t *testing.T) {

mockC.EXPECT().DelNetwork(gomock.Any(), gomock.Any()).Return(delNetworkReply, errors.New("error on DelNetwork"))

del(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
err := del(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
assert.Error(t, err)
}

func TestCmdDelErrTeardown(t *testing.T) {
Expand Down Expand Up @@ -278,5 +273,6 @@ func TestCmdDelErrTeardown(t *testing.T) {

mocksNetwork.EXPECT().TeardownNS(addr, int(delNetworkReply.DeviceNumber)).Return(errors.New("error on teardown"))

del(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
err := del(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
assert.Error(t, err)
}
16 changes: 8 additions & 8 deletions plugins/routed-eni/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const (

// NetworkAPIs defines network API calls
type NetworkAPIs interface {
SetupNS(hostVethName string, contVethName string, netnsPath string, addr *net.IPNet, table int, vpcCIDRs []string, useExternalSNAT bool) error
SetupNS(hostVethName string, contVethName string, netnsPath string, addr *net.IPNet, table int, vpcCIDRs []string, useExternalSNAT bool, mtu int) error
TeardownNS(addr *net.IPNet, table int) error
}

Expand Down Expand Up @@ -70,14 +70,14 @@ type createVethPairContext struct {
mtu int
}

func newCreateVethPairContext(contVethName string, hostVethName string, addr *net.IPNet) *createVethPairContext {
func newCreateVethPairContext(contVethName string, hostVethName string, addr *net.IPNet, mtu int) *createVethPairContext {
return &createVethPairContext{
contVethName: contVethName,
hostVethName: hostVethName,
addr: addr,
netLink: netlinkwrapper.NewNetLink(),
ip: ipwrapper.NewIP(),
mtu: networkutils.GetEthernetMTU(),
mtu: mtu,
}
}

Expand Down Expand Up @@ -164,13 +164,13 @@ func (createVethContext *createVethPairContext) run(hostNS ns.NetNS) error {
}

// SetupNS wires up linux networking for a pod's network
func (os *linuxNetwork) SetupNS(hostVethName string, contVethName string, netnsPath string, addr *net.IPNet, table int, vpcCIDRs []string, useExternalSNAT bool) error {
log.Debugf("SetupNS: hostVethName=%s,contVethName=%s, netnsPath=%s table=%d", hostVethName, contVethName, netnsPath, table)
return setupNS(hostVethName, contVethName, netnsPath, addr, table, vpcCIDRs, useExternalSNAT, os.netLink, os.ns)
func (os *linuxNetwork) SetupNS(hostVethName string, contVethName string, netnsPath string, addr *net.IPNet, table int, vpcCIDRs []string, useExternalSNAT bool, mtu int) error {
log.Debugf("SetupNS: hostVethName=%s, contVethName=%s, netnsPath=%s, table=%d, mtu=%d", hostVethName, contVethName, netnsPath, table, mtu)
return setupNS(hostVethName, contVethName, netnsPath, addr, table, vpcCIDRs, useExternalSNAT, os.netLink, os.ns, mtu)
}

func setupNS(hostVethName string, contVethName string, netnsPath string, addr *net.IPNet, table int, vpcCIDRs []string, useExternalSNAT bool,
netLink netlinkwrapper.NetLink, ns nswrapper.NS) error {
netLink netlinkwrapper.NetLink, ns nswrapper.NS, mtu int) error {
// Clean up if hostVeth exists.
if oldHostVeth, err := netLink.LinkByName(hostVethName); err == nil {
if err = netLink.LinkDel(oldHostVeth); err != nil {
Expand All @@ -179,7 +179,7 @@ func setupNS(hostVethName string, contVethName string, netnsPath string, addr *n
log.Debugf("Clean up old hostVeth: %v\n", hostVethName)
}

createVethContext := newCreateVethPairContext(contVethName, hostVethName, addr)
createVethContext := newCreateVethPairContext(contVethName, hostVethName, addr, mtu)
if err := ns.WithNetNSPath(netnsPath, createVethContext.run); err != nil {
log.Errorf("Failed to setup NS network %v", err)
return errors.Wrap(err, "setupNS network: failed to setup NS network")
Expand Down
11 changes: 6 additions & 5 deletions plugins/routed-eni/driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const (
testeniIP = "10.10.10.20"
testeniMAC = "01:23:45:67:89:ab"
testeniSubnet = "10.10.0.0/16"
mtu = 9001
)

func setup(t *testing.T) (*gomock.Controller,
Expand Down Expand Up @@ -529,7 +530,7 @@ func TestSetupPodNetwork(t *testing.T) {
Mask: net.IPv4Mask(255, 255, 255, 255),
}
var cidrs []string
err = setupNS(testHostVethName, testContVethName, testnetnsPath, addr, testTable, cidrs, true, mockNetLink, mockNS)
err = setupNS(testHostVethName, testContVethName, testnetnsPath, addr, testTable, cidrs, true, mockNetLink, mockNS, mtu)
assert.NoError(t, err)
}

Expand All @@ -548,7 +549,7 @@ func TestSetupPodNetworkErrLinkByName(t *testing.T) {
Mask: net.IPv4Mask(255, 255, 255, 255),
}
var cidrs []string
err := setupNS(testHostVethName, testContVethName, testnetnsPath, addr, testTable, cidrs, false, mockNetLink, mockNS)
err := setupNS(testHostVethName, testContVethName, testnetnsPath, addr, testTable, cidrs, false, mockNetLink, mockNS, mtu)

assert.Error(t, err)
}
Expand All @@ -570,7 +571,7 @@ func TestSetupPodNetworkErrLinkSetup(t *testing.T) {
Mask: net.IPv4Mask(255, 255, 255, 255),
}
var cidrs []string
err := setupNS(testHostVethName, testContVethName, testnetnsPath, addr, testTable, cidrs, false, mockNetLink, mockNS)
err := setupNS(testHostVethName, testContVethName, testnetnsPath, addr, testTable, cidrs, false, mockNetLink, mockNS, mtu)

assert.Error(t, err)
}
Expand Down Expand Up @@ -603,7 +604,7 @@ func TestSetupPodNetworkErrRouteReplace(t *testing.T) {
Mask: net.IPv4Mask(255, 255, 255, 255),
}
var cidrs []string
err = setupNS(testHostVethName, testContVethName, testnetnsPath, addr, testTable, cidrs, false, mockNetLink, mockNS)
err = setupNS(testHostVethName, testContVethName, testnetnsPath, addr, testTable, cidrs, false, mockNetLink, mockNS, mtu)

assert.Error(t, err)
}
Expand Down Expand Up @@ -651,7 +652,7 @@ func TestSetupPodNetworkPrimaryIntf(t *testing.T) {
}

var cidrs []string
err = setupNS(testHostVethName, testContVethName, testnetnsPath, addr, 0, cidrs, false, mockNetLink, mockNS)
err = setupNS(testHostVethName, testContVethName, testnetnsPath, addr, 0, cidrs, false, mockNetLink, mockNS, mtu)

assert.NoError(t, err)
}
Expand Down
8 changes: 4 additions & 4 deletions plugins/routed-eni/driver/mocks/driver_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions scripts/install-aws.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env bash
echo "====== Installing AWS-CNI ======"
sed -i s/__VETHPREFIX__/"${AWS_VPC_K8S_CNI_VETHPREFIX:-"veth"}"/g /app/10-aws.conflist
sed -i s/__MTU__/"${AWS_VPC_ENI_MTU:-"9001"}"/g /app/10-aws.conflist
cp /app/portmap /host/opt/cni/bin/
cp /app/aws-cni-support.sh /host/opt/cni/bin/

Expand Down

0 comments on commit 3e13f7c

Please sign in to comment.