Skip to content

Commit 7241bfc

Browse files
authored
Merge branch 'google:master' into master
2 parents c47a03a + b488752 commit 7241bfc

File tree

26 files changed

+210
-73
lines changed

26 files changed

+210
-73
lines changed

pkg/sentry/socket/netstack/stack.go

+30-7
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ func (s *Stack) SetInterface(ctx context.Context, msg *nlmsg.Message) *syserr.Er
136136
case linux.IFLA_LINKINFO:
137137
case linux.IFLA_ADDRESS:
138138
case linux.IFLA_MTU:
139+
case linux.IFLA_NET_NS_FD:
139140
default:
140141
ctx.Warningf("unexpected attribute: %x", attr)
141142
return syserr.ErrNotSupported
@@ -164,10 +165,34 @@ func (s *Stack) SetInterface(ctx context.Context, msg *nlmsg.Message) *syserr.Er
164165
// Netstack interfaces are always up.
165166
}
166167

167-
return s.setLink(tcpip.NICID(ifinfomsg.Index), attrs)
168+
return s.setLink(ctx, tcpip.NICID(ifinfomsg.Index), attrs)
168169
}
169170

170-
func (s *Stack) setLink(id tcpip.NICID, linkAttrs map[uint16]nlmsg.BytesView) *syserr.Error {
171+
func (s *Stack) setLink(ctx context.Context, id tcpip.NICID, linkAttrs map[uint16]nlmsg.BytesView) *syserr.Error {
172+
// IFLA_NET_NS_FD has to be handled first, because other parameters may be reseted.
173+
if v, ok := linkAttrs[linux.IFLA_NET_NS_FD]; ok {
174+
fd, ok := v.Uint32()
175+
if !ok {
176+
return syserr.ErrInvalidArgument
177+
}
178+
f := inet.NamespaceByFDFromContext(ctx)
179+
if f == nil {
180+
return syserr.ErrInvalidArgument
181+
}
182+
ns, err := f(int32(fd))
183+
if err != nil {
184+
return syserr.FromError(err)
185+
}
186+
defer ns.DecRef(ctx)
187+
peer := ns.Stack().(*Stack)
188+
if peer.Stack != s.Stack {
189+
var err tcpip.Error
190+
id, err = s.Stack.SetNICStack(id, peer.Stack)
191+
if err != nil {
192+
return syserr.TranslateNetstackError(err)
193+
}
194+
}
195+
}
171196
for t, v := range linkAttrs {
172197
switch t {
173198
case linux.IFLA_MASTER:
@@ -268,8 +293,7 @@ func (s *Stack) newVeth(ctx context.Context, linkAttrs map[uint16]nlmsg.BytesVie
268293
if err != nil {
269294
return syserr.TranslateNetstackError(err)
270295
}
271-
ep.SetStack(s.Stack, id)
272-
if err := s.setLink(id, linkAttrs); err != nil {
296+
if err := s.setLink(ctx, id, linkAttrs); err != nil {
273297
peerEP.Close()
274298
return err
275299
}
@@ -284,9 +308,8 @@ func (s *Stack) newVeth(ctx context.Context, linkAttrs map[uint16]nlmsg.BytesVie
284308
peerEP.Close()
285309
return syserr.TranslateNetstackError(err)
286310
}
287-
peerEP.SetStack(peerStack.Stack, peerID)
288311
if peerLinkAttrs != nil {
289-
if err := peerStack.setLink(peerID, peerLinkAttrs); err != nil {
312+
if err := peerStack.setLink(ctx, peerID, peerLinkAttrs); err != nil {
290313
peerStack.Stack.RemoveNIC(peerID)
291314
peerEP.Close()
292315
return err
@@ -310,7 +333,7 @@ func (s *Stack) newBridge(ctx context.Context, linkAttrs map[uint16]nlmsg.BytesV
310333
if err != nil {
311334
return syserr.TranslateNetstackError(err)
312335
}
313-
if err := s.setLink(id, linkAttrs); err != nil {
336+
if err := s.setLink(ctx, id, linkAttrs); err != nil {
314337
return err
315338
}
316339

pkg/tcpip/link/channel/channel.go

+3
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,6 @@ func (*Endpoint) AddHeader(*stack.PacketBuffer) {}
314314

315315
// ParseHeader implements stack.LinkEndpoint.ParseHeader.
316316
func (*Endpoint) ParseHeader(*stack.PacketBuffer) bool { return true }
317+
318+
// SetOnCloseAction implements stack.LinkEndpoint.
319+
func (*Endpoint) SetOnCloseAction(func()) {}

pkg/tcpip/link/fdbased/endpoint.go

+3
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,9 @@ func (e *endpoint) ARPHardwareType() header.ARPHardwareType {
831831
// Close implements stack.LinkEndpoint.
832832
func (e *endpoint) Close() {}
833833

834+
// SetOnCloseAction implements stack.LinkEndpoint.
835+
func (*endpoint) SetOnCloseAction(func()) {}
836+
834837
// InjectableEndpoint is an injectable fd-based endpoint. The endpoint writes
835838
// to the FD, but does not read from it. All reads come from injected packets.
836839
//

pkg/tcpip/link/loopback/loopback.go

+3
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,6 @@ func (*endpoint) ParseHeader(*stack.PacketBuffer) bool { return true }
135135

136136
// Close implements stack.LinkEndpoint.
137137
func (*endpoint) Close() {}
138+
139+
// SetOnCloseAction implements stack.LinkEndpoint.
140+
func (*endpoint) SetOnCloseAction(func()) {}

pkg/tcpip/link/muxed/injectable.go

+3
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ func (*InjectableEndpoint) ParseHeader(*stack.PacketBuffer) bool { return true }
165165
// Close implements stack.LinkEndpoint.
166166
func (*InjectableEndpoint) Close() {}
167167

168+
// SetOnCloseAction implements stack.LinkEndpoint.SetOnCloseAction.
169+
func (*InjectableEndpoint) SetOnCloseAction(func()) {}
170+
168171
// NewInjectableEndpoint creates a new multi-endpoint injectable endpoint.
169172
func NewInjectableEndpoint(routes map[tcpip.Address]stack.InjectableLinkEndpoint) *InjectableEndpoint {
170173
return &InjectableEndpoint{

pkg/tcpip/link/nested/nested.go

+5
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,8 @@ func (e *Endpoint) ParseHeader(pkt *stack.PacketBuffer) bool {
171171
func (e *Endpoint) Close() {
172172
e.child.Close()
173173
}
174+
175+
// SetOnCloseAction implement stack.LinkEndpoints.
176+
func (e *Endpoint) SetOnCloseAction(action func()) {
177+
e.child.SetOnCloseAction(action)
178+
}

pkg/tcpip/link/packetsocket/packetsocket_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ func (*nullEndpoint) ARPHardwareType() header.ARPHardwareType { return header.AR
5757
func (*nullEndpoint) AddHeader(*stack.PacketBuffer) {}
5858
func (*nullEndpoint) ParseHeader(*stack.PacketBuffer) bool { return true }
5959
func (*nullEndpoint) Close() {}
60+
func (*nullEndpoint) SetOnCloseAction(func()) {}
6061

6162
var _ stack.NetworkDispatcher = (*testNetworkDispatcher)(nil)
6263

pkg/tcpip/link/pipe/pipe.go

+3
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,6 @@ func (*Endpoint) ParseHeader(*stack.PacketBuffer) bool { return true }
151151

152152
// Close implements stack.LinkEndpoint.
153153
func (e *Endpoint) Close() {}
154+
155+
// SetOnCloseAction implements stack.LinkEndpoint.SetOnCloseAction.
156+
func (*Endpoint) SetOnCloseAction(func()) {}

pkg/tcpip/link/sharedmem/sharedmem.go

+3
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ func New(opts Options) (stack.LinkEndpoint, error) {
253253
return e, nil
254254
}
255255

256+
// SetOnCloseAction implements stack.LinkEndpoint.SetOnCloseAction.
257+
func (e *endpoint) SetOnCloseAction(func()) {}
258+
256259
// Close frees most resources associated with the endpoint. Wait() must be
257260
// called after Close() in order to free the rest.
258261
func (e *endpoint) Close() {

pkg/tcpip/link/sharedmem/sharedmem_server.go

+3
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ func NewServerEndpoint(opts Options) (stack.LinkEndpoint, error) {
118118
return e, nil
119119
}
120120

121+
// SetOnCloseAction implements stack.LinkEndpoint.SetOnCloseAction.
122+
func (*serverEndpoint) SetOnCloseAction(func()) {}
123+
121124
// Close frees all resources associated with the endpoint.
122125
func (e *serverEndpoint) Close() {
123126
// Tell dispatch goroutine to stop, then write to the eventfd so that it wakes

pkg/tcpip/link/veth/veth.go

+67-59
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,36 @@ import (
2525
var _ stack.LinkEndpoint = (*Endpoint)(nil)
2626
var _ stack.GSOEndpoint = (*Endpoint)(nil)
2727

28+
type veth struct {
29+
mu sync.RWMutex
30+
closed bool
31+
backlogQueue chan vethPacket
32+
mtu uint32
33+
endpoints [2]Endpoint
34+
}
35+
36+
func (v *veth) close() {
37+
v.mu.Lock()
38+
closed := v.closed
39+
v.closed = true
40+
v.mu.Unlock()
41+
if closed {
42+
return
43+
}
44+
45+
for i := range v.endpoints {
46+
e := &v.endpoints[i]
47+
e.mu.Lock()
48+
action := e.onCloseAction
49+
e.onCloseAction = nil
50+
e.mu.Unlock()
51+
if action != nil {
52+
action()
53+
}
54+
}
55+
close(v.backlogQueue)
56+
}
57+
2858
// +stateify savable
2959
type vethPacket struct {
3060
e *Endpoint
@@ -38,84 +68,55 @@ const backlogQueueSize = 64
3868
//
3969
// +stateify savable
4070
type Endpoint struct {
41-
pair *Endpoint
71+
peer *Endpoint
4272

43-
backlogQueue *chan vethPacket
73+
veth *veth
4474

4575
mu sync.RWMutex `state:"nosave"`
4676
// +checklocks:mu
4777
dispatcher stack.NetworkDispatcher
48-
49-
// +checklocks:mu
50-
stack *stack.Stack
51-
// +checklocks:mu
52-
idx tcpip.NICID
5378
// linkAddr is the local address of this endpoint.
5479
//
5580
// +checklocks:mu
5681
linkAddr tcpip.LinkAddress
5782
// +checklocks:mu
58-
mtu uint32
83+
onCloseAction func()
5984
}
6085

6186
// NewPair creates a new veth pair.
6287
func NewPair(mtu uint32) (*Endpoint, *Endpoint) {
63-
backlogQueue := make(chan vethPacket, backlogQueueSize)
64-
a := &Endpoint{
65-
mtu: mtu,
66-
linkAddr: tcpip.GetRandMacAddr(),
67-
backlogQueue: &backlogQueue,
68-
}
69-
b := &Endpoint{
88+
veth := veth{
89+
backlogQueue: make(chan vethPacket, backlogQueueSize),
7090
mtu: mtu,
71-
pair: a,
72-
linkAddr: tcpip.GetRandMacAddr(),
73-
backlogQueue: &backlogQueue,
91+
endpoints: [2]Endpoint{
92+
Endpoint{
93+
linkAddr: tcpip.GetRandMacAddr(),
94+
},
95+
Endpoint{
96+
linkAddr: tcpip.GetRandMacAddr(),
97+
},
98+
},
7499
}
75-
a.pair = b
100+
a := &veth.endpoints[0]
101+
b := &veth.endpoints[1]
102+
a.peer = b
103+
b.peer = a
104+
a.veth = &veth
105+
b.veth = &veth
76106
go func() {
77-
for t := range backlogQueue {
107+
for t := range veth.backlogQueue {
78108
t.e.InjectInbound(t.protocol, t.pkt)
79109
t.pkt.DecRef()
80110
}
111+
81112
}()
82113
return a, b
83114
}
84115

85-
// SetStack stores the stack and the device index.
86-
func (e *Endpoint) SetStack(s *stack.Stack, idx tcpip.NICID) {
87-
e.mu.Lock()
88-
defer e.mu.Unlock()
89-
e.stack = s
90-
e.idx = idx
91-
}
92-
93116
// Close closes e. Further packet injections will return an error, and all pending
94117
// packets are discarded. Close may be called concurrently with WritePackets.
95118
func (e *Endpoint) Close() {
96-
e.mu.Lock()
97-
stack := e.stack
98-
e.stack = nil
99-
e.mu.Unlock()
100-
if stack == nil {
101-
return
102-
}
103-
104-
e = e.pair
105-
e.mu.Lock()
106-
stack = e.stack
107-
idx := e.idx
108-
e.stack = nil
109-
e.mu.Unlock()
110-
if stack != nil {
111-
// The pair endpoint can live in the current stack or another one.
112-
// RemoveNIC will take the stack lock, so let's run it in another
113-
// goroutine to avoid lock conflicts.
114-
go func() {
115-
stack.RemoveNIC(idx)
116-
}()
117-
}
118-
close(*e.backlogQueue)
119+
e.veth.close()
119120
}
120121

121122
// InjectInbound injects an inbound packet. If the endpoint is not attached, the
@@ -146,16 +147,16 @@ func (e *Endpoint) IsAttached() bool {
146147

147148
// MTU implements stack.LinkEndpoint.MTU.
148149
func (e *Endpoint) MTU() uint32 {
149-
e.mu.RLock()
150-
defer e.mu.RUnlock()
151-
return e.mtu
150+
e.veth.mu.RLock()
151+
defer e.veth.mu.RUnlock()
152+
return e.veth.mtu
152153
}
153154

154155
// SetMTU implements stack.LinkEndpoint.SetMTU.
155156
func (e *Endpoint) SetMTU(mtu uint32) {
156-
e.mu.Lock()
157-
defer e.mu.Unlock()
158-
e.mtu = mtu
157+
e.veth.mu.Lock()
158+
defer e.veth.mu.Unlock()
159+
e.veth.mtu = mtu
159160
}
160161

161162
// Capabilities implements stack.LinkEndpoint.Capabilities.
@@ -204,8 +205,8 @@ func (e *Endpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error)
204205
newPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
205206
Payload: pkt.ToBuffer(),
206207
})
207-
(*e.backlogQueue) <- vethPacket{
208-
e: e.pair,
208+
(e.veth.backlogQueue) <- vethPacket{
209+
e: e.peer,
209210
protocol: pkt.NetworkProtocolNumber,
210211
pkt: newPkt,
211212
}
@@ -228,3 +229,10 @@ func (e *Endpoint) AddHeader(pkt *stack.PacketBuffer) {}
228229

229230
// ParseHeader implements stack.LinkEndpoint.ParseHeader.
230231
func (e *Endpoint) ParseHeader(pkt *stack.PacketBuffer) bool { return true }
232+
233+
// SetOnCloseAction implements stack.LinkEndpoint.
234+
func (e *Endpoint) SetOnCloseAction(action func()) {
235+
e.mu.Lock()
236+
defer e.mu.Unlock()
237+
e.onCloseAction = action
238+
}

pkg/tcpip/link/veth/veth_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,11 @@ func TestDestroyDevices(t *testing.T) {
110110
if err := s1.CreateNIC(vethFirstID, ethernet.New(veth1)); err != nil {
111111
t.Fatalf("s.CreateNIC(%d, _): %s", vethFirstID, err)
112112
}
113-
veth1.SetStack(s1, vethFirstID)
114113

115114
s2 := stack.New(stack.Options{})
116115
if err := s2.CreateNIC(vethSecondID, ethernet.New(veth2)); err != nil {
117116
t.Fatalf("s.CreateNIC(%d, _): %s", vethSecondID, err)
118117
}
119-
veth2.SetStack(s2, vethSecondID)
120118

121119
s1.RemoveNIC(vethFirstID)
122120
timeout := time.Millisecond

pkg/tcpip/link/waitable/waitable.go

+5
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ func (e *Endpoint) ParseHeader(pkt *stack.PacketBuffer) bool {
183183
return e.lower.ParseHeader(pkt)
184184
}
185185

186+
// SetOnCloseAction implements stack.LinkEndpoint.SetOnCloseAction.
187+
func (e *Endpoint) SetOnCloseAction(action func()) {
188+
e.lower.SetOnCloseAction(action)
189+
}
190+
186191
// Close implements stack.LinkEndpoint.
187192
func (e *Endpoint) Close() {
188193
e.lower.Close()

pkg/tcpip/link/waitable/waitable_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ func (*countedEndpoint) ParseHeader(*stack.PacketBuffer) bool {
108108
// Close implements stack.LinkEndpoint.
109109
func (*countedEndpoint) Close() {}
110110

111+
// SetOnCloseAction implements stack.LinkEndpoint.SetOnCloseAction.
112+
func (*countedEndpoint) SetOnCloseAction(func()) {}
113+
111114
func TestWaitWrite(t *testing.T) {
112115
ep := &countedEndpoint{}
113116
wep := New(ep)

pkg/tcpip/link/xdp/endpoint.go

+3
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,6 @@ func (ep *endpoint) dispatch() (bool, tcpip.Error) {
416416

417417
// Close implements stack.LinkEndpoint.
418418
func (*endpoint) Close() {}
419+
420+
// SetOnCloseAction implements stack.LinkEndpoint.
421+
func (*endpoint) SetOnCloseAction(func()) {}

pkg/tcpip/network/internal/testutil/testutil.go

+3
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ func (ep *MockLinkEndpoint) Close() {
111111
ep.WrittenPackets = nil
112112
}
113113

114+
// SetOnCloseAction implements stack.LinkEndpoint.SetOnCloseAction.
115+
func (*MockLinkEndpoint) SetOnCloseAction(func()) {}
116+
114117
// MakeRandPkt generates a randomized packet. transportHeaderLength indicates
115118
// how many random bytes will be copied in the Transport Header.
116119
// extraHeaderReserveLength indicates how much extra space will be reserved for

0 commit comments

Comments
 (0)