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 }