adds optional loopbackDSR argument to cni conf

This commit is contained in:
DavidSchott 2021-02-24 18:02:52 -08:00
Родитель bf753c6cc4
Коммит 8ce93fba3f
7 изменённых файлов: 88 добавлений и 39 удалений

Просмотреть файл

@ -108,6 +108,7 @@ type OptionalFlags struct {
AllowAclPortMapping bool `json:"allowAclPortMapping"`
ForceBridgeGateway bool `json:"forceBridgeGateway"` // Intended to be temporary workaround
EnableDualStack bool `json:"enableDualStack"`
LoopbackDSR bool `json:"loopbackDSR"`
}
func (r *Result) Print() {
@ -192,7 +193,13 @@ func (config *NetworkConfig) Serialize() []byte {
}
// GetNetworkInfo from the NetworkConfig
func (config *NetworkConfig) GetNetworkInfo(podNamespace string) *network.NetworkInfo {
func (config *NetworkConfig) GetNetworkInfo(podNamespace string) (ninfo *network.NetworkInfo, err error) {
if config.OptionalFlags.LoopbackDSR {
if err := hcn.DSRSupported(); err != nil {
logrus.Errorf("[cni-net] Failed to enable loopbackDSR on unsupported HCN version, err:%v.", err)
return nil, err
}
}
var subnets []network.SubnetInfo
// Note the code below is looking inside the ipam specific configuration.
if config.Ipam.Subnet != "" {
@ -234,7 +241,7 @@ func (config *NetworkConfig) GetNetworkInfo(podNamespace string) *network.Networ
dnsSettings.Options = config.RuntimeConfig.DNS.Options
}
ninfo := &network.NetworkInfo{
ninfo = &network.NetworkInfo{
ID: config.Name,
Name: config.Name,
Type: network.NetworkType(config.Name),
@ -251,7 +258,7 @@ func (config *NetworkConfig) GetNetworkInfo(podNamespace string) *network.Networ
}
}
return ninfo
return ninfo, err
}
// getInACLRule generates an In ACLs for mapped ports
@ -364,14 +371,14 @@ func GetCurrResult(network *network.NetworkInfo, endpoint *network.EndpointInfo,
var ip = GetIP(network, endpoint)
ip.InterfaceIndex = 0
cIP := cniTypesCurr.IPConfig{
Version: ip.Version,
Address: net.IPNet{
IP: ip.Address.IP,
Mask: ip.Address.Mask},
Gateway: ip.Gateway,
Interface: &ip.InterfaceIndex,
Version: ip.Version,
Address: net.IPNet{
IP: ip.Address.IP,
Mask: ip.Address.Mask},
Gateway: ip.Gateway,
Interface: &ip.InterfaceIndex,
}
result.IPs = append(result.IPs, &cIP)
@ -383,29 +390,29 @@ func GetCurrResult(network *network.NetworkInfo, endpoint *network.EndpointInfo,
ip4.InterfaceIndex = 0
cIP4 := cniTypesCurr.IPConfig{
Version: ip4.Version,
Address: net.IPNet{
IP: ip4.Address.IP,
Mask: ip4.Address.Mask},
Gateway: ip4.Gateway,
Interface: &ip4.InterfaceIndex,
Version: ip4.Version,
Address: net.IPNet{
IP: ip4.Address.IP,
Mask: ip4.Address.Mask},
Gateway: ip4.Gateway,
Interface: &ip4.InterfaceIndex,
}
result.IPs = append(result.IPs, &cIP4)
if ip6 != nil {
if ip6 != nil {
ip6.InterfaceIndex = 0
cIP6 := cniTypesCurr.IPConfig{
Version: ip6.Version,
Address: net.IPNet{
IP: ip6.Address.IP,
Mask: ip6.Address.Mask},
Gateway: ip6.Gateway,
Interface: &ip6.InterfaceIndex,
Version: ip6.Version,
Address: net.IPNet{
IP: ip6.Address.IP,
Mask: ip6.Address.Mask},
Gateway: ip6.Gateway,
Interface: &ip6.InterfaceIndex,
}
result.IPs = append(result.IPs, &cIP6)
}
}
@ -440,23 +447,23 @@ func GetDualStackAddresses(endpoint *network.EndpointInfo) (*IP, *IP) {
var ip4 *IP
var ip6 *IP
ip4address := net.IPNet{}
ip4address.IP = endpoint.IPAddress
ip4address.Mask = endpoint.IP4Mask
ip4address.Mask = endpoint.IP4Mask
ip4 = &IP{
Version: "4",
Address: cniTypes.IPNet(ip4address),
Gateway: endpoint.Gateway,
Version: "4",
Address: cniTypes.IPNet(ip4address),
Gateway: endpoint.Gateway,
InterfaceIndex: 0,
}
if endpoint.IPAddress6.IP != nil {
ip6 = &IP{
Version: "6",
Address: cniTypes.IPNet(endpoint.IPAddress6),
Gateway: endpoint.Gateway6,
Version: "6",
Address: cniTypes.IPNet(endpoint.IPAddress6),
Gateway: endpoint.Gateway6,
InterfaceIndex: 0,
}
}

Просмотреть файл

@ -121,7 +121,11 @@ func (plugin *netPlugin) Add(args *cniSkel.CmdArgs) (resultError error) {
// Convert cniConfig to NetworkInfo
// We don't set namespace, setting namespace is not valid for EP creation
networkInfo := cniConfig.GetNetworkInfo(k8sNamespace)
networkInfo, err := cniConfig.GetNetworkInfo(k8sNamespace)
if err != nil {
logrus.Errorf("[cni-net] Failed to get network information from network configuration, err:%v.", err)
return err
}
epInfo, err := cniConfig.GetEndpointInfo(networkInfo, args.ContainerID, "")
if err != nil {
@ -203,6 +207,12 @@ func (plugin *netPlugin) Add(args *cniSkel.CmdArgs) (resultError error) {
// Apply the Network Policy for Endpoint
epInfo.Policies = append(epInfo.Policies, networkInfo.Policies...)
// If LoopbackDSR is set, add to policies
if cniConfig.OptionalFlags.LoopbackDSR {
hcnLoopbackRoute, _ := network.GetLoopbackDSRPolicy(&epInfo.IPAddress)
epInfo.Policies = append(epInfo.Policies, hcnLoopbackRoute)
}
epInfo, err = plugin.nm.CreateEndpoint(nwConfig.ID, epInfo, args.Netns)
if err != nil {
logrus.Errorf("[cni-net] Failed to create endpoint, error : %v.", err)
@ -381,7 +391,11 @@ func (plugin *netPlugin) Delete(args *cniSkel.CmdArgs) error {
}
// Convert cniConfig to NetworkInfo
networkInfo := cniConfig.GetNetworkInfo(k8sNamespace)
networkInfo, err := cniConfig.GetNetworkInfo(k8sNamespace)
if err != nil {
logrus.Errorf("[cni-net] Failed to get network information from network configuration, err:%v.", err)
return err
}
epInfo, err := cniConfig.GetEndpointInfo(networkInfo, args.ContainerID, args.Netns)
if err != nil {
return err

Просмотреть файл

@ -7,9 +7,10 @@
        "dnsCapabilities": true
    },
    "delegate": {
        "type": "sdnoverlay",
        "type": "sdnbridge",
"optionalFlags" : {
"forceBridgeGateway" : true
"forceBridgeGateway" : true,
"loopbackDSR": false
},
        "AdditionalArgs": [
            {

Просмотреть файл

@ -8,6 +8,9 @@
    },
    "delegate": {
        "type": "sdnoverlay",
"optionalFlags" : {
"loopbackDSR": false
},
        "AdditionalArgs": [
            {
                "Name": "EndpointPolicy",

Просмотреть файл

@ -7,6 +7,9 @@
"portMappings": true,
"dnsCapabilities": true
},
"optionalFlags" : {
"loopbackDSR": false
},
"ipam": {
"subnet": "192.168.1.0/24",
"routes": [

Просмотреть файл

@ -3,6 +3,9 @@
"name": "l2tunnelNetwork",
"type": "l2tunnel",
"master": "Ethernet",
"optionalFlags" : {
"loopbackDSR": false
},
"ipam": {
"type": "azure-vnet-ipam",
"Subnet": "10.240.0.0/12"

Просмотреть файл

@ -6,9 +6,11 @@ package network
import (
"encoding/json"
"errors"
"github.com/Microsoft/hcsshim/hcn"
"net"
"strconv"
"strings"
"github.com/Microsoft/hcsshim/hcn"
)
type CNIPolicyType string
@ -57,7 +59,6 @@ func GetPortEnumValue(protocol string) (uint32, error) {
// GetPortMappingPolicy creates an HCN PortMappingPolicy and stores it in CNI Policy.
func GetPortMappingPolicy(externalPort int, internalPort int, protocol string, hostIp string, flags uint32) (Policy, error) {
// protocol can be passed either as a number or a name
protocolInt, err := GetPortEnumValue(protocol)
if err != nil {
@ -83,3 +84,20 @@ func GetPortMappingPolicy(externalPort int, internalPort int, protocol string, h
Data: rawData,
}, nil
}
// GetLoopbackDSRPolicy creates a policy to support loopback direct server return.
func GetLoopbackDSRPolicy(ip *net.IP) (Policy, error) {
hcnLoopbackRoute := hcn.OutboundNatPolicySetting{
Destinations: []string{ip.String()},
}
rawPolicy, _ := json.Marshal(hcnLoopbackRoute)
endpointPolicy := hcn.EndpointPolicy{
Type: hcn.OutBoundNAT,
Settings: rawPolicy,
}
rawData, _ := json.Marshal(endpointPolicy)
return Policy{
Type: EndpointPolicy,
Data: rawData,
}, nil
}