- The oldest kernel version currently supported is v3.10. Bridge
parameters can be set through netlink since v3.8 (see
torvalds/linux@25c71c7). As such, we don't need to fallback to sysfs to
set hairpin mode.
- `scanInterfaceStats()` is never called, so no need to keep it alive.
- Document why `default_pvid` is set through sysfs
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
| ... | ... |
@@ -9,10 +9,8 @@ import ( |
| 9 | 9 |
"net" |
| 10 | 10 |
"os" |
| 11 | 11 |
"os/exec" |
| 12 |
- "path/filepath" |
|
| 13 | 12 |
"strconv" |
| 14 | 13 |
"sync" |
| 15 |
- "syscall" |
|
| 16 | 14 |
|
| 17 | 15 |
"github.com/docker/docker/libnetwork/datastore" |
| 18 | 16 |
"github.com/docker/docker/libnetwork/discoverapi" |
| ... | ... |
@@ -891,32 +889,10 @@ func addToBridge(nlh *netlink.Handle, ifaceName, bridgeName string) error {
|
| 891 | 891 |
|
| 892 | 892 |
func setHairpinMode(nlh *netlink.Handle, link netlink.Link, enable bool) error {
|
| 893 | 893 |
err := nlh.LinkSetHairpin(link, enable) |
| 894 |
- if err != nil && err != syscall.EINVAL {
|
|
| 895 |
- // If error is not EINVAL something else went wrong, bail out right away |
|
| 894 |
+ if err != nil {
|
|
| 896 | 895 |
return fmt.Errorf("unable to set hairpin mode on %s via netlink: %v",
|
| 897 | 896 |
link.Attrs().Name, err) |
| 898 | 897 |
} |
| 899 |
- |
|
| 900 |
- // Hairpin mode successfully set up |
|
| 901 |
- if err == nil {
|
|
| 902 |
- return nil |
|
| 903 |
- } |
|
| 904 |
- |
|
| 905 |
- // The netlink method failed with EINVAL which is probably because of an older |
|
| 906 |
- // kernel. Try one more time via the sysfs method. |
|
| 907 |
- path := filepath.Join("/sys/class/net", link.Attrs().Name, "brport/hairpin_mode")
|
|
| 908 |
- |
|
| 909 |
- var val []byte |
|
| 910 |
- if enable {
|
|
| 911 |
- val = []byte{'1', '\n'}
|
|
| 912 |
- } else {
|
|
| 913 |
- val = []byte{'0', '\n'}
|
|
| 914 |
- } |
|
| 915 |
- |
|
| 916 |
- if err := os.WriteFile(path, val, 0644); err != nil {
|
|
| 917 |
- return fmt.Errorf("unable to set hairpin mode on %s via sysfs: %v", link.Attrs().Name, err)
|
|
| 918 |
- } |
|
| 919 |
- |
|
| 920 | 898 |
return nil |
| 921 | 899 |
} |
| 922 | 900 |
|
| ... | ... |
@@ -124,6 +124,8 @@ func setDefaultVlan() {
|
| 124 | 124 |
} |
| 125 | 125 |
|
| 126 | 126 |
brName := os.Args[2] |
| 127 |
+ // IFLA_BR_VLAN_DEFAULT_PVID was added in Linux v4.4 (see torvalds/linux@0f963b7), so we can't use netlink for |
|
| 128 |
+ // setting this until Docker drops support for CentOS/RHEL 7 (kernel 3.10, eol date: 2024-06-30). |
|
| 127 | 129 |
path := filepath.Join("/sys/class/net", brName, "bridge/default_pvid")
|
| 128 | 130 |
data := []byte{'0', '\n'}
|
| 129 | 131 |
|
| ... | ... |
@@ -3,7 +3,6 @@ package osl |
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"net" |
| 6 |
- "regexp" |
|
| 7 | 6 |
"sync" |
| 8 | 7 |
"syscall" |
| 9 | 8 |
"time" |
| ... | ... |
@@ -418,30 +417,6 @@ func setInterfaceRoutes(nlh *netlink.Handle, iface netlink.Link, i *nwIface) err |
| 418 | 418 |
return nil |
| 419 | 419 |
} |
| 420 | 420 |
|
| 421 |
-// In older kernels (like the one in Centos 6.6 distro) sysctl does not have netns support. Therefore |
|
| 422 |
-// we cannot gather the statistics from /sys/class/net/<dev>/statistics/<counter> files. Per-netns stats |
|
| 423 |
-// are naturally found in /proc/net/dev in kernels which support netns (ifconfig relies on that). |
|
| 424 |
-const ( |
|
| 425 |
- base = "[ ]*%s:([ ]+[0-9]+){16}"
|
|
| 426 |
-) |
|
| 427 |
- |
|
| 428 |
-func scanInterfaceStats(data, ifName string, i *types.InterfaceStatistics) error {
|
|
| 429 |
- var ( |
|
| 430 |
- bktStr string |
|
| 431 |
- bkt uint64 |
|
| 432 |
- ) |
|
| 433 |
- |
|
| 434 |
- regex := fmt.Sprintf(base, ifName) |
|
| 435 |
- re := regexp.MustCompile(regex) |
|
| 436 |
- line := re.FindString(data) |
|
| 437 |
- |
|
| 438 |
- _, err := fmt.Sscanf(line, "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", |
|
| 439 |
- &bktStr, &i.RxBytes, &i.RxPackets, &i.RxErrors, &i.RxDropped, &bkt, &bkt, &bkt, |
|
| 440 |
- &bkt, &i.TxBytes, &i.TxPackets, &i.TxErrors, &i.TxDropped, &bkt, &bkt, &bkt, &bkt) |
|
| 441 |
- |
|
| 442 |
- return err |
|
| 443 |
-} |
|
| 444 |
- |
|
| 445 | 421 |
func checkRouteConflict(nlh *netlink.Handle, address *net.IPNet, family int) error {
|
| 446 | 422 |
routes, err := nlh.RouteList(nil, family) |
| 447 | 423 |
if err != nil {
|
| ... | ... |
@@ -158,32 +158,6 @@ func verifyCleanup(t *testing.T, s Sandbox, wait bool) {
|
| 158 | 158 |
} |
| 159 | 159 |
} |
| 160 | 160 |
|
| 161 |
-func TestScanStatistics(t *testing.T) {
|
|
| 162 |
- data := |
|
| 163 |
- "Inter-| Receive | Transmit\n" + |
|
| 164 |
- " face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n" + |
|
| 165 |
- " eth0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + |
|
| 166 |
- " wlan0: 7787685 11141 0 0 0 0 0 0 1681390 7220 0 0 0 0 0 0\n" + |
|
| 167 |
- " lo: 783782 1853 0 0 0 0 0 0 783782 1853 0 0 0 0 0 0\n" + |
|
| 168 |
- "lxcbr0: 0 0 0 0 0 0 0 0 9006 61 0 0 0 0 0 0\n" |
|
| 169 |
- |
|
| 170 |
- i := &types.InterfaceStatistics{}
|
|
| 171 |
- |
|
| 172 |
- if err := scanInterfaceStats(data, "wlan0", i); err != nil {
|
|
| 173 |
- t.Fatal(err) |
|
| 174 |
- } |
|
| 175 |
- if i.TxBytes != 1681390 || i.TxPackets != 7220 || i.RxBytes != 7787685 || i.RxPackets != 11141 {
|
|
| 176 |
- t.Fatalf("Error scanning the statistics")
|
|
| 177 |
- } |
|
| 178 |
- |
|
| 179 |
- if err := scanInterfaceStats(data, "lxcbr0", i); err != nil {
|
|
| 180 |
- t.Fatal(err) |
|
| 181 |
- } |
|
| 182 |
- if i.TxBytes != 9006 || i.TxPackets != 61 || i.RxBytes != 0 || i.RxPackets != 0 {
|
|
| 183 |
- t.Fatalf("Error scanning the statistics")
|
|
| 184 |
- } |
|
| 185 |
-} |
|
| 186 |
- |
|
| 187 | 161 |
func TestDisableIPv6DAD(t *testing.T) {
|
| 188 | 162 |
defer testutils.SetupTestOSContext(t)() |
| 189 | 163 |
|