github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/overlay/ovmanager/ovmanager.go (about) 1 package ovmanager 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "strconv" 8 "sync" 9 10 "github.com/containerd/log" 11 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/bitmap" 12 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/driverapi" 13 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/drivers/overlay/overlayutils" 14 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/netlabel" 15 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/scope" 16 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/types" 17 ) 18 19 const ( 20 networkType = "overlay" 21 // The lowest VNI value to auto-assign. Windows does not support VXLAN IDs 22 // which overlap the range of 802.1Q VLAN IDs [0, 4095]. 23 vxlanIDStart = 4096 24 // The largest VNI value permitted by RFC 7348. 25 vxlanIDEnd = (1 << 24) - 1 26 ) 27 28 type networkTable map[string]*network 29 30 type driver struct { 31 mu sync.Mutex 32 networks networkTable 33 vxlanIdm *bitmap.Bitmap 34 } 35 36 type subnet struct { 37 subnetIP *net.IPNet 38 gwIP *net.IPNet 39 vni uint32 40 } 41 42 type network struct { 43 id string 44 driver *driver 45 subnets []*subnet 46 } 47 48 // Register registers a new instance of the overlay driver. 49 func Register(r driverapi.Registerer) error { 50 return r.RegisterDriver(networkType, newDriver(), driverapi.Capability{ 51 DataScope: scope.Global, 52 ConnectivityScope: scope.Global, 53 }) 54 } 55 56 func newDriver() *driver { 57 return &driver{ 58 networks: networkTable{}, 59 vxlanIdm: bitmap.New(vxlanIDEnd + 1), // The full range of valid vxlan IDs: [0, 2^24). 60 } 61 } 62 63 func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) { 64 if id == "" { 65 return nil, fmt.Errorf("invalid network id for overlay network") 66 } 67 68 if ipV4Data == nil { 69 return nil, fmt.Errorf("empty ipv4 data passed during overlay network creation") 70 } 71 72 n := &network{ 73 id: id, 74 driver: d, 75 subnets: []*subnet{}, 76 } 77 78 opts := make(map[string]string) 79 vxlanIDList := make([]uint32, 0, len(ipV4Data)) 80 for key, val := range option { 81 if key == netlabel.OverlayVxlanIDList { 82 log.G(context.TODO()).Debugf("overlay network option: %s", val) 83 var err error 84 vxlanIDList, err = overlayutils.AppendVNIList(vxlanIDList, val) 85 if err != nil { 86 return nil, err 87 } 88 } else { 89 opts[key] = val 90 } 91 } 92 93 d.mu.Lock() 94 defer d.mu.Unlock() 95 for i, ipd := range ipV4Data { 96 s := &subnet{ 97 subnetIP: ipd.Pool, 98 gwIP: ipd.Gateway, 99 } 100 101 if len(vxlanIDList) > i { // The VNI for this subnet was specified in the network options. 102 s.vni = vxlanIDList[i] 103 err := d.vxlanIdm.Set(uint64(s.vni)) // Mark VNI as in-use. 104 if err != nil { 105 // The VNI is already in use by another subnet/network. 106 n.releaseVxlanID() 107 return nil, fmt.Errorf("could not assign vxlan id %v to pool %s: %v", s.vni, s.subnetIP, err) 108 } 109 } else { 110 // Allocate an available VNI for the subnet, outside the range of 802.1Q VLAN IDs. 111 vni, err := d.vxlanIdm.SetAnyInRange(vxlanIDStart, vxlanIDEnd, true) 112 if err != nil { 113 n.releaseVxlanID() 114 return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err) 115 } 116 s.vni = uint32(vni) 117 } 118 119 n.subnets = append(n.subnets, s) 120 } 121 122 val := strconv.FormatUint(uint64(n.subnets[0].vni), 10) 123 for _, s := range n.subnets[1:] { 124 val = val + "," + strconv.FormatUint(uint64(s.vni), 10) 125 } 126 opts[netlabel.OverlayVxlanIDList] = val 127 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.mu.Lock() 143 defer d.mu.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) releaseVxlanID() { 159 for _, s := range n.subnets { 160 n.driver.vxlanIdm.Unset(uint64(s.vni)) 161 s.vni = 0 162 } 163 } 164 165 func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error { 166 return types.NotImplementedErrorf("not implemented") 167 } 168 169 func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) { 170 } 171 172 func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) { 173 return "", nil 174 } 175 176 func (d *driver) DeleteNetwork(nid string) error { 177 return types.NotImplementedErrorf("not implemented") 178 } 179 180 func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error { 181 return types.NotImplementedErrorf("not implemented") 182 } 183 184 func (d *driver) DeleteEndpoint(nid, eid string) error { 185 return types.NotImplementedErrorf("not implemented") 186 } 187 188 func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) { 189 return nil, types.NotImplementedErrorf("not implemented") 190 } 191 192 // Join method is invoked when a Sandbox is attached to an endpoint. 193 func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { 194 return types.NotImplementedErrorf("not implemented") 195 } 196 197 // Leave method is invoked when a Sandbox detaches from an endpoint. 198 func (d *driver) Leave(nid, eid string) error { 199 return types.NotImplementedErrorf("not implemented") 200 } 201 202 func (d *driver) Type() string { 203 return networkType 204 } 205 206 func (d *driver) IsBuiltIn() bool { 207 return true 208 } 209 210 func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error { 211 return types.NotImplementedErrorf("not implemented") 212 } 213 214 func (d *driver) RevokeExternalConnectivity(nid, eid string) error { 215 return types.NotImplementedErrorf("not implemented") 216 }