| // 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 stack |
| |
| import ( |
| "testing" |
| |
| "gvisor.dev/gvisor/pkg/tcpip" |
| "gvisor.dev/gvisor/pkg/tcpip/buffer" |
| "gvisor.dev/gvisor/pkg/tcpip/header" |
| ) |
| |
| var _ AddressableEndpoint = (*testIPv6Endpoint)(nil) |
| var _ NetworkEndpoint = (*testIPv6Endpoint)(nil) |
| var _ NDPEndpoint = (*testIPv6Endpoint)(nil) |
| |
| // An IPv6 NetworkEndpoint that throws away outgoing packets. |
| // |
| // We use this instead of ipv6.endpoint because the ipv6 package depends on |
| // the stack package which this test lives in, causing a cyclic dependency. |
| type testIPv6Endpoint struct { |
| AddressableEndpointState |
| |
| nic NetworkInterface |
| protocol *testIPv6Protocol |
| |
| invalidatedRtr tcpip.Address |
| } |
| |
| func (*testIPv6Endpoint) Enable() tcpip.Error { |
| return nil |
| } |
| |
| func (*testIPv6Endpoint) Enabled() bool { |
| return true |
| } |
| |
| func (*testIPv6Endpoint) Disable() {} |
| |
| // DefaultTTL implements NetworkEndpoint.DefaultTTL. |
| func (*testIPv6Endpoint) DefaultTTL() uint8 { |
| return 0 |
| } |
| |
| // MTU implements NetworkEndpoint.MTU. |
| func (e *testIPv6Endpoint) MTU() uint32 { |
| return e.nic.MTU() - header.IPv6MinimumSize |
| } |
| |
| // MaxHeaderLength implements NetworkEndpoint.MaxHeaderLength. |
| func (e *testIPv6Endpoint) MaxHeaderLength() uint16 { |
| return e.nic.MaxHeaderLength() + header.IPv6MinimumSize |
| } |
| |
| // WritePacket implements NetworkEndpoint.WritePacket. |
| func (*testIPv6Endpoint) WritePacket(*Route, *GSO, NetworkHeaderParams, *PacketBuffer) tcpip.Error { |
| return nil |
| } |
| |
| // WritePackets implements NetworkEndpoint.WritePackets. |
| func (*testIPv6Endpoint) WritePackets(*Route, *GSO, PacketBufferList, NetworkHeaderParams) (int, tcpip.Error) { |
| // Our tests don't use this so we don't support it. |
| return 0, &tcpip.ErrNotSupported{} |
| } |
| |
| // WriteHeaderIncludedPacket implements |
| // NetworkEndpoint.WriteHeaderIncludedPacket. |
| func (*testIPv6Endpoint) WriteHeaderIncludedPacket(*Route, *PacketBuffer) tcpip.Error { |
| // Our tests don't use this so we don't support it. |
| return &tcpip.ErrNotSupported{} |
| } |
| |
| // HandlePacket implements NetworkEndpoint.HandlePacket. |
| func (*testIPv6Endpoint) HandlePacket(*PacketBuffer) {} |
| |
| // Close implements NetworkEndpoint.Close. |
| func (e *testIPv6Endpoint) Close() { |
| e.AddressableEndpointState.Cleanup() |
| } |
| |
| // NetworkProtocolNumber implements NetworkEndpoint.NetworkProtocolNumber. |
| func (*testIPv6Endpoint) NetworkProtocolNumber() tcpip.NetworkProtocolNumber { |
| return header.IPv6ProtocolNumber |
| } |
| |
| func (e *testIPv6Endpoint) InvalidateDefaultRouter(rtr tcpip.Address) { |
| e.invalidatedRtr = rtr |
| } |
| |
| // Stats implements NetworkEndpoint. |
| func (*testIPv6Endpoint) Stats() NetworkEndpointStats { |
| return &testIPv6EndpointStats{} |
| } |
| |
| var _ NetworkEndpointStats = (*testIPv6EndpointStats)(nil) |
| |
| type testIPv6EndpointStats struct{} |
| |
| // IsNetworkEndpointStats implements stack.NetworkEndpointStats. |
| func (*testIPv6EndpointStats) IsNetworkEndpointStats() {} |
| |
| // We use this instead of ipv6.protocol because the ipv6 package depends on |
| // the stack package which this test lives in, causing a cyclic dependency. |
| type testIPv6Protocol struct{} |
| |
| // Number implements NetworkProtocol.Number. |
| func (*testIPv6Protocol) Number() tcpip.NetworkProtocolNumber { |
| return header.IPv6ProtocolNumber |
| } |
| |
| // MinimumPacketSize implements NetworkProtocol.MinimumPacketSize. |
| func (*testIPv6Protocol) MinimumPacketSize() int { |
| return header.IPv6MinimumSize |
| } |
| |
| // DefaultPrefixLen implements NetworkProtocol.DefaultPrefixLen. |
| func (*testIPv6Protocol) DefaultPrefixLen() int { |
| return header.IPv6AddressSize * 8 |
| } |
| |
| // ParseAddresses implements NetworkProtocol.ParseAddresses. |
| func (*testIPv6Protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { |
| h := header.IPv6(v) |
| return h.SourceAddress(), h.DestinationAddress() |
| } |
| |
| // NewEndpoint implements NetworkProtocol.NewEndpoint. |
| func (p *testIPv6Protocol) NewEndpoint(nic NetworkInterface, _ TransportDispatcher) NetworkEndpoint { |
| e := &testIPv6Endpoint{ |
| nic: nic, |
| protocol: p, |
| } |
| e.AddressableEndpointState.Init(e) |
| return e |
| } |
| |
| // SetOption implements NetworkProtocol.SetOption. |
| func (*testIPv6Protocol) SetOption(tcpip.SettableNetworkProtocolOption) tcpip.Error { |
| return nil |
| } |
| |
| // Option implements NetworkProtocol.Option. |
| func (*testIPv6Protocol) Option(tcpip.GettableNetworkProtocolOption) tcpip.Error { |
| return nil |
| } |
| |
| // Close implements NetworkProtocol.Close. |
| func (*testIPv6Protocol) Close() {} |
| |
| // Wait implements NetworkProtocol.Wait. |
| func (*testIPv6Protocol) Wait() {} |
| |
| // Parse implements NetworkProtocol.Parse. |
| func (*testIPv6Protocol) Parse(*PacketBuffer) (tcpip.TransportProtocolNumber, bool, bool) { |
| return 0, false, false |
| } |
| |
| func TestDisabledRxStatsWhenNICDisabled(t *testing.T) { |
| // When the NIC is disabled, the only field that matters is the stats field. |
| // This test is limited to stats counter checks. |
| nic := nic{ |
| stats: makeNICStats(), |
| } |
| |
| if got := nic.stats.DisabledRx.Packets.Value(); got != 0 { |
| t.Errorf("got DisabledRx.Packets = %d, want = 0", got) |
| } |
| if got := nic.stats.DisabledRx.Bytes.Value(); got != 0 { |
| t.Errorf("got DisabledRx.Bytes = %d, want = 0", got) |
| } |
| if got := nic.stats.Rx.Packets.Value(); got != 0 { |
| t.Errorf("got Rx.Packets = %d, want = 0", got) |
| } |
| if got := nic.stats.Rx.Bytes.Value(); got != 0 { |
| t.Errorf("got Rx.Bytes = %d, want = 0", got) |
| } |
| |
| if t.Failed() { |
| t.FailNow() |
| } |
| |
| nic.DeliverNetworkPacket("", "", 0, NewPacketBuffer(PacketBufferOptions{ |
| Data: buffer.View([]byte{1, 2, 3, 4}).ToVectorisedView(), |
| })) |
| |
| if got := nic.stats.DisabledRx.Packets.Value(); got != 1 { |
| t.Errorf("got DisabledRx.Packets = %d, want = 1", got) |
| } |
| if got := nic.stats.DisabledRx.Bytes.Value(); got != 4 { |
| t.Errorf("got DisabledRx.Bytes = %d, want = 4", got) |
| } |
| if got := nic.stats.Rx.Packets.Value(); got != 0 { |
| t.Errorf("got Rx.Packets = %d, want = 0", got) |
| } |
| if got := nic.stats.Rx.Bytes.Value(); got != 0 { |
| t.Errorf("got Rx.Bytes = %d, want = 0", got) |
| } |
| } |