Skip to content

Commit

Permalink
Add IPv6 suppport
Browse files Browse the repository at this point in the history
PR to add IPv6 support to the AWS VPC CNI. This change adds
ASSIGN_IPV4 and ASSIGN_IPV6 CNI config env vars, that default
to true and false respecitvely.

Co-authored-by: Angus Lees <gus@inodes.org>

(cherry picked from commit e845584)
  • Loading branch information
Claes Mogren authored and mogren committed Sep 7, 2020
1 parent fc24055 commit 5441eda
Show file tree
Hide file tree
Showing 25 changed files with 1,457 additions and 916 deletions.
90 changes: 60 additions & 30 deletions cmd/routed-eni-cni-plugin/cni.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,25 +173,35 @@ func add(args *skel.CmdArgs, cniTypes typeswrapper.CNITYPES, grpcClient grpcwrap
return errors.New("add cmd: failed to assign an IP address to container")
}

log.Infof("Received add network response for container %s interface %s: %+v",
args.ContainerID, args.IfName, r)
log.Infof("Received add network response for container %s interface %s: IP4 %s, IP6 %s, table %d, external-SNAT: %v, VPC CIDRs v4: %v, VPC CIDRs v6: %v",
args.ContainerID, args.IfName, r.IPv4Addr, r.IPv6Addr, r.DeviceNumber, r.UseExternalSNAT, r.VPCCIDRsv4, r.VPCCIDRsv6)

addr := &net.IPNet{
IP: net.ParseIP(r.IPv4Addr),
Mask: net.IPv4Mask(255, 255, 255, 255),
addrs := make([]*net.IP, 0, 2)
if r.IPv4Addr != "" {
addr := net.ParseIP(r.IPv4Addr)
addrs = append(addrs, &addr)
}
if r.IPv6Addr != "" {
addr := net.ParseIP(r.IPv6Addr)
addrs = append(addrs, &addr)
}

vpcCIDRs := r.VPCCIDRsv4
vpcCIDRs = append(vpcCIDRs, r.VPCCIDRsv6...)

if r.PodVlanId != 0 {
addr := &net.IPNet{
IP: net.ParseIP(r.IPv4Addr),
Mask: net.IPv4Mask(255, 255, 255, 255),
}
hostVethName := generateHostVethName("vlan", string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME))

err = driverClient.SetupPodENINetwork(hostVethName, args.IfName, args.Netns, addr, int(r.PodVlanId), r.PodENIMAC,
r.PodENISubnetGW, int(r.ParentIfIndex), mtu, log)
err = driverClient.SetupPodENINetwork(hostVethName, args.IfName, args.Netns, addr, int(r.PodVlanId), r.PodENIMAC, r.PodENISubnetGW, int(r.ParentIfIndex), mtu, log)
} else {
// build hostVethName
// 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, mtu, log)
err = driverClient.SetupNS(hostVethName, args.IfName, args.Netns, addrs, int(r.DeviceNumber), vpcCIDRs, r.UseExternalSNAT, mtu, log)
}

if err != nil {
Expand Down Expand Up @@ -222,11 +232,18 @@ func add(args *skel.CmdArgs, cniTypes typeswrapper.CNITYPES, grpcClient grpcwrap
return errors.Wrap(err, "add command: failed to setup network")
}

ips := []*current.IPConfig{
{
Version: "4",
Address: *addr,
},
ips := make([]*current.IPConfig, 0, len(addrs))
for _, addr := range addrs {
var version string
if addr4 := addr.To4(); addr4 != nil {
version = "4"
} else {
version = "6"
}
ips = append(ips, &current.IPConfig{
Version: version,
Address: *networkutils.IpToCIDR(addr),
})
}

result := &current.Result{
Expand Down Expand Up @@ -312,26 +329,39 @@ func del(args *skel.CmdArgs, cniTypes typeswrapper.CNITYPES, grpcClient grpcwrap
log.Infof("Received del network response for pod %s namespace %s sandbox %s: %+v", string(k8sArgs.K8S_POD_NAME),
string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_INFRA_CONTAINER_ID), r)

deletedPodIP := net.ParseIP(r.IPv4Addr)
if deletedPodIP != nil {
addr := &net.IPNet{
IP: deletedPodIP,
Mask: net.IPv4Mask(255, 255, 255, 255),
}

if r.PodVlanId != 0 {
err = driverClient.TeardownPodENINetwork(int(r.PodVlanId), log)
} else {
err = driverClient.TeardownNS(addr, int(r.DeviceNumber), log)
}

if r.PodVlanId != 0 {
err = driverClient.TeardownPodENINetwork(int(r.PodVlanId), log)
if err != nil {
log.Errorf("Failed on TeardownPodNetwork for container ID %s: %v",
args.ContainerID, err)
return errors.Wrap(err, "del cmd: failed on tear down pod network")
return errors.Wrap(err, "del cmd: failed on tear down pod EMI pod network")
}
} else {
log.Warnf("Container %s did not have a valid IP %s", args.ContainerID, r.IPv4Addr)
return nil
}

deletedAddrs := make([]*net.IP, 0, 2)
if r.IPv4Addr != "" {
addr := net.ParseIP(r.IPv4Addr)
if addr == nil {
log.Warnf("Container %s did not have a valid IP %s", args.ContainerID, r.IPv4Addr)
return nil
}
deletedAddrs = append(deletedAddrs, &addr)
}
if r.IPv6Addr != "" {
addr := net.ParseIP(r.IPv6Addr)
if addr == nil {
log.Warnf("Container %s did not have a valid IP6 %s", args.ContainerID, r.IPv6Addr)
return nil
}
deletedAddrs = append(deletedAddrs, &addr)
}

err = driverClient.TeardownNS(deletedAddrs, int(r.DeviceNumber), log)
if err != nil {
log.Errorf("Failed on TeardownPodNetwork for container ID %s: %v",
args.ContainerID, err)
return errors.Wrap(err, "del cmd: failed on tear down pod network")
}
return nil
}
Expand Down
33 changes: 12 additions & 21 deletions cmd/routed-eni-cni-plugin/cni_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,11 @@ func TestCmdAdd(t *testing.T) {

addNetworkReply := &rpc.AddNetworkReply{Success: true, IPv4Addr: ipAddr, DeviceNumber: devNum}
mockC.EXPECT().AddNetwork(gomock.Any(), gomock.Any()).Return(addNetworkReply, nil)

addr := &net.IPNet{
IP: net.ParseIP(addNetworkReply.IPv4Addr),
Mask: net.IPv4Mask(255, 255, 255, 255),
}
addr := net.ParseIP(addNetworkReply.IPv4Addr)
addrs := []*net.IP{&addr}

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

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

Expand Down Expand Up @@ -154,13 +151,11 @@ func TestCmdAddErrSetupPodNetwork(t *testing.T) {
addNetworkReply := &rpc.AddNetworkReply{Success: true, IPv4Addr: ipAddr, DeviceNumber: devNum}
mockC.EXPECT().AddNetwork(gomock.Any(), gomock.Any()).Return(addNetworkReply, nil)

addr := &net.IPNet{
IP: net.ParseIP(addNetworkReply.IPv4Addr),
Mask: net.IPv4Mask(255, 255, 255, 255),
}
addr := net.ParseIP(addNetworkReply.IPv4Addr)
addrs := []*net.IP{&addr}

mocksNetwork.EXPECT().SetupNS(gomock.Any(), cmdArgs.IfName, cmdArgs.Netns,
addr, int(addNetworkReply.DeviceNumber), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error on SetupPodNetwork"))
addrs, int(addNetworkReply.DeviceNumber), gomock.Any(), 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 @@ -194,12 +189,10 @@ func TestCmdDel(t *testing.T) {

mockC.EXPECT().DelNetwork(gomock.Any(), gomock.Any()).Return(delNetworkReply, nil)

addr := &net.IPNet{
IP: net.ParseIP(delNetworkReply.IPv4Addr),
Mask: net.IPv4Mask(255, 255, 255, 255),
}
addr := net.ParseIP(delNetworkReply.IPv4Addr)
addrs := []*net.IP{&addr}

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

err := del(cmdArgs, mocksTypes, mocksGRPC, mocksRPC, mocksNetwork)
assert.Nil(t, err)
Expand Down Expand Up @@ -255,12 +248,10 @@ func TestCmdDelErrTeardown(t *testing.T) {

mockC.EXPECT().DelNetwork(gomock.Any(), gomock.Any()).Return(delNetworkReply, nil)

addr := &net.IPNet{
IP: net.ParseIP(delNetworkReply.IPv4Addr),
Mask: net.IPv4Mask(255, 255, 255, 255),
}
addr := net.ParseIP(delNetworkReply.IPv4Addr)
addrs := []*net.IP{&addr}

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

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

0 comments on commit 5441eda

Please sign in to comment.