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