Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vpc-shared-eni: Enable IP forwarding and ARP proxy when using L3 mode #24

Merged
merged 1 commit into from
Aug 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions network/ipcfg/ip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.

package ipcfg

import (
"bytes"
"fmt"
"io/ioutil"
"strconv"
)

const (
ipv4Forwarding = "/proc/sys/net/ipv4/conf/%s/forwarding"
ipv4ProxyARP = "/proc/sys/net/ipv4/conf/%s/proxy_arp"
)

// SetIPv4Forwarding sets the IPv4 forwarding property of an interface to the given value.
func SetIPv4Forwarding(ifName string, value int) error {
return set(fmt.Sprintf(ipv4Forwarding, ifName), value)
}

// SetIPv4ProxyARP sets the IPv4 proxy ARP property of an interface to the given value.
func SetIPv4ProxyARP(ifName string, value int) error {
return set(fmt.Sprintf(ipv4ProxyARP, ifName), value)
}

// Set sets a system variable to the given value.
func set(name string, value int) error {
valueStr := strconv.Itoa(value)

// Do not rewrite if the value is already set.
currValue, err := ioutil.ReadFile(name)
if err == nil && bytes.Equal(bytes.TrimSpace(currValue), []byte(valueStr)) {
return nil
}

return ioutil.WriteFile(name, []byte(valueStr), 0644)
}
32 changes: 31 additions & 1 deletion plugins/vpc-shared-eni/network/bridge_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"github.com/aws/amazon-vpc-cni-plugins/network/ebtables"
"github.com/aws/amazon-vpc-cni-plugins/network/eni"
"github.com/aws/amazon-vpc-cni-plugins/network/ipcfg"
"github.com/aws/amazon-vpc-cni-plugins/network/netns"
"github.com/aws/amazon-vpc-cni-plugins/network/vpc"
"github.com/aws/amazon-vpc-cni-plugins/plugins/vpc-shared-eni/config"
Expand Down Expand Up @@ -456,8 +457,10 @@ func (nb *BridgeBuilder) createBridge(
return 0, err
}

// Setup bridge layer2 configuration.
if bridgeType == config.BridgeTypeL2 {
// In layer2 configuration, the bridge inherits shared ENI's IP address and default route.
// Frames are switched between veth pairs and the shared ENI.

// Assign IP address to bridge.
log.Infof("Assigning IP address %v to bridge link %s.", ipAddress, bridgeName)
address := &netlink.Addr{IPNet: ipAddress}
Expand Down Expand Up @@ -485,6 +488,33 @@ func (nb *BridgeBuilder) createBridge(
log.Errorf("Failed to add IP route %+v: %v.", route, err)
return 0, err
}
} else {
// In layer3 configuration, the IP address and default route remain on the shared ENI.
// IP datagrams are routed between the bridge and the shared ENI.

// Bridge proxies ARP requests originating from veth pairs to the VPC.
log.Infof("Enabling IPv4 proxy ARP on %s.", bridgeName)
err = ipcfg.SetIPv4ProxyARP(bridgeName, 1)
if err != nil {
log.Errorf("Failed to enable IPv4 proxy ARP on %s: %v.", bridgeName, err)
return 0, err
}

// Enable IPv4 forwarding on the bridge and shared ENI, so that IP datagrams can be
// routed between them.
log.Infof("Enabling IPv4 forwarding on %s.", bridgeName)
err = ipcfg.SetIPv4Forwarding(bridgeName, 1)
if err != nil {
log.Errorf("Failed to enable IPv4 forwarding on %s: %v.", bridgeName, err)
return 0, err
}

log.Infof("Enabling IPv4 forwarding on %s.", sharedENI.GetLinkName())
err = ipcfg.SetIPv4Forwarding(sharedENI.GetLinkName(), 1)
if err != nil {
log.Errorf("Failed to enable IPv4 forwarding on %s: %v.", sharedENI.GetLinkName(), err)
return 0, err
}
}

return bridgeLink.Attrs().Index, nil
Expand Down