libnetwork/drivers/bridge: assorted cleanups
### libnetwork/drivers/bridge: link.Enable, link.Disable use iptables types

The iptables package has types defined for these actions; use them directly
instead of creating a string only to convert it to a known value.

### libnetwork/drivers/bridge: link.Enable: don't register reload on error

Only register a reload function if we actually managed to enable the link.

### libnetwork/drivers/bridge: don't convert IP to string and back again

### libnetwork/drivers/bridge: driver.link: name return var for defer handling

Name the return variable to prevent accidental shadowing of the error,
which is used in defers.


### libnetwork/drivers/bridge: driver.link: don't defer in a loop

Collect a list of all the links we successfully enabled (if any), and
use a single defer to disable them.


### libnetwork/drivers/bridge: bridge.NetworkgetEndpoint(): move lock

Don't lock if there's no need to.

### ibnetwork/drivers/bridge: newLink: validate before creating


**- A picture of a cute animal (not mandatory but encouraged)**


libnetwork/drivers/bridge/link_test.go
//go:build linux

package bridge

import (
	"testing"

	"github.com/docker/docker/libnetwork/types"
)

func getPorts() []types.TransportPort {
	return []types.TransportPort{
		{Proto: types.TCP, Port: uint16(5000)},
		{Proto: types.UDP, Port: uint16(400)},
		{Proto: types.TCP, Port: uint16(600)},
	}
}

func TestLinkNew(t *testing.T) {
	ports := getPorts()

	link := newLink("172.0.17.3", "172.0.17.2", ports, "docker0")

	if link == nil {
		t.FailNow()
	}
	if link.parentIP != "172.0.17.3" {
		t.Fail()
	}
	if link.childIP != "172.0.17.2" {
		t.Fail()
	}
	for i, p := range link.ports {
		if p != ports[i] {
			t.Fail()
		}
	}
	if link.bridge != "docker0" {
		t.Fail()
	}
}

//go:build linux

package bridge

import (
	"net"
	"testing"

	"github.com/docker/docker/libnetwork/types"
)

func getPorts() []types.TransportPort {
	return []types.TransportPort{
		{Proto: types.TCP, Port: uint16(5000)},
		{Proto: types.UDP, Port: uint16(400)},
		{Proto: types.TCP, Port: uint16(600)},
	}
}

func TestLinkNew(t *testing.T) {
	ports := getPorts()

	const (
		pIP        = "172.0.17.3"
		cIP        = "172.0.17.2"
		bridgeName = "docker0"
	)

	parentIP := net.ParseIP(pIP)
	childIP := net.ParseIP(cIP)

	l, err := newLink(parentIP, childIP, ports, bridgeName)
	if err != nil {
		t.Errorf("unexpected error from newlink(): %v", err)
	}
	if l == nil {
		t.FailNow()
	}
	if l.parentIP.String() != pIP {
		t.Fail()
	}
	if l.childIP.String() != cIP {
		t.Fail()
	}
	for i, p := range l.ports {
		if p != ports[i] {
			t.Fail()
		}
	}
	if l.bridge != bridgeName {
		t.Fail()
	}
}

Any reason not to use `assert.Assert` above and `assert.Check` here and below?