github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/drivers/macvlan/macvlan_store.go (about) 1 package macvlan 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 8 "github.com/docker/libnetwork/datastore" 9 "github.com/docker/libnetwork/discoverapi" 10 "github.com/docker/libnetwork/netlabel" 11 "github.com/docker/libnetwork/types" 12 "github.com/sirupsen/logrus" 13 ) 14 15 const ( 16 macvlanPrefix = "macvlan" 17 macvlanNetworkPrefix = macvlanPrefix + "/network" 18 macvlanEndpointPrefix = macvlanPrefix + "/endpoint" 19 ) 20 21 // networkConfiguration for this driver's network specific configuration 22 type configuration struct { 23 ID string 24 Mtu int 25 dbIndex uint64 26 dbExists bool 27 Internal bool 28 Parent string 29 MacvlanMode string 30 CreatedSlaveLink bool 31 Ipv4Subnets []*ipv4Subnet 32 Ipv6Subnets []*ipv6Subnet 33 } 34 35 type ipv4Subnet struct { 36 SubnetIP string 37 GwIP string 38 } 39 40 type ipv6Subnet struct { 41 SubnetIP string 42 GwIP string 43 } 44 45 // initStore drivers are responsible for caching their own persistent state 46 func (d *driver) initStore(option map[string]interface{}) error { 47 if data, ok := option[netlabel.LocalKVClient]; ok { 48 var err error 49 dsc, ok := data.(discoverapi.DatastoreConfigData) 50 if !ok { 51 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 52 } 53 d.store, err = datastore.NewDataStoreFromConfig(dsc) 54 if err != nil { 55 return types.InternalErrorf("macvlan driver failed to initialize data store: %v", err) 56 } 57 58 err = d.populateNetworks() 59 if err != nil { 60 return err 61 } 62 err = d.populateEndpoints() 63 if err != nil { 64 return err 65 } 66 67 } 68 69 return nil 70 } 71 72 // populateNetworks is invoked at driver init to recreate persistently stored networks 73 func (d *driver) populateNetworks() error { 74 kvol, err := d.store.List(datastore.Key(macvlanPrefix), &configuration{}) 75 if err != nil && err != datastore.ErrKeyNotFound { 76 return fmt.Errorf("failed to get macvlan network configurations from store: %v", err) 77 } 78 // If empty it simply means no macvlan networks have been created yet 79 if err == datastore.ErrKeyNotFound { 80 return nil 81 } 82 for _, kvo := range kvol { 83 config := kvo.(*configuration) 84 if _, err = d.createNetwork(config); err != nil { 85 logrus.Warnf("Could not create macvlan network for id %s from persistent state", config.ID) 86 } 87 } 88 89 return nil 90 } 91 92 func (d *driver) populateEndpoints() error { 93 kvol, err := d.store.List(datastore.Key(macvlanEndpointPrefix), &endpoint{}) 94 if err != nil && err != datastore.ErrKeyNotFound { 95 return fmt.Errorf("failed to get macvlan endpoints from store: %v", err) 96 } 97 98 if err == datastore.ErrKeyNotFound { 99 return nil 100 } 101 102 for _, kvo := range kvol { 103 ep := kvo.(*endpoint) 104 n, ok := d.networks[ep.nid] 105 if !ok { 106 logrus.Debugf("Network (%.7s) not found for restored macvlan endpoint (%.7s)", ep.nid, ep.id) 107 logrus.Debugf("Deleting stale macvlan endpoint (%.7s) from store", ep.id) 108 if err := d.storeDelete(ep); err != nil { 109 logrus.Debugf("Failed to delete stale macvlan endpoint (%.7s) from store", ep.id) 110 } 111 continue 112 } 113 n.endpoints[ep.id] = ep 114 logrus.Debugf("Endpoint (%.7s) restored to network (%.7s)", ep.id, ep.nid) 115 } 116 117 return nil 118 } 119 120 // storeUpdate used to update persistent macvlan network records as they are created 121 func (d *driver) storeUpdate(kvObject datastore.KVObject) error { 122 if d.store == nil { 123 logrus.Warnf("macvlan store not initialized. kv object %s is not added to the store", datastore.Key(kvObject.Key()...)) 124 return nil 125 } 126 if err := d.store.PutObjectAtomic(kvObject); err != nil { 127 return fmt.Errorf("failed to update macvlan store for object type %T: %v", kvObject, err) 128 } 129 130 return nil 131 } 132 133 // storeDelete used to delete macvlan records from persistent cache as they are deleted 134 func (d *driver) storeDelete(kvObject datastore.KVObject) error { 135 if d.store == nil { 136 logrus.Debugf("macvlan store not initialized. kv object %s is not deleted from store", datastore.Key(kvObject.Key()...)) 137 return nil 138 } 139 retry: 140 if err := d.store.DeleteObjectAtomic(kvObject); err != nil { 141 if err == datastore.ErrKeyModified { 142 if err := d.store.GetObject(datastore.Key(kvObject.Key()...), kvObject); err != nil { 143 return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) 144 } 145 goto retry 146 } 147 return err 148 } 149 150 return nil 151 } 152 153 func (config *configuration) MarshalJSON() ([]byte, error) { 154 nMap := make(map[string]interface{}) 155 nMap["ID"] = config.ID 156 nMap["Mtu"] = config.Mtu 157 nMap["Parent"] = config.Parent 158 nMap["MacvlanMode"] = config.MacvlanMode 159 nMap["Internal"] = config.Internal 160 nMap["CreatedSubIface"] = config.CreatedSlaveLink 161 if len(config.Ipv4Subnets) > 0 { 162 iis, err := json.Marshal(config.Ipv4Subnets) 163 if err != nil { 164 return nil, err 165 } 166 nMap["Ipv4Subnets"] = string(iis) 167 } 168 if len(config.Ipv6Subnets) > 0 { 169 iis, err := json.Marshal(config.Ipv6Subnets) 170 if err != nil { 171 return nil, err 172 } 173 nMap["Ipv6Subnets"] = string(iis) 174 } 175 176 return json.Marshal(nMap) 177 } 178 179 func (config *configuration) UnmarshalJSON(b []byte) error { 180 var ( 181 err error 182 nMap map[string]interface{} 183 ) 184 185 if err = json.Unmarshal(b, &nMap); err != nil { 186 return err 187 } 188 config.ID = nMap["ID"].(string) 189 config.Mtu = int(nMap["Mtu"].(float64)) 190 config.Parent = nMap["Parent"].(string) 191 config.MacvlanMode = nMap["MacvlanMode"].(string) 192 config.Internal = nMap["Internal"].(bool) 193 config.CreatedSlaveLink = nMap["CreatedSubIface"].(bool) 194 if v, ok := nMap["Ipv4Subnets"]; ok { 195 if err := json.Unmarshal([]byte(v.(string)), &config.Ipv4Subnets); err != nil { 196 return err 197 } 198 } 199 if v, ok := nMap["Ipv6Subnets"]; ok { 200 if err := json.Unmarshal([]byte(v.(string)), &config.Ipv6Subnets); err != nil { 201 return err 202 } 203 } 204 205 return nil 206 } 207 208 func (config *configuration) Key() []string { 209 return []string{macvlanNetworkPrefix, config.ID} 210 } 211 212 func (config *configuration) KeyPrefix() []string { 213 return []string{macvlanNetworkPrefix} 214 } 215 216 func (config *configuration) Value() []byte { 217 b, err := json.Marshal(config) 218 if err != nil { 219 return nil 220 } 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 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 macvlan 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 macvlan 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 macvlan 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 macvlan 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{macvlanEndpointPrefix, ep.id} 312 } 313 314 func (ep *endpoint) KeyPrefix() []string { 315 return []string{macvlanEndpointPrefix} 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 }