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