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