interfaces_linux_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package netmon
  4. import (
  5. "errors"
  6. "fmt"
  7. "io/fs"
  8. "os"
  9. "path/filepath"
  10. "testing"
  11. "tailscale.com/tstest"
  12. )
  13. // test the specific /proc/net/route path as found on Google Cloud Run instances
  14. func TestGoogleCloudRunDefaultRouteInterface(t *testing.T) {
  15. dir := t.TempDir()
  16. tstest.Replace(t, &procNetRoutePath, filepath.Join(dir, "CloudRun"))
  17. buf := []byte("Iface\tDestination\tGateway\tFlags\tRefCnt\tUse\tMetric\tMask\tMTU\tWindow\tIRTT\n" +
  18. "eth0\t8008FEA9\t00000000\t0001\t0\t0\t0\t01FFFFFF\t0\t0\t0\n" +
  19. "eth1\t00000000\t00000000\t0001\t0\t0\t0\t00000000\t0\t0\t0\n")
  20. err := os.WriteFile(procNetRoutePath, buf, 0644)
  21. if err != nil {
  22. t.Fatal(err)
  23. }
  24. got, err := DefaultRouteInterface()
  25. if err != nil {
  26. t.Fatal(err)
  27. }
  28. if got != "eth1" {
  29. t.Fatalf("got %s, want eth1", got)
  30. }
  31. }
  32. // we read chunks of /proc/net/route at a time, test that files longer than the chunk
  33. // size can be handled.
  34. func TestExtremelyLongProcNetRoute(t *testing.T) {
  35. dir := t.TempDir()
  36. tstest.Replace(t, &procNetRoutePath, filepath.Join(dir, "VeryLong"))
  37. f, err := os.Create(procNetRoutePath)
  38. if err != nil {
  39. t.Fatal(err)
  40. }
  41. _, err = f.Write([]byte("Iface\tDestination\tGateway\tFlags\tRefCnt\tUse\tMetric\tMask\tMTU\tWindow\tIRTT\n"))
  42. if err != nil {
  43. t.Fatal(err)
  44. }
  45. for n := 0; n <= 900; n++ {
  46. line := fmt.Sprintf("eth%d\t8008FEA9\t00000000\t0001\t0\t0\t0\t01FFFFFF\t0\t0\t0\n", n)
  47. _, err := f.Write([]byte(line))
  48. if err != nil {
  49. t.Fatal(err)
  50. }
  51. }
  52. _, err = f.Write([]byte("tokenring1\t00000000\t00000000\t0001\t0\t0\t0\t00000000\t0\t0\t0\n"))
  53. if err != nil {
  54. t.Fatal(err)
  55. }
  56. got, err := DefaultRouteInterface()
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. if got != "tokenring1" {
  61. t.Fatalf("got %q, want tokenring1", got)
  62. }
  63. }
  64. // test the specific /proc/net/route path as found on AWS App Runner instances
  65. func TestAwsAppRunnerDefaultRouteInterface(t *testing.T) {
  66. dir := t.TempDir()
  67. tstest.Replace(t, &procNetRoutePath, filepath.Join(dir, "CloudRun"))
  68. buf := []byte("Iface\tDestination\tGateway\tFlags\tRefCnt\tUse\tMetric\tMask\tMTU\tWindow\tIRTT\n" +
  69. "eth0\t00000000\tF9AFFEA9\t0003\t0\t0\t0\t00000000\t0\t0\t0\n" +
  70. "*\tFEA9FEA9\t00000000\t0005\t0\t0\t0\tFFFFFFFF\t0\t0\t0\n" +
  71. "ecs-eth0\t02AAFEA9\t01ACFEA9\t0007\t0\t0\t0\tFFFFFFFF\t0\t0\t0\n" +
  72. "ecs-eth0\t00ACFEA9\t00000000\t0001\t0\t0\t0\t00FFFFFF\t0\t0\t0\n" +
  73. "eth0\t00AFFEA9\t00000000\t0001\t0\t0\t0\t00FFFFFF\t0\t0\t0\n")
  74. err := os.WriteFile(procNetRoutePath, buf, 0644)
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. got, err := DefaultRouteInterface()
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. if got != "eth0" {
  83. t.Fatalf("got %s, want eth0", got)
  84. }
  85. }
  86. func BenchmarkDefaultRouteInterface(b *testing.B) {
  87. b.ReportAllocs()
  88. for range b.N {
  89. if _, err := DefaultRouteInterface(); err != nil {
  90. b.Fatal(err)
  91. }
  92. }
  93. }
  94. func TestRouteLinuxNetlink(t *testing.T) {
  95. d, err := defaultRouteFromNetlink()
  96. if errors.Is(err, fs.ErrPermission) {
  97. t.Skip(err)
  98. }
  99. if err != nil {
  100. t.Fatal(err)
  101. }
  102. t.Logf("Got: %+v", d)
  103. }