github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/ipvlan/ipvlan_store.go (about) 1 //go:build linux 2 3 package ipvlan 4 5 import ( 6 "context" 7 "encoding/json" 8 "fmt" 9 "net" 10 11 "github.com/containerd/log" 12 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/datastore" 13 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/discoverapi" 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 ipvlanPrefix = "ipvlan" 21 ipvlanNetworkPrefix = ipvlanPrefix + "/network" 22 ipvlanEndpointPrefix = ipvlanPrefix + "/endpoint" 23 ) 24 25 // networkConfiguration for this driver's network specific configuration 26 type configuration struct { 27 ID string 28 Mtu int 29 dbIndex uint64 30 dbExists bool 31 Internal bool 32 Parent string 33 IpvlanMode string 34 IpvlanFlag string 35 CreatedSlaveLink bool 36 Ipv4Subnets []*ipSubnet 37 Ipv6Subnets []*ipSubnet 38 } 39 40 type ipSubnet struct { 41 SubnetIP string 42 GwIP string 43 } 44 45 // initStore drivers are responsible for caching their own persistent state 46 func (d *driver) initStore(option map[string]interface{}) error { 47 if data, ok := option[netlabel.LocalKVClient]; ok { 48 var err error 49 dsc, ok := data.(discoverapi.DatastoreConfigData) 50 if !ok { 51 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 52 } 53 d.store, err = datastore.FromConfig(dsc) 54 if err != nil { 55 return types.InternalErrorf("ipvlan driver failed to initialize data store: %v", err) 56 } 57 58 err = d.populateNetworks() 59 if err != nil { 60 return err 61 } 62 err = d.populateEndpoints() 63 if err != nil { 64 return err 65 } 66 } 67 68 return nil 69 } 70 71 // populateNetworks is invoked at driver init to recreate persistently stored networks 72 func (d *driver) populateNetworks() error { 73 kvol, err := d.store.List(datastore.Key(ipvlanNetworkPrefix), &configuration{}) 74 if err != nil && err != datastore.ErrKeyNotFound { 75 return fmt.Errorf("failed to get ipvlan network configurations from store: %v", err) 76 } 77 // If empty it simply means no ipvlan networks have been created yet 78 if err == datastore.ErrKeyNotFound { 79 return nil 80 } 81 for _, kvo := range kvol { 82 config := kvo.(*configuration) 83 if _, err = d.createNetwork(config); err != nil { 84 log.G(context.TODO()).Warnf("could not create ipvlan network for id %s from persistent state", config.ID) 85 } 86 } 87 88 return nil 89 } 90 91 func (d *driver) populateEndpoints() error { 92 kvol, err := d.store.List(datastore.Key(ipvlanEndpointPrefix), &endpoint{}) 93 if err != nil && err != datastore.ErrKeyNotFound { 94 return fmt.Errorf("failed to get ipvlan endpoints from store: %v", err) 95 } 96 97 if err == datastore.ErrKeyNotFound { 98 return nil 99 } 100 101 for _, kvo := range kvol { 102 ep := kvo.(*endpoint) 103 n, ok := d.networks[ep.nid] 104 if !ok { 105 log.G(context.TODO()).Debugf("Network (%.7s) not found for restored ipvlan endpoint (%.7s)", ep.nid, ep.id) 106 log.G(context.TODO()).Debugf("Deleting stale ipvlan endpoint (%.7s) from store", ep.id) 107 if err := d.storeDelete(ep); err != nil { 108 log.G(context.TODO()).Debugf("Failed to delete stale ipvlan endpoint (%.7s) from store", ep.id) 109 } 110 continue 111 } 112 n.endpoints[ep.id] = ep 113 log.G(context.TODO()).Debugf("Endpoint (%.7s) restored to network (%.7s)", ep.id, ep.nid) 114 } 115 116 return nil 117 } 118 119 // storeUpdate used to update persistent ipvlan network records as they are created 120 func (d *driver) storeUpdate(kvObject datastore.KVObject) error { 121 if d.store == nil { 122 log.G(context.TODO()).Warnf("ipvlan store not initialized. kv object %s is not added to the store", datastore.Key(kvObject.Key()...)) 123 return nil 124 } 125 if err := d.store.PutObjectAtomic(kvObject); err != nil { 126 return fmt.Errorf("failed to update ipvlan store for object type %T: %v", kvObject, err) 127 } 128 129 return nil 130 } 131 132 // storeDelete used to delete ipvlan network records from persistent cache as they are deleted 133 func (d *driver) storeDelete(kvObject datastore.KVObject) error { 134 if d.store == nil { 135 log.G(context.TODO()).Debugf("ipvlan store not initialized. kv object %s is not deleted from store", datastore.Key(kvObject.Key()...)) 136 return nil 137 } 138 retry: 139 if err := d.store.DeleteObjectAtomic(kvObject); err != nil { 140 if err == datastore.ErrKeyModified { 141 if err := d.store.GetObject(datastore.Key(kvObject.Key()...), kvObject); err != nil { 142 return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) 143 } 144 goto retry 145 } 146 return err 147 } 148 149 return nil 150 } 151 152 func (config *configuration) MarshalJSON() ([]byte, error) { 153 nMap := make(map[string]interface{}) 154 nMap["ID"] = config.ID 155 nMap["Mtu"] = config.Mtu 156 nMap["Parent"] = config.Parent 157 nMap["IpvlanMode"] = config.IpvlanMode 158 nMap["IpvlanFlag"] = config.IpvlanFlag 159 nMap["Internal"] = config.Internal 160 nMap["CreatedSubIface"] = config.CreatedSlaveLink 161 if len(config.Ipv4Subnets) > 0 { 162 iis, err := json.Marshal(config.Ipv4Subnets) 163 if err != nil { 164 return nil, err 165 } 166 nMap["Ipv4Subnets"] = string(iis) 167 } 168 if len(config.Ipv6Subnets) > 0 { 169 iis, err := json.Marshal(config.Ipv6Subnets) 170 if err != nil { 171 return nil, err 172 } 173 nMap["Ipv6Subnets"] = string(iis) 174 } 175 176 return json.Marshal(nMap) 177 } 178 179 func (config *configuration) UnmarshalJSON(b []byte) error { 180 var ( 181 err error 182 nMap map[string]interface{} 183 ) 184 185 if err = json.Unmarshal(b, &nMap); err != nil { 186 return err 187 } 188 config.ID = nMap["ID"].(string) 189 config.Mtu = int(nMap["Mtu"].(float64)) 190 config.Parent = nMap["Parent"].(string) 191 config.IpvlanMode = nMap["IpvlanMode"].(string) 192 if v, ok := nMap["IpvlanFlag"]; ok { 193 config.IpvlanFlag = v.(string) 194 } else { 195 // Migrate config from an older daemon which did not have the flag configurable. 196 config.IpvlanFlag = flagBridge 197 } 198 config.Internal = nMap["Internal"].(bool) 199 config.CreatedSlaveLink = nMap["CreatedSubIface"].(bool) 200 if v, ok := nMap["Ipv4Subnets"]; ok { 201 if err := json.Unmarshal([]byte(v.(string)), &config.Ipv4Subnets); err != nil { 202 return err 203 } 204 } 205 if v, ok := nMap["Ipv6Subnets"]; ok { 206 if err := json.Unmarshal([]byte(v.(string)), &config.Ipv6Subnets); err != nil { 207 return err 208 } 209 } 210 211 return nil 212 } 213 214 func (config *configuration) Key() []string { 215 return []string{ipvlanNetworkPrefix, config.ID} 216 } 217 218 func (config *configuration) KeyPrefix() []string { 219 return []string{ipvlanNetworkPrefix} 220 } 221 222 func (config *configuration) Value() []byte { 223 b, err := json.Marshal(config) 224 if err != nil { 225 return nil 226 } 227 return b 228 } 229 230 func (config *configuration) SetValue(value []byte) error { 231 return json.Unmarshal(value, config) 232 } 233 234 func (config *configuration) Index() uint64 { 235 return config.dbIndex 236 } 237 238 func (config *configuration) SetIndex(index uint64) { 239 config.dbIndex = index 240 config.dbExists = true 241 } 242 243 func (config *configuration) Exists() bool { 244 return config.dbExists 245 } 246 247 func (config *configuration) Skip() bool { 248 return false 249 } 250 251 func (config *configuration) New() datastore.KVObject { 252 return &configuration{} 253 } 254 255 func (config *configuration) CopyTo(o datastore.KVObject) error { 256 dstNcfg := o.(*configuration) 257 *dstNcfg = *config 258 return nil 259 } 260 261 func (config *configuration) DataScope() string { 262 return scope.Local 263 } 264 265 func (ep *endpoint) MarshalJSON() ([]byte, error) { 266 epMap := make(map[string]interface{}) 267 epMap["id"] = ep.id 268 epMap["nid"] = ep.nid 269 epMap["SrcName"] = ep.srcName 270 if len(ep.mac) != 0 { 271 epMap["MacAddress"] = ep.mac.String() 272 } 273 if ep.addr != nil { 274 epMap["Addr"] = ep.addr.String() 275 } 276 if ep.addrv6 != nil { 277 epMap["Addrv6"] = ep.addrv6.String() 278 } 279 return json.Marshal(epMap) 280 } 281 282 func (ep *endpoint) UnmarshalJSON(b []byte) error { 283 var ( 284 err error 285 epMap map[string]interface{} 286 ) 287 288 if err = json.Unmarshal(b, &epMap); err != nil { 289 return fmt.Errorf("Failed to unmarshal to ipvlan endpoint: %v", err) 290 } 291 292 if v, ok := epMap["MacAddress"]; ok { 293 if ep.mac, err = net.ParseMAC(v.(string)); err != nil { 294 return types.InternalErrorf("failed to decode ipvlan endpoint MAC address (%s) after json unmarshal: %v", v.(string), err) 295 } 296 } 297 if v, ok := epMap["Addr"]; ok { 298 if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { 299 return types.InternalErrorf("failed to decode ipvlan endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err) 300 } 301 } 302 if v, ok := epMap["Addrv6"]; ok { 303 if ep.addrv6, err = types.ParseCIDR(v.(string)); err != nil { 304 return types.InternalErrorf("failed to decode ipvlan endpoint IPv6 address (%s) after json unmarshal: %v", v.(string), err) 305 } 306 } 307 ep.id = epMap["id"].(string) 308 ep.nid = epMap["nid"].(string) 309 ep.srcName = epMap["SrcName"].(string) 310 311 return nil 312 } 313 314 func (ep *endpoint) Key() []string { 315 return []string{ipvlanEndpointPrefix, ep.id} 316 } 317 318 func (ep *endpoint) KeyPrefix() []string { 319 return []string{ipvlanEndpointPrefix} 320 } 321 322 func (ep *endpoint) Value() []byte { 323 b, err := json.Marshal(ep) 324 if err != nil { 325 return nil 326 } 327 return b 328 } 329 330 func (ep *endpoint) SetValue(value []byte) error { 331 return json.Unmarshal(value, ep) 332 } 333 334 func (ep *endpoint) Index() uint64 { 335 return ep.dbIndex 336 } 337 338 func (ep *endpoint) SetIndex(index uint64) { 339 ep.dbIndex = index 340 ep.dbExists = true 341 } 342 343 func (ep *endpoint) Exists() bool { 344 return ep.dbExists 345 } 346 347 func (ep *endpoint) Skip() bool { 348 return false 349 } 350 351 func (ep *endpoint) New() datastore.KVObject { 352 return &endpoint{} 353 } 354 355 func (ep *endpoint) CopyTo(o datastore.KVObject) error { 356 dstEp := o.(*endpoint) 357 *dstEp = *ep 358 return nil 359 } 360 361 func (ep *endpoint) DataScope() string { 362 return scope.Local 363 }