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