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