ovmanager.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. package ovmanager
  2. import (
  3. "context"
  4. "fmt"
  5. "net"
  6. "strconv"
  7. "sync"
  8. "github.com/containerd/log"
  9. "github.com/docker/docker/libnetwork/bitmap"
  10. "github.com/docker/docker/libnetwork/driverapi"
  11. "github.com/docker/docker/libnetwork/drivers/overlay/overlayutils"
  12. "github.com/docker/docker/libnetwork/netlabel"
  13. "github.com/docker/docker/libnetwork/scope"
  14. "github.com/docker/docker/libnetwork/types"
  15. )
  16. const (
  17. networkType = "overlay"
  18. // The lowest VNI value to auto-assign. Windows does not support VXLAN IDs
  19. // which overlap the range of 802.1Q VLAN IDs [0, 4095].
  20. vxlanIDStart = 4096
  21. // The largest VNI value permitted by RFC 7348.
  22. vxlanIDEnd = (1 << 24) - 1
  23. )
  24. type networkTable map[string]*network
  25. type driver struct {
  26. mu sync.Mutex
  27. networks networkTable
  28. vxlanIdm *bitmap.Bitmap
  29. }
  30. type subnet struct {
  31. subnetIP *net.IPNet
  32. gwIP *net.IPNet
  33. vni uint32
  34. }
  35. type network struct {
  36. id string
  37. driver *driver
  38. subnets []*subnet
  39. }
  40. // Register registers a new instance of the overlay driver.
  41. func Register(r driverapi.Registerer) error {
  42. return r.RegisterDriver(networkType, newDriver(), driverapi.Capability{
  43. DataScope: scope.Global,
  44. ConnectivityScope: scope.Global,
  45. })
  46. }
  47. func newDriver() *driver {
  48. return &driver{
  49. networks: networkTable{},
  50. vxlanIdm: bitmap.New(vxlanIDEnd + 1), // The full range of valid vxlan IDs: [0, 2^24).
  51. }
  52. }
  53. func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
  54. if id == "" {
  55. return nil, fmt.Errorf("invalid network id for overlay network")
  56. }
  57. if ipV4Data == nil {
  58. return nil, fmt.Errorf("empty ipv4 data passed during overlay network creation")
  59. }
  60. n := &network{
  61. id: id,
  62. driver: d,
  63. subnets: []*subnet{},
  64. }
  65. opts := make(map[string]string)
  66. vxlanIDList := make([]uint32, 0, len(ipV4Data))
  67. for key, val := range option {
  68. if key == netlabel.OverlayVxlanIDList {
  69. log.G(context.TODO()).Debugf("overlay network option: %s", val)
  70. var err error
  71. vxlanIDList, err = overlayutils.AppendVNIList(vxlanIDList, val)
  72. if err != nil {
  73. return nil, err
  74. }
  75. } else {
  76. opts[key] = val
  77. }
  78. }
  79. d.mu.Lock()
  80. defer d.mu.Unlock()
  81. for i, ipd := range ipV4Data {
  82. s := &subnet{
  83. subnetIP: ipd.Pool,
  84. gwIP: ipd.Gateway,
  85. }
  86. if len(vxlanIDList) > i { // The VNI for this subnet was specified in the network options.
  87. s.vni = vxlanIDList[i]
  88. err := d.vxlanIdm.Set(uint64(s.vni)) // Mark VNI as in-use.
  89. if err != nil {
  90. // The VNI is already in use by another subnet/network.
  91. n.releaseVxlanID()
  92. return nil, fmt.Errorf("could not assign vxlan id %v to pool %s: %v", s.vni, s.subnetIP, err)
  93. }
  94. } else {
  95. // Allocate an available VNI for the subnet, outside the range of 802.1Q VLAN IDs.
  96. vni, err := d.vxlanIdm.SetAnyInRange(vxlanIDStart, vxlanIDEnd, true)
  97. if err != nil {
  98. n.releaseVxlanID()
  99. return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err)
  100. }
  101. s.vni = uint32(vni)
  102. }
  103. n.subnets = append(n.subnets, s)
  104. }
  105. val := strconv.FormatUint(uint64(n.subnets[0].vni), 10)
  106. for _, s := range n.subnets[1:] {
  107. val = val + "," + strconv.FormatUint(uint64(s.vni), 10)
  108. }
  109. opts[netlabel.OverlayVxlanIDList] = val
  110. if _, ok := d.networks[id]; ok {
  111. n.releaseVxlanID()
  112. return nil, fmt.Errorf("network %s already exists", id)
  113. }
  114. d.networks[id] = n
  115. return opts, nil
  116. }
  117. func (d *driver) NetworkFree(id string) error {
  118. if id == "" {
  119. return fmt.Errorf("invalid network id passed while freeing overlay network")
  120. }
  121. d.mu.Lock()
  122. defer d.mu.Unlock()
  123. n, ok := d.networks[id]
  124. if !ok {
  125. return fmt.Errorf("overlay network with id %s not found", id)
  126. }
  127. // Release all vxlan IDs in one shot.
  128. n.releaseVxlanID()
  129. delete(d.networks, id)
  130. return nil
  131. }
  132. func (n *network) releaseVxlanID() {
  133. for _, s := range n.subnets {
  134. n.driver.vxlanIdm.Unset(uint64(s.vni))
  135. s.vni = 0
  136. }
  137. }
  138. func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
  139. return types.NotImplementedErrorf("not implemented")
  140. }
  141. func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
  142. }
  143. func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
  144. return "", nil
  145. }
  146. func (d *driver) DeleteNetwork(nid string) error {
  147. return types.NotImplementedErrorf("not implemented")
  148. }
  149. func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
  150. return types.NotImplementedErrorf("not implemented")
  151. }
  152. func (d *driver) DeleteEndpoint(nid, eid string) error {
  153. return types.NotImplementedErrorf("not implemented")
  154. }
  155. func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
  156. return nil, types.NotImplementedErrorf("not implemented")
  157. }
  158. // Join method is invoked when a Sandbox is attached to an endpoint.
  159. func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
  160. return types.NotImplementedErrorf("not implemented")
  161. }
  162. // Leave method is invoked when a Sandbox detaches from an endpoint.
  163. func (d *driver) Leave(nid, eid string) error {
  164. return types.NotImplementedErrorf("not implemented")
  165. }
  166. func (d *driver) Type() string {
  167. return networkType
  168. }
  169. func (d *driver) IsBuiltIn() bool {
  170. return true
  171. }
  172. func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
  173. return types.NotImplementedErrorf("not implemented")
  174. }
  175. func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
  176. return types.NotImplementedErrorf("not implemented")
  177. }