Multicast addresses aren't added by the daemon so, if they're present,
it's because they were explicitly added - possibly to a user-managed
bridge. So, don't remove.
Signed-off-by: Rob Murray <rob.murray@docker.com>
| ... | ... |
@@ -102,6 +102,10 @@ func (i *bridgeInterface) programIPv6Addresses(config *networkConfiguration) err |
| 102 | 102 |
if p, _ := ea.Prefix(64); p == linkLocalPrefix {
|
| 103 | 103 |
continue |
| 104 | 104 |
} |
| 105 |
+ // Don't delete multicast addresses as they're never added by the daemon. |
|
| 106 |
+ if ea.IsMulticast() {
|
|
| 107 |
+ continue |
|
| 108 |
+ } |
|
| 105 | 109 |
// Ignore the prefix length when comparing addresses, it's informational |
| 106 | 110 |
// (RFC-5942 section 4), and removing/re-adding an address that's still valid |
| 107 | 111 |
// would disrupt traffic on live-restore. |
| ... | ... |
@@ -2,10 +2,12 @@ package bridge |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"net" |
| 5 |
+ "sort" |
|
| 5 | 6 |
"testing" |
| 6 | 7 |
|
| 7 | 8 |
"github.com/docker/docker/internal/testutils/netnsutils" |
| 8 | 9 |
"github.com/vishvananda/netlink" |
| 10 |
+ "golang.org/x/sys/unix" |
|
| 9 | 11 |
"gotest.tools/v3/assert" |
| 10 | 12 |
is "gotest.tools/v3/assert/cmp" |
| 11 | 13 |
) |
| ... | ... |
@@ -98,14 +100,16 @@ func TestProgramIPv6Addresses(t *testing.T) {
|
| 98 | 98 |
|
| 99 | 99 |
checkAddrs := func(i *bridgeInterface, nc *networkConfiguration, expAddrs []string) {
|
| 100 | 100 |
t.Helper() |
| 101 |
- exp := []netlink.Addr{}
|
|
| 102 |
- for _, a := range expAddrs {
|
|
| 103 |
- ipNet := cidrToIPNet(t, a) |
|
| 104 |
- exp = append(exp, netlink.Addr{IPNet: ipNet})
|
|
| 101 |
+ nladdrs, err := i.addresses(netlink.FAMILY_V6) |
|
| 102 |
+ actual := []string{}
|
|
| 103 |
+ for _, a := range nladdrs {
|
|
| 104 |
+ actual = append(actual, a.String()) |
|
| 105 | 105 |
} |
| 106 |
- actual, err := i.addresses(netlink.FAMILY_V6) |
|
| 107 | 106 |
assert.NilError(t, err) |
| 108 |
- assert.DeepEqual(t, exp, actual) |
|
| 107 |
+ exp := append([]string(nil), expAddrs...) |
|
| 108 |
+ sort.Strings(exp) |
|
| 109 |
+ sort.Strings(actual) |
|
| 110 |
+ assert.DeepEqual(t, actual, exp) |
|
| 109 | 111 |
assert.Check(t, is.DeepEqual(i.bridgeIPv6, nc.AddressIPv6)) |
| 110 | 112 |
assert.Check(t, is.DeepEqual(i.gatewayIPv6, nc.AddressIPv6.IP)) |
| 111 | 113 |
} |
| ... | ... |
@@ -147,4 +151,14 @@ func TestProgramIPv6Addresses(t *testing.T) {
|
| 147 | 147 |
err = i.programIPv6Addresses(nc) |
| 148 | 148 |
assert.NilError(t, err) |
| 149 | 149 |
checkAddrs(i, nc, []string{"2000:3000::1/64", "fe80::1/64"})
|
| 150 |
+ |
|
| 151 |
+ // Add a multicast address to the bridge and check it's not removed. |
|
| 152 |
+ mcNlAddr, err := netlink.ParseAddr("ff05::db8:0:1234/96")
|
|
| 153 |
+ assert.NilError(t, err) |
|
| 154 |
+ mcNlAddr.Flags = unix.IFA_F_MCAUTOJOIN |
|
| 155 |
+ err = i.nlh.AddrAdd(i.Link, mcNlAddr) |
|
| 156 |
+ assert.NilError(t, err) |
|
| 157 |
+ err = i.programIPv6Addresses(nc) |
|
| 158 |
+ assert.NilError(t, err) |
|
| 159 |
+ checkAddrs(i, nc, []string{"2000:3000::1/64", "fe80::1/64", "ff05::db8:0:1234/96"})
|
|
| 150 | 160 |
} |