github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/libnetwork/drivers/bridge/bridge_store.go (about) 1 // +build linux 2 3 package bridge 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 // network config prefix was not specific enough. 19 // To be backward compatible, need custom endpoint 20 // prefix with different root 21 bridgePrefix = "bridge" 22 bridgeEndpointPrefix = "bridge-endpoint" 23 ) 24 25 func (d *driver) initStore(option map[string]interface{}) error { 26 if data, ok := option[netlabel.LocalKVClient]; ok { 27 var err error 28 dsc, ok := data.(discoverapi.DatastoreConfigData) 29 if !ok { 30 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 31 } 32 d.store, err = datastore.NewDataStoreFromConfig(dsc) 33 if err != nil { 34 return types.InternalErrorf("bridge driver failed to initialize data store: %v", err) 35 } 36 37 err = d.populateNetworks() 38 if err != nil { 39 return err 40 } 41 42 err = d.populateEndpoints() 43 if err != nil { 44 return err 45 } 46 } 47 48 return nil 49 } 50 51 func (d *driver) populateNetworks() error { 52 kvol, err := d.store.List(datastore.Key(bridgePrefix), &networkConfiguration{}) 53 if err != nil && err != datastore.ErrKeyNotFound { 54 return fmt.Errorf("failed to get bridge network configurations from store: %v", err) 55 } 56 57 // It's normal for network configuration state to be empty. Just return. 58 if err == datastore.ErrKeyNotFound { 59 return nil 60 } 61 62 for _, kvo := range kvol { 63 ncfg := kvo.(*networkConfiguration) 64 if err = d.createNetwork(ncfg); err != nil { 65 logrus.Warnf("could not create bridge network for id %s bridge name %s while booting up from persistent state: %v", ncfg.ID, ncfg.BridgeName, err) 66 } 67 logrus.Debugf("Network (%.7s) restored", ncfg.ID) 68 } 69 70 return nil 71 } 72 73 func (d *driver) populateEndpoints() error { 74 kvol, err := d.store.List(datastore.Key(bridgeEndpointPrefix), &bridgeEndpoint{}) 75 if err != nil && err != datastore.ErrKeyNotFound { 76 return fmt.Errorf("failed to get bridge endpoints from store: %v", err) 77 } 78 79 if err == datastore.ErrKeyNotFound { 80 return nil 81 } 82 83 for _, kvo := range kvol { 84 ep := kvo.(*bridgeEndpoint) 85 n, ok := d.networks[ep.nid] 86 if !ok { 87 logrus.Debugf("Network (%.7s) not found for restored bridge endpoint (%.7s)", ep.nid, ep.id) 88 logrus.Debugf("Deleting stale bridge endpoint (%.7s) from store", ep.id) 89 if err := d.storeDelete(ep); err != nil { 90 logrus.Debugf("Failed to delete stale bridge endpoint (%.7s) from store", ep.id) 91 } 92 continue 93 } 94 n.endpoints[ep.id] = ep 95 n.restorePortAllocations(ep) 96 logrus.Debugf("Endpoint (%.7s) restored to network (%.7s)", ep.id, ep.nid) 97 } 98 99 return nil 100 } 101 102 func (d *driver) storeUpdate(kvObject datastore.KVObject) error { 103 if d.store == nil { 104 logrus.Warnf("bridge store not initialized. kv object %s is not added to the store", datastore.Key(kvObject.Key()...)) 105 return nil 106 } 107 108 if err := d.store.PutObjectAtomic(kvObject); err != nil { 109 return fmt.Errorf("failed to update bridge store for object type %T: %v", kvObject, err) 110 } 111 112 return nil 113 } 114 115 func (d *driver) storeDelete(kvObject datastore.KVObject) error { 116 if d.store == nil { 117 logrus.Debugf("bridge store not initialized. kv object %s is not deleted from store", datastore.Key(kvObject.Key()...)) 118 return nil 119 } 120 121 retry: 122 if err := d.store.DeleteObjectAtomic(kvObject); err != nil { 123 if err == datastore.ErrKeyModified { 124 if err := d.store.GetObject(datastore.Key(kvObject.Key()...), kvObject); err != nil { 125 return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) 126 } 127 goto retry 128 } 129 return err 130 } 131 132 return nil 133 } 134 135 func (ncfg *networkConfiguration) MarshalJSON() ([]byte, error) { 136 nMap := make(map[string]interface{}) 137 nMap["ID"] = ncfg.ID 138 nMap["BridgeName"] = ncfg.BridgeName 139 nMap["EnableIPv6"] = ncfg.EnableIPv6 140 nMap["EnableIPMasquerade"] = ncfg.EnableIPMasquerade 141 nMap["EnableICC"] = ncfg.EnableICC 142 nMap["InhibitIPv4"] = ncfg.InhibitIPv4 143 nMap["Mtu"] = ncfg.Mtu 144 nMap["Internal"] = ncfg.Internal 145 nMap["DefaultBridge"] = ncfg.DefaultBridge 146 nMap["DefaultBindingIP"] = ncfg.DefaultBindingIP.String() 147 nMap["HostIP"] = ncfg.HostIP.String() 148 nMap["DefaultGatewayIPv4"] = ncfg.DefaultGatewayIPv4.String() 149 nMap["DefaultGatewayIPv6"] = ncfg.DefaultGatewayIPv6.String() 150 nMap["ContainerIfacePrefix"] = ncfg.ContainerIfacePrefix 151 nMap["BridgeIfaceCreator"] = ncfg.BridgeIfaceCreator 152 153 if ncfg.AddressIPv4 != nil { 154 nMap["AddressIPv4"] = ncfg.AddressIPv4.String() 155 } 156 157 if ncfg.AddressIPv6 != nil { 158 nMap["AddressIPv6"] = ncfg.AddressIPv6.String() 159 } 160 161 return json.Marshal(nMap) 162 } 163 164 func (ncfg *networkConfiguration) UnmarshalJSON(b []byte) error { 165 var ( 166 err error 167 nMap map[string]interface{} 168 ) 169 170 if err = json.Unmarshal(b, &nMap); err != nil { 171 return err 172 } 173 174 if v, ok := nMap["AddressIPv4"]; ok { 175 if ncfg.AddressIPv4, err = types.ParseCIDR(v.(string)); err != nil { 176 return types.InternalErrorf("failed to decode bridge network address IPv4 after json unmarshal: %s", v.(string)) 177 } 178 } 179 180 if v, ok := nMap["AddressIPv6"]; ok { 181 if ncfg.AddressIPv6, err = types.ParseCIDR(v.(string)); err != nil { 182 return types.InternalErrorf("failed to decode bridge network address IPv6 after json unmarshal: %s", v.(string)) 183 } 184 } 185 186 if v, ok := nMap["ContainerIfacePrefix"]; ok { 187 ncfg.ContainerIfacePrefix = v.(string) 188 } 189 190 if v, ok := nMap["HostIP"]; ok { 191 ncfg.HostIP = net.ParseIP(v.(string)) 192 } 193 194 ncfg.DefaultBridge = nMap["DefaultBridge"].(bool) 195 ncfg.DefaultBindingIP = net.ParseIP(nMap["DefaultBindingIP"].(string)) 196 ncfg.DefaultGatewayIPv4 = net.ParseIP(nMap["DefaultGatewayIPv4"].(string)) 197 ncfg.DefaultGatewayIPv6 = net.ParseIP(nMap["DefaultGatewayIPv6"].(string)) 198 ncfg.ID = nMap["ID"].(string) 199 ncfg.BridgeName = nMap["BridgeName"].(string) 200 ncfg.EnableIPv6 = nMap["EnableIPv6"].(bool) 201 ncfg.EnableIPMasquerade = nMap["EnableIPMasquerade"].(bool) 202 ncfg.EnableICC = nMap["EnableICC"].(bool) 203 if v, ok := nMap["InhibitIPv4"]; ok { 204 ncfg.InhibitIPv4 = v.(bool) 205 } 206 207 ncfg.Mtu = int(nMap["Mtu"].(float64)) 208 if v, ok := nMap["Internal"]; ok { 209 ncfg.Internal = v.(bool) 210 } 211 212 if v, ok := nMap["BridgeIfaceCreator"]; ok { 213 ncfg.BridgeIfaceCreator = ifaceCreator(v.(float64)) 214 } 215 216 return nil 217 } 218 219 func (ncfg *networkConfiguration) Key() []string { 220 return []string{bridgePrefix, ncfg.ID} 221 } 222 223 func (ncfg *networkConfiguration) KeyPrefix() []string { 224 return []string{bridgePrefix} 225 } 226 227 func (ncfg *networkConfiguration) Value() []byte { 228 b, err := json.Marshal(ncfg) 229 if err != nil { 230 return nil 231 } 232 return b 233 } 234 235 func (ncfg *networkConfiguration) SetValue(value []byte) error { 236 return json.Unmarshal(value, ncfg) 237 } 238 239 func (ncfg *networkConfiguration) Index() uint64 { 240 return ncfg.dbIndex 241 } 242 243 func (ncfg *networkConfiguration) SetIndex(index uint64) { 244 ncfg.dbIndex = index 245 ncfg.dbExists = true 246 } 247 248 func (ncfg *networkConfiguration) Exists() bool { 249 return ncfg.dbExists 250 } 251 252 func (ncfg *networkConfiguration) Skip() bool { 253 return false 254 } 255 256 func (ncfg *networkConfiguration) New() datastore.KVObject { 257 return &networkConfiguration{} 258 } 259 260 func (ncfg *networkConfiguration) CopyTo(o datastore.KVObject) error { 261 dstNcfg := o.(*networkConfiguration) 262 *dstNcfg = *ncfg 263 return nil 264 } 265 266 func (ncfg *networkConfiguration) DataScope() string { 267 return datastore.LocalScope 268 } 269 270 func (ep *bridgeEndpoint) MarshalJSON() ([]byte, error) { 271 epMap := make(map[string]interface{}) 272 epMap["id"] = ep.id 273 epMap["nid"] = ep.nid 274 epMap["SrcName"] = ep.srcName 275 epMap["MacAddress"] = ep.macAddress.String() 276 epMap["Addr"] = ep.addr.String() 277 if ep.addrv6 != nil { 278 epMap["Addrv6"] = ep.addrv6.String() 279 } 280 epMap["Config"] = ep.config 281 epMap["ContainerConfig"] = ep.containerConfig 282 epMap["ExternalConnConfig"] = ep.extConnConfig 283 epMap["PortMapping"] = ep.portMapping 284 285 return json.Marshal(epMap) 286 } 287 288 func (ep *bridgeEndpoint) UnmarshalJSON(b []byte) error { 289 var ( 290 err error 291 epMap map[string]interface{} 292 ) 293 294 if err = json.Unmarshal(b, &epMap); err != nil { 295 return fmt.Errorf("Failed to unmarshal to bridge endpoint: %v", err) 296 } 297 298 if v, ok := epMap["MacAddress"]; ok { 299 if ep.macAddress, err = net.ParseMAC(v.(string)); err != nil { 300 return types.InternalErrorf("failed to decode bridge endpoint MAC address (%s) after json unmarshal: %v", v.(string), err) 301 } 302 } 303 if v, ok := epMap["Addr"]; ok { 304 if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { 305 return types.InternalErrorf("failed to decode bridge endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err) 306 } 307 } 308 if v, ok := epMap["Addrv6"]; ok { 309 if ep.addrv6, err = types.ParseCIDR(v.(string)); err != nil { 310 return types.InternalErrorf("failed to decode bridge endpoint IPv6 address (%s) after json unmarshal: %v", v.(string), err) 311 } 312 } 313 ep.id = epMap["id"].(string) 314 ep.nid = epMap["nid"].(string) 315 ep.srcName = epMap["SrcName"].(string) 316 d, _ := json.Marshal(epMap["Config"]) 317 if err := json.Unmarshal(d, &ep.config); err != nil { 318 logrus.Warnf("Failed to decode endpoint config %v", err) 319 } 320 d, _ = json.Marshal(epMap["ContainerConfig"]) 321 if err := json.Unmarshal(d, &ep.containerConfig); err != nil { 322 logrus.Warnf("Failed to decode endpoint container config %v", err) 323 } 324 d, _ = json.Marshal(epMap["ExternalConnConfig"]) 325 if err := json.Unmarshal(d, &ep.extConnConfig); err != nil { 326 logrus.Warnf("Failed to decode endpoint external connectivity configuration %v", err) 327 } 328 d, _ = json.Marshal(epMap["PortMapping"]) 329 if err := json.Unmarshal(d, &ep.portMapping); err != nil { 330 logrus.Warnf("Failed to decode endpoint port mapping %v", err) 331 } 332 333 return nil 334 } 335 336 func (ep *bridgeEndpoint) Key() []string { 337 return []string{bridgeEndpointPrefix, ep.id} 338 } 339 340 func (ep *bridgeEndpoint) KeyPrefix() []string { 341 return []string{bridgeEndpointPrefix} 342 } 343 344 func (ep *bridgeEndpoint) Value() []byte { 345 b, err := json.Marshal(ep) 346 if err != nil { 347 return nil 348 } 349 return b 350 } 351 352 func (ep *bridgeEndpoint) SetValue(value []byte) error { 353 return json.Unmarshal(value, ep) 354 } 355 356 func (ep *bridgeEndpoint) Index() uint64 { 357 return ep.dbIndex 358 } 359 360 func (ep *bridgeEndpoint) SetIndex(index uint64) { 361 ep.dbIndex = index 362 ep.dbExists = true 363 } 364 365 func (ep *bridgeEndpoint) Exists() bool { 366 return ep.dbExists 367 } 368 369 func (ep *bridgeEndpoint) Skip() bool { 370 return false 371 } 372 373 func (ep *bridgeEndpoint) New() datastore.KVObject { 374 return &bridgeEndpoint{} 375 } 376 377 func (ep *bridgeEndpoint) CopyTo(o datastore.KVObject) error { 378 dstEp := o.(*bridgeEndpoint) 379 *dstEp = *ep 380 return nil 381 } 382 383 func (ep *bridgeEndpoint) DataScope() string { 384 return datastore.LocalScope 385 } 386 387 func (n *bridgeNetwork) restorePortAllocations(ep *bridgeEndpoint) { 388 if ep.extConnConfig == nil || 389 ep.extConnConfig.ExposedPorts == nil || 390 ep.extConnConfig.PortBindings == nil { 391 return 392 } 393 tmp := ep.extConnConfig.PortBindings 394 ep.extConnConfig.PortBindings = ep.portMapping 395 _, err := n.allocatePorts(ep, n.config.DefaultBindingIP, n.driver.config.EnableUserlandProxy) 396 if err != nil { 397 logrus.Warnf("Failed to reserve existing port mapping for endpoint %.7s:%v", ep.id, err) 398 } 399 ep.extConnConfig.PortBindings = tmp 400 }