Skip to content

Commit

Permalink
V2 API support for win-overlay CNI
Browse files Browse the repository at this point in the history
This PR bring V2 API support into win-overlay CNI. With the current V1
API, only docker runtime works for win-overlay. By bringing new changes, we
should be able to use containerd as the runtime.Below are the key
points regarding this implementation.
	1. Clear seperation for V1 & V2 API support
	2. New cni.conf sample that works for win-overlay

Signed-off-by: selansen <[email protected]>
  • Loading branch information
selansen committed Apr 6, 2022
1 parent 16e4a82 commit 71b88c5
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 13 deletions.
2 changes: 2 additions & 0 deletions pkg/hns/endpoint_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type EndpointInfo struct {
NetworkId string
Gateway net.IP
IpAddress net.IP
MacAddress string
}

// GetSandboxContainerID returns the sandbox ID of this pod.
Expand Down Expand Up @@ -248,6 +249,7 @@ func GenerateHcnEndpoint(epInfo *EndpointInfo, n *NetConf) (*hcn.HostComputeEndp
Minor: 0,
},
Name: epInfo.EndpointName,
MacAddress: epInfo.MacAddress,
HostComputeNetwork: epInfo.NetworkId,
Dns: hcn.Dns{
Domain: epInfo.DNS.Domain,
Expand Down
46 changes: 46 additions & 0 deletions plugins/main/windows/win-overlay/sample-v2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"cniVersion": "0.2.0",
"name": "OVNKubernetesHybridOverlayNetwork",
"type": "win-overlay",
"ipam": {
"type": "host-local",
"subnet": "10.132.0.0/24"
},
"apiVersion": 2,
"capabilities": {
"portMappings": true,
"dns": true
},
"policies": [
{
"name": "EndpointPolicy",
"value": {
"Type": "OutBoundNAT",
"Settings": {
"Exceptions": [
"172.30.0.0/16"
]
}
}
},
{
"name": "EndpointPolicy",
"value": {
"Type": "SDNRoute",
"Settings": {
"DestinationPrefix": "172.30.0.0/16",
"NeedEncap": true
}
}
},
{
"name": "EndpointPolicy",
"value": {
"Type": "ProviderAddress",
"Settings": {
"ProviderAddress": "10.0.133.170"
}
}
}
]
}
138 changes: 125 additions & 13 deletions plugins/main/windows/win-overlay/win-overlay_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ package main
import (
"encoding/json"
"fmt"
"net"
"runtime"
"strings"

"github.com/Microsoft/hcsshim"

"github.com/Microsoft/hcsshim/hcn"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
current "github.com/containernetworking/cni/pkg/types/100"
Expand Down Expand Up @@ -55,16 +57,103 @@ func loadNetConf(bytes []byte) (*NetConf, string, error) {
return n, n.CNIVersion, nil
}

func cmdAdd(args *skel.CmdArgs) error {
success := false
n, cniVersion, err := loadNetConf(args.StdinData)
func processEndpointArgs(args *skel.CmdArgs, n *NetConf) (*hns.EndpointInfo, error) {
epInfo := new(hns.EndpointInfo)
epInfo.NetworkName = n.Name
epInfo.EndpointName = hns.ConstructEndpointName(args.ContainerID, args.Netns, epInfo.NetworkName)

if n.IPAM.Type != "" {
r, err := ipam.ExecAdd(n.IPAM.Type, args.StdinData)
if err != nil {
return nil, errors.Annotatef(err, "error while executing IPAM addition")
}

// convert whatever the IPAM result was into the current result
result, err := current.NewResultFromResult(r)
if err != nil {
return nil, errors.Annotatef(err, "error while converting the result from IPAM addition")
} else {
if len(result.IPs) == 0 {
return nil, fmt.Errorf("IPAM plugin return is missing IP config")
}
epInfo.IpAddress = result.IPs[0].Address.IP.To4()
epInfo.MacAddress = fmt.Sprintf("%v-%02x-%02x-%02x-%02x", n.EndpointMacPrefix, epInfo.IpAddress[0], epInfo.IpAddress[1], epInfo.IpAddress[2], epInfo.IpAddress[3])
}
}
epInfo.DNS = n.GetDNS()
if n.LoopbackDSR {
n.ApplyLoopbackDSRPolicy(&epInfo.IpAddress)
}
return epInfo, nil
}

func cmdHcnAdd(args *skel.CmdArgs, n *NetConf) (*current.Result, error) {
if len(n.EndpointMacPrefix) != 0 {
if len(n.EndpointMacPrefix) != 5 || n.EndpointMacPrefix[2] != '-' {
return nil, fmt.Errorf("endpointMacPrefix [%v] is invalid, value must be of the format xx-xx", n.EndpointMacPrefix)
}
} else {
n.EndpointMacPrefix = "0E-2A"
}

networkName := n.Name
hnsNetwork, err := hcsshim.GetHNSNetworkByName(networkName)
hcnNetwork, err := hcn.GetNetworkByName(networkName)
if err != nil {
return errors.Annotate(err, "error while loadNetConf")
return nil, errors.Annotatef(err, "error while hcn.GetNetworkByName(%s)", networkName)
}
if hcnNetwork == nil {
return nil, fmt.Errorf("network %v is not found", networkName)
}
if hnsNetwork == nil {
return nil, fmt.Errorf("network %v not found", networkName)
}

if !strings.EqualFold(string (hcnNetwork.Type), "Overlay") {
return nil, fmt.Errorf("network %v is of an unexpected type: %v", networkName, hcnNetwork.Type)
}

epName := hns.ConstructEndpointName(args.ContainerID, args.Netns, n.Name)

hcnEndpoint, err := hns.AddHcnEndpoint(epName, hcnNetwork.Id, args.Netns, func() (*hcn.HostComputeEndpoint, error) {
epInfo, err := processEndpointArgs(args, n)
if err != nil {
return nil, errors.Annotate(err, "error while processing endpoint args")
}
epInfo.NetworkId = hcnNetwork.Id
gatewayAddr := net.ParseIP(hnsNetwork.Subnets[0].GatewayAddress)
epInfo.Gateway = gatewayAddr.To4()
n.ApplyDefaultPAPolicy(hnsNetwork.ManagementIP)
if n.IPMasq {
n.ApplyOutboundNatPolicy(hnsNetwork.Subnets[0].AddressPrefix)
}
hcnEndpoint, err := hns.GenerateHcnEndpoint(epInfo, &n.NetConf)

if err != nil {
return nil, errors.Annotate(err, "error while generating HostComputeEndpoint")
}
return hcnEndpoint, nil
})
if err != nil {
return nil, errors.Annotate(err, "error while adding HostComputeEndpoint")
}

result, err := hns.ConstructHcnResult(hcnNetwork, hcnEndpoint)

if err != nil {
ipam.ExecDel(n.IPAM.Type, args.StdinData)
return nil, errors.Annotate(err, "error while constructing HostComputeEndpoint addition result")
}

return result, nil

}
func cmdHnsAdd(args *skel.CmdArgs, n *NetConf) (*current.Result, error) {
success := false

if len(n.EndpointMacPrefix) != 0 {
if len(n.EndpointMacPrefix) != 5 || n.EndpointMacPrefix[2] != '-' {
return fmt.Errorf("endpointMacPrefix [%v] is invalid, value must be of the format xx-xx", n.EndpointMacPrefix)
return nil, fmt.Errorf("endpointMacPrefix [%v] is invalid, value must be of the format xx-xx", n.EndpointMacPrefix)
}
} else {
n.EndpointMacPrefix = "0E-2A"
Expand All @@ -73,15 +162,15 @@ func cmdAdd(args *skel.CmdArgs) error {
networkName := n.Name
hnsNetwork, err := hcsshim.GetHNSNetworkByName(networkName)
if err != nil {
return errors.Annotatef(err, "error while GETHNSNewtorkByName(%s)", networkName)
return nil, errors.Annotatef(err, "error while GETHNSNewtorkByName(%s)", networkName)
}

if hnsNetwork == nil {
return fmt.Errorf("network %v not found", networkName)
return nil, fmt.Errorf("network %v not found", networkName)
}

if !strings.EqualFold(hnsNetwork.Type, "Overlay") {
return fmt.Errorf("network %v is of an unexpected type: %v", networkName, hnsNetwork.Type)
return nil, fmt.Errorf("network %v is of an unexpected type: %v", networkName, hnsNetwork.Type)
}

epName := hns.ConstructEndpointName(args.ContainerID, args.Netns, n.Name)
Expand Down Expand Up @@ -140,15 +229,34 @@ func cmdAdd(args *skel.CmdArgs) error {
}
}()
if err != nil {
return errors.Annotatef(err, "error while AddHnsEndpoint(%v,%v,%v)", epName, hnsNetwork.Id, args.ContainerID)
return nil, errors.Annotatef(err, "error while AddHnsEndpoint(%v,%v,%v)", epName, hnsNetwork.Id, args.ContainerID)
}

result, err := hns.ConstructHnsResult(hnsNetwork, hnsEndpoint)
if err != nil {
return errors.Annotatef(err, "error while constructResult")
return nil, errors.Annotatef(err, "error while constructResult")
}

success = true
return result, nil
}
func cmdAdd(args *skel.CmdArgs) error {
n, cniVersion, err := loadNetConf(args.StdinData)
if err != nil {
return err
}

var result *current.Result
if n.ApiVersion == 2 {
result, err = cmdHcnAdd(args, n)
} else {
result, err = cmdHnsAdd(args, n)
}
if err != nil {
ipam.ExecDel(n.IPAM.Type, args.StdinData)
return err
}

return types.PrintResult(result, cniVersion)
}

Expand All @@ -158,12 +266,16 @@ func cmdDel(args *skel.CmdArgs) error {
return err
}

if err := ipam.ExecDel(n.IPAM.Type, args.StdinData); err != nil {
return err
if n.IPAM.Type != "" {
if err := ipam.ExecDel(n.IPAM.Type, args.StdinData); err != nil {
return err
}
}

epName := hns.ConstructEndpointName(args.ContainerID, args.Netns, n.Name)

if n.ApiVersion == 2 {
return hns.RemoveHcnEndpoint(epName)
}
return hns.RemoveHnsEndpoint(epName, args.Netns, args.ContainerID)
}

Expand Down

0 comments on commit 71b88c5

Please sign in to comment.