summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/stack/stack_test.go
diff options
context:
space:
mode:
authorChris Kuiper <ckuiper@google.com>2018-12-16 23:04:56 -0800
committerShentubot <shentubot@google.com>2018-12-16 23:05:59 -0800
commite491ebbacf548a2a2f818f1093b09d6f1c13e7e0 (patch)
tree054813166ec5294ff089682c8528a43fdf704a66 /pkg/tcpip/stack/stack_test.go
parentf74eed464b55d9640432432cd96d811578e9081e (diff)
Allow sending of multicast and IPv6 link-local packets w/o route.
Same as with broadcast packets, sending of a multicast packet shouldn't require accessing the route table. The same applies to IPv6 link-local addresses, which aren't routable at all (they don't belong to any subnet by definition). PiperOrigin-RevId: 225775870 Change-Id: Ic53e6560c125a83be2be9c3d112e66b36e8dfe7b
Diffstat (limited to 'pkg/tcpip/stack/stack_test.go')
-rw-r--r--pkg/tcpip/stack/stack_test.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go
index dc05517ba..391319f35 100644
--- a/pkg/tcpip/stack/stack_test.go
+++ b/pkg/tcpip/stack/stack_test.go
@@ -680,6 +680,92 @@ func TestBroadcastNeedsNoRoute(t *testing.T) {
}
}
+func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) {
+ for _, tc := range []struct {
+ name string
+ routeNeeded bool
+ address tcpip.Address
+ }{
+ // IPv4 multicast address range: 224.0.0.0 - 239.255.255.255
+ // <=> 0xe0.0x00.0x00.0x00 - 0xef.0xff.0xff.0xff
+ {"IPv4 Multicast 1", false, "\xe0\x00\x00\x00"},
+ {"IPv4 Multicast 2", false, "\xef\xff\xff\xff"},
+ {"IPv4 Unicast 1", true, "\xdf\xff\xff\xff"},
+ {"IPv4 Unicast 2", true, "\xf0\x00\x00\x00"},
+ {"IPv4 Unicast 3", true, "\x00\x00\x00\x00"},
+
+ // IPv6 multicast address is 0xff[8] + flags[4] + scope[4] + groupId[112]
+ {"IPv6 Multicast 1", false, "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Multicast 2", false, "\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Multicast 3", false, "\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
+
+ // IPv6 link-local address starts with fe80::/10.
+ {"IPv6 Unicast Link-Local 1", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Unicast Link-Local 2", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+ {"IPv6 Unicast Link-Local 3", false, "\xfe\x80\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff"},
+ {"IPv6 Unicast Link-Local 4", false, "\xfe\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Unicast Link-Local 5", false, "\xfe\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
+
+ // IPv6 addresses that are neither multicast nor link-local.
+ {"IPv6 Unicast Not Link-Local 1", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Unicast Not Link-Local 2", true, "\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"},
+ {"IPv6 Unicast Not Link-local 3", true, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Unicast Not Link-Local 4", true, "\xfe\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Unicast Not Link-Local 5", true, "\xfe\xdf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Unicast Not Link-Local 6", true, "\xfd\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ {"IPv6 Unicast Not Link-Local 7", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ s := stack.New([]string{"fakeNet"}, nil, stack.Options{})
+
+ id, _ := channel.New(10, defaultMTU, "")
+ if err := s.CreateNIC(1, id); err != nil {
+ t.Fatalf("CreateNIC failed: %v", err)
+ }
+
+ s.SetRouteTable([]tcpip.Route{})
+
+ var anyAddr tcpip.Address
+ if len(tc.address) == header.IPv4AddressSize {
+ anyAddr = header.IPv4Any
+ } else {
+ anyAddr = header.IPv6Any
+ }
+
+ // If there is no endpoint, it won't work.
+ if _, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber); err != tcpip.ErrNoRoute {
+ t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute)
+ }
+
+ if err := s.AddAddress(1, fakeNetNumber, anyAddr); err != nil {
+ t.Fatalf("AddAddress(%v, %v) failed: %v", fakeNetNumber, anyAddr, err)
+ }
+
+ r, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber)
+ if tc.routeNeeded {
+ // Route table is empty but we need a route, this should cause an error.
+ if err != tcpip.ErrNoRoute {
+ t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute)
+ }
+ } else {
+ if err != nil {
+ t.Fatalf("FindRoute(1, %v, %v, %v) failed: %v", anyAddr, tc.address, fakeNetNumber, err)
+ }
+ if r.LocalAddress != anyAddr {
+ t.Errorf("Bad local address: got %v, want = %v", r.LocalAddress, anyAddr)
+ }
+ if r.RemoteAddress != tc.address {
+ t.Errorf("Bad remote address: got %v, want = %v", r.RemoteAddress, tc.address)
+ }
+ }
+ // If the NIC doesn't exist, it won't work.
+ if _, err := s.FindRoute(2, anyAddr, tc.address, fakeNetNumber); err != tcpip.ErrNoRoute {
+ t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute)
+ }
+ })
+ }
+}
+
// Set the subnet, then check that packet is delivered.
func TestSubnetAcceptsMatchingPacket(t *testing.T) {
s := stack.New([]string{"fakeNet"}, nil, stack.Options{})