Skip to content
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
67 changes: 46 additions & 21 deletions cni/azure-windows-multitenancy.conflist
Original file line number Diff line number Diff line change
@@ -1,23 +1,48 @@
{
"cniVersion":"0.3.0",
"name":"azure",
"plugins":[
{
"type":"azure-vnet",
"mode":"bridge",
"bridge":"azure0",
"multiTenancy":true,
"enableSnatOnHost":true,
"ipam":{
"type":"azure-vnet-ipam"
}
},
{
"type":"portmap",
"capabilities":{
"portMappings":true
},
"snat":true
}
]
"cniVersion": "0.3.0",
"name": "azure",
"plugins": [
{
"type": "azure-vnet",
"mode": "bridge",
"bridge": "azure0",
"multiTenancy":true,
"enableSnatOnHost":true,
"capabilities": {
"portMappings": true
},
"ipam": {
"type": "azure-vnet-ipam"
},
"dns": {
"Nameservers": [
"10.0.0.10",
"168.63.129.16"
],
"Search": [
"svc.cluster.local"
]
},
"AdditionalArgs": [
{
"Name": "EndpointPolicy",
"Value": {
"Type": "OutBoundNAT",
"ExceptionList": [
"10.240.0.0/16",
"10.0.0.0/8"
]
}
},
{
"Name": "EndpointPolicy",
"Value": {
"Type": "ROUTE",
"DestinationPrefix": "10.0.0.0/8",
"NeedEncap": true
}
}
]
}
]
}
30 changes: 1 addition & 29 deletions network/endpoint_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,7 @@ func (nw *network) newEndpointImpl(epInfo *EndpointInfo) (*endpoint, error) {
VirtualNetwork: nw.HnsId,
DNSSuffix: epInfo.DNS.Suffix,
DNSServerList: strings.Join(epInfo.DNS.Servers, ","),
}

// Set outbound NAT policy
outBoundNatPolicy := hcsshim.OutboundNatPolicy{}
outBoundNatPolicy.Policy.Type = hcsshim.OutboundNat

exceptionList, err := policy.GetOutBoundNatExceptionList(epInfo.Policies)
if err != nil {
log.Printf("[net] Failed to parse outbound NAT policy %v", err)
return nil, err
}

if exceptionList != nil {
for _, ipAddress := range exceptionList {
outBoundNatPolicy.Exceptions = append(outBoundNatPolicy.Exceptions, ipAddress)
}
}

if epInfo.Data[CnetAddressSpace] != nil {
if cnetAddressSpace := epInfo.Data[CnetAddressSpace].([]string); cnetAddressSpace != nil {
for _, ipAddress := range cnetAddressSpace {
outBoundNatPolicy.Exceptions = append(outBoundNatPolicy.Exceptions, ipAddress)
}
}
}

if outBoundNatPolicy.Exceptions != nil {
serializedOutboundNatPolicy, _ := json.Marshal(outBoundNatPolicy)
hnsEndpoint.Policies = append(hnsEndpoint.Policies, serializedOutboundNatPolicy)
Policies: policy.SerializePolicies(policy.EndpointPolicy, epInfo.Policies, epInfo.Data),
}

// HNS currently supports only one IP address per endpoint.
Expand Down
2 changes: 1 addition & 1 deletion network/network_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (nm *networkManager) newNetworkImpl(nwInfo *NetworkInfo, extIf *externalInt
Name: nwInfo.Id,
NetworkAdapterName: networkAdapterName,
DNSServerList: strings.Join(nwInfo.DNS.Servers, ","),
Policies: policy.SerializePolicies(policy.NetworkPolicy, nwInfo.Policies),
Policies: policy.SerializePolicies(policy.NetworkPolicy, nwInfo.Policies, nil),
}

// Set the VLAN and OutboundNAT policies
Expand Down
41 changes: 0 additions & 41 deletions network/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package policy

import (
"encoding/json"
"log"
)

const (
Expand All @@ -17,43 +16,3 @@ type Policy struct {
Type CNIPolicyType
Data json.RawMessage
}

// SerializePolicies serializes policies to json.
func SerializePolicies(policyType CNIPolicyType, policies []Policy) []json.RawMessage {
var jsonPolicies []json.RawMessage
for _, policy := range policies {
if policy.Type == policyType {
jsonPolicies = append(jsonPolicies, policy.Data)
}
}
return jsonPolicies
}

// GetOutBoundNatExceptionList returns exception list for outbound nat policy
func GetOutBoundNatExceptionList(policies []Policy) ([]string, error) {
type KVPair struct {
Type CNIPolicyType `json:"Type"`
ExceptionList json.RawMessage `json:"ExceptionList"`
}

for _, policy := range policies {
if policy.Type == EndpointPolicy {
var data KVPair
if err := json.Unmarshal(policy.Data, &data); err != nil {
return nil, err
}

if data.Type == OutBoundNatPolicy {
var exceptionList []string
if err := json.Unmarshal(data.ExceptionList, &exceptionList); err != nil {
return nil, err
}

return exceptionList, nil
}
}
}

log.Printf("OutBoundNAT policy not set.")
return nil, nil
}
110 changes: 110 additions & 0 deletions network/policy/policy_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package policy

import (
"encoding/json"
"fmt"
"log"

"github.com/Microsoft/hcsshim"
)

// SerializePolicies serializes policies to json.
func SerializePolicies(policyType CNIPolicyType, policies []Policy, epInfoData map[string]interface{}) []json.RawMessage {
var jsonPolicies []json.RawMessage
for _, policy := range policies {
if policy.Type == policyType {
if isPolicyTypeOutBoundNAT := IsPolicyTypeOutBoundNAT(policy); isPolicyTypeOutBoundNAT {
if serializedOutboundNatPolicy, err := SerializeOutBoundNATPolicy(policies, epInfoData); err != nil {
log.Printf("Failed to serialize OutBoundNAT policy")
} else {
jsonPolicies = append(jsonPolicies, serializedOutboundNatPolicy)
}
} else {
jsonPolicies = append(jsonPolicies, policy.Data)
}
}
}
return jsonPolicies
}

// GetOutBoundNatExceptionList returns exception list for outbound nat policy
func GetOutBoundNatExceptionList(policies []Policy) ([]string, error) {
type KVPair struct {
Type CNIPolicyType `json:"Type"`
ExceptionList json.RawMessage `json:"ExceptionList"`
}

for _, policy := range policies {
if policy.Type == EndpointPolicy {
var data KVPair
if err := json.Unmarshal(policy.Data, &data); err != nil {
return nil, err
}

if data.Type == OutBoundNatPolicy {
var exceptionList []string
if err := json.Unmarshal(data.ExceptionList, &exceptionList); err != nil {
return nil, err
}

return exceptionList, nil
}
}
}

log.Printf("OutBoundNAT policy not set")
return nil, nil
}

// IsPolicyTypeOutBoundNAT return true if the policy type is OutBoundNAT
func IsPolicyTypeOutBoundNAT(policy Policy) bool {
if policy.Type == EndpointPolicy {
type KVPair struct {
Type CNIPolicyType `json:"Type"`
ExceptionList json.RawMessage `json:"ExceptionList"`
}
var data KVPair
if err := json.Unmarshal(policy.Data, &data); err != nil {
return false
}

if data.Type == OutBoundNatPolicy {
return true
}
}

return false
}

// SerializeOutBoundNATPolicy formulates OutBoundNAT policy and returns serialized json
func SerializeOutBoundNATPolicy(policies []Policy, epInfoData map[string]interface{}) (json.RawMessage, error) {
outBoundNatPolicy := hcsshim.OutboundNatPolicy{}
outBoundNatPolicy.Policy.Type = hcsshim.OutboundNat

exceptionList, err := GetOutBoundNatExceptionList(policies)
if err != nil {
log.Printf("Failed to parse outbound NAT policy %v", err)
return nil, err
}

if exceptionList != nil {
for _, ipAddress := range exceptionList {
outBoundNatPolicy.Exceptions = append(outBoundNatPolicy.Exceptions, ipAddress)
}
}

if epInfoData["cnetAddressSpace"] != nil {
if cnetAddressSpace := epInfoData["cnetAddressSpace"].([]string); cnetAddressSpace != nil {
for _, ipAddress := range cnetAddressSpace {
outBoundNatPolicy.Exceptions = append(outBoundNatPolicy.Exceptions, ipAddress)
}
}
}

if outBoundNatPolicy.Exceptions != nil {
serializedOutboundNatPolicy, _ := json.Marshal(outBoundNatPolicy)
return serializedOutboundNatPolicy, nil
}

return nil, fmt.Errorf("OutBoundNAT policy not set")
}