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