summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/tests/integration/loopback_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tcpip/tests/integration/loopback_test.go')
-rw-r--r--pkg/tcpip/tests/integration/loopback_test.go782
1 files changed, 0 insertions, 782 deletions
diff --git a/pkg/tcpip/tests/integration/loopback_test.go b/pkg/tcpip/tests/integration/loopback_test.go
deleted file mode 100644
index f33223e79..000000000
--- a/pkg/tcpip/tests/integration/loopback_test.go
+++ /dev/null
@@ -1,782 +0,0 @@
-// Copyright 2020 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package loopback_test
-
-import (
- "bytes"
- "testing"
- "time"
-
- "github.com/google/go-cmp/cmp"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/buffer"
- "gvisor.dev/gvisor/pkg/tcpip/checker"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "gvisor.dev/gvisor/pkg/tcpip/link/channel"
- "gvisor.dev/gvisor/pkg/tcpip/link/loopback"
- "gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
- "gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
- "gvisor.dev/gvisor/pkg/tcpip/stack"
- "gvisor.dev/gvisor/pkg/tcpip/tests/utils"
- "gvisor.dev/gvisor/pkg/tcpip/testutil"
- "gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
- "gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
- "gvisor.dev/gvisor/pkg/tcpip/transport/udp"
- "gvisor.dev/gvisor/pkg/waiter"
-)
-
-var _ ipv6.NDPDispatcher = (*ndpDispatcher)(nil)
-
-type ndpDispatcher struct{}
-
-func (*ndpDispatcher) OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult) {
-}
-
-func (*ndpDispatcher) OnOffLinkRouteUpdated(tcpip.NICID, tcpip.Subnet, tcpip.Address, header.NDPRoutePreference) {
-}
-
-func (*ndpDispatcher) OnOffLinkRouteInvalidated(tcpip.NICID, tcpip.Subnet, tcpip.Address) {}
-
-func (*ndpDispatcher) OnOnLinkPrefixDiscovered(tcpip.NICID, tcpip.Subnet) {
-}
-
-func (*ndpDispatcher) OnOnLinkPrefixInvalidated(tcpip.NICID, tcpip.Subnet) {}
-
-func (*ndpDispatcher) OnAutoGenAddress(tcpip.NICID, tcpip.AddressWithPrefix) {
-}
-
-func (*ndpDispatcher) OnAutoGenAddressDeprecated(tcpip.NICID, tcpip.AddressWithPrefix) {}
-
-func (*ndpDispatcher) OnAutoGenAddressInvalidated(tcpip.NICID, tcpip.AddressWithPrefix) {}
-
-func (*ndpDispatcher) OnRecursiveDNSServerOption(tcpip.NICID, []tcpip.Address, time.Duration) {}
-
-func (*ndpDispatcher) OnDNSSearchListOption(tcpip.NICID, []string, time.Duration) {}
-
-func (*ndpDispatcher) OnDHCPv6Configuration(tcpip.NICID, ipv6.DHCPv6ConfigurationFromNDPRA) {}
-
-// TestInitialLoopbackAddresses tests that the loopback interface does not
-// auto-generate a link-local address when it is brought up.
-func TestInitialLoopbackAddresses(t *testing.T) {
- const nicID = 1
-
- s := stack.New(stack.Options{
- NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocolWithOptions(ipv6.Options{
- NDPDisp: &ndpDispatcher{},
- AutoGenLinkLocal: true,
- OpaqueIIDOpts: ipv6.OpaqueInterfaceIdentifierOptions{
- NICNameFromID: func(nicID tcpip.NICID, nicName string) string {
- t.Fatalf("should not attempt to get name for NIC with ID = %d; nicName = %s", nicID, nicName)
- return ""
- },
- },
- })},
- })
-
- if err := s.CreateNIC(nicID, loopback.New()); err != nil {
- t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
- }
-
- nicsInfo := s.NICInfo()
- if nicInfo, ok := nicsInfo[nicID]; !ok {
- t.Fatalf("did not find NIC with ID = %d in s.NICInfo() = %#v", nicID, nicsInfo)
- } else if got := len(nicInfo.ProtocolAddresses); got != 0 {
- t.Fatalf("got len(nicInfo.ProtocolAddresses) = %d, want = 0; nicInfo.ProtocolAddresses = %#v", got, nicInfo.ProtocolAddresses)
- }
-}
-
-// TestLoopbackAcceptAllInSubnetUDP tests that a loopback interface considers
-// itself bound to all addresses in the subnet of an assigned address and UDP
-// traffic is sent/received correctly.
-func TestLoopbackAcceptAllInSubnetUDP(t *testing.T) {
- const (
- nicID = 1
- localPort = 80
- )
-
- data := []byte{1, 2, 3, 4}
-
- ipv4ProtocolAddress := tcpip.ProtocolAddress{
- Protocol: header.IPv4ProtocolNumber,
- AddressWithPrefix: utils.Ipv4Addr,
- }
- ipv4Bytes := []byte(ipv4ProtocolAddress.AddressWithPrefix.Address)
- ipv4Bytes[len(ipv4Bytes)-1]++
- otherIPv4Address := tcpip.Address(ipv4Bytes)
-
- ipv6ProtocolAddress := tcpip.ProtocolAddress{
- Protocol: header.IPv6ProtocolNumber,
- AddressWithPrefix: utils.Ipv6Addr,
- }
- ipv6Bytes := []byte(utils.Ipv6Addr.Address)
- ipv6Bytes[len(ipv6Bytes)-1]++
- otherIPv6Address := tcpip.Address(ipv6Bytes)
-
- tests := []struct {
- name string
- addAddress tcpip.ProtocolAddress
- bindAddr tcpip.Address
- dstAddr tcpip.Address
- expectRx bool
- }{
- {
- name: "IPv4 bind to wildcard and send to assigned address",
- addAddress: ipv4ProtocolAddress,
- dstAddr: ipv4ProtocolAddress.AddressWithPrefix.Address,
- expectRx: true,
- },
- {
- name: "IPv4 bind to wildcard and send to other subnet-local address",
- addAddress: ipv4ProtocolAddress,
- dstAddr: otherIPv4Address,
- expectRx: true,
- },
- {
- name: "IPv4 bind to wildcard send to other address",
- addAddress: ipv4ProtocolAddress,
- dstAddr: utils.RemoteIPv4Addr,
- expectRx: false,
- },
- {
- name: "IPv4 bind to other subnet-local address and send to assigned address",
- addAddress: ipv4ProtocolAddress,
- bindAddr: otherIPv4Address,
- dstAddr: ipv4ProtocolAddress.AddressWithPrefix.Address,
- expectRx: false,
- },
- {
- name: "IPv4 bind and send to other subnet-local address",
- addAddress: ipv4ProtocolAddress,
- bindAddr: otherIPv4Address,
- dstAddr: otherIPv4Address,
- expectRx: true,
- },
- {
- name: "IPv4 bind to assigned address and send to other subnet-local address",
- addAddress: ipv4ProtocolAddress,
- bindAddr: ipv4ProtocolAddress.AddressWithPrefix.Address,
- dstAddr: otherIPv4Address,
- expectRx: false,
- },
-
- {
- name: "IPv6 bind and send to assigned address",
- addAddress: ipv6ProtocolAddress,
- bindAddr: utils.Ipv6Addr.Address,
- dstAddr: utils.Ipv6Addr.Address,
- expectRx: true,
- },
- {
- name: "IPv6 bind to wildcard and send to other subnet-local address",
- addAddress: ipv6ProtocolAddress,
- dstAddr: otherIPv6Address,
- expectRx: false,
- },
- }
-
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- s := stack.New(stack.Options{
- NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
- TransportProtocols: []stack.TransportProtocolFactory{udp.NewProtocol},
- })
- if err := s.CreateNIC(nicID, loopback.New()); err != nil {
- t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
- }
- if err := s.AddProtocolAddress(nicID, test.addAddress, stack.AddressProperties{}); err != nil {
- t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, test.addAddress, err)
- }
- s.SetRouteTable([]tcpip.Route{
- {
- Destination: header.IPv4EmptySubnet,
- NIC: nicID,
- },
- {
- Destination: header.IPv6EmptySubnet,
- NIC: nicID,
- },
- })
-
- var wq waiter.Queue
- rep, err := s.NewEndpoint(udp.ProtocolNumber, test.addAddress.Protocol, &wq)
- if err != nil {
- t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, test.addAddress.Protocol, err)
- }
- defer rep.Close()
-
- bindAddr := tcpip.FullAddress{Addr: test.bindAddr, Port: localPort}
- if err := rep.Bind(bindAddr); err != nil {
- t.Fatalf("rep.Bind(%+v): %s", bindAddr, err)
- }
-
- sep, err := s.NewEndpoint(udp.ProtocolNumber, test.addAddress.Protocol, &wq)
- if err != nil {
- t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, test.addAddress.Protocol, err)
- }
- defer sep.Close()
-
- wopts := tcpip.WriteOptions{
- To: &tcpip.FullAddress{
- Addr: test.dstAddr,
- Port: localPort,
- },
- }
- var r bytes.Reader
- r.Reset(data)
- n, err := sep.Write(&r, wopts)
- if err != nil {
- t.Fatalf("sep.Write(_, _): %s", err)
- }
- if want := int64(len(data)); n != want {
- t.Fatalf("got sep.Write(_, _) = (%d, nil), want = (%d, nil)", n, want)
- }
-
- var buf bytes.Buffer
- opts := tcpip.ReadOptions{NeedRemoteAddr: true}
- if res, err := rep.Read(&buf, opts); test.expectRx {
- if err != nil {
- t.Fatalf("rep.Read(_, %#v): %s", opts, err)
- }
- if diff := cmp.Diff(tcpip.ReadResult{
- Count: buf.Len(),
- Total: buf.Len(),
- RemoteAddr: tcpip.FullAddress{
- Addr: test.addAddress.AddressWithPrefix.Address,
- },
- }, res,
- checker.IgnoreCmpPath("ControlMessages", "RemoteAddr.NIC", "RemoteAddr.Port"),
- ); diff != "" {
- t.Errorf("rep.Read: unexpected result (-want +got):\n%s", diff)
- }
- if diff := cmp.Diff(data, buf.Bytes()); diff != "" {
- t.Errorf("got UDP payload mismatch (-want +got):\n%s", diff)
- }
- } else if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
- t.Fatalf("got rep.Read = (%v, %s) [with data %x], want = (_, %s)", res, err, buf.Bytes(), &tcpip.ErrWouldBlock{})
- }
- })
- }
-}
-
-// TestLoopbackSubnetLifetimeBoundToAddr tests that the lifetime of an address
-// in a loopback interface's associated subnet is bound to the permanently bound
-// address.
-func TestLoopbackSubnetLifetimeBoundToAddr(t *testing.T) {
- const nicID = 1
-
- protoAddr := tcpip.ProtocolAddress{
- Protocol: ipv4.ProtocolNumber,
- AddressWithPrefix: utils.Ipv4Addr,
- }
- addrBytes := []byte(utils.Ipv4Addr.Address)
- addrBytes[len(addrBytes)-1]++
- otherAddr := tcpip.Address(addrBytes)
-
- s := stack.New(stack.Options{
- NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol},
- })
- if err := s.CreateNIC(nicID, loopback.New()); err != nil {
- t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
- }
- if err := s.AddProtocolAddress(nicID, protoAddr, stack.AddressProperties{}); err != nil {
- t.Fatalf("s.AddProtocolAddress(%d, %+v, {}): %s", nicID, protoAddr, err)
- }
- s.SetRouteTable([]tcpip.Route{
- {
- Destination: header.IPv4EmptySubnet,
- NIC: nicID,
- },
- })
-
- r, err := s.FindRoute(nicID, otherAddr, utils.RemoteIPv4Addr, ipv4.ProtocolNumber, false /* multicastLoop */)
- if err != nil {
- t.Fatalf("s.FindRoute(%d, %s, %s, %d, false): %s", nicID, otherAddr, utils.RemoteIPv4Addr, ipv4.ProtocolNumber, err)
- }
- defer r.Release()
-
- params := stack.NetworkHeaderParams{
- Protocol: 111,
- TTL: 64,
- TOS: stack.DefaultTOS,
- }
- data := buffer.View([]byte{1, 2, 3, 4})
- if err := r.WritePacket(params, stack.NewPacketBuffer(stack.PacketBufferOptions{
- ReserveHeaderBytes: int(r.MaxHeaderLength()),
- Data: data.ToVectorisedView(),
- })); err != nil {
- t.Fatalf("r.WritePacket(%#v, _): %s", params, err)
- }
-
- // Removing the address should make the endpoint invalid.
- if err := s.RemoveAddress(nicID, protoAddr.AddressWithPrefix.Address); err != nil {
- t.Fatalf("s.RemoveAddress(%d, %s): %s", nicID, protoAddr.AddressWithPrefix.Address, err)
- }
- {
- err := r.WritePacket(params, stack.NewPacketBuffer(stack.PacketBufferOptions{
- ReserveHeaderBytes: int(r.MaxHeaderLength()),
- Data: data.ToVectorisedView(),
- }))
- if _, ok := err.(*tcpip.ErrInvalidEndpointState); !ok {
- t.Fatalf("got r.WritePacket(%#v, _) = %s, want = %s", params, err, &tcpip.ErrInvalidEndpointState{})
- }
- }
-}
-
-// TestLoopbackAcceptAllInSubnetTCP tests that a loopback interface considers
-// itself bound to all addresses in the subnet of an assigned address and TCP
-// traffic is sent/received correctly.
-func TestLoopbackAcceptAllInSubnetTCP(t *testing.T) {
- const (
- nicID = 1
- localPort = 80
- )
-
- ipv4ProtocolAddress := tcpip.ProtocolAddress{
- Protocol: header.IPv4ProtocolNumber,
- AddressWithPrefix: utils.Ipv4Addr,
- }
- ipv4ProtocolAddress.AddressWithPrefix.PrefixLen = 8
- ipv4Bytes := []byte(ipv4ProtocolAddress.AddressWithPrefix.Address)
- ipv4Bytes[len(ipv4Bytes)-1]++
- otherIPv4Address := tcpip.Address(ipv4Bytes)
-
- ipv6ProtocolAddress := tcpip.ProtocolAddress{
- Protocol: header.IPv6ProtocolNumber,
- AddressWithPrefix: utils.Ipv6Addr,
- }
- ipv6Bytes := []byte(utils.Ipv6Addr.Address)
- ipv6Bytes[len(ipv6Bytes)-1]++
- otherIPv6Address := tcpip.Address(ipv6Bytes)
-
- tests := []struct {
- name string
- addAddress tcpip.ProtocolAddress
- bindAddr tcpip.Address
- dstAddr tcpip.Address
- expectAccept bool
- }{
- {
- name: "IPv4 bind to wildcard and send to assigned address",
- addAddress: ipv4ProtocolAddress,
- dstAddr: ipv4ProtocolAddress.AddressWithPrefix.Address,
- expectAccept: true,
- },
- {
- name: "IPv4 bind to wildcard and send to other subnet-local address",
- addAddress: ipv4ProtocolAddress,
- dstAddr: otherIPv4Address,
- expectAccept: true,
- },
- {
- name: "IPv4 bind to wildcard send to other address",
- addAddress: ipv4ProtocolAddress,
- dstAddr: utils.RemoteIPv4Addr,
- expectAccept: false,
- },
- {
- name: "IPv4 bind to other subnet-local address and send to assigned address",
- addAddress: ipv4ProtocolAddress,
- bindAddr: otherIPv4Address,
- dstAddr: ipv4ProtocolAddress.AddressWithPrefix.Address,
- expectAccept: false,
- },
- {
- name: "IPv4 bind and send to other subnet-local address",
- addAddress: ipv4ProtocolAddress,
- bindAddr: otherIPv4Address,
- dstAddr: otherIPv4Address,
- expectAccept: true,
- },
- {
- name: "IPv4 bind to assigned address and send to other subnet-local address",
- addAddress: ipv4ProtocolAddress,
- bindAddr: ipv4ProtocolAddress.AddressWithPrefix.Address,
- dstAddr: otherIPv4Address,
- expectAccept: false,
- },
-
- {
- name: "IPv6 bind and send to assigned address",
- addAddress: ipv6ProtocolAddress,
- bindAddr: utils.Ipv6Addr.Address,
- dstAddr: utils.Ipv6Addr.Address,
- expectAccept: true,
- },
- {
- name: "IPv6 bind to wildcard and send to other subnet-local address",
- addAddress: ipv6ProtocolAddress,
- dstAddr: otherIPv6Address,
- expectAccept: false,
- },
- }
-
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- s := stack.New(stack.Options{
- NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
- TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
- })
- if err := s.CreateNIC(nicID, loopback.New()); err != nil {
- t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
- }
- if err := s.AddProtocolAddress(nicID, test.addAddress, stack.AddressProperties{}); err != nil {
- t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, test.addAddress, err)
- }
- s.SetRouteTable([]tcpip.Route{
- {
- Destination: header.IPv4EmptySubnet,
- NIC: nicID,
- },
- {
- Destination: header.IPv6EmptySubnet,
- NIC: nicID,
- },
- })
-
- var wq waiter.Queue
- we, ch := waiter.NewChannelEntry(nil)
- wq.EventRegister(&we, waiter.ReadableEvents)
- defer wq.EventUnregister(&we)
- listeningEndpoint, err := s.NewEndpoint(tcp.ProtocolNumber, test.addAddress.Protocol, &wq)
- if err != nil {
- t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, test.addAddress.Protocol, err)
- }
- defer listeningEndpoint.Close()
-
- bindAddr := tcpip.FullAddress{Addr: test.bindAddr, Port: localPort}
- if err := listeningEndpoint.Bind(bindAddr); err != nil {
- t.Fatalf("listeningEndpoint.Bind(%#v): %s", bindAddr, err)
- }
-
- if err := listeningEndpoint.Listen(1); err != nil {
- t.Fatalf("listeningEndpoint.Listen(1): %s", err)
- }
-
- connectingEndpoint, err := s.NewEndpoint(tcp.ProtocolNumber, test.addAddress.Protocol, &wq)
- if err != nil {
- t.Fatalf("s.NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, test.addAddress.Protocol, err)
- }
- defer connectingEndpoint.Close()
-
- connectAddr := tcpip.FullAddress{
- Addr: test.dstAddr,
- Port: localPort,
- }
- {
- err := connectingEndpoint.Connect(connectAddr)
- if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
- t.Fatalf("connectingEndpoint.Connect(%#v): %s", connectAddr, err)
- }
- }
-
- if !test.expectAccept {
- _, _, err := listeningEndpoint.Accept(nil)
- if _, ok := err.(*tcpip.ErrWouldBlock); !ok {
- t.Fatalf("got listeningEndpoint.Accept(nil) = %s, want = %s", err, &tcpip.ErrWouldBlock{})
- }
- return
- }
-
- // Wait for the listening endpoint to be "readable". That is, wait for a
- // new connection.
- <-ch
- var addr tcpip.FullAddress
- if _, _, err := listeningEndpoint.Accept(&addr); err != nil {
- t.Fatalf("listeningEndpoint.Accept(nil): %s", err)
- }
- if addr.Addr != test.addAddress.AddressWithPrefix.Address {
- t.Errorf("got addr.Addr = %s, want = %s", addr.Addr, test.addAddress.AddressWithPrefix.Address)
- }
- })
- }
-}
-
-func TestExternalLoopbackTraffic(t *testing.T) {
- const (
- nicID1 = 1
- nicID2 = 2
-
- numPackets = 1
- ttl = 64
- )
- ipv4Loopback := testutil.MustParse4("127.0.0.1")
-
- loopbackSourcedICMPv4 := func(e *channel.Endpoint) {
- utils.RxICMPv4EchoRequest(e, ipv4Loopback, utils.Ipv4Addr.Address, ttl)
- }
-
- loopbackSourcedICMPv6 := func(e *channel.Endpoint) {
- utils.RxICMPv6EchoRequest(e, header.IPv6Loopback, utils.Ipv6Addr.Address, ttl)
- }
-
- loopbackDestinedICMPv4 := func(e *channel.Endpoint) {
- utils.RxICMPv4EchoRequest(e, utils.RemoteIPv4Addr, ipv4Loopback, ttl)
- }
-
- loopbackDestinedICMPv6 := func(e *channel.Endpoint) {
- utils.RxICMPv6EchoRequest(e, utils.RemoteIPv6Addr, header.IPv6Loopback, ttl)
- }
-
- invalidSrcAddrStat := func(s tcpip.IPStats) *tcpip.StatCounter {
- return s.InvalidSourceAddressesReceived
- }
-
- invalidDestAddrStat := func(s tcpip.IPStats) *tcpip.StatCounter {
- return s.InvalidDestinationAddressesReceived
- }
-
- tests := []struct {
- name string
- allowExternalLoopback bool
- forwarding bool
- rxICMP func(*channel.Endpoint)
- invalidAddressStat func(tcpip.IPStats) *tcpip.StatCounter
- shouldAccept bool
- }{
- {
- name: "IPv4 external loopback sourced traffic without forwarding and drop external loopback disabled",
- allowExternalLoopback: true,
- forwarding: false,
- rxICMP: loopbackSourcedICMPv4,
- invalidAddressStat: invalidSrcAddrStat,
- shouldAccept: true,
- },
- {
- name: "IPv4 external loopback sourced traffic without forwarding and drop external loopback enabled",
- allowExternalLoopback: false,
- forwarding: false,
- rxICMP: loopbackSourcedICMPv4,
- invalidAddressStat: invalidSrcAddrStat,
- shouldAccept: false,
- },
- {
- name: "IPv4 external loopback sourced traffic with forwarding and drop external loopback disabled",
- allowExternalLoopback: true,
- forwarding: true,
- rxICMP: loopbackSourcedICMPv4,
- invalidAddressStat: invalidSrcAddrStat,
- shouldAccept: true,
- },
- {
- name: "IPv4 external loopback sourced traffic with forwarding and drop external loopback enabled",
- allowExternalLoopback: false,
- forwarding: true,
- rxICMP: loopbackSourcedICMPv4,
- invalidAddressStat: invalidSrcAddrStat,
- shouldAccept: false,
- },
- {
- name: "IPv4 external loopback destined traffic without forwarding and drop external loopback disabled",
- allowExternalLoopback: true,
- forwarding: false,
- rxICMP: loopbackDestinedICMPv4,
- invalidAddressStat: invalidDestAddrStat,
- shouldAccept: false,
- },
- {
- name: "IPv4 external loopback destined traffic without forwarding and drop external loopback enabled",
- allowExternalLoopback: false,
- forwarding: false,
- rxICMP: loopbackDestinedICMPv4,
- invalidAddressStat: invalidDestAddrStat,
- shouldAccept: false,
- },
- {
- name: "IPv4 external loopback destined traffic with forwarding and drop external loopback disabled",
- allowExternalLoopback: true,
- forwarding: true,
- rxICMP: loopbackDestinedICMPv4,
- invalidAddressStat: invalidDestAddrStat,
- shouldAccept: true,
- },
- {
- name: "IPv4 external loopback destined traffic with forwarding and drop external loopback enabled",
- allowExternalLoopback: false,
- forwarding: true,
- rxICMP: loopbackDestinedICMPv4,
- invalidAddressStat: invalidDestAddrStat,
- shouldAccept: false,
- },
-
- {
- name: "IPv6 external loopback sourced traffic without forwarding and drop external loopback disabled",
- allowExternalLoopback: true,
- forwarding: false,
- rxICMP: loopbackSourcedICMPv6,
- invalidAddressStat: invalidSrcAddrStat,
- shouldAccept: true,
- },
- {
- name: "IPv6 external loopback sourced traffic without forwarding and drop external loopback enabled",
- allowExternalLoopback: false,
- forwarding: false,
- rxICMP: loopbackSourcedICMPv6,
- invalidAddressStat: invalidSrcAddrStat,
- shouldAccept: false,
- },
- {
- name: "IPv6 external loopback sourced traffic with forwarding and drop external loopback disabled",
- allowExternalLoopback: true,
- forwarding: true,
- rxICMP: loopbackSourcedICMPv6,
- invalidAddressStat: invalidSrcAddrStat,
- shouldAccept: true,
- },
- {
- name: "IPv6 external loopback sourced traffic with forwarding and drop external loopback enabled",
- allowExternalLoopback: false,
- forwarding: true,
- rxICMP: loopbackSourcedICMPv6,
- invalidAddressStat: invalidSrcAddrStat,
- shouldAccept: false,
- },
- {
- name: "IPv6 external loopback destined traffic without forwarding and drop external loopback disabled",
- allowExternalLoopback: true,
- forwarding: false,
- rxICMP: loopbackDestinedICMPv6,
- invalidAddressStat: invalidDestAddrStat,
- shouldAccept: false,
- },
- {
- name: "IPv6 external loopback destined traffic without forwarding and drop external loopback enabled",
- allowExternalLoopback: false,
- forwarding: false,
- rxICMP: loopbackDestinedICMPv6,
- invalidAddressStat: invalidDestAddrStat,
- shouldAccept: false,
- },
- {
- name: "IPv6 external loopback destined traffic with forwarding and drop external loopback disabled",
- allowExternalLoopback: true,
- forwarding: true,
- rxICMP: loopbackDestinedICMPv6,
- invalidAddressStat: invalidDestAddrStat,
- shouldAccept: true,
- },
- {
- name: "IPv6 external loopback destined traffic with forwarding and drop external loopback enabled",
- allowExternalLoopback: false,
- forwarding: true,
- rxICMP: loopbackDestinedICMPv6,
- invalidAddressStat: invalidDestAddrStat,
- shouldAccept: false,
- },
- }
-
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- s := stack.New(stack.Options{
- NetworkProtocols: []stack.NetworkProtocolFactory{
- ipv4.NewProtocolWithOptions(ipv4.Options{
- AllowExternalLoopbackTraffic: test.allowExternalLoopback,
- }),
- ipv6.NewProtocolWithOptions(ipv6.Options{
- AllowExternalLoopbackTraffic: test.allowExternalLoopback,
- }),
- },
- TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4, icmp.NewProtocol6},
- })
- e := channel.New(1, header.IPv6MinimumMTU, "")
- if err := s.CreateNIC(nicID1, e); err != nil {
- t.Fatalf("CreateNIC(%d, _): %s", nicID1, err)
- }
- v4Addr := tcpip.ProtocolAddress{
- Protocol: ipv4.ProtocolNumber,
- AddressWithPrefix: utils.Ipv4Addr,
- }
- if err := s.AddProtocolAddress(nicID1, v4Addr, stack.AddressProperties{}); err != nil {
- t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID1, v4Addr, err)
- }
- v6Addr := tcpip.ProtocolAddress{
- Protocol: ipv6.ProtocolNumber,
- AddressWithPrefix: utils.Ipv6Addr,
- }
- if err := s.AddProtocolAddress(nicID1, v6Addr, stack.AddressProperties{}); err != nil {
- t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID1, v6Addr, err)
- }
-
- if err := s.CreateNIC(nicID2, loopback.New()); err != nil {
- t.Fatalf("CreateNIC(%d, _): %s", nicID2, err)
- }
- protocolAddrV4 := tcpip.ProtocolAddress{
- Protocol: ipv4.ProtocolNumber,
- AddressWithPrefix: tcpip.AddressWithPrefix{
- Address: ipv4Loopback,
- PrefixLen: 8,
- },
- }
- if err := s.AddProtocolAddress(nicID2, protocolAddrV4, stack.AddressProperties{}); err != nil {
- t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID2, protocolAddrV4, err)
- }
- protocolAddrV6 := tcpip.ProtocolAddress{
- Protocol: ipv6.ProtocolNumber,
- AddressWithPrefix: header.IPv6Loopback.WithPrefix(),
- }
- if err := s.AddProtocolAddress(nicID2, protocolAddrV6, stack.AddressProperties{}); err != nil {
- t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID2, protocolAddrV6, err)
- }
-
- if test.forwarding {
- if err := s.SetForwardingDefaultAndAllNICs(ipv4.ProtocolNumber, true); err != nil {
- t.Fatalf("SetForwardingDefaultAndAllNICs(%d, true): %s", ipv4.ProtocolNumber, err)
- }
- if err := s.SetForwardingDefaultAndAllNICs(ipv6.ProtocolNumber, true); err != nil {
- t.Fatalf("SetForwardingDefaultAndAllNICs(%d, true): %s", ipv6.ProtocolNumber, err)
- }
- }
-
- s.SetRouteTable([]tcpip.Route{
- tcpip.Route{
- Destination: header.IPv4EmptySubnet,
- NIC: nicID1,
- },
- tcpip.Route{
- Destination: header.IPv6EmptySubnet,
- NIC: nicID1,
- },
- tcpip.Route{
- Destination: ipv4Loopback.WithPrefix().Subnet(),
- NIC: nicID2,
- },
- tcpip.Route{
- Destination: header.IPv6Loopback.WithPrefix().Subnet(),
- NIC: nicID2,
- },
- })
-
- stats := s.Stats().IP
- invalidAddressStat := test.invalidAddressStat(stats)
- deliveredPacketsStat := stats.PacketsDelivered
- if got := invalidAddressStat.Value(); got != 0 {
- t.Fatalf("got invalidAddressStat.Value() = %d, want = 0", got)
- }
- if got := deliveredPacketsStat.Value(); got != 0 {
- t.Fatalf("got deliveredPacketsStat.Value() = %d, want = 0", got)
- }
- test.rxICMP(e)
- var expectedInvalidPackets uint64
- if !test.shouldAccept {
- expectedInvalidPackets = numPackets
- }
- if got := invalidAddressStat.Value(); got != expectedInvalidPackets {
- t.Fatalf("got invalidAddressStat.Value() = %d, want = %d", got, expectedInvalidPackets)
- }
- if got, want := deliveredPacketsStat.Value(), numPackets-expectedInvalidPackets; got != want {
- t.Fatalf("got deliveredPacketsStat.Value() = %d, want = %d", got, want)
- }
- })
- }
-}