mirror of
https://github.com/moby/moby.git
synced 2026-07-24 16:26:51 +00:00
libnet/portmapperapi: add PortMapper interface, registry
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This commit is contained in:
@@ -86,6 +86,7 @@ type Controller struct {
|
||||
id string
|
||||
drvRegistry drvregistry.Networks
|
||||
ipamRegistry drvregistry.IPAMs
|
||||
pmRegistry drvregistry.PortMappers
|
||||
sandboxes map[string]*Sandbox
|
||||
cfg *config.Config
|
||||
store *datastore.Store
|
||||
@@ -173,13 +174,20 @@ func New(ctx context.Context, cfgOptions ...config.Option) (_ *Controller, retEr
|
||||
}
|
||||
c.drvRegistry.Notify = c
|
||||
|
||||
// Register portmappers before network drivers to make sure they can
|
||||
// restore existing sandboxes (with port mappings) during their
|
||||
// initialization, if the daemon is started in live restore mode.
|
||||
if err := registerPortMappers(ctx, &c.pmRegistry, c.cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// External plugins don't need config passed through daemon. They can
|
||||
// bootstrap themselves.
|
||||
if err := remotedriver.Register(&c.drvRegistry, c.cfg.PluginGetter); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := registerNetworkDrivers(&c.drvRegistry, c.store, c.makeDriverConfig); err != nil {
|
||||
if err := registerNetworkDrivers(&c.drvRegistry, c.store, &c.pmRegistry, c.makeDriverConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/bridge/internal/iptabler"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/bridge/internal/nftabler"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/bridge/internal/rlkclient"
|
||||
"github.com/docker/docker/daemon/libnetwork/drvregistry"
|
||||
"github.com/docker/docker/daemon/libnetwork/internal/netiputil"
|
||||
"github.com/docker/docker/daemon/libnetwork/internal/nftables"
|
||||
"github.com/docker/docker/daemon/libnetwork/iptables"
|
||||
@@ -178,6 +179,7 @@ type driver struct {
|
||||
portDriverClient portDriverClient
|
||||
configNetwork sync.Mutex
|
||||
firewaller firewaller.Firewaller
|
||||
portmappers *drvregistry.PortMappers
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
@@ -192,17 +194,18 @@ const (
|
||||
)
|
||||
|
||||
// New constructs a new bridge driver
|
||||
func newDriver(store *datastore.Store) *driver {
|
||||
func newDriver(store *datastore.Store, pms *drvregistry.PortMappers) *driver {
|
||||
return &driver{
|
||||
store: store,
|
||||
nlh: ns.NlHandle(),
|
||||
networks: map[string]*bridgeNetwork{},
|
||||
store: store,
|
||||
nlh: ns.NlHandle(),
|
||||
networks: map[string]*bridgeNetwork{},
|
||||
portmappers: pms,
|
||||
}
|
||||
}
|
||||
|
||||
// Register registers a new instance of bridge driver.
|
||||
func Register(r driverapi.Registerer, store *datastore.Store, config map[string]interface{}) error {
|
||||
d := newDriver(store)
|
||||
func Register(r driverapi.Registerer, store *datastore.Store, pms *drvregistry.PortMappers, config map[string]interface{}) error {
|
||||
d := newDriver(store, pms)
|
||||
if err := d.configure(config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/docker/docker/daemon/libnetwork/driverapi"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/bridge/internal/firewaller"
|
||||
"github.com/docker/docker/daemon/libnetwork/drvregistry"
|
||||
"github.com/docker/docker/daemon/libnetwork/internal/netiputil"
|
||||
"github.com/docker/docker/daemon/libnetwork/ipamapi"
|
||||
"github.com/docker/docker/daemon/libnetwork/ipams/defaultipam"
|
||||
@@ -280,7 +281,7 @@ func getIPv6Data(t *testing.T) []driverapi.IPAMData {
|
||||
|
||||
func TestCreateFullOptions(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
config := &configuration{
|
||||
EnableIPForwarding: true,
|
||||
@@ -335,7 +336,7 @@ func TestCreateFullOptions(t *testing.T) {
|
||||
|
||||
func TestCreateNoConfig(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
err := d.configure(nil)
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -350,7 +351,7 @@ func TestCreateNoConfig(t *testing.T) {
|
||||
|
||||
func TestCreateFullOptionsLabels(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
config := &configuration{
|
||||
EnableIPForwarding: true,
|
||||
@@ -537,7 +538,7 @@ func TestCreateVeth(t *testing.T) {
|
||||
func TestCreate(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
if err := d.configure(nil); err != nil {
|
||||
t.Fatalf("Failed to setup driver config: %v", err)
|
||||
@@ -563,7 +564,7 @@ func TestCreate(t *testing.T) {
|
||||
func TestCreateFail(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
if err := d.configure(nil); err != nil {
|
||||
t.Fatalf("Failed to setup driver config: %v", err)
|
||||
@@ -582,7 +583,7 @@ func TestCreateMultipleNetworks(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
useStubFirewaller(t)
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
checkFirewallerNetworks := func() {
|
||||
t.Helper()
|
||||
@@ -795,7 +796,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
useStubFirewaller(t)
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
portallocator.Get().ReleaseAll()
|
||||
|
||||
var proxyBinary string
|
||||
@@ -909,7 +910,7 @@ func TestLinkContainers(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
useStubFirewaller(t)
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
config := &configuration{
|
||||
EnableIPTables: true,
|
||||
@@ -1178,7 +1179,7 @@ func TestValidateFixedCIDRV6(t *testing.T) {
|
||||
func TestSetDefaultGw(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
if err := d.configure(nil); err != nil {
|
||||
t.Fatalf("Failed to setup driver config: %v", err)
|
||||
@@ -1228,7 +1229,7 @@ func TestSetDefaultGw(t *testing.T) {
|
||||
|
||||
func TestCreateWithExistingBridge(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
if err := d.configure(nil); err != nil {
|
||||
t.Fatalf("Failed to setup driver config: %v", err)
|
||||
@@ -1300,7 +1301,7 @@ func TestCreateParallel(t *testing.T) {
|
||||
c := netnsutils.SetupTestOSContextEx(t)
|
||||
defer c.Cleanup(t)
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
portallocator.Get().ReleaseAll()
|
||||
|
||||
if err := d.configure(nil); err != nil {
|
||||
@@ -1351,7 +1352,7 @@ func useStubFirewaller(t *testing.T) {
|
||||
// Regression test for https://github.com/moby/moby/issues/46445
|
||||
func TestSetupIP6TablesWithHostIPv4(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
dc := &configuration{
|
||||
EnableIPTables: true,
|
||||
EnableIP6Tables: true,
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/docker/daemon/libnetwork/drvregistry"
|
||||
"github.com/docker/docker/daemon/libnetwork/netlabel"
|
||||
"github.com/docker/docker/internal/nlwrap"
|
||||
"github.com/docker/docker/internal/testutils/netnsutils"
|
||||
@@ -15,7 +16,7 @@ import (
|
||||
|
||||
func TestLinkCreate(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
err := d.configure(nil)
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -78,7 +79,7 @@ func TestLinkCreate(t *testing.T) {
|
||||
|
||||
func TestLinkCreateTwo(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
err := d.configure(nil)
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -106,7 +107,7 @@ func TestLinkCreateTwo(t *testing.T) {
|
||||
|
||||
func TestLinkCreateNoEnableIPv6(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
err := d.configure(nil)
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -131,7 +132,7 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
|
||||
|
||||
func TestLinkDelete(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
err := d.configure(nil)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/bridge/internal/firewaller"
|
||||
"github.com/docker/docker/daemon/libnetwork/drvregistry"
|
||||
"github.com/docker/docker/daemon/libnetwork/netlabel"
|
||||
"github.com/docker/docker/daemon/libnetwork/ns"
|
||||
"github.com/docker/docker/daemon/libnetwork/portallocator"
|
||||
@@ -31,7 +32,7 @@ func TestPortMappingConfig(t *testing.T) {
|
||||
defer netnsutils.SetupTestOSContext(t)()
|
||||
useStubFirewaller(t)
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
config := &configuration{
|
||||
EnableIPTables: true,
|
||||
@@ -116,7 +117,7 @@ func TestPortMappingV6Config(t *testing.T) {
|
||||
t.Fatalf("Could not bring loopback iface up: %v", err)
|
||||
}
|
||||
|
||||
d := newDriver(storeutils.NewTempStore(t))
|
||||
d := newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{})
|
||||
|
||||
config := &configuration{
|
||||
EnableIPTables: true,
|
||||
@@ -791,7 +792,7 @@ func TestAddPortMappings(t *testing.T) {
|
||||
GwModeIPv6: tc.gwMode6,
|
||||
},
|
||||
bridge: &bridgeInterface{},
|
||||
driver: newDriver(storeutils.NewTempStore(t)),
|
||||
driver: newDriver(storeutils.NewTempStore(t), &drvregistry.PortMappers{}),
|
||||
}
|
||||
genericOption := map[string]interface{}{
|
||||
netlabel.GenericData: &configuration{
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package libnetwork
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/daemon/libnetwork/config"
|
||||
"github.com/docker/docker/daemon/libnetwork/datastore"
|
||||
"github.com/docker/docker/daemon/libnetwork/driverapi"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/bridge"
|
||||
@@ -11,14 +13,17 @@ import (
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/macvlan"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/null"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/overlay"
|
||||
"github.com/docker/docker/daemon/libnetwork/drvregistry"
|
||||
)
|
||||
|
||||
func registerNetworkDrivers(r driverapi.Registerer, store *datastore.Store, driverConfig func(string) map[string]interface{}) error {
|
||||
func registerNetworkDrivers(r driverapi.Registerer, store *datastore.Store, pms *drvregistry.PortMappers, driverConfig func(string) map[string]interface{}) error {
|
||||
for _, nr := range []struct {
|
||||
ntype string
|
||||
register func(driverapi.Registerer, *datastore.Store, map[string]interface{}) error
|
||||
}{
|
||||
{ntype: bridge.NetworkType, register: bridge.Register},
|
||||
{ntype: bridge.NetworkType, register: func(r driverapi.Registerer, store *datastore.Store, cfg map[string]interface{}) error {
|
||||
return bridge.Register(r, store, pms, cfg)
|
||||
}},
|
||||
{ntype: host.NetworkType, register: func(r driverapi.Registerer, _ *datastore.Store, _ map[string]interface{}) error {
|
||||
return host.Register(r)
|
||||
}},
|
||||
@@ -38,3 +43,7 @@ func registerNetworkDrivers(r driverapi.Registerer, store *datastore.Store, driv
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func registerPortMappers(ctx context.Context, r *drvregistry.PortMappers, cfg *config.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
package libnetwork
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/daemon/libnetwork/config"
|
||||
"github.com/docker/docker/daemon/libnetwork/datastore"
|
||||
"github.com/docker/docker/daemon/libnetwork/driverapi"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/null"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/windows"
|
||||
"github.com/docker/docker/daemon/libnetwork/drivers/windows/overlay"
|
||||
"github.com/docker/docker/daemon/libnetwork/drvregistry"
|
||||
)
|
||||
|
||||
func registerNetworkDrivers(r driverapi.Registerer, store *datastore.Store, _ func(string) map[string]interface{}) error {
|
||||
func registerNetworkDrivers(r driverapi.Registerer, store *datastore.Store, _ *drvregistry.PortMappers, _ func(string) map[string]interface{}) error {
|
||||
for _, nr := range []struct {
|
||||
ntype string
|
||||
register func(driverapi.Registerer) error
|
||||
@@ -25,3 +28,7 @@ func registerNetworkDrivers(r driverapi.Registerer, store *datastore.Store, _ fu
|
||||
|
||||
return windows.RegisterBuiltinLocalDrivers(r, store)
|
||||
}
|
||||
|
||||
func registerPortMappers(ctx context.Context, r *drvregistry.PortMappers, cfg *config.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
41
daemon/libnetwork/drvregistry/portmappers.go
Normal file
41
daemon/libnetwork/drvregistry/portmappers.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package drvregistry
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/daemon/libnetwork/portmapperapi"
|
||||
)
|
||||
|
||||
type PortMappers struct {
|
||||
drivers map[string]portmapperapi.PortMapper
|
||||
}
|
||||
|
||||
// Register a portmapper with the registry.
|
||||
func (r *PortMappers) Register(name string, pm portmapperapi.PortMapper) error {
|
||||
if strings.TrimSpace(name) == "" {
|
||||
return errors.New("portmapper name cannot be empty")
|
||||
}
|
||||
|
||||
if _, ok := r.drivers[name]; ok {
|
||||
return errors.New("portmapper already registered")
|
||||
}
|
||||
|
||||
if r.drivers == nil {
|
||||
r.drivers = make(map[string]portmapperapi.PortMapper)
|
||||
}
|
||||
|
||||
r.drivers[name] = pm
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get retrieves a portmapper by name from the registry.
|
||||
func (r *PortMappers) Get(name string) (portmapperapi.PortMapper, error) {
|
||||
pm, ok := r.drivers[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("portmapper %s not found", name)
|
||||
}
|
||||
return pm, nil
|
||||
}
|
||||
67
daemon/libnetwork/drvregistry/portmappers_test.go
Normal file
67
daemon/libnetwork/drvregistry/portmappers_test.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package drvregistry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/daemon/libnetwork/portmapperapi"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
type fakePortMapper struct{}
|
||||
|
||||
func (f fakePortMapper) MapPorts(_ context.Context, _ []portmapperapi.PortBindingReq, _ portmapperapi.Firewaller) ([]portmapperapi.PortBinding, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f fakePortMapper) UnmapPorts(_ context.Context, _ []portmapperapi.PortBinding, _ portmapperapi.Firewaller) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestRegisterPortMappers(t *testing.T) {
|
||||
t.Run("register port mapper", func(t *testing.T) {
|
||||
var pms PortMappers
|
||||
|
||||
pm := fakePortMapper{}
|
||||
err := pms.Register("test", pm)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
t.Run("empty name", func(t *testing.T) {
|
||||
var pms PortMappers
|
||||
|
||||
err := pms.Register("", nil)
|
||||
assert.ErrorContains(t, err, "portmapper name cannot be empty")
|
||||
})
|
||||
|
||||
t.Run("duplicate port mapper", func(t *testing.T) {
|
||||
var pms PortMappers
|
||||
|
||||
err := pms.Register("test", nil)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = pms.Register("test", nil)
|
||||
assert.ErrorContains(t, err, "portmapper already registered")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetPortMapper(t *testing.T) {
|
||||
t.Run("get existing port mapper", func(t *testing.T) {
|
||||
var pms PortMappers
|
||||
|
||||
pm := fakePortMapper{}
|
||||
err := pms.Register("test", pm)
|
||||
assert.NilError(t, err)
|
||||
|
||||
retrieved, err := pms.Get("test")
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, retrieved, pm)
|
||||
})
|
||||
|
||||
t.Run("get nonexistent port mapper", func(t *testing.T) {
|
||||
var pms PortMappers
|
||||
|
||||
_, err := pms.Get("nonexistent")
|
||||
assert.ErrorContains(t, err, "portmapper nonexistent not found")
|
||||
})
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package portmapperapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
@@ -8,6 +9,31 @@ import (
|
||||
"github.com/docker/docker/daemon/libnetwork/types"
|
||||
)
|
||||
|
||||
// Registerer provides a callback interface for registering port-mappers.
|
||||
type Registerer interface {
|
||||
// Register provides a way for port-mappers to dynamically register with libnetwork.
|
||||
Register(name string, driver PortMapper) error
|
||||
}
|
||||
|
||||
// PortMapper maps / unmaps container ports to host ports.
|
||||
type PortMapper interface {
|
||||
// MapPorts takes a list of port binding requests, and returns a list of
|
||||
// PortBinding. Both lists MUST have the same size.
|
||||
//
|
||||
// Multiple port bindings are passed when they're all requesting the
|
||||
// same port range, or an ephemeral port, over multiple IP addresses and
|
||||
// all pointing to the same container port. In that case, the PortMapper
|
||||
// MUST assign the same HostPort for all IP addresses.
|
||||
//
|
||||
// When an ephemeral port, or a single port from a range is requested
|
||||
// MapPorts should attempt a few times to find a free port available
|
||||
// across all IP addresses.
|
||||
MapPorts(ctx context.Context, reqs []PortBindingReq, fwn Firewaller) ([]PortBinding, error)
|
||||
|
||||
// UnmapPorts takes a list of port bindings to unmap.
|
||||
UnmapPorts(ctx context.Context, pbs []PortBinding, fwn Firewaller) error
|
||||
}
|
||||
|
||||
type PortBindingReq struct {
|
||||
types.PortBinding
|
||||
// ChildHostIP is a temporary field used to pass the host IP address as
|
||||
|
||||
14
daemon/libnetwork/portmapperapi/firewaller.go
Normal file
14
daemon/libnetwork/portmapperapi/firewaller.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package portmapperapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/daemon/libnetwork/types"
|
||||
)
|
||||
|
||||
type Firewaller interface {
|
||||
// AddPorts adds the configuration needed for NATing ports.
|
||||
AddPorts(ctx context.Context, pbs []types.PortBinding) error
|
||||
// DelPorts deletes the configuration needed for NATing ports.
|
||||
DelPorts(ctx context.Context, pbs []types.PortBinding) error
|
||||
}
|
||||
Reference in New Issue
Block a user