libnetwork: improve tests & fix some bugs
<!--
Please make sure you've read and understood our contributing guidelines;
https://github.com/moby/moby/blob/master/CONTRIBUTING.md

** Make sure all your commits include a signature generated with `git commit -s` **

For additional information on our contributing process, read our contributing
guide https://docs.docker.com/opensource/code/

If this is a bug fix, make sure your description includes "fixes #xxxx", or
"closes #xxxx"

Please provide the following information:
-->

**- What I did**
- Improved the isolation between libnetwork tests, so they won't interfere with—or depend on running after—other tests
- Improved and cleaned up the libnetwork tests in other ways; see individual commits
- Fixed bugs in the libnetwork implementation which were uncovered by the improved tests

**- How I did it**
- Changed all the libnetwork tests to run in separate network namespaces, with private `NetworkController` instances
- Eliminated lots of shared global state in tests
- Fixed instances of accidentally-shared state in the libnetwork implementation

**- How to verify it**
CI

**- Description for the changelog**
<!--
Write a short (one line) summary that describes the changes in this
pull request for inclusion in the changelog:
-->


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


libnetwork/drivers/bridge/interface.go
//go:build linux
// +build linux

package bridge

import (
	"fmt"
	"net"

	"github.com/sirupsen/logrus"
	"github.com/vishvananda/netlink"
)

const (
	// DefaultBridgeName is the default name for the bridge interface managed
	// by the driver when unspecified by the caller.
	DefaultBridgeName = "docker0"
)

// Interface models the bridge network device.
type bridgeInterface struct {
	Link        netlink.Link
	bridgeIPv4  *net.IPNet
	bridgeIPv6  *net.IPNet
	gatewayIPv4 net.IP
	gatewayIPv6 net.IP
	nlh         *netlink.Handle
}

// newInterface creates a new bridge interface structure. It attempts to find
// an already existing device identified by the configuration BridgeName field,
// or the default bridge name when unspecified, but doesn't attempt to create
// one when missing
func newInterface(nlh *netlink.Handle, config *networkConfiguration) (*bridgeInterface, error) {
	var err error
	i := &bridgeInterface{nlh: nlh}

	// Initialize the bridge name to the default if unspecified.
	if config.BridgeName == "" {
		config.BridgeName = DefaultBridgeName
	}

	// Attempt to find an existing bridge named with the specified name.
	i.Link, err = nlh.LinkByName(config.BridgeName)
	if err != nil {
		logrus.Debugf("Did not find any interface with name %s: %v", config.BridgeName, err)
	} else if _, ok := i.Link.(*netlink.Bridge); !ok {
		return nil, fmt.Errorf("existing interface %s is not a bridge", i.Link.Attrs().Name)
	}
	return i, nil
}

// exists indicates if the existing bridge interface exists on the system.
func (i *bridgeInterface) exists() bool {
	return i.Link != nil
}

// addresses returns all IPv4 addresses and all IPv6 addresses for the bridge interface.
func (i *bridgeInterface) addresses() ([]netlink.Addr, []netlink.Addr, error) {
	v4addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V4)
	if err != nil {
		return nil, nil, fmt.Errorf("Failed to retrieve V4 addresses: %v", err)
	}

	v6addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V6)
	if err != nil {
		return nil, nil, fmt.Errorf("Failed to retrieve V6 addresses: %v", err)
	}

	if len(v4addr) == 0 {
		return nil, v6addr, nil
	}
	return v4addr, v6addr, nil
}

func (i *bridgeInterface) programIPv6Address() error {
	_, nlAddressList, err := i.addresses()
	if err != nil {
		return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: fmt.Errorf("failed to retrieve address list: %v", err)}
	}
	nlAddr := netlink.Addr{IPNet: i.bridgeIPv6}
	if findIPv6Address(nlAddr, nlAddressList) {
		return nil
	}
	if err := i.nlh.AddrAdd(i.Link, &nlAddr); err != nil {
		return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: err}
	}
	return nil
}

//go:build linux
// +build linux

package bridge

import (
	"fmt"
	"net"

	"github.com/sirupsen/logrus"
	"github.com/vishvananda/netlink"
)

const (
	// DefaultBridgeName is the default name for the bridge interface managed
	// by the driver when unspecified by the caller.
	DefaultBridgeName = "docker0"
)

// Interface models the bridge network device.
type bridgeInterface struct {
	Link        netlink.Link
	bridgeIPv4  *net.IPNet
	bridgeIPv6  *net.IPNet
	gatewayIPv4 net.IP
	gatewayIPv6 net.IP
	nlh         *netlink.Handle
}

// newInterface creates a new bridge interface structure. It attempts to find
// an already existing device identified by the configuration BridgeName field,
// or the default bridge name when unspecified, but doesn't attempt to create
// one when missing
func newInterface(nlh *netlink.Handle, config *networkConfiguration) (*bridgeInterface, error) {
	var err error
	i := &bridgeInterface{nlh: nlh}

	// Initialize the bridge name to the default if unspecified.
	if config.BridgeName == "" {
		config.BridgeName = DefaultBridgeName
	}

	// Attempt to find an existing bridge named with the specified name.
	i.Link, err = nlh.LinkByName(config.BridgeName)
	if err != nil {
		logrus.Debugf("Did not find any interface with name %s: %v", config.BridgeName, err)
	} else if _, ok := i.Link.(*netlink.Bridge); !ok {
		return nil, fmt.Errorf("existing interface %s is not a bridge", i.Link.Attrs().Name)
	}
	return i, nil
}

// exists indicates if the existing bridge interface exists on the system.
func (i *bridgeInterface) exists() bool {
	return i.Link != nil
}

// addresses returns all IPv4 addresses and all IPv6 addresses for the bridge interface.
func (i *bridgeInterface) addresses() ([]netlink.Addr, []netlink.Addr, error) {
	if !i.exists() {
		// A nonexistent interface, by definition, cannot have any addresses.
		return nil, nil, nil
	}
	v4addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V4)
	if err != nil {
		return nil, nil, fmt.Errorf("Failed to retrieve V4 addresses: %v", err)
	}

	v6addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V6)
	if err != nil {
		return nil, nil, fmt.Errorf("Failed to retrieve V6 addresses: %v", err)
	}

	if len(v4addr) == 0 {
		return nil, v6addr, nil
	}
	return v4addr, v6addr, nil
}

func (i *bridgeInterface) programIPv6Address() error {
	_, nlAddressList, err := i.addresses()
	if err != nil {
		return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: fmt.Errorf("failed to retrieve address list: %v", err)}
	}
	nlAddr := netlink.Addr{IPNet: i.bridgeIPv6}
	if findIPv6Address(nlAddr, nlAddressList) {
		return nil
	}
	if err := i.nlh.AddrAdd(i.Link, &nlAddr); err != nil {
		return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: err}
	}
	return nil
}

Hm.. nice find!