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