gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/link/packetsocket/packetsocket_test.go (about)

     1  // Copyright 2022 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package packetsocket_test
    16  
    17  import (
    18  	"math"
    19  	"os"
    20  	"testing"
    21  
    22  	"gvisor.dev/gvisor/pkg/refs"
    23  	"gvisor.dev/gvisor/pkg/tcpip"
    24  	"gvisor.dev/gvisor/pkg/tcpip/header"
    25  	"gvisor.dev/gvisor/pkg/tcpip/link/packetsocket"
    26  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    27  )
    28  
    29  var _ stack.LinkEndpoint = (*nullEndpoint)(nil)
    30  
    31  type nullEndpoint struct {
    32  	disp stack.NetworkDispatcher
    33  }
    34  
    35  func (*nullEndpoint) MTU() uint32 {
    36  	return math.MaxUint32
    37  }
    38  func (*nullEndpoint) Capabilities() stack.LinkEndpointCapabilities {
    39  	return 0
    40  }
    41  func (*nullEndpoint) MaxHeaderLength() uint16 {
    42  	return 0
    43  }
    44  func (*nullEndpoint) LinkAddress() tcpip.LinkAddress {
    45  	var l tcpip.LinkAddress
    46  	return l
    47  }
    48  func (*nullEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) {
    49  	return pkts.Len(), nil
    50  }
    51  func (e *nullEndpoint) Attach(d stack.NetworkDispatcher)      { e.disp = d }
    52  func (e *nullEndpoint) IsAttached() bool                      { return e.disp != nil }
    53  func (*nullEndpoint) Wait()                                   {}
    54  func (*nullEndpoint) ARPHardwareType() header.ARPHardwareType { return header.ARPHardwareNone }
    55  func (*nullEndpoint) AddHeader(*stack.PacketBuffer)           {}
    56  func (*nullEndpoint) ParseHeader(*stack.PacketBuffer) bool    { return true }
    57  
    58  var _ stack.NetworkDispatcher = (*testNetworkDispatcher)(nil)
    59  
    60  type linkPacketInfo struct {
    61  	pkt      *stack.PacketBuffer
    62  	protocol tcpip.NetworkProtocolNumber
    63  }
    64  
    65  type networkPacketInfo struct {
    66  	pkt      *stack.PacketBuffer
    67  	protocol tcpip.NetworkProtocolNumber
    68  }
    69  
    70  type testNetworkDispatcher struct {
    71  	t *testing.T
    72  
    73  	linkPacket linkPacketInfo
    74  
    75  	networkPacket networkPacketInfo
    76  }
    77  
    78  func (t *testNetworkDispatcher) reset() {
    79  	if pkt := t.linkPacket.pkt; pkt != nil {
    80  		pkt.DecRef()
    81  	}
    82  	if pkt := t.networkPacket.pkt; pkt != nil {
    83  		pkt.DecRef()
    84  	}
    85  
    86  	*t = testNetworkDispatcher{}
    87  }
    88  
    89  func (t *testNetworkDispatcher) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {
    90  	networkPacket := networkPacketInfo{
    91  		pkt:      pkt.IncRef(),
    92  		protocol: protocol,
    93  	}
    94  
    95  	if t.networkPacket != (networkPacketInfo{}) {
    96  		t.t.Fatalf("already delivered network packet = %#v; new = %#v", t.networkPacket, networkPacket)
    97  	}
    98  
    99  	t.networkPacket = networkPacket
   100  }
   101  
   102  func (t *testNetworkDispatcher) DeliverLinkPacket(protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {
   103  	linkPacket := linkPacketInfo{
   104  		pkt:      pkt.IncRef(),
   105  		protocol: protocol,
   106  	}
   107  
   108  	if t.linkPacket != (linkPacketInfo{}) {
   109  		t.t.Fatalf("already delivered link packet = %#v; new = %#v", t.linkPacket, linkPacket)
   110  	}
   111  
   112  	t.linkPacket = linkPacket
   113  }
   114  
   115  func TestPacketDispatch(t *testing.T) {
   116  	const protocol = 5
   117  
   118  	var nullEP nullEndpoint
   119  	ep := packetsocket.New(&nullEP)
   120  
   121  	var d testNetworkDispatcher
   122  	defer d.reset()
   123  	ep.Attach(&d)
   124  
   125  	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{})
   126  	defer pkt.DecRef()
   127  	pkt.NetworkProtocolNumber = protocol
   128  
   129  	{
   130  		pkt.PktType = tcpip.PacketOutgoing
   131  		var pkts stack.PacketBufferList
   132  		pkts.PushBack(pkt)
   133  		if n, err := ep.WritePackets(pkts); err != nil {
   134  			t.Fatalf("ep.WritePackets(_): %s", err)
   135  		} else if n != 1 {
   136  			t.Fatalf("got ep.WritePackets(_) = %d, want = 1", n)
   137  		}
   138  
   139  		if want := (networkPacketInfo{}); d.networkPacket != want {
   140  			t.Errorf("got d.networkPacket = %#v, want = %#v", d.networkPacket, want)
   141  		}
   142  		if want := (linkPacketInfo{pkt: pkt, protocol: protocol}); d.linkPacket != want {
   143  			t.Errorf("got d.linkPacket = %#v, want = %#v", d.linkPacket, want)
   144  		}
   145  	}
   146  
   147  	d.reset()
   148  	{
   149  		pkt.PktType = tcpip.PacketHost
   150  		nullEP.disp.DeliverNetworkPacket(protocol, pkt)
   151  		if want := (networkPacketInfo{pkt: pkt, protocol: protocol}); d.networkPacket != want {
   152  			t.Errorf("got d.networkPacket = %#v, want = %#v", d.networkPacket, want)
   153  		}
   154  		if want := (linkPacketInfo{pkt: pkt, protocol: protocol}); d.linkPacket != want {
   155  			t.Errorf("got d.linkPacket = %#v, want = %#v", d.linkPacket, want)
   156  		}
   157  	}
   158  }
   159  
   160  func TestMain(m *testing.M) {
   161  	refs.SetLeakMode(refs.LeaksPanic)
   162  	code := m.Run()
   163  	refs.DoLeakCheck()
   164  	os.Exit(code)
   165  }