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