github.com/rawahars/moby@v24.0.4+incompatible/libnetwork/drivers/bridge/bridge_store.go (about) 1 //go:build linux 2 // +build linux 3 4 package bridge 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "net" 10 11 "github.com/docker/docker/libnetwork/datastore" 12 "github.com/docker/docker/libnetwork/discoverapi" 13 "github.com/docker/docker/libnetwork/netlabel" 14 "github.com/docker/docker/libnetwork/types" 15 "github.com/sirupsen/logrus" 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.NewDataStoreFromConfig(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(datastore.Key(bridgePrefix), &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 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) 67 } 68 logrus.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(datastore.Key(bridgeEndpointPrefix), &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 logrus.Debugf("Network (%.7s) not found for restored bridge endpoint (%.7s)", ep.nid, ep.id) 89 logrus.Debugf("Deleting stale bridge endpoint (%.7s) from store", ep.id) 90 if err := d.storeDelete(ep); err != nil { 91 logrus.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 logrus.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 logrus.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 logrus.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(datastore.Key(kvObject.Key()...), 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 nMap["HostIP"] = ncfg.HostIP.String() 149 nMap["DefaultGatewayIPv4"] = ncfg.DefaultGatewayIPv4.String() 150 nMap["DefaultGatewayIPv6"] = ncfg.DefaultGatewayIPv6.String() 151 nMap["ContainerIfacePrefix"] = ncfg.ContainerIfacePrefix 152 nMap["BridgeIfaceCreator"] = ncfg.BridgeIfaceCreator 153 154 if ncfg.AddressIPv4 != nil { 155 nMap["AddressIPv4"] = ncfg.AddressIPv4.String() 156 } 157 158 if ncfg.AddressIPv6 != nil { 159 nMap["AddressIPv6"] = ncfg.AddressIPv6.String() 160 } 161 162 return json.Marshal(nMap) 163 } 164 165 func (ncfg *networkConfiguration) UnmarshalJSON(b []byte) error { 166 var ( 167 err error 168 nMap map[string]interface{} 169 ) 170 171 if err = json.Unmarshal(b, &nMap); err != nil { 172 return err 173 } 174 175 if v, ok := nMap["AddressIPv4"]; ok { 176 if ncfg.AddressIPv4, err = types.ParseCIDR(v.(string)); err != nil { 177 return types.InternalErrorf("failed to decode bridge network address IPv4 after json unmarshal: %s", v.(string)) 178 } 179 } 180 181 if v, ok := nMap["AddressIPv6"]; ok { 182 if ncfg.AddressIPv6, err = types.ParseCIDR(v.(string)); err != nil { 183 return types.InternalErrorf("failed to decode bridge network address IPv6 after json unmarshal: %s", v.(string)) 184 } 185 } 186 187 if v, ok := nMap["ContainerIfacePrefix"]; ok { 188 ncfg.ContainerIfacePrefix = v.(string) 189 } 190 191 if v, ok := nMap["HostIP"]; ok { 192 ncfg.HostIP = net.ParseIP(v.(string)) 193 } 194 195 ncfg.DefaultBridge = nMap["DefaultBridge"].(bool) 196 ncfg.DefaultBindingIP = net.ParseIP(nMap["DefaultBindingIP"].(string)) 197 ncfg.DefaultGatewayIPv4 = net.ParseIP(nMap["DefaultGatewayIPv4"].(string)) 198 ncfg.DefaultGatewayIPv6 = net.ParseIP(nMap["DefaultGatewayIPv6"].(string)) 199 ncfg.ID = nMap["ID"].(string) 200 ncfg.BridgeName = nMap["BridgeName"].(string) 201 ncfg.EnableIPv6 = nMap["EnableIPv6"].(bool) 202 ncfg.EnableIPMasquerade = nMap["EnableIPMasquerade"].(bool) 203 ncfg.EnableICC = nMap["EnableICC"].(bool) 204 if v, ok := nMap["InhibitIPv4"]; ok { 205 ncfg.InhibitIPv4 = v.(bool) 206 } 207 208 ncfg.Mtu = int(nMap["Mtu"].(float64)) 209 if v, ok := nMap["Internal"]; ok { 210 ncfg.Internal = v.(bool) 211 } 212 213 if v, ok := nMap["BridgeIfaceCreator"]; ok { 214 ncfg.BridgeIfaceCreator = ifaceCreator(v.(float64)) 215 } 216 217 return nil 218 } 219 220 func (ncfg *networkConfiguration) Key() []string { 221 return []string{bridgePrefix, ncfg.ID} 222 } 223 224 func (ncfg *networkConfiguration) KeyPrefix() []string { 225 return []string{bridgePrefix} 226 } 227 228 func (ncfg *networkConfiguration) Value() []byte { 229 b, err := json.Marshal(ncfg) 230 if err != nil { 231 return nil 232 } 233 return b 234 } 235 236 func (ncfg *networkConfiguration) SetValue(value []byte) error { 237 return json.Unmarshal(value, ncfg) 238 } 239 240 func (ncfg *networkConfiguration) Index() uint64 { 241 return ncfg.dbIndex 242 } 243 244 func (ncfg *networkConfiguration) SetIndex(index uint64) { 245 ncfg.dbIndex = index 246 ncfg.dbExists = true 247 } 248 249 func (ncfg *networkConfiguration) Exists() bool { 250 return ncfg.dbExists 251 } 252 253 func (ncfg *networkConfiguration) Skip() bool { 254 return false 255 } 256 257 func (ncfg *networkConfiguration) New() datastore.KVObject { 258 return &networkConfiguration{} 259 } 260 261 func (ncfg *networkConfiguration) CopyTo(o datastore.KVObject) error { 262 dstNcfg := o.(*networkConfiguration) 263 *dstNcfg = *ncfg 264 return nil 265 } 266 267 func (ncfg *networkConfiguration) DataScope() string { 268 return datastore.LocalScope 269 } 270 271 func (ep *bridgeEndpoint) MarshalJSON() ([]byte, error) { 272 epMap := make(map[string]interface{}) 273 epMap["id"] = ep.id 274 epMap["nid"] = ep.nid 275 epMap["SrcName"] = ep.srcName 276 epMap["MacAddress"] = ep.macAddress.String() 277 epMap["Addr"] = ep.addr.String() 278 if ep.addrv6 != nil { 279 epMap["Addrv6"] = ep.addrv6.String() 280 } 281 epMap["Config"] = ep.config 282 epMap["ContainerConfig"] = ep.containerConfig 283 epMap["ExternalConnConfig"] = ep.extConnConfig 284 epMap["PortMapping"] = ep.portMapping 285 286 return json.Marshal(epMap) 287 } 288 289 func (ep *bridgeEndpoint) UnmarshalJSON(b []byte) error { 290 var ( 291 err error 292 epMap map[string]interface{} 293 ) 294 295 if err = json.Unmarshal(b, &epMap); err != nil { 296 return fmt.Errorf("Failed to unmarshal to bridge endpoint: %v", err) 297 } 298 299 if v, ok := epMap["MacAddress"]; ok { 300 if ep.macAddress, err = net.ParseMAC(v.(string)); err != nil { 301 return types.InternalErrorf("failed to decode bridge endpoint MAC address (%s) after json unmarshal: %v", v.(string), err) 302 } 303 } 304 if v, ok := epMap["Addr"]; ok { 305 if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { 306 return types.InternalErrorf("failed to decode bridge endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err) 307 } 308 } 309 if v, ok := epMap["Addrv6"]; ok { 310 if ep.addrv6, err = types.ParseCIDR(v.(string)); err != nil { 311 return types.InternalErrorf("failed to decode bridge endpoint IPv6 address (%s) after json unmarshal: %v", v.(string), err) 312 } 313 } 314 ep.id = epMap["id"].(string) 315 ep.nid = epMap["nid"].(string) 316 ep.srcName = epMap["SrcName"].(string) 317 d, _ := json.Marshal(epMap["Config"]) 318 if err := json.Unmarshal(d, &ep.config); err != nil { 319 logrus.Warnf("Failed to decode endpoint config %v", err) 320 } 321 d, _ = json.Marshal(epMap["ContainerConfig"]) 322 if err := json.Unmarshal(d, &ep.containerConfig); err != nil { 323 logrus.Warnf("Failed to decode endpoint container config %v", err) 324 } 325 d, _ = json.Marshal(epMap["ExternalConnConfig"]) 326 if err := json.Unmarshal(d, &ep.extConnConfig); err != nil { 327 logrus.Warnf("Failed to decode endpoint external connectivity configuration %v", err) 328 } 329 d, _ = json.Marshal(epMap["PortMapping"]) 330 if err := json.Unmarshal(d, &ep.portMapping); err != nil { 331 logrus.Warnf("Failed to decode endpoint port mapping %v", err) 332 } 333 334 return nil 335 } 336 337 func (ep *bridgeEndpoint) Key() []string { 338 return []string{bridgeEndpointPrefix, ep.id} 339 } 340 341 func (ep *bridgeEndpoint) KeyPrefix() []string { 342 return []string{bridgeEndpointPrefix} 343 } 344 345 func (ep *bridgeEndpoint) Value() []byte { 346 b, err := json.Marshal(ep) 347 if err != nil { 348 return nil 349 } 350 return b 351 } 352 353 func (ep *bridgeEndpoint) SetValue(value []byte) error { 354 return json.Unmarshal(value, ep) 355 } 356 357 func (ep *bridgeEndpoint) Index() uint64 { 358 return ep.dbIndex 359 } 360 361 func (ep *bridgeEndpoint) SetIndex(index uint64) { 362 ep.dbIndex = index 363 ep.dbExists = true 364 } 365 366 func (ep *bridgeEndpoint) Exists() bool { 367 return ep.dbExists 368 } 369 370 func (ep *bridgeEndpoint) Skip() bool { 371 return false 372 } 373 374 func (ep *bridgeEndpoint) New() datastore.KVObject { 375 return &bridgeEndpoint{} 376 } 377 378 func (ep *bridgeEndpoint) CopyTo(o datastore.KVObject) error { 379 dstEp := o.(*bridgeEndpoint) 380 *dstEp = *ep 381 return nil 382 } 383 384 func (ep *bridgeEndpoint) DataScope() string { 385 return datastore.LocalScope 386 } 387 388 func (n *bridgeNetwork) restorePortAllocations(ep *bridgeEndpoint) { 389 if ep.extConnConfig == nil || 390 ep.extConnConfig.ExposedPorts == nil || 391 ep.extConnConfig.PortBindings == nil { 392 return 393 } 394 tmp := ep.extConnConfig.PortBindings 395 ep.extConnConfig.PortBindings = ep.portMapping 396 _, err := n.allocatePorts(ep, n.config.DefaultBindingIP, n.driver.config.EnableUserlandProxy) 397 if err != nil { 398 logrus.Warnf("Failed to reserve existing port mapping for endpoint %.7s:%v", ep.id, err) 399 } 400 ep.extConnConfig.PortBindings = tmp 401 }