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