Skip to content

Commit ecbb95e

Browse files
authored
Merge pull request #35 from dariopb/master
Adds support for port forwarding on non-nat network types
2 parents 84f9a31 + 032bbff commit ecbb95e

File tree

3 files changed

+87
-20
lines changed

3 files changed

+87
-20
lines changed

cni/cni.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77
"encoding/json"
88
"fmt"
99
"net"
10+
"strconv"
1011
"strings"
1112

13+
"github.com/Microsoft/hcsshim/hcn"
1214
network "github.com/Microsoft/windows-container-networking/network"
1315
cniSkel "github.com/containernetworking/cni/pkg/skel"
1416
cniTypes "github.com/containernetworking/cni/pkg/types"
@@ -68,6 +70,7 @@ type NetworkConfig struct {
6870
Type string `json:"type"` // As per SPEC, Type is Name of the Binary
6971
Ipam IpamConfig `json:"ipam"`
7072
DNS cniTypes.DNS `json:"dns"`
73+
OptionalFlags OptionalFlags `json:"optionalFlags"`
7174
RuntimeConfig RuntimeConfig `json:"runtimeConfig"`
7275
AdditionalArgs []KVP
7376
}
@@ -100,6 +103,11 @@ type K8SPodEnvArgs struct {
100103
K8S_POD_INFRA_CONTAINER_ID cniTypes.UnmarshallableString `json:"K8S_POD_INFRA_CONTAINER_ID,omitempty"`
101104
}
102105

106+
type OptionalFlags struct {
107+
LocalRoutePortMapping bool `json:"localRoutedPortMapping"`
108+
AllowAclPortMapping bool `json:"allowAclPortMapping"`
109+
}
110+
103111
func (r *Result) Print() {
104112
fmt.Printf(r.String())
105113
}
@@ -243,6 +251,41 @@ func (config *NetworkConfig) GetNetworkInfo(podNamespace string) *network.Networ
243251
return ninfo
244252
}
245253

254+
// getInACLRule generates an In ACLs for mapped ports
255+
func getInACLRule(mapping *PortMapping, aclPriority uint16) (*network.Policy, error) {
256+
257+
var err error
258+
259+
in := hcn.AclPolicySetting{
260+
Protocols: mapping.Protocol,
261+
Action: hcn.ActionTypeAllow,
262+
Direction: hcn.DirectionTypeIn,
263+
LocalPorts: strconv.Itoa(mapping.ContainerPort),
264+
Priority: aclPriority,
265+
}
266+
267+
rawJSON, err := json.Marshal(in)
268+
if err != nil {
269+
return nil, fmt.Errorf("failed marshalling acl: %v", err)
270+
}
271+
272+
inPol := hcn.EndpointPolicy{
273+
Type: hcn.ACL,
274+
Settings: rawJSON,
275+
}
276+
277+
rawData, err := json.Marshal(inPol)
278+
inPolicy := network.Policy{
279+
Type: network.EndpointPolicy,
280+
Data: rawData}
281+
282+
if err != nil {
283+
return nil, fmt.Errorf("failed marshalling acl: %v", err)
284+
}
285+
286+
return &inPolicy, nil
287+
}
288+
246289
// GetEndpointInfo constructs endpoint info using endpoint id, containerid and netns
247290
func (config *NetworkConfig) GetEndpointInfo(
248291
networkInfo *network.NetworkInfo,
@@ -269,13 +312,27 @@ func (config *NetworkConfig) GetEndpointInfo(
269312

270313
runtimeConf := config.RuntimeConfig
271314
logrus.Debugf("Parsing port mappings from %+v", runtimeConf.PortMappings)
315+
316+
flags := uint32(0)
317+
if config.OptionalFlags.LocalRoutePortMapping {
318+
flags = 1
319+
}
320+
var aclPriority uint16 = 1000
272321
for _, mapping := range runtimeConf.PortMappings {
273-
policy, err := network.GetPortMappingPolicy(mapping.HostPort, mapping.ContainerPort, mapping.Protocol)
322+
policy, err := network.GetPortMappingPolicy(mapping.HostPort, mapping.ContainerPort, mapping.Protocol, flags)
274323
if err != nil {
275324
return nil, fmt.Errorf("failed during GetEndpointInfo from netconf: %v", err)
276325
}
277326
logrus.Debugf("Created raw policy from mapping: %+v --- %+v", mapping, policy)
278327
epInfo.Policies = append(epInfo.Policies, policy)
328+
329+
if config.OptionalFlags.AllowAclPortMapping {
330+
pol, err := getInACLRule(&mapping, aclPriority)
331+
if err != nil {
332+
return nil, fmt.Errorf("failed getInACLRule: %v", err)
333+
}
334+
epInfo.Policies = append(epInfo.Policies, *pol)
335+
}
279336
}
280337

281338
return epInfo, nil

network/policy.go

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/json"
88
"errors"
99
"github.com/Microsoft/hcsshim/hcn"
10+
"strconv"
1011
"strings"
1112
)
1213

@@ -24,32 +25,40 @@ type Policy struct {
2425
}
2526

2627
// GetPortMappingPolicy creates an HCN PortMappingPolicy and stores it in CNI Policy.
27-
func GetPortMappingPolicy(externalPort int, internalPort int, protocol string) (Policy, error) {
28+
func GetPortMappingPolicy(externalPort int, internalPort int, protocol string, flags uint32) (Policy, error) {
2829
var protocolInt uint32
29-
switch strings.ToLower(protocol) {
30-
case "tcp":
31-
protocolInt = 6
32-
break
33-
case "udp":
34-
protocolInt = 17
35-
break
36-
case "icmpv4":
37-
protocolInt = 1
38-
break
39-
case "icmpv6":
40-
protocolInt = 58
41-
break
42-
case "igmp":
43-
protocolInt = 2
44-
break
45-
default:
46-
return Policy{}, errors.New("invalid protocol supplied to port mapping policy")
30+
31+
// protocol can be passed either as a number or a name
32+
u, error := strconv.ParseUint(protocol, 0, 10)
33+
if error != nil {
34+
switch strings.ToLower(protocol) {
35+
case "tcp":
36+
protocolInt = 6
37+
break
38+
case "udp":
39+
protocolInt = 17
40+
break
41+
case "icmpv4":
42+
protocolInt = 1
43+
break
44+
case "icmpv6":
45+
protocolInt = 58
46+
break
47+
case "igmp":
48+
protocolInt = 2
49+
break
50+
default:
51+
return Policy{}, errors.New("invalid protocol supplied to port mapping policy")
52+
}
53+
} else {
54+
protocolInt = uint32(u)
4755
}
4856

4957
portMappingPolicy := hcn.PortMappingPolicySetting{
5058
ExternalPort: uint16(externalPort),
5159
InternalPort: uint16(internalPort),
5260
Protocol: protocolInt,
61+
Flags: flags,
5362
}
5463
rawPolicy, _ := json.Marshal(portMappingPolicy)
5564
endpointPolicy := hcn.EndpointPolicy{

vendor/github.com/Microsoft/hcsshim/hcn/hcnpolicy.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)