ov_network_windows.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. package overlay
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "net"
  7. "strconv"
  8. "strings"
  9. "sync"
  10. "github.com/Microsoft/hcsshim"
  11. "github.com/containerd/log"
  12. "github.com/docker/docker/libnetwork/driverapi"
  13. "github.com/docker/docker/libnetwork/netlabel"
  14. "github.com/docker/docker/libnetwork/portmapper"
  15. "github.com/docker/docker/libnetwork/types"
  16. )
  17. var (
  18. hostMode bool
  19. networkMu sync.Mutex
  20. )
  21. type networkTable map[string]*network
  22. type subnet struct {
  23. vni uint32
  24. subnetIP *net.IPNet
  25. gwIP *net.IP
  26. }
  27. type subnetJSON struct {
  28. SubnetIP string
  29. GwIP string
  30. Vni uint32
  31. }
  32. type network struct {
  33. id string
  34. name string
  35. hnsID string
  36. providerAddress string
  37. interfaceName string
  38. endpoints endpointTable
  39. driver *driver
  40. initEpoch int
  41. initErr error
  42. subnets []*subnet
  43. secure bool
  44. portMapper *portmapper.PortMapper
  45. sync.Mutex
  46. }
  47. func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
  48. return nil, types.NotImplementedErrorf("not implemented")
  49. }
  50. func (d *driver) NetworkFree(id string) error {
  51. return types.NotImplementedErrorf("not implemented")
  52. }
  53. func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
  54. var (
  55. networkName string
  56. interfaceName string
  57. staleNetworks []string
  58. )
  59. if id == "" {
  60. return fmt.Errorf("invalid network id")
  61. }
  62. if nInfo == nil {
  63. return fmt.Errorf("invalid network info structure")
  64. }
  65. if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" {
  66. return types.InvalidParameterErrorf("ipv4 pool is empty")
  67. }
  68. staleNetworks = make([]string, 0)
  69. vnis := make([]uint32, 0, len(ipV4Data))
  70. existingNetwork := d.network(id)
  71. if existingNetwork != nil {
  72. log.G(context.TODO()).Debugf("Network preexists. Deleting %s", id)
  73. err := d.DeleteNetwork(id)
  74. if err != nil {
  75. log.G(context.TODO()).Errorf("Error deleting stale network %s", err.Error())
  76. }
  77. }
  78. n := &network{
  79. id: id,
  80. driver: d,
  81. endpoints: endpointTable{},
  82. subnets: []*subnet{},
  83. portMapper: portmapper.New(),
  84. }
  85. genData, ok := option[netlabel.GenericData].(map[string]string)
  86. if !ok {
  87. return fmt.Errorf("Unknown generic data option")
  88. }
  89. for label, value := range genData {
  90. switch label {
  91. case "com.docker.network.windowsshim.networkname":
  92. networkName = value
  93. case "com.docker.network.windowsshim.interface":
  94. interfaceName = value
  95. case "com.docker.network.windowsshim.hnsid":
  96. n.hnsID = value
  97. case netlabel.OverlayVxlanIDList:
  98. vniStrings := strings.Split(value, ",")
  99. for _, vniStr := range vniStrings {
  100. vni, err := strconv.Atoi(vniStr)
  101. if err != nil {
  102. return fmt.Errorf("invalid vxlan id value %q passed", vniStr)
  103. }
  104. vnis = append(vnis, uint32(vni))
  105. }
  106. }
  107. }
  108. // If we are getting vnis from libnetwork, either we get for
  109. // all subnets or none.
  110. if len(vnis) < len(ipV4Data) {
  111. return fmt.Errorf("insufficient vnis(%d) passed to overlay. Windows driver requires VNIs to be prepopulated", len(vnis))
  112. }
  113. for i, ipd := range ipV4Data {
  114. s := &subnet{
  115. subnetIP: ipd.Pool,
  116. gwIP: &ipd.Gateway.IP,
  117. }
  118. if len(vnis) != 0 {
  119. s.vni = vnis[i]
  120. }
  121. d.Lock()
  122. for _, network := range d.networks {
  123. found := false
  124. for _, sub := range network.subnets {
  125. if sub.vni == s.vni {
  126. staleNetworks = append(staleNetworks, network.id)
  127. found = true
  128. break
  129. }
  130. }
  131. if found {
  132. break
  133. }
  134. }
  135. d.Unlock()
  136. n.subnets = append(n.subnets, s)
  137. }
  138. for _, staleNetwork := range staleNetworks {
  139. d.DeleteNetwork(staleNetwork)
  140. }
  141. n.name = networkName
  142. if n.name == "" {
  143. n.name = id
  144. }
  145. n.interfaceName = interfaceName
  146. if nInfo != nil {
  147. if err := nInfo.TableEventRegister(ovPeerTable, driverapi.EndpointObject); err != nil {
  148. return err
  149. }
  150. }
  151. d.addNetwork(n)
  152. err := d.createHnsNetwork(n)
  153. if err != nil {
  154. d.deleteNetwork(id)
  155. } else {
  156. genData["com.docker.network.windowsshim.hnsid"] = n.hnsID
  157. }
  158. return err
  159. }
  160. func (d *driver) DeleteNetwork(nid string) error {
  161. if nid == "" {
  162. return fmt.Errorf("invalid network id")
  163. }
  164. n := d.network(nid)
  165. if n == nil {
  166. return types.ForbiddenErrorf("could not find network with id %s", nid)
  167. }
  168. _, err := hcsshim.HNSNetworkRequest("DELETE", n.hnsID, "")
  169. if err != nil {
  170. return types.ForbiddenErrorf(err.Error())
  171. }
  172. d.deleteNetwork(nid)
  173. return nil
  174. }
  175. func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
  176. return nil
  177. }
  178. func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
  179. return nil
  180. }
  181. func (d *driver) addNetwork(n *network) {
  182. d.Lock()
  183. d.networks[n.id] = n
  184. d.Unlock()
  185. }
  186. func (d *driver) deleteNetwork(nid string) {
  187. d.Lock()
  188. delete(d.networks, nid)
  189. d.Unlock()
  190. }
  191. func (d *driver) network(nid string) *network {
  192. d.Lock()
  193. defer d.Unlock()
  194. return d.networks[nid]
  195. }
  196. // func (n *network) restoreNetworkEndpoints() error {
  197. // log.G(ctx).Infof("Restoring endpoints for overlay network: %s", n.id)
  198. // hnsresponse, err := hcsshim.HNSListEndpointRequest("GET", "", "")
  199. // if err != nil {
  200. // return err
  201. // }
  202. // for _, endpoint := range hnsresponse {
  203. // if endpoint.VirtualNetwork != n.hnsID {
  204. // continue
  205. // }
  206. // ep := n.convertToOverlayEndpoint(&endpoint)
  207. // if ep != nil {
  208. // log.G(ctx).Debugf("Restored endpoint:%s Remote:%t", ep.id, ep.remote)
  209. // n.addEndpoint(ep)
  210. // }
  211. // }
  212. // return nil
  213. // }
  214. func (n *network) convertToOverlayEndpoint(v *hcsshim.HNSEndpoint) *endpoint {
  215. ep := &endpoint{
  216. id: v.Name,
  217. profileID: v.Id,
  218. nid: n.id,
  219. remote: v.IsRemoteEndpoint,
  220. }
  221. mac, err := net.ParseMAC(v.MacAddress)
  222. if err != nil {
  223. return nil
  224. }
  225. ep.mac = mac
  226. ep.addr = &net.IPNet{
  227. IP: v.IPAddress,
  228. Mask: net.CIDRMask(32, 32),
  229. }
  230. return ep
  231. }
  232. func (d *driver) createHnsNetwork(n *network) error {
  233. subnets := []hcsshim.Subnet{}
  234. for _, s := range n.subnets {
  235. subnet := hcsshim.Subnet{
  236. AddressPrefix: s.subnetIP.String(),
  237. }
  238. if s.gwIP != nil {
  239. subnet.GatewayAddress = s.gwIP.String()
  240. }
  241. vsidPolicy, err := json.Marshal(hcsshim.VsidPolicy{
  242. Type: "VSID",
  243. VSID: uint(s.vni),
  244. })
  245. if err != nil {
  246. return err
  247. }
  248. subnet.Policies = append(subnet.Policies, vsidPolicy)
  249. subnets = append(subnets, subnet)
  250. }
  251. network := &hcsshim.HNSNetwork{
  252. Name: n.name,
  253. Type: d.Type(),
  254. Subnets: subnets,
  255. NetworkAdapterName: n.interfaceName,
  256. AutomaticDNS: true,
  257. }
  258. configurationb, err := json.Marshal(network)
  259. if err != nil {
  260. return err
  261. }
  262. configuration := string(configurationb)
  263. log.G(context.TODO()).Infof("HNSNetwork Request =%v", configuration)
  264. hnsresponse, err := hcsshim.HNSNetworkRequest("POST", "", configuration)
  265. if err != nil {
  266. return err
  267. }
  268. n.hnsID = hnsresponse.Id
  269. n.providerAddress = hnsresponse.ManagementIP
  270. return nil
  271. }
  272. // contains return true if the passed ip belongs to one the network's
  273. // subnets
  274. func (n *network) contains(ip net.IP) bool {
  275. for _, s := range n.subnets {
  276. if s.subnetIP.Contains(ip) {
  277. return true
  278. }
  279. }
  280. return false
  281. }
  282. // getSubnetforIP returns the subnet to which the given IP belongs
  283. func (n *network) getSubnetforIP(ip *net.IPNet) *subnet {
  284. for _, s := range n.subnets {
  285. // first check if the mask lengths are the same
  286. i, _ := s.subnetIP.Mask.Size()
  287. j, _ := ip.Mask.Size()
  288. if i != j {
  289. continue
  290. }
  291. if s.subnetIP.Contains(ip.IP) {
  292. return s
  293. }
  294. }
  295. return nil
  296. }
  297. // getMatchingSubnet return the network's subnet that matches the input
  298. func (n *network) getMatchingSubnet(ip *net.IPNet) *subnet {
  299. if ip == nil {
  300. return nil
  301. }
  302. for _, s := range n.subnets {
  303. // first check if the mask lengths are the same
  304. i, _ := s.subnetIP.Mask.Size()
  305. j, _ := ip.Mask.Size()
  306. if i != j {
  307. continue
  308. }
  309. if s.subnetIP.IP.Equal(ip.IP) {
  310. return s
  311. }
  312. }
  313. return nil
  314. }