device_windows.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright 2018 flannel authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // +build windows
  15. package vxlan
  16. import (
  17. "encoding/json"
  18. "github.com/Microsoft/hcsshim/hcn"
  19. "github.com/coreos/flannel/pkg/ip"
  20. log "github.com/golang/glog"
  21. "github.com/juju/errors"
  22. "k8s.io/apimachinery/pkg/util/wait"
  23. "time"
  24. )
  25. type vxlanDeviceAttrs struct {
  26. vni uint32
  27. name string
  28. gbp bool
  29. addressPrefix ip.IP4Net
  30. }
  31. type vxlanDevice struct {
  32. link *hcn.HostComputeNetwork
  33. macPrefix string
  34. directRouting bool
  35. }
  36. func newVXLANDevice(devAttrs *vxlanDeviceAttrs) (*vxlanDevice, error) {
  37. subnet := createSubnet(devAttrs.addressPrefix.String(), (devAttrs.addressPrefix.IP + 1).String(), "0.0.0.0/0")
  38. network := &hcn.HostComputeNetwork{
  39. Type: "Overlay",
  40. Name: devAttrs.name,
  41. Ipams: []hcn.Ipam{
  42. {
  43. Type: "Static",
  44. Subnets: []hcn.Subnet{
  45. *subnet,
  46. },
  47. },
  48. },
  49. Flags: hcn.EnableNonPersistent,
  50. SchemaVersion: hcn.SchemaVersion{
  51. Major: 2,
  52. Minor: 0,
  53. },
  54. }
  55. vsid := &hcn.VsidPolicySetting{
  56. IsolationId: devAttrs.vni,
  57. }
  58. vsidJson, err := json.Marshal(vsid)
  59. if err != nil {
  60. return nil, err
  61. }
  62. sp := &hcn.SubnetPolicy{
  63. Type: hcn.VSID,
  64. }
  65. sp.Settings = vsidJson
  66. spJson, err := json.Marshal(sp)
  67. if err != nil {
  68. return nil, err
  69. }
  70. network.Ipams[0].Subnets[0].Policies = append(network.Ipams[0].Subnets[0].Policies, spJson)
  71. hnsNetwork, err := ensureNetwork(network, devAttrs.addressPrefix.String())
  72. if err != nil {
  73. return nil, err
  74. }
  75. return &vxlanDevice{
  76. link: hnsNetwork,
  77. }, nil
  78. }
  79. func ensureNetwork(expectedNetwork *hcn.HostComputeNetwork, expectedAddressPrefix string) (*hcn.HostComputeNetwork, error) {
  80. createNetwork := true
  81. networkName := expectedNetwork.Name
  82. // 1. Check if the HostComputeNetwork exists and has the expected settings
  83. existingNetwork, err := hcn.GetNetworkByName(networkName)
  84. if err == nil {
  85. if existingNetwork.Type == expectedNetwork.Type {
  86. if existingNetwork.Ipams[0].Subnets[0].IpAddressPrefix == expectedAddressPrefix {
  87. createNetwork = false
  88. log.Infof("Found existing HostComputeNetwork %s", networkName)
  89. }
  90. }
  91. }
  92. // 2. Create a new HNSNetwork
  93. if createNetwork {
  94. if existingNetwork != nil {
  95. if err := existingNetwork.Delete(); err != nil {
  96. return nil, errors.Annotatef(err, "failed to delete existing HostComputeNetwork %s", networkName)
  97. }
  98. log.Infof("Deleted stale HostComputeNetwork %s", networkName)
  99. }
  100. log.Infof("Attempting to create HostComputeNetwork %v", expectedNetwork)
  101. newNetwork, err := expectedNetwork.Create()
  102. if err != nil {
  103. return nil, errors.Annotatef(err, "failed to create HostComputeNetwork %s", networkName)
  104. }
  105. var waitErr, lastErr error
  106. // Wait for the network to populate Management IP
  107. log.Infof("Waiting to get ManagementIP from HostComputeNetwork %s", networkName)
  108. waitErr = wait.Poll(500*time.Millisecond, 5*time.Second, func() (done bool, err error) {
  109. newNetwork, lastErr = hcn.GetNetworkByID(newNetwork.Id)
  110. return newNetwork != nil && len(getManagementIP(newNetwork)) != 0, nil
  111. })
  112. if waitErr == wait.ErrWaitTimeout {
  113. return nil, errors.Annotatef(lastErr, "timeout, failed to get management IP from HostComputeNetwork %s", networkName)
  114. }
  115. managementIP := getManagementIP(newNetwork)
  116. // Wait for the interface with the management IP
  117. log.Infof("Waiting to get net interface for HostComputeNetwork %s (%s)", networkName, managementIP)
  118. managementIPv4, err := ip.ParseIP4(managementIP)
  119. if err != nil {
  120. return nil, errors.Annotatef(err, "Failed to parse management ip (%s)", managementIP)
  121. }
  122. waitErr = wait.Poll(500*time.Millisecond, 5*time.Second, func() (done bool, err error) {
  123. _, lastErr = ip.GetInterfaceByIP(managementIPv4.ToIP())
  124. return lastErr == nil, nil
  125. })
  126. if waitErr == wait.ErrWaitTimeout {
  127. return nil, errors.Annotatef(lastErr, "timeout, failed to get net interface for HostComputeNetwork %s (%s)", networkName, managementIP)
  128. }
  129. log.Infof("Created HostComputeNetwork %s", networkName)
  130. existingNetwork = newNetwork
  131. }
  132. addHostRoute := true
  133. for _, policy := range existingNetwork.Policies {
  134. if policy.Type == hcn.HostRoute {
  135. addHostRoute = false
  136. }
  137. }
  138. if addHostRoute {
  139. hostRoutePolicy := hcn.NetworkPolicy{
  140. Type: hcn.HostRoute,
  141. Settings: []byte("{}"),
  142. }
  143. networkRequest := hcn.PolicyNetworkRequest{
  144. Policies: []hcn.NetworkPolicy{hostRoutePolicy},
  145. }
  146. err = existingNetwork.AddPolicy(networkRequest)
  147. if err != nil {
  148. log.Infof("Could not apply HostRoute policy for local host to local pod connectivity. This policy requires Windows 18321.1000.19h1_release.190117-1502 or newer")
  149. }
  150. }
  151. return existingNetwork, nil
  152. }
  153. func getManagementIP(network *hcn.HostComputeNetwork) string {
  154. for _, policy := range network.Policies {
  155. if policy.Type == hcn.ProviderAddress {
  156. policySettings := hcn.ProviderAddressEndpointPolicySetting{}
  157. err := json.Unmarshal(policy.Settings, &policySettings)
  158. if err != nil {
  159. return ""
  160. }
  161. return policySettings.ProviderAddress
  162. }
  163. }
  164. return ""
  165. }
  166. func createSubnet(AddressPrefix string, NextHop string, DestPrefix string) *hcn.Subnet {
  167. return &hcn.Subnet{
  168. IpAddressPrefix: AddressPrefix,
  169. Routes: []hcn.Route{
  170. {
  171. NextHop: NextHop,
  172. DestinationPrefix: DestPrefix,
  173. },
  174. },
  175. }
  176. }