This is purely cosmetic - if a non-default MTU is configured, the bridge
will have the default MTU=1500 until a container's 'veth' is connected
and an MTU is set on the veth. That's a disconcerting, it looks like the
config has been ignored - so, set the bridge's MTU explicitly.
Fixes #37937
Signed-off-by: Rob Murray <rob.murray@docker.com>
| ... | ... |
@@ -240,7 +240,7 @@ func TestDefaultNetworkOpts(t *testing.T) {
|
| 240 | 240 |
|
| 241 | 241 |
// Create a new network |
| 242 | 242 |
networkName := "testnet" |
| 243 |
- network.CreateNoError(ctx, t, c, networkName, func(create *types.NetworkCreate) {
|
|
| 243 |
+ networkId := network.CreateNoError(ctx, t, c, networkName, func(create *types.NetworkCreate) {
|
|
| 244 | 244 |
if tc.configFrom {
|
| 245 | 245 |
create.ConfigFrom = &ntypes.ConfigReference{
|
| 246 | 246 |
Network: "from-net", |
| ... | ... |
@@ -249,6 +249,15 @@ func TestDefaultNetworkOpts(t *testing.T) {
|
| 249 | 249 |
}) |
| 250 | 250 |
defer c.NetworkRemove(ctx, networkName) |
| 251 | 251 |
|
| 252 |
+ // Check the MTU of the bridge itself, before any devices are connected. (The |
|
| 253 |
+ // bridge's MTU will be set to the minimum MTU of anything connected to it, but |
|
| 254 |
+ // it's set explicitly on the bridge anyway - so it doesn't look like the option |
|
| 255 |
+ // was ignored.) |
|
| 256 |
+ cmd := exec.Command("ip", "link", "show", "br-"+networkId[:12])
|
|
| 257 |
+ output, err := cmd.CombinedOutput() |
|
| 258 |
+ assert.NilError(t, err) |
|
| 259 |
+ assert.Check(t, is.Contains(string(output), fmt.Sprintf(" mtu %d ", tc.mtu)), "Bridge MTU should have been set to %d", tc.mtu)
|
|
| 260 |
+ |
|
| 252 | 261 |
// Start a container to inspect the MTU of its network interface |
| 253 | 262 |
id1 := container.Run(ctx, t, c, container.WithNetworkMode(networkName)) |
| 254 | 263 |
defer c.ContainerRemove(ctx, id1, containertypes.RemoveOptions{Force: true})
|
| ... | ... |
@@ -735,6 +735,14 @@ func (d *driver) createNetwork(config *networkConfiguration) (err error) {
|
| 735 | 735 |
bridgeSetup.queueStep(setupDefaultSysctl) |
| 736 | 736 |
} |
| 737 | 737 |
|
| 738 |
+ // Always set the bridge's MTU if specified. This is purely cosmetic; a bridge's |
|
| 739 |
+ // MTU is the min MTU of device connected to it, and MTU will be set on each |
|
| 740 |
+ // 'veth'. But, for a non-default MTU, the bridge's MTU will look wrong until a |
|
| 741 |
+ // container is attached. |
|
| 742 |
+ if config.Mtu > 0 {
|
|
| 743 |
+ bridgeSetup.queueStep(setupMTU) |
|
| 744 |
+ } |
|
| 745 |
+ |
|
| 738 | 746 |
// Even if a bridge exists try to setup IPv4. |
| 739 | 747 |
bridgeSetup.queueStep(setupBridgeIPv4) |
| 740 | 748 |
|
| ... | ... |
@@ -45,6 +45,14 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
|
| 45 | 45 |
return nil |
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 |
+func setupMTU(config *networkConfiguration, i *bridgeInterface) error {
|
|
| 49 |
+ if err := i.nlh.LinkSetMTU(i.Link, config.Mtu); err != nil {
|
|
| 50 |
+ log.G(context.TODO()).WithError(err).Errorf("Failed to set bridge MTU %s via netlink", config.BridgeName)
|
|
| 51 |
+ return err |
|
| 52 |
+ } |
|
| 53 |
+ return nil |
|
| 54 |
+} |
|
| 55 |
+ |
|
| 48 | 56 |
func setupDefaultSysctl(config *networkConfiguration, i *bridgeInterface) error {
|
| 49 | 57 |
// Disable IPv6 router advertisements originating on the bridge |
| 50 | 58 |
sysPath := filepath.Join("/proc/sys/net/ipv6/conf/", config.BridgeName, "accept_ra")
|