gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/transport/packet/packet_test.go (about) 1 // Copyright 2023 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 packet_test 16 17 import ( 18 "bytes" 19 "testing" 20 21 "github.com/google/go-cmp/cmp" 22 "gvisor.dev/gvisor/pkg/tcpip" 23 "gvisor.dev/gvisor/pkg/tcpip/faketime" 24 "gvisor.dev/gvisor/pkg/tcpip/header" 25 "gvisor.dev/gvisor/pkg/tcpip/link/channel" 26 "gvisor.dev/gvisor/pkg/tcpip/link/ethernet" 27 "gvisor.dev/gvisor/pkg/tcpip/stack" 28 "gvisor.dev/gvisor/pkg/tcpip/transport/raw" 29 "gvisor.dev/gvisor/pkg/waiter" 30 ) 31 32 func TestWriteRaw(t *testing.T) { 33 const nicID = 1 34 35 tests := []struct { 36 name string 37 len int 38 expectErr tcpip.Error 39 }{ 40 { 41 name: "small", 42 len: header.EthernetMinimumSize - 1, 43 expectErr: &tcpip.ErrMalformedHeader{}, 44 }, 45 { 46 name: "exact", 47 len: header.EthernetMinimumSize, 48 expectErr: nil, 49 }, 50 { 51 name: "bigger", 52 len: header.EthernetMinimumSize + 1, 53 expectErr: nil, 54 }, 55 } 56 57 for _, test := range tests { 58 t.Run(test.name, func(t *testing.T) { 59 s := stack.New(stack.Options{ 60 RawFactory: &raw.EndpointFactory{}, 61 AllowPacketEndpointWrite: true, 62 Clock: &faketime.NullClock{}, 63 }) 64 defer s.Destroy() 65 66 chEP := channel.New(1, header.IPv6MinimumMTU, "") 67 if err := s.CreateNIC(nicID, ethernet.New(chEP)); err != nil { 68 t.Errorf("CreateNIC(%d, _) failed: %s", nicID, err) 69 } 70 71 var wq waiter.Queue 72 ep, err := s.NewPacketEndpoint(false /* cooked */, 0 /* netProto */, &wq) 73 if err != nil { 74 t.Fatalf("s.NewPacketEndpoint(false, 0, _): %s", err) 75 } 76 defer ep.Close() 77 78 bindAddr := tcpip.FullAddress{NIC: nicID} 79 if err := ep.Bind(bindAddr); err != nil { 80 t.Fatalf("ep.Bind(%#v): %s", bindAddr, err) 81 } 82 83 data := make([]byte, test.len) 84 for i := range data { 85 data[i] = byte(i) 86 } 87 88 var r bytes.Reader 89 r.Reset(data) 90 n, err := ep.Write(&r, tcpip.WriteOptions{}) 91 if diff := cmp.Diff(test.expectErr, err); diff != "" { 92 t.Fatalf("ep.Write(..) mismatch:\n%s", diff) 93 } 94 if test.expectErr != nil { 95 return 96 } 97 if want := int64(len(data)); n != want { 98 t.Errorf("got ep.Write(..) = %d, want = %d", n, want) 99 } 100 pkt := chEP.Read() 101 if pkt == nil { 102 t.Fatal("Packet wasn't written out") 103 } 104 defer pkt.DecRef() 105 106 if diff := cmp.Diff(data, stack.PayloadSince(pkt.LinkHeader()).AsSlice()); diff != "" { 107 t.Errorf("packet data mismatch:\n%s", diff) 108 } 109 if len := len(pkt.LinkHeader().Slice()); len != header.EthernetMinimumSize { 110 t.Errorf("got len(pkt.LinkHeader().Slice()) = %d, want = %d", len, header.EthernetMinimumSize) 111 } 112 }) 113 } 114 }