Merge pull request #47311 from akerouanton/25.0-libnet-bridge-mtu-ignore-einval

[25.0 backport] libnet: bridge: ignore EINVAL when configuring bridge MTU
This commit is contained in:
Sebastiaan van Stijn 2024-02-03 11:36:47 +01:00 committed by GitHub
commit 1ae115175c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 0 deletions

View file

@ -2,9 +2,11 @@ package bridge
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"syscall"
"github.com/containerd/log"
"github.com/docker/docker/libnetwork/netutils"
@ -47,6 +49,14 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
func setupMTU(config *networkConfiguration, i *bridgeInterface) error {
if err := i.nlh.LinkSetMTU(i.Link, config.Mtu); err != nil {
// Before Linux v4.17, bridges couldn't be configured "manually" with an MTU greater than 1500, although it
// could be autoconfigured with such a value when interfaces were added to the bridge. In that case, the
// bridge MTU would be set automatically by the kernel to the lowest MTU of all interfaces attached. To keep
// compatibility with older kernels, we need to discard -EINVAL.
// TODO(aker): remove this once we drop support for CentOS/RHEL 7.
if config.Mtu > 1500 && config.Mtu <= 0xFFFF && errors.Is(err, syscall.EINVAL) {
return nil
}
log.G(context.TODO()).WithError(err).Errorf("Failed to set bridge MTU %s via netlink", config.BridgeName)
return err
}

View file

@ -3,11 +3,13 @@ package bridge
import (
"bytes"
"net"
"syscall"
"testing"
"github.com/docker/docker/internal/testutils/netnsutils"
"github.com/docker/docker/libnetwork/netutils"
"github.com/vishvananda/netlink"
"gotest.tools/v3/assert"
)
func TestSetupNewBridge(t *testing.T) {
@ -92,3 +94,35 @@ func TestGenerateRandomMAC(t *testing.T) {
t.Fatalf("Generated twice the same MAC address %v", mac1)
}
}
func TestMTUBiggerThan1500(t *testing.T) {
defer netnsutils.SetupTestOSContext(t)()
nh, err := netlink.NewHandle()
if err != nil {
t.Fatal(err)
}
defer nh.Close()
config := &networkConfiguration{BridgeName: DefaultBridgeName, Mtu: 9000}
br := &bridgeInterface{nlh: nh}
assert.NilError(t, setupDevice(config, br))
assert.NilError(t, setupMTU(config, br))
}
func TestMTUBiggerThan64K(t *testing.T) {
defer netnsutils.SetupTestOSContext(t)()
nh, err := netlink.NewHandle()
if err != nil {
t.Fatal(err)
}
defer nh.Close()
config := &networkConfiguration{BridgeName: DefaultBridgeName, Mtu: 65536}
br := &bridgeInterface{nlh: nh}
assert.NilError(t, setupDevice(config, br))
assert.ErrorIs(t, setupMTU(config, br), syscall.EINVAL)
}