//go:build linux
package overlay
import (
"encoding/binary"
"hash/fnv"
"net"
"net/netip"
"testing"
)
func legacyBuildSPI(src, dst net.IP, st uint32) int {
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, st)
h := fnv.New32a()
h.Write(src)
h.Write(b)
h.Write(dst)
return int(binary.BigEndian.Uint32(h.Sum(nil)))
}
func TestBuildSPI(t *testing.T) {
cases := []struct {
src, dst string
st uint32
}{
{"1.2.3.4", "5.6.7.8", 1234},
{"::ffff:1.2.3.4", "::ffff:5.6.7.8", 1234},
{"10.0.0.1", "2001:db8::1", 5678},
{"2002::abcd:1", "172.15.14.13", 54321},
{"2002:db8::42", "2002:db8::69", 9999},
}
for _, tc := range cases {
// The legacy buildSPI function is sensitive to whether src and
// dst are in 4-byte or 16-byte form. Versions of the driver
// using this function always pass the results of net.ParseIP(),
// which always parses the address into 16-byte form.
expected := legacyBuildSPI(net.ParseIP(tc.src), net.ParseIP(tc.dst), tc.st)
src, dst := netip.MustParseAddr(tc.src), netip.MustParseAddr(tc.dst)
actual := buildSPI(src, dst, tc.st)
if expected != actual {
t.Errorf("buildSPI(%v, %v, %v) = %v; want %v", src, dst, tc.st, actual, expected)
}
actual = buildSPI(src.Unmap(), dst.Unmap(), tc.st)
if expected != actual {
t.Errorf("buildSPI(%v, %v, %v) = %v; want %v", src.Unmap(), dst.Unmap(), tc.st, actual, expected)
}
}
}