mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Allow clients to store an opaque NICContext with NICs
...retrievable later via stack.NICInfo(). Clients of this library can use it to add metadata that should be tracked alongside a NIC, to avoid having to keep a map[tcpip.NICID]metadata mirroring stack.Stack's nic map. PiperOrigin-RevId: 288924900
This commit is contained in:
committed by
gVisor bot
parent
290908fa8a
commit
e752ddbb72
@@ -27,10 +27,11 @@ import (
|
||||
// NIC represents a "network interface card" to which the networking stack is
|
||||
// attached.
|
||||
type NIC struct {
|
||||
stack *Stack
|
||||
id tcpip.NICID
|
||||
name string
|
||||
linkEP LinkEndpoint
|
||||
stack *Stack
|
||||
id tcpip.NICID
|
||||
name string
|
||||
linkEP LinkEndpoint
|
||||
context NICContext
|
||||
|
||||
mu sync.RWMutex
|
||||
spoofing bool
|
||||
@@ -84,7 +85,7 @@ const (
|
||||
)
|
||||
|
||||
// newNIC returns a new NIC using the default NDP configurations from stack.
|
||||
func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint) *NIC {
|
||||
func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint, ctx NICContext) *NIC {
|
||||
// TODO(b/141011931): Validate a LinkEndpoint (ep) is valid. For
|
||||
// example, make sure that the link address it provides is a valid
|
||||
// unicast ethernet address.
|
||||
@@ -98,6 +99,7 @@ func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint) *NIC {
|
||||
id: id,
|
||||
name: name,
|
||||
linkEP: ep,
|
||||
context: ctx,
|
||||
primary: make(map[tcpip.NetworkProtocolNumber][]*referencedNetworkEndpoint),
|
||||
endpoints: make(map[NetworkEndpointID]*referencedNetworkEndpoint),
|
||||
mcastJoins: make(map[NetworkEndpointID]int32),
|
||||
|
||||
@@ -796,6 +796,9 @@ func (s *Stack) NewPacketEndpoint(cooked bool, netProto tcpip.NetworkProtocolNum
|
||||
return s.rawFactory.NewPacketEndpoint(s, cooked, netProto, waiterQueue)
|
||||
}
|
||||
|
||||
// NICContext is an opaque pointer used to store client-supplied NIC metadata.
|
||||
type NICContext interface{}
|
||||
|
||||
// NICOptions specifies the configuration of a NIC as it is being created.
|
||||
// The zero value creates an enabled, unnamed NIC.
|
||||
type NICOptions struct {
|
||||
@@ -805,6 +808,12 @@ type NICOptions struct {
|
||||
// Disabled specifies whether to avoid calling Attach on the passed
|
||||
// LinkEndpoint.
|
||||
Disabled bool
|
||||
|
||||
// Context specifies user-defined data that will be returned in stack.NICInfo
|
||||
// for the NIC. Clients of this library can use it to add metadata that
|
||||
// should be tracked alongside a NIC, to avoid having to keep a
|
||||
// map[tcpip.NICID]metadata mirroring stack.Stack's nic map.
|
||||
Context NICContext
|
||||
}
|
||||
|
||||
// CreateNICWithOptions creates a NIC with the provided id, LinkEndpoint, and
|
||||
@@ -819,7 +828,7 @@ func (s *Stack) CreateNICWithOptions(id tcpip.NICID, ep LinkEndpoint, opts NICOp
|
||||
return tcpip.ErrDuplicateNICID
|
||||
}
|
||||
|
||||
n := newNIC(s, id, opts.Name, ep)
|
||||
n := newNIC(s, id, opts.Name, ep, opts.Context)
|
||||
|
||||
s.nics[id] = n
|
||||
if !opts.Disabled {
|
||||
@@ -886,6 +895,10 @@ type NICInfo struct {
|
||||
MTU uint32
|
||||
|
||||
Stats NICStats
|
||||
|
||||
// Context is user-supplied data optionally supplied in CreateNICWithOptions.
|
||||
// See type NICOptions for more details.
|
||||
Context NICContext
|
||||
}
|
||||
|
||||
// NICInfo returns a map of NICIDs to their associated information.
|
||||
@@ -908,6 +921,7 @@ func (s *Stack) NICInfo() map[tcpip.NICID]NICInfo {
|
||||
Flags: flags,
|
||||
MTU: nic.linkEP.MTU(),
|
||||
Stats: nic.stats,
|
||||
Context: nic.context,
|
||||
}
|
||||
}
|
||||
return nics
|
||||
|
||||
@@ -2001,6 +2001,46 @@ func TestNICAutoGenAddr(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestNICContextPreservation tests that you can read out via stack.NICInfo the
|
||||
// Context data you pass via NICContext.Context in stack.CreateNICWithOptions.
|
||||
func TestNICContextPreservation(t *testing.T) {
|
||||
var ctx *int
|
||||
tests := []struct {
|
||||
name string
|
||||
opts stack.NICOptions
|
||||
want stack.NICContext
|
||||
}{
|
||||
{
|
||||
"context_set",
|
||||
stack.NICOptions{Context: ctx},
|
||||
ctx,
|
||||
},
|
||||
{
|
||||
"context_not_set",
|
||||
stack.NICOptions{},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
s := stack.New(stack.Options{})
|
||||
id := tcpip.NICID(1)
|
||||
ep := channel.New(0, 0, tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"))
|
||||
if err := s.CreateNICWithOptions(id, ep, test.opts); err != nil {
|
||||
t.Fatalf("got stack.CreateNICWithOptions(%d, %+v, %+v) = %s, want nil", id, ep, test.opts, err)
|
||||
}
|
||||
nicinfos := s.NICInfo()
|
||||
nicinfo, ok := nicinfos[id]
|
||||
if !ok {
|
||||
t.Fatalf("got nicinfos[%d] = _, %t, want _, true; nicinfos = %+v", id, ok, nicinfos)
|
||||
}
|
||||
if got, want := nicinfo.Context == test.want, true; got != want {
|
||||
t.Fatal("got nicinfo.Context == ctx = %t, want %t; nicinfo.Context = %p, ctx = %p", got, want, nicinfo.Context, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestNICAutoGenAddrWithOpaque tests the auto-generation of IPv6 link-local
|
||||
// addresses with opaque interface identifiers. Link Local addresses should
|
||||
// always be generated with opaque IIDs if configured to use them, even if the
|
||||
|
||||
Reference in New Issue
Block a user