1package hcn
2
3import (
4	"encoding/json"
5	"fmt"
6	"math"
7
8	"github.com/Microsoft/hcsshim/internal/hcserror"
9	"github.com/Microsoft/hcsshim/internal/interop"
10	"github.com/sirupsen/logrus"
11)
12
13// Globals are all global properties of the HCN Service.
14type Globals struct {
15	Version Version `json:"Version"`
16}
17
18// Version is the HCN Service version.
19type Version struct {
20	Major int `json:"Major"`
21	Minor int `json:"Minor"`
22}
23
24type VersionRange struct {
25	MinVersion Version
26	MaxVersion Version
27}
28
29type VersionRanges []VersionRange
30
31var (
32	// HNSVersion1803 added ACL functionality.
33	HNSVersion1803 = VersionRanges{VersionRange{MinVersion: Version{Major: 7, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
34	// V2ApiSupport allows the use of V2 Api calls and V2 Schema.
35	V2ApiSupport = VersionRanges{VersionRange{MinVersion: Version{Major: 9, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
36	// Remote Subnet allows for Remote Subnet policies on Overlay networks
37	RemoteSubnetVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 9, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
38	// A Host Route policy allows for local container to local host communication Overlay networks
39	HostRouteVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 9, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
40	// HNS 9.3 through 10.0 (not included), and 10.2+ allows for Direct Server Return for loadbalancing
41	DSRVersion = VersionRanges{
42		VersionRange{MinVersion: Version{Major: 9, Minor: 3}, MaxVersion: Version{Major: 9, Minor: math.MaxInt32}},
43		VersionRange{MinVersion: Version{Major: 10, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
44	}
45	// HNS 9.3 through 10.0 (not included) and, 10.4+ provide support for configuring endpoints with /32 prefixes
46	Slash32EndpointPrefixesVersion = VersionRanges{
47		VersionRange{MinVersion: Version{Major: 9, Minor: 3}, MaxVersion: Version{Major: 9, Minor: math.MaxInt32}},
48		VersionRange{MinVersion: Version{Major: 10, Minor: 4}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
49	}
50	// HNS 9.3 through 10.0 (not included) and, 10.4+ allow for HNS ACL Policies to support protocol 252 for VXLAN
51	AclSupportForProtocol252Version = VersionRanges{
52		VersionRange{MinVersion: Version{Major: 11, Minor: 0}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
53	}
54	// HNS 12.0 allows for session affinity for loadbalancing
55	SessionAffinityVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 12, Minor: 0}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
56	// HNS 10.5 through 11 (not included) and 12.0+ supports Ipv6 dual stack.
57	IPv6DualStackVersion = VersionRanges{
58		VersionRange{MinVersion: Version{Major: 10, Minor: 5}, MaxVersion: Version{Major: 10, Minor: math.MaxInt32}},
59		VersionRange{MinVersion: Version{Major: 12, Minor: 0}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
60	}
61	// HNS 13.0 allows for Set Policy support
62	SetPolicyVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 13, Minor: 0}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
63	// HNS 10.3 allows for VXLAN ports
64	VxlanPortVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 10, Minor: 3}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
65
66	//HNS 9.5 through 10.0(not included), 10.5 through 11.0(not included), 11.11 through 12.0(not included), 12.1 through 13.0(not included), 13.1+ allows for Network L4Proxy Policy support
67	L4ProxyPolicyVersion = VersionRanges{
68		VersionRange{MinVersion: Version{Major: 9, Minor: 5}, MaxVersion: Version{Major: 9, Minor: math.MaxInt32}},
69		VersionRange{MinVersion: Version{Major: 10, Minor: 5}, MaxVersion: Version{Major: 10, Minor: math.MaxInt32}},
70		VersionRange{MinVersion: Version{Major: 11, Minor: 11}, MaxVersion: Version{Major: 11, Minor: math.MaxInt32}},
71		VersionRange{MinVersion: Version{Major: 12, Minor: 1}, MaxVersion: Version{Major: 12, Minor: math.MaxInt32}},
72		VersionRange{MinVersion: Version{Major: 13, Minor: 1}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
73	}
74
75	//HNS 13.2 allows for L4WfpProxy Policy support
76	L4WfpProxyPolicyVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 13, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
77)
78
79// GetGlobals returns the global properties of the HCN Service.
80func GetGlobals() (*Globals, error) {
81	var version Version
82	err := hnsCall("GET", "/globals/version", "", &version)
83	if err != nil {
84		return nil, err
85	}
86
87	globals := &Globals{
88		Version: version,
89	}
90
91	return globals, nil
92}
93
94type hnsResponse struct {
95	Success bool
96	Error   string
97	Output  json.RawMessage
98}
99
100func hnsCall(method, path, request string, returnResponse interface{}) error {
101	var responseBuffer *uint16
102	logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
103
104	err := _hnsCall(method, path, request, &responseBuffer)
105	if err != nil {
106		return hcserror.New(err, "hnsCall ", "")
107	}
108	response := interop.ConvertAndFreeCoTaskMemString(responseBuffer)
109
110	hnsresponse := &hnsResponse{}
111	if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil {
112		return err
113	}
114
115	if !hnsresponse.Success {
116		return fmt.Errorf("HNS failed with error : %s", hnsresponse.Error)
117	}
118
119	if len(hnsresponse.Output) == 0 {
120		return nil
121	}
122
123	logrus.Debugf("Network Response : %s", hnsresponse.Output)
124	err = json.Unmarshal(hnsresponse.Output, returnResponse)
125	if err != nil {
126		return err
127	}
128
129	return nil
130}
131