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