tests: fix SEG6 route test on recent kernels

The SEG6 route test was failing on newer kernels:

* Using loopback (`lo`) for SRv6 inline routes no longer preserves the
  `encap seg6` attribute. Switched to a dummy device (`dummy0`) to ensure
  SRv6 routes are accepted.
* Removed the artificial `::` SID from the inline segment list, which
  caused the kernel to drop the SRH.
* Added cleanup to delete the dummy device after the test.
* Updated route checks to use `RouteListFiltered` with `RT_FILTER_OIF|RT_FILTER_DST`
  since modern kernels add extra auto-routes (e.g., fe80::/64), which broke
  the naive `len(routes) == 1` assertion.

These changes make `TestSEG6RouteAddDel` stable across recent kernels while
still validating both INLINE (IPv6) and ENCAP (IPv4) SRv6 routes.
This commit is contained in:
Vishvananda Abrams
2025-08-27 19:33:03 +00:00
committed by Alessandro Boch
parent 7b78f24353
commit db0dbb948c

View File

@@ -5,7 +5,6 @@ package netlink
import ( import (
"net" "net"
"os"
"runtime" "runtime"
"strconv" "strconv"
"testing" "testing"
@@ -2016,18 +2015,26 @@ func TestSEG6LocalEqual(t *testing.T) {
} }
} }
func TestSEG6RouteAddDel(t *testing.T) { func TestSEG6RouteAddDel(t *testing.T) {
if os.Getenv("CI") == "true" { // add/del routes with LWTUNNEL_SEG6 to/from interface.
t.Skipf("Fails in CI with: route_test.go:*: Invalid Type. SEG6_IPTUN_MODE_INLINE routes not added properly")
}
// add/del routes with LWTUNNEL_SEG6 to/from loopback interface.
// Test both seg6 modes: encap (IPv4) & inline (IPv6). // Test both seg6 modes: encap (IPv4) & inline (IPv6).
t.Cleanup(setUpSEG6NetlinkTest(t)) t.Cleanup(setUpSEG6NetlinkTest(t))
// get loopback interface and bring it up // loopback doesn't work on recent kernels, so use a dummy
link, err := LinkByName("lo") err := LinkAdd(&Dummy{LinkAttrs{Name: "dummy0"}})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
link, err := LinkByName("dummy0")
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if err := LinkDel(link); err != nil {
t.Logf("failed to delete device: %v", err)
}
})
if err := LinkSetUp(link); err != nil { if err := LinkSetUp(link); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -2041,7 +2048,6 @@ func TestSEG6RouteAddDel(t *testing.T) {
Mask: net.CIDRMask(32, 32), Mask: net.CIDRMask(32, 32),
} }
var s1, s2 []net.IP var s1, s2 []net.IP
s1 = append(s1, net.ParseIP("::")) // inline requires "::"
s1 = append(s1, net.ParseIP("fc00:a000::12")) s1 = append(s1, net.ParseIP("fc00:a000::12"))
s1 = append(s1, net.ParseIP("fc00:a000::11")) s1 = append(s1, net.ParseIP("fc00:a000::11"))
s2 = append(s2, net.ParseIP("fc00:a000::22")) s2 = append(s2, net.ParseIP("fc00:a000::22"))
@@ -2061,7 +2067,9 @@ func TestSEG6RouteAddDel(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// SEG6_IPTUN_MODE_INLINE // SEG6_IPTUN_MODE_INLINE
routes, err := RouteList(link, FAMILY_V6) // Kernel adds multiple routes so filter them
filtV6 := &Route{LinkIndex: link.Attrs().Index, Dst: dst1}
routes, err := RouteListFiltered(FAMILY_V6, filtV6, RT_FILTER_OIF|RT_FILTER_DST)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -2074,7 +2082,9 @@ func TestSEG6RouteAddDel(t *testing.T) {
} }
} }
// SEG6_IPTUN_MODE_ENCAP // SEG6_IPTUN_MODE_ENCAP
routes, err = RouteList(link, FAMILY_V4) // Kernel adds multiple routes so filter them
filtV4 := &Route{LinkIndex: link.Attrs().Index, Dst: dst2}
routes, err = RouteListFiltered(FAMILY_V4, filtV4, RT_FILTER_OIF|RT_FILTER_DST)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }