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