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