diff --git a/pkg/tcpip/errors.go b/pkg/tcpip/errors.go index 63d1fd9f4..8d11bba76 100644 --- a/pkg/tcpip/errors.go +++ b/pkg/tcpip/errors.go @@ -274,6 +274,19 @@ func (*ErrDuplicateNICID) IgnoreStats() bool { } func (*ErrDuplicateNICID) String() string { return "duplicate nic id" } +// ErrInvalidNICID indicates the operation used an invalid NIC ID. +// +// +stateify savable +type ErrInvalidNICID struct{} + +func (*ErrInvalidNICID) isError() {} + +// IgnoreStats implements Error. +func (*ErrInvalidNICID) IgnoreStats() bool { + return false +} +func (*ErrInvalidNICID) String() string { return "invalid nic id" } + // ErrInvalidEndpointState indicates the endpoint is in an invalid state. // // +stateify savable diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 825d0bff3..9d0009ee5 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -846,6 +846,9 @@ func (s *Stack) CreateNICWithOptions(id tcpip.NICID, ep LinkEndpoint, opts NICOp s.mu.Lock() defer s.mu.Unlock() + if id == 0 { + return &tcpip.ErrInvalidNICID{} + } // Make sure id is unique. if _, ok := s.nics[id]; ok { return &tcpip.ErrDuplicateNICID{} diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index e8b92ef72..5ca31b25f 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -2446,6 +2446,16 @@ func TestCreateNICWithOptions(t *testing.T) { desc string calls []callArgsAndExpect }{ + { + desc: "InvalidNICID", + calls: []callArgsAndExpect{ + { + nicID: tcpip.NICID(0), + opts: stack.NICOptions{Name: "eth0"}, + err: &tcpip.ErrInvalidNICID{}, + }, + }, + }, { desc: "DuplicateNICID", calls: []callArgsAndExpect{ @@ -2544,7 +2554,7 @@ func TestNICStats(t *testing.T) { var txBytesTotal, rxBytesTotal, txPacketsTotal, rxPacketsTotal int for i, nic := range nics { - nicid := tcpip.NICID(i) + nicid := tcpip.NICID(i + 1) ep := channel.New(1, defaultMTU, "") if err := s.CreateNIC(nicid, ep); err != nil { t.Fatal("CreateNIC failed: ", err)