netkernelconf_linux.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package netkernelconf
  4. import (
  5. "fmt"
  6. "github.com/safchain/ethtool"
  7. )
  8. // CheckUDPGROForwarding checks if the machine is optimally configured to
  9. // forward UDP packets between the default route and Tailscale TUN interfaces.
  10. // It returns a non-nil warn in the case that the configuration is suboptimal.
  11. // It returns a non-nil err in the case that an error is encountered while
  12. // performing the check.
  13. func CheckUDPGROForwarding(tunInterface, defaultRouteInterface string) (warn, err error) {
  14. const txFeature = "tx-udp-segmentation"
  15. const rxWantFeature = "rx-udp-gro-forwarding"
  16. const rxDoNotWantFeature = "rx-gro-list"
  17. const kbLink = "\nSee https://tailscale.com/s/ethtool-config-udp-gro"
  18. errWithPrefix := func(format string, a ...any) error {
  19. const errPrefix = "couldn't check system's UDP GRO forwarding configuration, "
  20. return fmt.Errorf(errPrefix+format, a...)
  21. }
  22. e, err := ethtool.NewEthtool()
  23. if err != nil {
  24. return nil, errWithPrefix("failed to init ethtool: %v", err)
  25. }
  26. defer e.Close()
  27. tunFeatures, err := e.Features(tunInterface)
  28. if err != nil {
  29. return nil, errWithPrefix("failed to retrieve TUN device features: %v", err)
  30. }
  31. if !tunFeatures[txFeature] {
  32. // if txFeature is disabled/nonexistent on the TUN then UDP GRO
  33. // forwarding doesn't matter, we won't be taking advantage of it.
  34. return nil, nil
  35. }
  36. defaultFeatures, err := e.Features(defaultRouteInterface)
  37. if err != nil {
  38. return nil, errWithPrefix("failed to retrieve default route interface features: %v", err)
  39. }
  40. defaultHasRxWant, ok := defaultFeatures[rxWantFeature]
  41. if !ok {
  42. // unlikely the feature is nonexistant with txFeature in the TUN driver
  43. // being added to the kernel later than rxWantFeature, but let's be sure
  44. return nil, nil
  45. }
  46. if !defaultHasRxWant || defaultFeatures[rxDoNotWantFeature] {
  47. return fmt.Errorf("UDP GRO forwarding is suboptimally configured on %s, UDP forwarding throughput capability will increase with a configuration change.%s", defaultRouteInterface, kbLink), nil
  48. }
  49. return nil, nil
  50. }