ovmanager.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package ovmanager
  2. import (
  3. "fmt"
  4. "net"
  5. "strconv"
  6. "strings"
  7. "sync"
  8. "github.com/Sirupsen/logrus"
  9. "github.com/docker/libnetwork/datastore"
  10. "github.com/docker/libnetwork/discoverapi"
  11. "github.com/docker/libnetwork/driverapi"
  12. "github.com/docker/libnetwork/idm"
  13. "github.com/docker/libnetwork/netlabel"
  14. "github.com/docker/libnetwork/types"
  15. )
  16. const (
  17. networkType = "overlay"
  18. vxlanIDStart = 4096
  19. vxlanIDEnd = (1 << 24) - 1
  20. )
  21. type networkTable map[string]*network
  22. type driver struct {
  23. config map[string]interface{}
  24. networks networkTable
  25. store datastore.DataStore
  26. vxlanIdm *idm.Idm
  27. sync.Mutex
  28. }
  29. type subnet struct {
  30. subnetIP *net.IPNet
  31. gwIP *net.IPNet
  32. vni uint32
  33. }
  34. type network struct {
  35. id string
  36. driver *driver
  37. subnets []*subnet
  38. sync.Mutex
  39. }
  40. // Init registers a new instance of overlay driver
  41. func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
  42. var err error
  43. c := driverapi.Capability{
  44. DataScope: datastore.GlobalScope,
  45. ConnectivityScope: datastore.GlobalScope,
  46. }
  47. d := &driver{
  48. networks: networkTable{},
  49. config: config,
  50. }
  51. d.vxlanIdm, err = idm.New(nil, "vxlan-id", 0, vxlanIDEnd)
  52. if err != nil {
  53. return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
  54. }
  55. return dc.RegisterDriver(networkType, d, c)
  56. }
  57. func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
  58. if id == "" {
  59. return nil, fmt.Errorf("invalid network id for overlay network")
  60. }
  61. if ipV4Data == nil {
  62. return nil, fmt.Errorf("empty ipv4 data passed during overlay network creation")
  63. }
  64. n := &network{
  65. id: id,
  66. driver: d,
  67. subnets: []*subnet{},
  68. }
  69. opts := make(map[string]string)
  70. vxlanIDList := make([]uint32, 0, len(ipV4Data))
  71. for key, val := range option {
  72. if key == netlabel.OverlayVxlanIDList {
  73. logrus.Debugf("overlay network option: %s", val)
  74. valStrList := strings.Split(val, ",")
  75. for _, idStr := range valStrList {
  76. vni, err := strconv.Atoi(idStr)
  77. if err != nil {
  78. return nil, fmt.Errorf("invalid vxlan id value %q passed", idStr)
  79. }
  80. vxlanIDList = append(vxlanIDList, uint32(vni))
  81. }
  82. } else {
  83. opts[key] = val
  84. }
  85. }
  86. for i, ipd := range ipV4Data {
  87. s := &subnet{
  88. subnetIP: ipd.Pool,
  89. gwIP: ipd.Gateway,
  90. }
  91. if len(vxlanIDList) > i {
  92. s.vni = vxlanIDList[i]
  93. }
  94. if err := n.obtainVxlanID(s); err != nil {
  95. n.releaseVxlanID()
  96. return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err)
  97. }
  98. n.subnets = append(n.subnets, s)
  99. }
  100. val := fmt.Sprintf("%d", n.subnets[0].vni)
  101. for _, s := range n.subnets[1:] {
  102. val = val + fmt.Sprintf(",%d", s.vni)
  103. }
  104. opts[netlabel.OverlayVxlanIDList] = val
  105. d.Lock()
  106. d.networks[id] = n
  107. d.Unlock()
  108. return opts, nil
  109. }
  110. func (d *driver) NetworkFree(id string) error {
  111. if id == "" {
  112. return fmt.Errorf("invalid network id passed while freeing overlay network")
  113. }
  114. d.Lock()
  115. n, ok := d.networks[id]
  116. d.Unlock()
  117. if !ok {
  118. return fmt.Errorf("overlay network with id %s not found", id)
  119. }
  120. // Release all vxlan IDs in one shot.
  121. n.releaseVxlanID()
  122. d.Lock()
  123. delete(d.networks, id)
  124. d.Unlock()
  125. return nil
  126. }
  127. func (n *network) obtainVxlanID(s *subnet) error {
  128. var (
  129. err error
  130. vni uint64
  131. )
  132. n.Lock()
  133. vni = uint64(s.vni)
  134. n.Unlock()
  135. if vni == 0 {
  136. vni, err = n.driver.vxlanIdm.GetIDInRange(vxlanIDStart, vxlanIDEnd)
  137. if err != nil {
  138. return err
  139. }
  140. n.Lock()
  141. s.vni = uint32(vni)
  142. n.Unlock()
  143. return nil
  144. }
  145. return n.driver.vxlanIdm.GetSpecificID(vni)
  146. }
  147. func (n *network) releaseVxlanID() {
  148. n.Lock()
  149. vnis := make([]uint32, 0, len(n.subnets))
  150. for _, s := range n.subnets {
  151. vnis = append(vnis, s.vni)
  152. s.vni = 0
  153. }
  154. n.Unlock()
  155. for _, vni := range vnis {
  156. n.driver.vxlanIdm.Release(uint64(vni))
  157. }
  158. }
  159. func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
  160. return types.NotImplementedErrorf("not implemented")
  161. }
  162. func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
  163. }
  164. func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
  165. return "", nil
  166. }
  167. func (d *driver) DeleteNetwork(nid string) error {
  168. return types.NotImplementedErrorf("not implemented")
  169. }
  170. func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
  171. return types.NotImplementedErrorf("not implemented")
  172. }
  173. func (d *driver) DeleteEndpoint(nid, eid string) error {
  174. return types.NotImplementedErrorf("not implemented")
  175. }
  176. func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
  177. return nil, types.NotImplementedErrorf("not implemented")
  178. }
  179. // Join method is invoked when a Sandbox is attached to an endpoint.
  180. func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
  181. return types.NotImplementedErrorf("not implemented")
  182. }
  183. // Leave method is invoked when a Sandbox detaches from an endpoint.
  184. func (d *driver) Leave(nid, eid string) error {
  185. return types.NotImplementedErrorf("not implemented")
  186. }
  187. func (d *driver) Type() string {
  188. return networkType
  189. }
  190. func (d *driver) IsBuiltIn() bool {
  191. return true
  192. }
  193. // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
  194. func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
  195. return types.NotImplementedErrorf("not implemented")
  196. }
  197. // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
  198. func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
  199. return types.NotImplementedErrorf("not implemented")
  200. }
  201. func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
  202. return types.NotImplementedErrorf("not implemented")
  203. }
  204. func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
  205. return types.NotImplementedErrorf("not implemented")
  206. }