Allow overlapping change in bridge's IPv6 network.
**- What I did**

The original ticket reports that the daemon won't start if the `fixed-cidr-v6` address is changed from `fe80::/64` to, for example, `fe80::/80` ... those are link local addresses, which turn out to be a special case. But, the same applies to any IPv6 subnet - if the daemon is started with IPv6 enabled on the default bridge, then the `fixed-cidr-v6` is changed to an overlapping subnet, the daemon fails to start. (For example, `2001:db8::/64` to `2001:db8::/80`.)

This change makes it possible to change the configured address for the default bridge to an overlapping subnet (without manually deleting the `docker0` bridge).

Link-local addresses were a special case because they were not released when a container stopped. So, for the default bridge where IP addresses are based on MAC addresses - and MAC addresses were recycled - with `fixed-cidr-v6=fe80::/64`, once a container was stopped new containers could not be started.  For non-default bridge networks with a link-local subnet, addresses leaked when containers stopped.

Linux always uses the `fe80::/64` network, the 'veth' devices get addresses in that subnet. So, overlapping LL subnets are not allowed by this change, other LL subnets are ok.

**- How I did it**

The code was doing this:
```
setupBridgeIPv6():
   - programIPv6Address(<default link local address>)
   - programIPv6Address(<configured address>)
if !config.InhibitIPv4 then setupVerifyAndReconcile():
  - some IPv4 stuff
  - remove global-unicast IPv6 addresses, apart from the configured on
```

So, it was trying to add the new configured address before deleting the old one. Nowhere in the code has a complete picture of the IPv6 addresses the bridge needs, so it's not able to reconcile existing/required config properly.

This change calculates the IPv6 addresses needed on the bridge, then reconciles them with the addresses on an existing bridge by deleting then adding addresses as required - all in `setupBridgeIPv6()`.

If the configured subnet is link-local, it replaces the default link local address/network.

Link local addresses are returned to their address pool when containers are stopped.

Also...

The only remaining calls of `bridgeInterface.addresses()` want either IPv4 or IPv6, but not both. So, made the address family a param.

Because the IPv6 addresses are now calculated and applied in one go, there's no need for `setupVerifyAndReconcile()` to check the set of IPv6 addresses on the bridge. And, that code was guarded by `!config.InhibitIPv4`, which can't have been right. So, removed its IPv6 parts, and added IPv4 to the function's name.

Fixes #46829

**- How to verify it**

New integration test, and updated unit tests.

Overlapping change to `--fixed-cidr-v6`:
```
# dockerd  --ipv6 --experimental --ip6tables --fixed-cidr-v6=fc00:1234::/64
...
# ip a
[...]
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:b8:f5:44:23 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fc00:1234::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::1/64 scope link
       valid_lft forever preferred_lft forever

# dockerd  --ipv6 --experimental --ip6tables --fixed-cidr-v6=fc00:1234::/80
...
# ip a
[...]
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:b8:f5:44:23 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fc00:1234::1/80 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::1/64 scope link
       valid_lft forever preferred_lft forever
```

Explicit errors if `--fixed-cidr-v6` is link local and overlaps with (but isn't equal to) `fe80::/64`:

```
# dockerd --ipv6 --experimental --ip6tables --fixed-cidr-v6=fe80::/65 --validate
unable to configure the Docker daemon with file /etc/docker/daemon.json: merged configuration validation from file and command line flags failed: invalid fixed-cidr-v6: clash with the Link-Local prefix 'fe80::/64'

# docker network create --subnet=fe80::/65 testnet
Error response from daemon: clash with the Link-Local prefix 'fe80::/64'
```

**- Description for the changelog**

Allow overlapping change in bridge's IPv6 subnet, support link-local subnets.
libnetwork/drivers/bridge/interface_linux_test.go
package bridge

import (
	"testing"

	"github.com/docker/docker/internal/testutils/netnsutils"
	"github.com/vishvananda/netlink"
)

func TestInterfaceDefaultName(t *testing.T) {
	defer netnsutils.SetupTestOSContext(t)()

	nh, err := netlink.NewHandle()
	if err != nil {
		t.Fatal(err)
	}
	config := &networkConfiguration{}
	_, err = newInterface(nh, config)
	if err != nil {
		t.Fatalf("newInterface() failed: %v", err)
	}

	if config.BridgeName != DefaultBridgeName {
		t.Fatalf("Expected default interface name %q, got %q", DefaultBridgeName, config.BridgeName)
	}
}

func TestAddressesEmptyInterface(t *testing.T) {
	defer netnsutils.SetupTestOSContext(t)()

	nh, err := netlink.NewHandle()
	if err != nil {
		t.Fatal(err)
	}
	inf, err := newInterface(nh, &networkConfiguration{})
	if err != nil {
		t.Fatalf("newInterface() failed: %v", err)
	}

	addrsv4, addrsv6, err := inf.addresses()
	if err != nil {
		t.Fatalf("Failed to get addresses of default interface: %v", err)
	}
	if len(addrsv4) != 0 {
		t.Fatalf("Default interface has unexpected IPv4: %s", addrsv4)
	}
	if len(addrsv6) != 0 {
		t.Fatalf("Default interface has unexpected IPv6: %v", addrsv6)
	}
}

package bridge

import (
	"net"
	"net/netip"
	"strings"
	"testing"

	"github.com/docker/docker/internal/testutils/netnsutils"
	"github.com/google/go-cmp/cmp"
	"github.com/vishvananda/netlink"
	"gotest.tools/v3/assert"
	is "gotest.tools/v3/assert/cmp"
)

func cidrToIPNet(t *testing.T, cidr string) *net.IPNet {
	t.Helper()
	ip, ipNet, err := net.ParseCIDR(cidr)
	assert.Assert(t, is.Nil(err))
	return &net.IPNet{IP: ip, Mask: ipNet.Mask}
}

func addAddr(t *testing.T, link netlink.Link, addr string) {
	t.Helper()
	ipNet := cidrToIPNet(t, addr)
	err := netlink.AddrAdd(link, &netlink.Addr{IPNet: ipNet})
	assert.Assert(t, is.Nil(err))
}

func prepTestBridge(t *testing.T, nc *networkConfiguration) *bridgeInterface {
	t.Helper()
	nh, err := netlink.NewHandle()
	assert.Assert(t, err)
	i, err := newInterface(nh, nc)
	assert.Assert(t, err)
	err = setupDevice(nc, i)
	assert.Assert(t, err)
	return i
}

func TestInterfaceDefaultName(t *testing.T) {
	defer netnsutils.SetupTestOSContext(t)()

	nh, err := netlink.NewHandle()
	if err != nil {
		t.Fatal(err)
	}
	config := &networkConfiguration{}
	_, err = newInterface(nh, config)
	assert.Check(t, err)
	assert.Equal(t, config.BridgeName, DefaultBridgeName)
}

func TestAddressesNoInterface(t *testing.T) {
	i := bridgeInterface{}
	addrs, err := i.addresses(netlink.FAMILY_V6)
	assert.NilError(t, err)
	assert.Check(t, is.Len(addrs, 0))
}

func TestAddressesEmptyInterface(t *testing.T) {
	defer netnsutils.SetupTestOSContext(t)()

	nh, err := netlink.NewHandle()
	assert.NilError(t, err)

	inf, err := newInterface(nh, &networkConfiguration{})
	assert.NilError(t, err)

	addrsv4, err := inf.addresses(netlink.FAMILY_V4)
	assert.NilError(t, err)
	assert.Check(t, is.Len(addrsv4, 0))

	addrsv6, err := inf.addresses(netlink.FAMILY_V6)
	assert.NilError(t, err)
	assert.Check(t, is.Len(addrsv6, 0))
}

func TestAddressesNonEmptyInterface(t *testing.T) {
	defer netnsutils.SetupTestOSContext(t)()

	i := prepTestBridge(t, &networkConfiguration{})

	const expAddrV4, expAddrV6 = "192.168.1.2/24", "fd00:1234::/64"
	addAddr(t, i.Link, expAddrV4)
	addAddr(t, i.Link, expAddrV6)

	addrs, err := i.addresses(netlink.FAMILY_V4)
	assert.NilError(t, err)
	assert.Check(t, is.Len(addrs, 1))
	assert.Equal(t, addrs[0].IPNet.String(), expAddrV4)

	addrs, err = i.addresses(netlink.FAMILY_V6)
	assert.NilError(t, err)
	assert.Check(t, is.Len(addrs, 1))
	assert.Equal(t, addrs[0].IPNet.String(), expAddrV6)
}

func TestGetRequiredIPv6Addrs(t *testing.T) {
	testcases := []struct {
		name         string
		addressIPv6  string
		expReqdAddrs []string
	}{
		{
			name:         "Regular address, expect default link local",
			addressIPv6:  "2000:3000::1/80",
			expReqdAddrs: []string{"fe80::1/64", "2000:3000::1/80"},
		},
		{
			name:         "Standard link local address only",
			addressIPv6:  "fe80::1/64",
			expReqdAddrs: []string{"fe80::1/64"},
		},
		{
			name:         "Nonstandard link local address",
			addressIPv6:  "fe80:abcd::1/42",
			expReqdAddrs: []string{"fe80:abcd::1/42", "fe80::1/64"},
		},
	}

	for _, tc := range testcases {
		t.Run(tc.name, func(t *testing.T) {
			config := &networkConfiguration{
				AddressIPv6: cidrToIPNet(t, tc.addressIPv6),
			}

			expResult := map[netip.Addr]netip.Prefix{}
			for _, addr := range tc.expReqdAddrs {
				expResult[netip.MustParseAddr(strings.Split(addr, "/")[0])] = netip.MustParsePrefix(addr)
			}

			reqd, addr, gw, err := getRequiredIPv6Addrs(config)
			assert.Check(t, is.Nil(err))
			assert.Check(t, is.DeepEqual(addr, config.AddressIPv6))
			assert.Check(t, is.DeepEqual(gw, config.AddressIPv6.IP))
			assert.Check(t, is.DeepEqual(reqd, expResult,
				cmp.Comparer(func(a, b netip.Prefix) bool { return a == b })))
		})
	}
}

func TestProgramIPv6Addresses(t *testing.T) {
	defer netnsutils.SetupTestOSContext(t)()

	checkAddrs := func(i *bridgeInterface, expAddrs []string) {
		t.Helper()
		exp := []netlink.Addr{}
		for _, a := range expAddrs {
			ipNet := cidrToIPNet(t, a)
			exp = append(exp, netlink.Addr{IPNet: ipNet})
		}
		actual, err := i.addresses(netlink.FAMILY_V6)
		assert.NilError(t, err)
		assert.DeepEqual(t, exp, actual)
	}

	nc := &networkConfiguration{}
	i := prepTestBridge(t, nc)

	// The bridge has no addresses, ask for a regular IPv6 network and expect it to
	// be added to the bridge, with the default link local address.
	nc.AddressIPv6 = cidrToIPNet(t, "2000:3000::1/64")
	err := i.programIPv6Addresses(nc)
	assert.NilError(t, err)
	checkAddrs(i, []string{"2000:3000::1/64", "fe80::1/64"})

	// Shrink the subnet of that regular address, the prefix length of the address
	// will not be modified - but it's informational-only, the address itself has
	// not changed.
	nc.AddressIPv6 = cidrToIPNet(t, "2000:3000::1/80")
	err = i.programIPv6Addresses(nc)
	assert.NilError(t, err)
	checkAddrs(i, []string{"2000:3000::1/64", "fe80::1/64"})

	// Ask for link-local only, by specifying an address with the Link Local prefix.
	// The regular address should be removed.
	nc.AddressIPv6 = cidrToIPNet(t, "fe80::1/64")
	err = i.programIPv6Addresses(nc)
	assert.NilError(t, err)
	checkAddrs(i, []string{"fe80::1/64"})

	// Swap the standard link local address for a nonstandard one.
	nc.AddressIPv6 = cidrToIPNet(t, "fe80:5555::1/55")
	err = i.programIPv6Addresses(nc)
	assert.NilError(t, err)
	checkAddrs(i, []string{"fe80:5555::1/55", "fe80::1/64"})
}

There are no subtests, so this helper function could close over `t`.
```suggestion
	checkAddrs := func(i *bridgeInterface, expAddrs []string) {
```