From d02b74a5dcfed4bfc8f2f8e545bca4d2afabb296 Mon Sep 17 00:00:00 2001 From: Googler Date: Fri, 27 Apr 2018 10:37:02 -0700 Subject: Check in gVisor. PiperOrigin-RevId: 194583126 Change-Id: Ica1d8821a90f74e7e745962d71801c598c652463 --- pkg/tcpip/stack/BUILD | 70 +++ pkg/tcpip/stack/linkaddrcache.go | 313 +++++++++++++ pkg/tcpip/stack/linkaddrcache_test.go | 256 +++++++++++ pkg/tcpip/stack/nic.go | 453 +++++++++++++++++++ pkg/tcpip/stack/registration.go | 322 ++++++++++++++ pkg/tcpip/stack/route.go | 133 ++++++ pkg/tcpip/stack/stack.go | 811 ++++++++++++++++++++++++++++++++++ pkg/tcpip/stack/stack_global_state.go | 9 + pkg/tcpip/stack/stack_test.go | 760 +++++++++++++++++++++++++++++++ pkg/tcpip/stack/transport_demuxer.go | 166 +++++++ pkg/tcpip/stack/transport_test.go | 420 ++++++++++++++++++ 11 files changed, 3713 insertions(+) create mode 100644 pkg/tcpip/stack/BUILD create mode 100644 pkg/tcpip/stack/linkaddrcache.go create mode 100644 pkg/tcpip/stack/linkaddrcache_test.go create mode 100644 pkg/tcpip/stack/nic.go create mode 100644 pkg/tcpip/stack/registration.go create mode 100644 pkg/tcpip/stack/route.go create mode 100644 pkg/tcpip/stack/stack.go create mode 100644 pkg/tcpip/stack/stack_global_state.go create mode 100644 pkg/tcpip/stack/stack_test.go create mode 100644 pkg/tcpip/stack/transport_demuxer.go create mode 100644 pkg/tcpip/stack/transport_test.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD new file mode 100644 index 000000000..079ade2c8 --- /dev/null +++ b/pkg/tcpip/stack/BUILD @@ -0,0 +1,70 @@ +package(licenses = ["notice"]) # BSD + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_stateify") + +go_stateify( + name = "stack_state", + srcs = [ + "registration.go", + "stack.go", + ], + out = "stack_state.go", + package = "stack", +) + +go_library( + name = "stack", + srcs = [ + "linkaddrcache.go", + "nic.go", + "registration.go", + "route.go", + "stack.go", + "stack_global_state.go", + "stack_state.go", + "transport_demuxer.go", + ], + importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/stack", + visibility = [ + "//visibility:public", + ], + deps = [ + "//pkg/ilist", + "//pkg/sleep", + "//pkg/state", + "//pkg/tcpip", + "//pkg/tcpip/buffer", + "//pkg/tcpip/header", + "//pkg/tcpip/ports", + "//pkg/tcpip/seqnum", + "//pkg/waiter", + ], +) + +go_test( + name = "stack_x_test", + size = "small", + srcs = [ + "stack_test.go", + "transport_test.go", + ], + deps = [ + ":stack", + "//pkg/tcpip", + "//pkg/tcpip/buffer", + "//pkg/tcpip/link/channel", + "//pkg/waiter", + ], +) + +go_test( + name = "stack_test", + size = "small", + srcs = ["linkaddrcache_test.go"], + embed = [":stack"], + deps = [ + "//pkg/sleep", + "//pkg/tcpip", + ], +) diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go new file mode 100644 index 000000000..789f97882 --- /dev/null +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -0,0 +1,313 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stack + +import ( + "fmt" + "sync" + "time" + + "gvisor.googlesource.com/gvisor/pkg/sleep" + "gvisor.googlesource.com/gvisor/pkg/tcpip" +) + +const linkAddrCacheSize = 512 // max cache entries + +// linkAddrCache is a fixed-sized cache mapping IP addresses to link addresses. +// +// The entries are stored in a ring buffer, oldest entry replaced first. +// +// This struct is safe for concurrent use. +type linkAddrCache struct { + // ageLimit is how long a cache entry is valid for. + ageLimit time.Duration + + // resolutionTimeout is the amount of time to wait for a link request to + // resolve an address. + resolutionTimeout time.Duration + + // resolutionAttempts is the number of times an address is attempted to be + // resolved before failing. + resolutionAttempts int + + mu sync.Mutex + cache map[tcpip.FullAddress]*linkAddrEntry + next int // array index of next available entry + entries [linkAddrCacheSize]linkAddrEntry +} + +// entryState controls the state of a single entry in the cache. +type entryState int + +const ( + // incomplete means that there is an outstanding request to resolve the + // address. This is the initial state. + incomplete entryState = iota + // ready means that the address has been resolved and can be used. + ready + // failed means that address resolution timed out and the address + // could not be resolved. + failed + // expired means that the cache entry has expired and the address must be + // resolved again. + expired +) + +// String implements Stringer. +func (s entryState) String() string { + switch s { + case incomplete: + return "incomplete" + case ready: + return "ready" + case failed: + return "failed" + case expired: + return "expired" + default: + return fmt.Sprintf("invalid entryState: %d", s) + } +} + +// A linkAddrEntry is an entry in the linkAddrCache. +// This struct is thread-compatible. +type linkAddrEntry struct { + addr tcpip.FullAddress + linkAddr tcpip.LinkAddress + expiration time.Time + s entryState + + // wakers is a set of waiters for address resolution result. Anytime + // state transitions out of 'incomplete' these waiters are notified. + wakers map[*sleep.Waker]struct{} + + cancel chan struct{} +} + +func (e *linkAddrEntry) state() entryState { + if e.s != expired && time.Now().After(e.expiration) { + // Force the transition to ensure waiters are notified. + e.changeState(expired) + } + return e.s +} + +func (e *linkAddrEntry) changeState(ns entryState) { + if e.s == ns { + return + } + + // Validate state transition. + switch e.s { + case incomplete: + // All transitions are valid. + case ready, failed: + if ns != expired { + panic(fmt.Sprintf("invalid state transition from %v to %v", e.s, ns)) + } + case expired: + // Terminal state. + panic(fmt.Sprintf("invalid state transition from %v to %v", e.s, ns)) + default: + panic(fmt.Sprintf("invalid state: %v", e.s)) + } + + // Notify whoever is waiting on address resolution when transitioning + // out of 'incomplete'. + if e.s == incomplete { + for w := range e.wakers { + w.Assert() + } + e.wakers = nil + } + e.s = ns +} + +func (e *linkAddrEntry) addWaker(w *sleep.Waker) { + e.wakers[w] = struct{}{} +} + +func (e *linkAddrEntry) removeWaker(w *sleep.Waker) { + delete(e.wakers, w) +} + +// add adds a k -> v mapping to the cache. +func (c *linkAddrCache) add(k tcpip.FullAddress, v tcpip.LinkAddress) { + c.mu.Lock() + defer c.mu.Unlock() + + entry := c.cache[k] + if entry != nil { + s := entry.state() + if s != expired && entry.linkAddr == v { + // Disregard repeated calls. + return + } + // Check if entry is waiting for address resolution. + if s == incomplete { + entry.linkAddr = v + } else { + // Otherwise create a new entry to replace it. + entry = c.makeAndAddEntry(k, v) + } + } else { + entry = c.makeAndAddEntry(k, v) + } + + entry.changeState(ready) +} + +// makeAndAddEntry is a helper function to create and add a new +// entry to the cache map and evict older entry as needed. +func (c *linkAddrCache) makeAndAddEntry(k tcpip.FullAddress, v tcpip.LinkAddress) *linkAddrEntry { + // Take over the next entry. + entry := &c.entries[c.next] + if c.cache[entry.addr] == entry { + delete(c.cache, entry.addr) + } + + // Mark the soon-to-be-replaced entry as expired, just in case there is + // someone waiting for address resolution on it. + entry.changeState(expired) + if entry.cancel != nil { + entry.cancel <- struct{}{} + } + + *entry = linkAddrEntry{ + addr: k, + linkAddr: v, + expiration: time.Now().Add(c.ageLimit), + wakers: make(map[*sleep.Waker]struct{}), + cancel: make(chan struct{}, 1), + } + + c.cache[k] = entry + c.next++ + if c.next == len(c.entries) { + c.next = 0 + } + return entry +} + +// get reports any known link address for k. +func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) (tcpip.LinkAddress, *tcpip.Error) { + if linkRes != nil { + if addr, ok := linkRes.ResolveStaticAddress(k.Addr); ok { + return addr, nil + } + } + + c.mu.Lock() + entry := c.cache[k] + if entry == nil || entry.state() == expired { + c.mu.Unlock() + if linkRes == nil { + return "", tcpip.ErrNoLinkAddress + } + c.startAddressResolution(k, linkRes, localAddr, linkEP, waker) + return "", tcpip.ErrWouldBlock + } + defer c.mu.Unlock() + + switch s := entry.state(); s { + case expired: + // It's possible that entry expired between state() call above and here + // in that case it's safe to consider it ready. + fallthrough + case ready: + return entry.linkAddr, nil + case failed: + return "", tcpip.ErrNoLinkAddress + case incomplete: + // Address resolution is still in progress. + entry.addWaker(waker) + return "", tcpip.ErrWouldBlock + default: + panic(fmt.Sprintf("invalid cache entry state: %d", s)) + } +} + +// removeWaker removes a waker previously added through get(). +func (c *linkAddrCache) removeWaker(k tcpip.FullAddress, waker *sleep.Waker) { + c.mu.Lock() + defer c.mu.Unlock() + + if entry := c.cache[k]; entry != nil { + entry.removeWaker(waker) + } +} + +func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) { + c.mu.Lock() + defer c.mu.Unlock() + + // Look up again with lock held to ensure entry wasn't added by someone else. + if e := c.cache[k]; e != nil && e.state() != expired { + return + } + + // Add 'incomplete' entry in the cache to mark that resolution is in progress. + e := c.makeAndAddEntry(k, "") + e.addWaker(waker) + + go func() { // S/R-FIXME + for i := 0; ; i++ { + // Send link request, then wait for the timeout limit and check + // whether the request succeeded. + linkRes.LinkAddressRequest(k.Addr, localAddr, linkEP) + c.mu.Lock() + cancel := e.cancel + c.mu.Unlock() + + select { + case <-time.After(c.resolutionTimeout): + if stop := c.checkLinkRequest(k, i); stop { + return + } + case <-cancel: + return + } + } + }() +} + +// checkLinkRequest checks whether previous attempt to resolve address has succeeded +// and mark the entry accordingly, e.g. ready, failed, etc. Return true if request +// can stop, false if another request should be sent. +func (c *linkAddrCache) checkLinkRequest(k tcpip.FullAddress, attempt int) bool { + c.mu.Lock() + defer c.mu.Unlock() + + entry, ok := c.cache[k] + if !ok { + // Entry was evicted from the cache. + return true + } + + switch s := entry.state(); s { + case ready, failed, expired: + // Entry was made ready by resolver or failed. Either way we're done. + return true + case incomplete: + if attempt+1 >= c.resolutionAttempts { + // Max number of retries reached, mark entry as failed. + entry.changeState(failed) + return true + } + // No response yet, need to send another ARP request. + return false + default: + panic(fmt.Sprintf("invalid cache entry state: %d", s)) + } +} + +func newLinkAddrCache(ageLimit, resolutionTimeout time.Duration, resolutionAttempts int) *linkAddrCache { + return &linkAddrCache{ + ageLimit: ageLimit, + resolutionTimeout: resolutionTimeout, + resolutionAttempts: resolutionAttempts, + cache: make(map[tcpip.FullAddress]*linkAddrEntry, linkAddrCacheSize), + } +} diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go new file mode 100644 index 000000000..e9897b2bd --- /dev/null +++ b/pkg/tcpip/stack/linkaddrcache_test.go @@ -0,0 +1,256 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stack + +import ( + "fmt" + "sync" + "testing" + "time" + + "gvisor.googlesource.com/gvisor/pkg/sleep" + "gvisor.googlesource.com/gvisor/pkg/tcpip" +) + +type testaddr struct { + addr tcpip.FullAddress + linkAddr tcpip.LinkAddress +} + +var testaddrs []testaddr + +type testLinkAddressResolver struct { + cache *linkAddrCache + delay time.Duration +} + +func (r *testLinkAddressResolver) LinkAddressRequest(addr, _ tcpip.Address, _ LinkEndpoint) *tcpip.Error { + go func() { + if r.delay > 0 { + time.Sleep(r.delay) + } + r.fakeRequest(addr) + }() + return nil +} + +func (r *testLinkAddressResolver) fakeRequest(addr tcpip.Address) { + for _, ta := range testaddrs { + if ta.addr.Addr == addr { + r.cache.add(ta.addr, ta.linkAddr) + break + } + } +} + +func (*testLinkAddressResolver) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) { + if addr == "broadcast" { + return "mac_broadcast", true + } + return "", false +} + +func (*testLinkAddressResolver) LinkAddressProtocol() tcpip.NetworkProtocolNumber { + return 1 +} + +func getBlocking(c *linkAddrCache, addr tcpip.FullAddress, linkRes LinkAddressResolver) (tcpip.LinkAddress, *tcpip.Error) { + w := sleep.Waker{} + s := sleep.Sleeper{} + s.AddWaker(&w, 123) + defer s.Done() + + for { + if got, err := c.get(addr, linkRes, "", nil, &w); err != tcpip.ErrWouldBlock { + return got, err + } + s.Fetch(true) + } +} + +func init() { + for i := 0; i < 4*linkAddrCacheSize; i++ { + addr := fmt.Sprintf("Addr%06d", i) + testaddrs = append(testaddrs, testaddr{ + addr: tcpip.FullAddress{NIC: 1, Addr: tcpip.Address(addr)}, + linkAddr: tcpip.LinkAddress("Link" + addr), + }) + } +} + +func TestCacheOverflow(t *testing.T) { + c := newLinkAddrCache(1<<63-1, 1*time.Second, 3) + for i := len(testaddrs) - 1; i >= 0; i-- { + e := testaddrs[i] + c.add(e.addr, e.linkAddr) + got, err := c.get(e.addr, nil, "", nil, nil) + if err != nil { + t.Errorf("insert %d, c.get(%q)=%q, got error: %v", i, string(e.addr.Addr), got, err) + } + if got != e.linkAddr { + t.Errorf("insert %d, c.get(%q)=%q, want %q", i, string(e.addr.Addr), got, e.linkAddr) + } + } + // Expect to find at least half of the most recent entries. + for i := 0; i < linkAddrCacheSize/2; i++ { + e := testaddrs[i] + got, err := c.get(e.addr, nil, "", nil, nil) + if err != nil { + t.Errorf("check %d, c.get(%q)=%q, got error: %v", i, string(e.addr.Addr), got, err) + } + if got != e.linkAddr { + t.Errorf("check %d, c.get(%q)=%q, want %q", i, string(e.addr.Addr), got, e.linkAddr) + } + } + // The earliest entries should no longer be in the cache. + for i := len(testaddrs) - 1; i >= len(testaddrs)-linkAddrCacheSize; i-- { + e := testaddrs[i] + if _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { + t.Errorf("check %d, c.get(%q), got error: %v, want: error ErrNoLinkAddress", i, string(e.addr.Addr), err) + } + } +} + +func TestCacheConcurrent(t *testing.T) { + c := newLinkAddrCache(1<<63-1, 1*time.Second, 3) + + var wg sync.WaitGroup + for r := 0; r < 16; r++ { + wg.Add(1) + go func() { + for _, e := range testaddrs { + c.add(e.addr, e.linkAddr) + c.get(e.addr, nil, "", nil, nil) // make work for gotsan + } + wg.Done() + }() + } + wg.Wait() + + // All goroutines add in the same order and add more values than + // can fit in the cache, so our eviction strategy requires that + // the last entry be present and the first be missing. + e := testaddrs[len(testaddrs)-1] + got, err := c.get(e.addr, nil, "", nil, nil) + if err != nil { + t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) + } + if got != e.linkAddr { + t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, e.linkAddr) + } + + e = testaddrs[0] + if _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { + t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err) + } +} + +func TestCacheAgeLimit(t *testing.T) { + c := newLinkAddrCache(1*time.Millisecond, 1*time.Second, 3) + e := testaddrs[0] + c.add(e.addr, e.linkAddr) + time.Sleep(50 * time.Millisecond) + if _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { + t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err) + } +} + +func TestCacheReplace(t *testing.T) { + c := newLinkAddrCache(1<<63-1, 1*time.Second, 3) + e := testaddrs[0] + l2 := e.linkAddr + "2" + c.add(e.addr, e.linkAddr) + got, err := c.get(e.addr, nil, "", nil, nil) + if err != nil { + t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) + } + if got != e.linkAddr { + t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, e.linkAddr) + } + + c.add(e.addr, l2) + got, err = c.get(e.addr, nil, "", nil, nil) + if err != nil { + t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) + } + if got != l2 { + t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, l2) + } +} + +func TestCacheResolution(t *testing.T) { + c := newLinkAddrCache(1<<63-1, 250*time.Millisecond, 1) + linkRes := &testLinkAddressResolver{cache: c} + for i, ta := range testaddrs { + got, err := getBlocking(c, ta.addr, linkRes) + if err != nil { + t.Errorf("check %d, c.get(%q)=%q, got error: %v", i, string(ta.addr.Addr), got, err) + } + if got != ta.linkAddr { + t.Errorf("check %d, c.get(%q)=%q, want %q", i, string(ta.addr.Addr), got, ta.linkAddr) + } + } + + // Check that after resolved, address stays in the cache and never returns WouldBlock. + for i := 0; i < 10; i++ { + e := testaddrs[len(testaddrs)-1] + got, err := c.get(e.addr, linkRes, "", nil, nil) + if err != nil { + t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) + } + if got != e.linkAddr { + t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, e.linkAddr) + } + } +} + +func TestCacheResolutionFailed(t *testing.T) { + c := newLinkAddrCache(1<<63-1, 10*time.Millisecond, 5) + linkRes := &testLinkAddressResolver{cache: c} + + // First, sanity check that resolution is working... + e := testaddrs[0] + got, err := getBlocking(c, e.addr, linkRes) + if err != nil { + t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) + } + if got != e.linkAddr { + t.Errorf("c.get(%q)=%q, want %q", string(e.addr.Addr), got, e.linkAddr) + } + + e.addr.Addr += "2" + if _, err := getBlocking(c, e.addr, linkRes); err != tcpip.ErrNoLinkAddress { + t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err) + } +} + +func TestCacheResolutionTimeout(t *testing.T) { + resolverDelay := 50 * time.Millisecond + expiration := resolverDelay / 2 + c := newLinkAddrCache(expiration, 1*time.Millisecond, 3) + linkRes := &testLinkAddressResolver{cache: c, delay: resolverDelay} + + e := testaddrs[0] + if _, err := getBlocking(c, e.addr, linkRes); err != tcpip.ErrNoLinkAddress { + t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err) + } +} + +// TestStaticResolution checks that static link addresses are resolved immediately and don't +// send resolution requests. +func TestStaticResolution(t *testing.T) { + c := newLinkAddrCache(1<<63-1, time.Millisecond, 1) + linkRes := &testLinkAddressResolver{cache: c, delay: time.Minute} + + addr := tcpip.Address("broadcast") + want := tcpip.LinkAddress("mac_broadcast") + got, err := c.get(tcpip.FullAddress{Addr: addr}, linkRes, "", nil, nil) + if err != nil { + t.Errorf("c.get(%q)=%q, got error: %v", string(addr), string(got), err) + } + if got != want { + t.Errorf("c.get(%q)=%q, want %q", string(addr), string(got), string(want)) + } +} diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go new file mode 100644 index 000000000..8ff4310d5 --- /dev/null +++ b/pkg/tcpip/stack/nic.go @@ -0,0 +1,453 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stack + +import ( + "strings" + "sync" + "sync/atomic" + + "gvisor.googlesource.com/gvisor/pkg/ilist" + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" +) + +// 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 + + demux *transportDemuxer + + mu sync.RWMutex + spoofing bool + promiscuous bool + primary map[tcpip.NetworkProtocolNumber]*ilist.List + endpoints map[NetworkEndpointID]*referencedNetworkEndpoint + subnets []tcpip.Subnet +} + +func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint) *NIC { + return &NIC{ + stack: stack, + id: id, + name: name, + linkEP: ep, + demux: newTransportDemuxer(stack), + primary: make(map[tcpip.NetworkProtocolNumber]*ilist.List), + endpoints: make(map[NetworkEndpointID]*referencedNetworkEndpoint), + } +} + +// attachLinkEndpoint attaches the NIC to the endpoint, which will enable it +// to start delivering packets. +func (n *NIC) attachLinkEndpoint() { + n.linkEP.Attach(n) +} + +// setPromiscuousMode enables or disables promiscuous mode. +func (n *NIC) setPromiscuousMode(enable bool) { + n.mu.Lock() + n.promiscuous = enable + n.mu.Unlock() +} + +// setSpoofing enables or disables address spoofing. +func (n *NIC) setSpoofing(enable bool) { + n.mu.Lock() + n.spoofing = enable + n.mu.Unlock() +} + +// primaryEndpoint returns the primary endpoint of n for the given network +// protocol. +func (n *NIC) primaryEndpoint(protocol tcpip.NetworkProtocolNumber) *referencedNetworkEndpoint { + n.mu.RLock() + defer n.mu.RUnlock() + + list := n.primary[protocol] + if list == nil { + return nil + } + + for e := list.Front(); e != nil; e = e.Next() { + r := e.(*referencedNetworkEndpoint) + if r.tryIncRef() { + return r + } + } + + return nil +} + +// findEndpoint finds the endpoint, if any, with the given address. +func (n *NIC) findEndpoint(protocol tcpip.NetworkProtocolNumber, address tcpip.Address) *referencedNetworkEndpoint { + id := NetworkEndpointID{address} + + n.mu.RLock() + ref := n.endpoints[id] + if ref != nil && !ref.tryIncRef() { + ref = nil + } + spoofing := n.spoofing + n.mu.RUnlock() + + if ref != nil || !spoofing { + return ref + } + + // Try again with the lock in exclusive mode. If we still can't get the + // endpoint, create a new "temporary" endpoint. It will only exist while + // there's a route through it. + n.mu.Lock() + ref = n.endpoints[id] + if ref == nil || !ref.tryIncRef() { + ref, _ = n.addAddressLocked(protocol, address, true) + if ref != nil { + ref.holdsInsertRef = false + } + } + n.mu.Unlock() + return ref +} + +func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) { + netProto, ok := n.stack.networkProtocols[protocol] + if !ok { + return nil, tcpip.ErrUnknownProtocol + } + + // Create the new network endpoint. + ep, err := netProto.NewEndpoint(n.id, addr, n.stack, n, n.linkEP) + if err != nil { + return nil, err + } + + id := *ep.ID() + if ref, ok := n.endpoints[id]; ok { + if !replace { + return nil, tcpip.ErrDuplicateAddress + } + + n.removeEndpointLocked(ref) + } + + ref := &referencedNetworkEndpoint{ + refs: 1, + ep: ep, + nic: n, + protocol: protocol, + holdsInsertRef: true, + } + + // Set up cache if link address resolution exists for this protocol. + if n.linkEP.Capabilities()&CapabilityResolutionRequired != 0 { + if linkRes := n.stack.linkAddrResolvers[protocol]; linkRes != nil { + ref.linkCache = n.stack + } + } + + n.endpoints[id] = ref + + l, ok := n.primary[protocol] + if !ok { + l = &ilist.List{} + n.primary[protocol] = l + } + + l.PushBack(ref) + + return ref, nil +} + +// AddAddress adds a new address to n, so that it starts accepting packets +// targeted at the given address (and network protocol). +func (n *NIC) AddAddress(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error { + // Add the endpoint. + n.mu.Lock() + _, err := n.addAddressLocked(protocol, addr, false) + n.mu.Unlock() + + return err +} + +// Addresses returns the addresses associated with this NIC. +func (n *NIC) Addresses() []tcpip.ProtocolAddress { + n.mu.RLock() + defer n.mu.RUnlock() + addrs := make([]tcpip.ProtocolAddress, 0, len(n.endpoints)) + for nid, ep := range n.endpoints { + addrs = append(addrs, tcpip.ProtocolAddress{ + Protocol: ep.protocol, + Address: nid.LocalAddress, + }) + } + return addrs +} + +// AddSubnet adds a new subnet to n, so that it starts accepting packets +// targeted at the given address and network protocol. +func (n *NIC) AddSubnet(protocol tcpip.NetworkProtocolNumber, subnet tcpip.Subnet) { + n.mu.Lock() + n.subnets = append(n.subnets, subnet) + n.mu.Unlock() +} + +// Subnets returns the Subnets associated with this NIC. +func (n *NIC) Subnets() []tcpip.Subnet { + n.mu.RLock() + defer n.mu.RUnlock() + sns := make([]tcpip.Subnet, 0, len(n.subnets)+len(n.endpoints)) + for nid := range n.endpoints { + sn, err := tcpip.NewSubnet(nid.LocalAddress, tcpip.AddressMask(strings.Repeat("\xff", len(nid.LocalAddress)))) + if err != nil { + // This should never happen as the mask has been carefully crafted to + // match the address. + panic("Invalid endpoint subnet: " + err.Error()) + } + sns = append(sns, sn) + } + return append(sns, n.subnets...) +} + +func (n *NIC) removeEndpointLocked(r *referencedNetworkEndpoint) { + id := *r.ep.ID() + + // Nothing to do if the reference has already been replaced with a + // different one. + if n.endpoints[id] != r { + return + } + + if r.holdsInsertRef { + panic("Reference count dropped to zero before being removed") + } + + delete(n.endpoints, id) + n.primary[r.protocol].Remove(r) + r.ep.Close() +} + +func (n *NIC) removeEndpoint(r *referencedNetworkEndpoint) { + n.mu.Lock() + n.removeEndpointLocked(r) + n.mu.Unlock() +} + +// RemoveAddress removes an address from n. +func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error { + n.mu.Lock() + r := n.endpoints[NetworkEndpointID{addr}] + if r == nil || !r.holdsInsertRef { + n.mu.Unlock() + return tcpip.ErrBadLocalAddress + } + + r.holdsInsertRef = false + n.mu.Unlock() + + r.decRef() + + return nil +} + +// DeliverNetworkPacket finds the appropriate network protocol endpoint and +// hands the packet over for further processing. This function is called when +// the NIC receives a packet from the physical interface. +// Note that the ownership of the slice backing vv is retained by the caller. +// This rule applies only to the slice itself, not to the items of the slice; +// the ownership of the items is not retained by the caller. +func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { + netProto, ok := n.stack.networkProtocols[protocol] + if !ok { + atomic.AddUint64(&n.stack.stats.UnknownProtocolRcvdPackets, 1) + return + } + + if len(vv.First()) < netProto.MinimumPacketSize() { + atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1) + return + } + + src, dst := netProto.ParseAddresses(vv.First()) + id := NetworkEndpointID{dst} + + n.mu.RLock() + ref := n.endpoints[id] + if ref != nil && !ref.tryIncRef() { + ref = nil + } + promiscuous := n.promiscuous + subnets := n.subnets + n.mu.RUnlock() + + if ref == nil { + // Check if the packet is for a subnet this NIC cares about. + if !promiscuous { + for _, sn := range subnets { + if sn.Contains(dst) { + promiscuous = true + break + } + } + } + if promiscuous { + // Try again with the lock in exclusive mode. If we still can't + // get the endpoint, create a new "temporary" one. It will only + // exist while there's a route through it. + n.mu.Lock() + ref = n.endpoints[id] + if ref == nil || !ref.tryIncRef() { + ref, _ = n.addAddressLocked(protocol, dst, true) + if ref != nil { + ref.holdsInsertRef = false + } + } + n.mu.Unlock() + } + } + + if ref == nil { + atomic.AddUint64(&n.stack.stats.UnknownNetworkEndpointRcvdPackets, 1) + return + } + + r := makeRoute(protocol, dst, src, ref) + r.LocalLinkAddress = linkEP.LinkAddress() + r.RemoteLinkAddress = remoteLinkAddr + ref.ep.HandlePacket(&r, vv) + ref.decRef() +} + +// DeliverTransportPacket delivers the packets to the appropriate transport +// protocol endpoint. +func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) { + state, ok := n.stack.transportProtocols[protocol] + if !ok { + atomic.AddUint64(&n.stack.stats.UnknownProtocolRcvdPackets, 1) + return + } + + transProto := state.proto + if len(vv.First()) < transProto.MinimumPacketSize() { + atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1) + return + } + + srcPort, dstPort, err := transProto.ParsePorts(vv.First()) + if err != nil { + atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1) + return + } + + id := TransportEndpointID{dstPort, r.LocalAddress, srcPort, r.RemoteAddress} + if n.demux.deliverPacket(r, protocol, vv, id) { + return + } + if n.stack.demux.deliverPacket(r, protocol, vv, id) { + return + } + + // Try to deliver to per-stack default handler. + if state.defaultHandler != nil { + if state.defaultHandler(r, id, vv) { + return + } + } + + // We could not find an appropriate destination for this packet, so + // deliver it to the global handler. + if !transProto.HandleUnknownDestinationPacket(r, id, vv) { + atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1) + } +} + +// DeliverTransportControlPacket delivers control packets to the appropriate +// transport protocol endpoint. +func (n *NIC) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv *buffer.VectorisedView) { + state, ok := n.stack.transportProtocols[trans] + if !ok { + return + } + + transProto := state.proto + + // ICMPv4 only guarantees that 8 bytes of the transport protocol will + // be present in the payload. We know that the ports are within the + // first 8 bytes for all known transport protocols. + if len(vv.First()) < 8 { + return + } + + srcPort, dstPort, err := transProto.ParsePorts(vv.First()) + if err != nil { + return + } + + id := TransportEndpointID{srcPort, local, dstPort, remote} + if n.demux.deliverControlPacket(net, trans, typ, extra, vv, id) { + return + } + if n.stack.demux.deliverControlPacket(net, trans, typ, extra, vv, id) { + return + } +} + +// ID returns the identifier of n. +func (n *NIC) ID() tcpip.NICID { + return n.id +} + +type referencedNetworkEndpoint struct { + ilist.Entry + refs int32 + ep NetworkEndpoint + nic *NIC + protocol tcpip.NetworkProtocolNumber + + // linkCache is set if link address resolution is enabled for this + // protocol. Set to nil otherwise. + linkCache LinkAddressCache + + // holdsInsertRef is protected by the NIC's mutex. It indicates whether + // the reference count is biased by 1 due to the insertion of the + // endpoint. It is reset to false when RemoveAddress is called on the + // NIC. + holdsInsertRef bool +} + +// decRef decrements the ref count and cleans up the endpoint once it reaches +// zero. +func (r *referencedNetworkEndpoint) decRef() { + if atomic.AddInt32(&r.refs, -1) == 0 { + r.nic.removeEndpoint(r) + } +} + +// incRef increments the ref count. It must only be called when the caller is +// known to be holding a reference to the endpoint, otherwise tryIncRef should +// be used. +func (r *referencedNetworkEndpoint) incRef() { + atomic.AddInt32(&r.refs, 1) +} + +// tryIncRef attempts to increment the ref count from n to n+1, but only if n is +// not zero. That is, it will increment the count if the endpoint is still +// alive, and do nothing if it has already been clean up. +func (r *referencedNetworkEndpoint) tryIncRef() bool { + for { + v := atomic.LoadInt32(&r.refs) + if v == 0 { + return false + } + + if atomic.CompareAndSwapInt32(&r.refs, v, v+1) { + return true + } + } +} diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go new file mode 100644 index 000000000..e7e6381ac --- /dev/null +++ b/pkg/tcpip/stack/registration.go @@ -0,0 +1,322 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stack + +import ( + "sync" + + "gvisor.googlesource.com/gvisor/pkg/sleep" + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +// NetworkEndpointID is the identifier of a network layer protocol endpoint. +// Currently the local address is sufficient because all supported protocols +// (i.e., IPv4 and IPv6) have different sizes for their addresses. +type NetworkEndpointID struct { + LocalAddress tcpip.Address +} + +// TransportEndpointID is the identifier of a transport layer protocol endpoint. +type TransportEndpointID struct { + // LocalPort is the local port associated with the endpoint. + LocalPort uint16 + + // LocalAddress is the local [network layer] address associated with + // the endpoint. + LocalAddress tcpip.Address + + // RemotePort is the remote port associated with the endpoint. + RemotePort uint16 + + // RemoteAddress it the remote [network layer] address associated with + // the endpoint. + RemoteAddress tcpip.Address +} + +// ControlType is the type of network control message. +type ControlType int + +// The following are the allowed values for ControlType values. +const ( + ControlPacketTooBig ControlType = iota + ControlPortUnreachable + ControlUnknown +) + +// TransportEndpoint is the interface that needs to be implemented by transport +// protocol (e.g., tcp, udp) endpoints that can handle packets. +type TransportEndpoint interface { + // HandlePacket is called by the stack when new packets arrive to + // this transport endpoint. + HandlePacket(r *Route, id TransportEndpointID, vv *buffer.VectorisedView) + + // HandleControlPacket is called by the stack when new control (e.g., + // ICMP) packets arrive to this transport endpoint. + HandleControlPacket(id TransportEndpointID, typ ControlType, extra uint32, vv *buffer.VectorisedView) +} + +// TransportProtocol is the interface that needs to be implemented by transport +// protocols (e.g., tcp, udp) that want to be part of the networking stack. +type TransportProtocol interface { + // Number returns the transport protocol number. + Number() tcpip.TransportProtocolNumber + + // NewEndpoint creates a new endpoint of the transport protocol. + NewEndpoint(stack *Stack, netProto tcpip.NetworkProtocolNumber, waitQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) + + // MinimumPacketSize returns the minimum valid packet size of this + // transport protocol. The stack automatically drops any packets smaller + // than this targeted at this protocol. + MinimumPacketSize() int + + // ParsePorts returns the source and destination ports stored in a + // packet of this protocol. + ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) + + // HandleUnknownDestinationPacket handles packets targeted at this + // protocol but that don't match any existing endpoint. For example, + // it is targeted at a port that have no listeners. + // + // The return value indicates whether the packet was well-formed (for + // stats purposes only). + HandleUnknownDestinationPacket(r *Route, id TransportEndpointID, vv *buffer.VectorisedView) bool + + // SetOption allows enabling/disabling protocol specific features. + // SetOption returns an error if the option is not supported or the + // provided option value is invalid. + SetOption(option interface{}) *tcpip.Error + + // Option allows retrieving protocol specific option values. + // Option returns an error if the option is not supported or the + // provided option value is invalid. + Option(option interface{}) *tcpip.Error +} + +// TransportDispatcher contains the methods used by the network stack to deliver +// packets to the appropriate transport endpoint after it has been handled by +// the network layer. +type TransportDispatcher interface { + // DeliverTransportPacket delivers packets to the appropriate + // transport protocol endpoint. + DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) + + // DeliverTransportControlPacket delivers control packets to the + // appropriate transport protocol endpoint. + DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv *buffer.VectorisedView) +} + +// NetworkEndpoint is the interface that needs to be implemented by endpoints +// of network layer protocols (e.g., ipv4, ipv6). +type NetworkEndpoint interface { + // MTU is the maximum transmission unit for this endpoint. This is + // generally calculated as the MTU of the underlying data link endpoint + // minus the network endpoint max header length. + MTU() uint32 + + // Capabilities returns the set of capabilities supported by the + // underlying link-layer endpoint. + Capabilities() LinkEndpointCapabilities + + // MaxHeaderLength returns the maximum size the network (and lower + // level layers combined) headers can have. Higher levels use this + // information to reserve space in the front of the packets they're + // building. + MaxHeaderLength() uint16 + + // WritePacket writes a packet to the given destination address and + // protocol. + WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error + + // ID returns the network protocol endpoint ID. + ID() *NetworkEndpointID + + // NICID returns the id of the NIC this endpoint belongs to. + NICID() tcpip.NICID + + // HandlePacket is called by the link layer when new packets arrive to + // this network endpoint. + HandlePacket(r *Route, vv *buffer.VectorisedView) + + // Close is called when the endpoint is reomved from a stack. + Close() +} + +// NetworkProtocol is the interface that needs to be implemented by network +// protocols (e.g., ipv4, ipv6) that want to be part of the networking stack. +type NetworkProtocol interface { + // Number returns the network protocol number. + Number() tcpip.NetworkProtocolNumber + + // MinimumPacketSize returns the minimum valid packet size of this + // network protocol. The stack automatically drops any packets smaller + // than this targeted at this protocol. + MinimumPacketSize() int + + // ParsePorts returns the source and destination addresses stored in a + // packet of this protocol. + ParseAddresses(v buffer.View) (src, dst tcpip.Address) + + // NewEndpoint creates a new endpoint of this protocol. + NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache LinkAddressCache, dispatcher TransportDispatcher, sender LinkEndpoint) (NetworkEndpoint, *tcpip.Error) + + // SetOption allows enabling/disabling protocol specific features. + // SetOption returns an error if the option is not supported or the + // provided option value is invalid. + SetOption(option interface{}) *tcpip.Error + + // Option allows retrieving protocol specific option values. + // Option returns an error if the option is not supported or the + // provided option value is invalid. + Option(option interface{}) *tcpip.Error +} + +// NetworkDispatcher contains the methods used by the network stack to deliver +// packets to the appropriate network endpoint after it has been handled by +// the data link layer. +type NetworkDispatcher interface { + // DeliverNetworkPacket finds the appropriate network protocol + // endpoint and hands the packet over for further processing. + DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) +} + +// LinkEndpointCapabilities is the type associated with the capabilities +// supported by a link-layer endpoint. It is a set of bitfields. +type LinkEndpointCapabilities uint + +// The following are the supported link endpoint capabilities. +const ( + CapabilityChecksumOffload LinkEndpointCapabilities = 1 << iota + CapabilityResolutionRequired +) + +// LinkEndpoint is the interface implemented by data link layer protocols (e.g., +// ethernet, loopback, raw) and used by network layer protocols to send packets +// out through the implementer's data link endpoint. +type LinkEndpoint interface { + // MTU is the maximum transmission unit for this endpoint. This is + // usually dictated by the backing physical network; when such a + // physical network doesn't exist, the limit is generally 64k, which + // includes the maximum size of an IP packet. + MTU() uint32 + + // Capabilities returns the set of capabilities supported by the + // endpoint. + Capabilities() LinkEndpointCapabilities + + // MaxHeaderLength returns the maximum size the data link (and + // lower level layers combined) headers can have. Higher levels use this + // information to reserve space in the front of the packets they're + // building. + MaxHeaderLength() uint16 + + // LinkAddress returns the link address (typically a MAC) of the + // link endpoint. + LinkAddress() tcpip.LinkAddress + + // WritePacket writes a packet with the given protocol through the given + // route. + WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error + + // Attach attaches the data link layer endpoint to the network-layer + // dispatcher of the stack. + Attach(dispatcher NetworkDispatcher) +} + +// A LinkAddressResolver is an extension to a NetworkProtocol that +// can resolve link addresses. +type LinkAddressResolver interface { + // LinkAddressRequest sends a request for the LinkAddress of addr. + // The request is sent on linkEP with localAddr as the source. + // + // A valid response will cause the discovery protocol's network + // endpoint to call AddLinkAddress. + LinkAddressRequest(addr, localAddr tcpip.Address, linkEP LinkEndpoint) *tcpip.Error + + // ResolveStaticAddress attempts to resolve address without sending + // requests. It either resolves the name immediately or returns the + // empty LinkAddress. + // + // It can be used to resolve broadcast addresses for example. + ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) + + // LinkAddressProtocol returns the network protocol of the + // addresses this this resolver can resolve. + LinkAddressProtocol() tcpip.NetworkProtocolNumber +} + +// A LinkAddressCache caches link addresses. +type LinkAddressCache interface { + // CheckLocalAddress determines if the given local address exists, and if it + // does not exist. + CheckLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) tcpip.NICID + + // AddLinkAddress adds a link address to the cache. + AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress) + + // GetLinkAddress looks up the cache to translate address to link address (e.g. IP -> MAC). + // If the LinkEndpoint requests address resolution and there is a LinkAddressResolver + // registered with the network protocol, the cache attempts to resolve the address + // and returns ErrWouldBlock. Waker is notified when address resolution is + // complete (success or not). + GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, w *sleep.Waker) (tcpip.LinkAddress, *tcpip.Error) + + // RemoveWaker removes a waker that has been added in GetLinkAddress(). + RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep.Waker) +} + +// TransportProtocolFactory functions are used by the stack to instantiate +// transport protocols. +type TransportProtocolFactory func() TransportProtocol + +// NetworkProtocolFactory provides methods to be used by the stack to +// instantiate network protocols. +type NetworkProtocolFactory func() NetworkProtocol + +var ( + transportProtocols = make(map[string]TransportProtocolFactory) + networkProtocols = make(map[string]NetworkProtocolFactory) + + linkEPMu sync.RWMutex + nextLinkEndpointID tcpip.LinkEndpointID = 1 + linkEndpoints = make(map[tcpip.LinkEndpointID]LinkEndpoint) +) + +// RegisterTransportProtocolFactory registers a new transport protocol factory +// with the stack so that it becomes available to users of the stack. This +// function is intended to be called by init() functions of the protocols. +func RegisterTransportProtocolFactory(name string, p TransportProtocolFactory) { + transportProtocols[name] = p +} + +// RegisterNetworkProtocolFactory registers a new network protocol factory with +// the stack so that it becomes available to users of the stack. This function +// is intended to be called by init() functions of the protocols. +func RegisterNetworkProtocolFactory(name string, p NetworkProtocolFactory) { + networkProtocols[name] = p +} + +// RegisterLinkEndpoint register a link-layer protocol endpoint and returns an +// ID that can be used to refer to it. +func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID { + linkEPMu.Lock() + defer linkEPMu.Unlock() + + v := nextLinkEndpointID + nextLinkEndpointID++ + + linkEndpoints[v] = linkEP + + return v +} + +// FindLinkEndpoint finds the link endpoint associated with the given ID. +func FindLinkEndpoint(id tcpip.LinkEndpointID) LinkEndpoint { + linkEPMu.RLock() + defer linkEPMu.RUnlock() + + return linkEndpoints[id] +} diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go new file mode 100644 index 000000000..12f5efba5 --- /dev/null +++ b/pkg/tcpip/stack/route.go @@ -0,0 +1,133 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stack + +import ( + "gvisor.googlesource.com/gvisor/pkg/sleep" + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" +) + +// Route represents a route through the networking stack to a given destination. +type Route struct { + // RemoteAddress is the final destination of the route. + RemoteAddress tcpip.Address + + // RemoteLinkAddress is the link-layer (MAC) address of the + // final destination of the route. + RemoteLinkAddress tcpip.LinkAddress + + // LocalAddress is the local address where the route starts. + LocalAddress tcpip.Address + + // LocalLinkAddress is the link-layer (MAC) address of the + // where the route starts. + LocalLinkAddress tcpip.LinkAddress + + // NextHop is the next node in the path to the destination. + NextHop tcpip.Address + + // NetProto is the network-layer protocol. + NetProto tcpip.NetworkProtocolNumber + + // ref a reference to the network endpoint through which the route + // starts. + ref *referencedNetworkEndpoint +} + +// makeRoute initializes a new route. It takes ownership of the provided +// reference to a network endpoint. +func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, ref *referencedNetworkEndpoint) Route { + return Route{ + NetProto: netProto, + LocalAddress: localAddr, + RemoteAddress: remoteAddr, + ref: ref, + } +} + +// NICID returns the id of the NIC from which this route originates. +func (r *Route) NICID() tcpip.NICID { + return r.ref.ep.NICID() +} + +// MaxHeaderLength forwards the call to the network endpoint's implementation. +func (r *Route) MaxHeaderLength() uint16 { + return r.ref.ep.MaxHeaderLength() +} + +// PseudoHeaderChecksum forwards the call to the network endpoint's +// implementation. +func (r *Route) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber) uint16 { + return header.PseudoHeaderChecksum(protocol, r.LocalAddress, r.RemoteAddress) +} + +// Capabilities returns the link-layer capabilities of the route. +func (r *Route) Capabilities() LinkEndpointCapabilities { + return r.ref.ep.Capabilities() +} + +// Resolve attempts to resolve the link address if necessary. Returns ErrWouldBlock in +// case address resolution requires blocking, e.g. wait for ARP reply. Waker is +// notified when address resolution is complete (success or not). +func (r *Route) Resolve(waker *sleep.Waker) *tcpip.Error { + if !r.IsResolutionRequired() { + // Nothing to do if there is no cache (which does the resolution on cache miss) or + // link address is already known. + return nil + } + + nextAddr := r.NextHop + if nextAddr == "" { + nextAddr = r.RemoteAddress + } + linkAddr, err := r.ref.linkCache.GetLinkAddress(r.ref.nic.ID(), nextAddr, r.LocalAddress, r.NetProto, waker) + if err != nil { + return err + } + r.RemoteLinkAddress = linkAddr + return nil +} + +// RemoveWaker removes a waker that has been added in Resolve(). +func (r *Route) RemoveWaker(waker *sleep.Waker) { + nextAddr := r.NextHop + if nextAddr == "" { + nextAddr = r.RemoteAddress + } + r.ref.linkCache.RemoveWaker(r.ref.nic.ID(), nextAddr, waker) +} + +// IsResolutionRequired returns true if Resolve() must be called to resolve +// the link address before the this route can be written to. +func (r *Route) IsResolutionRequired() bool { + return r.ref.linkCache != nil && r.RemoteLinkAddress == "" +} + +// WritePacket writes the packet through the given route. +func (r *Route) WritePacket(hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error { + return r.ref.ep.WritePacket(r, hdr, payload, protocol) +} + +// MTU returns the MTU of the underlying network endpoint. +func (r *Route) MTU() uint32 { + return r.ref.ep.MTU() +} + +// Release frees all resources associated with the route. +func (r *Route) Release() { + if r.ref != nil { + r.ref.decRef() + r.ref = nil + } +} + +// Clone Clone a route such that the original one can be released and the new +// one will remain valid. +func (r *Route) Clone() Route { + r.ref.incRef() + return *r +} diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go new file mode 100644 index 000000000..558ecdb72 --- /dev/null +++ b/pkg/tcpip/stack/stack.go @@ -0,0 +1,811 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package stack provides the glue between networking protocols and the +// consumers of the networking stack. +// +// For consumers, the only function of interest is New(), everything else is +// provided by the tcpip/public package. +// +// For protocol implementers, RegisterTransportProtocolFactory() and +// RegisterNetworkProtocolFactory() are used to register protocol factories with +// the stack, which will then be used to instantiate protocol objects when +// consumers interact with the stack. +package stack + +import ( + "sync" + "sync/atomic" + "time" + + "gvisor.googlesource.com/gvisor/pkg/sleep" + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" + "gvisor.googlesource.com/gvisor/pkg/tcpip/ports" + "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +const ( + // ageLimit is set to the same cache stale time used in Linux. + ageLimit = 1 * time.Minute + // resolutionTimeout is set to the same ARP timeout used in Linux. + resolutionTimeout = 1 * time.Second + // resolutionAttempts is set to the same ARP retries used in Linux. + resolutionAttempts = 3 +) + +type transportProtocolState struct { + proto TransportProtocol + defaultHandler func(*Route, TransportEndpointID, *buffer.VectorisedView) bool +} + +// TCPProbeFunc is the expected function type for a TCP probe function to be +// passed to stack.AddTCPProbe. +type TCPProbeFunc func(s TCPEndpointState) + +// TCPEndpointID is the unique 4 tuple that identifies a given endpoint. +type TCPEndpointID struct { + // LocalPort is the local port associated with the endpoint. + LocalPort uint16 + + // LocalAddress is the local [network layer] address associated with + // the endpoint. + LocalAddress tcpip.Address + + // RemotePort is the remote port associated with the endpoint. + RemotePort uint16 + + // RemoteAddress it the remote [network layer] address associated with + // the endpoint. + RemoteAddress tcpip.Address +} + +// TCPFastRecoveryState holds a copy of the internal fast recovery state of a +// TCP endpoint. +type TCPFastRecoveryState struct { + // Active if true indicates the endpoint is in fast recovery. + Active bool + + // First is the first unacknowledged sequence number being recovered. + First seqnum.Value + + // Last is the 'recover' sequence number that indicates the point at + // which we should exit recovery barring any timeouts etc. + Last seqnum.Value + + // MaxCwnd is the maximum value we are permitted to grow the congestion + // window during recovery. This is set at the time we enter recovery. + MaxCwnd int +} + +// TCPReceiverState holds a copy of the internal state of the receiver for +// a given TCP endpoint. +type TCPReceiverState struct { + // RcvNxt is the TCP variable RCV.NXT. + RcvNxt seqnum.Value + + // RcvAcc is the TCP variable RCV.ACC. + RcvAcc seqnum.Value + + // RcvWndScale is the window scaling to use for inbound segments. + RcvWndScale uint8 + + // PendingBufUsed is the number of bytes pending in the receive + // queue. + PendingBufUsed seqnum.Size + + // PendingBufSize is the size of the socket receive buffer. + PendingBufSize seqnum.Size +} + +// TCPSenderState holds a copy of the internal state of the sender for +// a given TCP Endpoint. +type TCPSenderState struct { + // LastSendTime is the time at which we sent the last segment. + LastSendTime time.Time + + // DupAckCount is the number of Duplicate ACK's received. + DupAckCount int + + // SndCwnd is the size of the sending congestion window in packets. + SndCwnd int + + // Ssthresh is the slow start threshold in packets. + Ssthresh int + + // SndCAAckCount is the number of packets consumed in congestion + // avoidance mode. + SndCAAckCount int + + // Outstanding is the number of packets in flight. + Outstanding int + + // SndWnd is the send window size in bytes. + SndWnd seqnum.Size + + // SndUna is the next unacknowledged sequence number. + SndUna seqnum.Value + + // SndNxt is the sequence number of the next segment to be sent. + SndNxt seqnum.Value + + // RTTMeasureSeqNum is the sequence number being used for the latest RTT + // measurement. + RTTMeasureSeqNum seqnum.Value + + // RTTMeasureTime is the time when the RTTMeasureSeqNum was sent. + RTTMeasureTime time.Time + + // Closed indicates that the caller has closed the endpoint for sending. + Closed bool + + // SRTT is the smoothed round-trip time as defined in section 2 of + // RFC 6298. + SRTT time.Duration + + // RTO is the retransmit timeout as defined in section of 2 of RFC 6298. + RTO time.Duration + + // RTTVar is the round-trip time variation as defined in section 2 of + // RFC 6298. + RTTVar time.Duration + + // SRTTInited if true indicates take a valid RTT measurement has been + // completed. + SRTTInited bool + + // MaxPayloadSize is the maximum size of the payload of a given segment. + // It is initialized on demand. + MaxPayloadSize int + + // SndWndScale is the number of bits to shift left when reading the send + // window size from a segment. + SndWndScale uint8 + + // MaxSentAck is the highest acknowledgemnt number sent till now. + MaxSentAck seqnum.Value + + // FastRecovery holds the fast recovery state for the endpoint. + FastRecovery TCPFastRecoveryState +} + +// TCPSACKInfo holds TCP SACK related information for a given TCP endpoint. +type TCPSACKInfo struct { + // Blocks is the list of SACK block currently received by the + // TCP endpoint. + Blocks []header.SACKBlock +} + +// TCPEndpointState is a copy of the internal state of a TCP endpoint. +type TCPEndpointState struct { + // ID is a copy of the TransportEndpointID for the endpoint. + ID TCPEndpointID + + // SegTime denotes the absolute time when this segment was received. + SegTime time.Time + + // RcvBufSize is the size of the receive socket buffer for the endpoint. + RcvBufSize int + + // RcvBufUsed is the amount of bytes actually held in the receive socket + // buffer for the endpoint. + RcvBufUsed int + + // RcvClosed if true, indicates the endpoint has been closed for reading. + RcvClosed bool + + // SendTSOk is used to indicate when the TS Option has been negotiated. + // When sendTSOk is true every non-RST segment should carry a TS as per + // RFC7323#section-1.1. + SendTSOk bool + + // RecentTS is the timestamp that should be sent in the TSEcr field of + // the timestamp for future segments sent by the endpoint. This field is + // updated if required when a new segment is received by this endpoint. + RecentTS uint32 + + // TSOffset is a randomized offset added to the value of the TSVal field + // in the timestamp option. + TSOffset uint32 + + // SACKPermitted is set to true if the peer sends the TCPSACKPermitted + // option in the SYN/SYN-ACK. + SACKPermitted bool + + // SACK holds TCP SACK related information for this endpoint. + SACK TCPSACKInfo + + // SndBufSize is the size of the socket send buffer. + SndBufSize int + + // SndBufUsed is the number of bytes held in the socket send buffer. + SndBufUsed int + + // SndClosed indicates that the endpoint has been closed for sends. + SndClosed bool + + // SndBufInQueue is the number of bytes in the send queue. + SndBufInQueue seqnum.Size + + // PacketTooBigCount is used to notify the main protocol routine how + // many times a "packet too big" control packet is received. + PacketTooBigCount int + + // SndMTU is the smallest MTU seen in the control packets received. + SndMTU int + + // Receiver holds variables related to the TCP receiver for the endpoint. + Receiver TCPReceiverState + + // Sender holds state related to the TCP Sender for the endpoint. + Sender TCPSenderState +} + +// Stack is a networking stack, with all supported protocols, NICs, and route +// table. +type Stack struct { + transportProtocols map[tcpip.TransportProtocolNumber]*transportProtocolState + networkProtocols map[tcpip.NetworkProtocolNumber]NetworkProtocol + linkAddrResolvers map[tcpip.NetworkProtocolNumber]LinkAddressResolver + + demux *transportDemuxer + + stats tcpip.Stats + + linkAddrCache *linkAddrCache + + mu sync.RWMutex + nics map[tcpip.NICID]*NIC + + // route is the route table passed in by the user via SetRouteTable(), + // it is used by FindRoute() to build a route for a specific + // destination. + routeTable []tcpip.Route + + *ports.PortManager + + // If not nil, then any new endpoints will have this probe function + // invoked everytime they receive a TCP segment. + tcpProbeFunc TCPProbeFunc +} + +// New allocates a new networking stack with only the requested networking and +// transport protocols configured with default options. +// +// Protocol options can be changed by calling the +// SetNetworkProtocolOption/SetTransportProtocolOption methods provided by the +// stack. Please refer to individual protocol implementations as to what options +// are supported. +func New(network []string, transport []string) *Stack { + s := &Stack{ + transportProtocols: make(map[tcpip.TransportProtocolNumber]*transportProtocolState), + networkProtocols: make(map[tcpip.NetworkProtocolNumber]NetworkProtocol), + linkAddrResolvers: make(map[tcpip.NetworkProtocolNumber]LinkAddressResolver), + nics: make(map[tcpip.NICID]*NIC), + linkAddrCache: newLinkAddrCache(ageLimit, resolutionTimeout, resolutionAttempts), + PortManager: ports.NewPortManager(), + } + + // Add specified network protocols. + for _, name := range network { + netProtoFactory, ok := networkProtocols[name] + if !ok { + continue + } + netProto := netProtoFactory() + s.networkProtocols[netProto.Number()] = netProto + if r, ok := netProto.(LinkAddressResolver); ok { + s.linkAddrResolvers[r.LinkAddressProtocol()] = r + } + } + + // Add specified transport protocols. + for _, name := range transport { + transProtoFactory, ok := transportProtocols[name] + if !ok { + continue + } + transProto := transProtoFactory() + s.transportProtocols[transProto.Number()] = &transportProtocolState{ + proto: transProto, + } + } + + // Create the global transport demuxer. + s.demux = newTransportDemuxer(s) + + return s +} + +// SetNetworkProtocolOption allows configuring individual protocol level +// options. This method returns an error if the protocol is not supported or +// option is not supported by the protocol implementation or the provided value +// is incorrect. +func (s *Stack) SetNetworkProtocolOption(network tcpip.NetworkProtocolNumber, option interface{}) *tcpip.Error { + netProto, ok := s.networkProtocols[network] + if !ok { + return tcpip.ErrUnknownProtocol + } + return netProto.SetOption(option) +} + +// NetworkProtocolOption allows retrieving individual protocol level option +// values. This method returns an error if the protocol is not supported or +// option is not supported by the protocol implementation. +// e.g. +// var v ipv4.MyOption +// err := s.NetworkProtocolOption(tcpip.IPv4ProtocolNumber, &v) +// if err != nil { +// ... +// } +func (s *Stack) NetworkProtocolOption(network tcpip.NetworkProtocolNumber, option interface{}) *tcpip.Error { + netProto, ok := s.networkProtocols[network] + if !ok { + return tcpip.ErrUnknownProtocol + } + return netProto.Option(option) +} + +// SetTransportProtocolOption allows configuring individual protocol level +// options. This method returns an error if the protocol is not supported or +// option is not supported by the protocol implementation or the provided value +// is incorrect. +func (s *Stack) SetTransportProtocolOption(transport tcpip.TransportProtocolNumber, option interface{}) *tcpip.Error { + transProtoState, ok := s.transportProtocols[transport] + if !ok { + return tcpip.ErrUnknownProtocol + } + return transProtoState.proto.SetOption(option) +} + +// TransportProtocolOption allows retrieving individual protocol level option +// values. This method returns an error if the protocol is not supported or +// option is not supported by the protocol implementation. +// var v tcp.SACKEnabled +// if err := s.TransportProtocolOption(tcpip.TCPProtocolNumber, &v); err != nil { +// ... +// } +func (s *Stack) TransportProtocolOption(transport tcpip.TransportProtocolNumber, option interface{}) *tcpip.Error { + transProtoState, ok := s.transportProtocols[transport] + if !ok { + return tcpip.ErrUnknownProtocol + } + return transProtoState.proto.Option(option) +} + +// SetTransportProtocolHandler sets the per-stack default handler for the given +// protocol. +// +// It must be called only during initialization of the stack. Changing it as the +// stack is operating is not supported. +func (s *Stack) SetTransportProtocolHandler(p tcpip.TransportProtocolNumber, h func(*Route, TransportEndpointID, *buffer.VectorisedView) bool) { + state := s.transportProtocols[p] + if state != nil { + state.defaultHandler = h + } +} + +// Stats returns a snapshot of the current stats. +// +// NOTE: The underlying stats are updated using atomic instructions as a result +// the snapshot returned does not represent the value of all the stats at any +// single given point of time. +// TODO: Make stats available in sentry for debugging/diag. +func (s *Stack) Stats() tcpip.Stats { + return tcpip.Stats{ + UnknownProtocolRcvdPackets: atomic.LoadUint64(&s.stats.UnknownProtocolRcvdPackets), + UnknownNetworkEndpointRcvdPackets: atomic.LoadUint64(&s.stats.UnknownNetworkEndpointRcvdPackets), + MalformedRcvdPackets: atomic.LoadUint64(&s.stats.MalformedRcvdPackets), + DroppedPackets: atomic.LoadUint64(&s.stats.DroppedPackets), + } +} + +// MutableStats returns a mutable copy of the current stats. +// +// This is not generally exported via the public interface, but is available +// internally. +func (s *Stack) MutableStats() *tcpip.Stats { + return &s.stats +} + +// SetRouteTable assigns the route table to be used by this stack. It +// specifies which NIC to use for given destination address ranges. +func (s *Stack) SetRouteTable(table []tcpip.Route) { + s.mu.Lock() + defer s.mu.Unlock() + + s.routeTable = table +} + +// NewEndpoint creates a new transport layer endpoint of the given protocol. +func (s *Stack) NewEndpoint(transport tcpip.TransportProtocolNumber, network tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + t, ok := s.transportProtocols[transport] + if !ok { + return nil, tcpip.ErrUnknownProtocol + } + + return t.proto.NewEndpoint(s, network, waiterQueue) +} + +// createNIC creates a NIC with the provided id and link-layer endpoint, and +// optionally enable it. +func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID, enabled bool) *tcpip.Error { + ep := FindLinkEndpoint(linkEP) + if ep == nil { + return tcpip.ErrBadLinkEndpoint + } + + s.mu.Lock() + defer s.mu.Unlock() + + // Make sure id is unique. + if _, ok := s.nics[id]; ok { + return tcpip.ErrDuplicateNICID + } + + n := newNIC(s, id, name, ep) + + s.nics[id] = n + if enabled { + n.attachLinkEndpoint() + } + + return nil +} + +// CreateNIC creates a NIC with the provided id and link-layer endpoint. +func (s *Stack) CreateNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error { + return s.createNIC(id, "", linkEP, true) +} + +// CreateNamedNIC creates a NIC with the provided id and link-layer endpoint, +// and a human-readable name. +func (s *Stack) CreateNamedNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID) *tcpip.Error { + return s.createNIC(id, name, linkEP, true) +} + +// CreateDisabledNIC creates a NIC with the provided id and link-layer endpoint, +// but leave it disable. Stack.EnableNIC must be called before the link-layer +// endpoint starts delivering packets to it. +func (s *Stack) CreateDisabledNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error { + return s.createNIC(id, "", linkEP, false) +} + +// EnableNIC enables the given NIC so that the link-layer endpoint can start +// delivering packets to it. +func (s *Stack) EnableNIC(id tcpip.NICID) *tcpip.Error { + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[id] + if nic == nil { + return tcpip.ErrUnknownNICID + } + + nic.attachLinkEndpoint() + + return nil +} + +// NICSubnets returns a map of NICIDs to their associated subnets. +func (s *Stack) NICSubnets() map[tcpip.NICID][]tcpip.Subnet { + s.mu.RLock() + defer s.mu.RUnlock() + + nics := map[tcpip.NICID][]tcpip.Subnet{} + + for id, nic := range s.nics { + nics[id] = append(nics[id], nic.Subnets()...) + } + return nics +} + +// NICInfo captures the name and addresses assigned to a NIC. +type NICInfo struct { + Name string + LinkAddress tcpip.LinkAddress + ProtocolAddresses []tcpip.ProtocolAddress +} + +// NICInfo returns a map of NICIDs to their associated information. +func (s *Stack) NICInfo() map[tcpip.NICID]NICInfo { + s.mu.RLock() + defer s.mu.RUnlock() + + nics := make(map[tcpip.NICID]NICInfo) + for id, nic := range s.nics { + nics[id] = NICInfo{ + Name: nic.name, + LinkAddress: nic.linkEP.LinkAddress(), + ProtocolAddresses: nic.Addresses(), + } + } + return nics +} + +// AddAddress adds a new network-layer address to the specified NIC. +func (s *Stack) AddAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error { + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[id] + if nic == nil { + return tcpip.ErrUnknownNICID + } + + return nic.AddAddress(protocol, addr) +} + +// AddSubnet adds a subnet range to the specified NIC. +func (s *Stack) AddSubnet(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, subnet tcpip.Subnet) *tcpip.Error { + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[id] + if nic == nil { + return tcpip.ErrUnknownNICID + } + + nic.AddSubnet(protocol, subnet) + return nil +} + +// RemoveAddress removes an existing network-layer address from the specified +// NIC. +func (s *Stack) RemoveAddress(id tcpip.NICID, addr tcpip.Address) *tcpip.Error { + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[id] + if nic == nil { + return tcpip.ErrUnknownNICID + } + + return nic.RemoveAddress(addr) +} + +// FindRoute creates a route to the given destination address, leaving through +// the given nic and local address (if provided). +func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber) (Route, *tcpip.Error) { + s.mu.RLock() + defer s.mu.RUnlock() + + for i := range s.routeTable { + if (id != 0 && id != s.routeTable[i].NIC) || (len(remoteAddr) != 0 && !s.routeTable[i].Match(remoteAddr)) { + continue + } + + nic := s.nics[s.routeTable[i].NIC] + if nic == nil { + continue + } + + var ref *referencedNetworkEndpoint + if len(localAddr) != 0 { + ref = nic.findEndpoint(netProto, localAddr) + } else { + ref = nic.primaryEndpoint(netProto) + } + if ref == nil { + continue + } + + if len(remoteAddr) == 0 { + // If no remote address was provided, then the route + // provided will refer to the link local address. + remoteAddr = ref.ep.ID().LocalAddress + } + + r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, ref) + r.NextHop = s.routeTable[i].Gateway + return r, nil + } + + return Route{}, tcpip.ErrNoRoute +} + +// CheckNetworkProtocol checks if a given network protocol is enabled in the +// stack. +func (s *Stack) CheckNetworkProtocol(protocol tcpip.NetworkProtocolNumber) bool { + _, ok := s.networkProtocols[protocol] + return ok +} + +// CheckLocalAddress determines if the given local address exists, and if it +// does, returns the id of the NIC it's bound to. Returns 0 if the address +// does not exist. +func (s *Stack) CheckLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) tcpip.NICID { + s.mu.RLock() + defer s.mu.RUnlock() + + // If a NIC is specified, we try to find the address there only. + if nicid != 0 { + nic := s.nics[nicid] + if nic == nil { + return 0 + } + + ref := nic.findEndpoint(protocol, addr) + if ref == nil { + return 0 + } + + ref.decRef() + + return nic.id + } + + // Go through all the NICs. + for _, nic := range s.nics { + ref := nic.findEndpoint(protocol, addr) + if ref != nil { + ref.decRef() + return nic.id + } + } + + return 0 +} + +// SetPromiscuousMode enables or disables promiscuous mode in the given NIC. +func (s *Stack) SetPromiscuousMode(nicID tcpip.NICID, enable bool) *tcpip.Error { + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[nicID] + if nic == nil { + return tcpip.ErrUnknownNICID + } + + nic.setPromiscuousMode(enable) + + return nil +} + +// SetSpoofing enables or disables address spoofing in the given NIC, allowing +// endpoints to bind to any address in the NIC. +func (s *Stack) SetSpoofing(nicID tcpip.NICID, enable bool) *tcpip.Error { + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[nicID] + if nic == nil { + return tcpip.ErrUnknownNICID + } + + nic.setSpoofing(enable) + + return nil +} + +// AddLinkAddress adds a link address to the stack link cache. +func (s *Stack) AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress) { + fullAddr := tcpip.FullAddress{NIC: nicid, Addr: addr} + s.linkAddrCache.add(fullAddr, linkAddr) + // TODO: provide a way for a + // transport endpoint to receive a signal that AddLinkAddress + // for a particular address has been called. +} + +// GetLinkAddress implements LinkAddressCache.GetLinkAddress. +func (s *Stack) GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, waker *sleep.Waker) (tcpip.LinkAddress, *tcpip.Error) { + s.mu.RLock() + nic := s.nics[nicid] + if nic == nil { + s.mu.RUnlock() + return "", tcpip.ErrUnknownNICID + } + s.mu.RUnlock() + + fullAddr := tcpip.FullAddress{NIC: nicid, Addr: addr} + linkRes := s.linkAddrResolvers[protocol] + return s.linkAddrCache.get(fullAddr, linkRes, localAddr, nic.linkEP, waker) +} + +// RemoveWaker implements LinkAddressCache.RemoveWaker. +func (s *Stack) RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep.Waker) { + s.mu.RLock() + defer s.mu.RUnlock() + + if nic := s.nics[nicid]; nic == nil { + fullAddr := tcpip.FullAddress{NIC: nicid, Addr: addr} + s.linkAddrCache.removeWaker(fullAddr, waker) + } +} + +// RegisterTransportEndpoint registers the given endpoint with the stack +// transport dispatcher. Received packets that match the provided id will be +// delivered to the given endpoint; specifying a nic is optional, but +// nic-specific IDs have precedence over global ones. +func (s *Stack) RegisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint) *tcpip.Error { + if nicID == 0 { + return s.demux.registerEndpoint(netProtos, protocol, id, ep) + } + + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[nicID] + if nic == nil { + return tcpip.ErrUnknownNICID + } + + return nic.demux.registerEndpoint(netProtos, protocol, id, ep) +} + +// UnregisterTransportEndpoint removes the endpoint with the given id from the +// stack transport dispatcher. +func (s *Stack) UnregisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID) { + if nicID == 0 { + s.demux.unregisterEndpoint(netProtos, protocol, id) + return + } + + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[nicID] + if nic != nil { + nic.demux.unregisterEndpoint(netProtos, protocol, id) + } +} + +// NetworkProtocolInstance returns the protocol instance in the stack for the +// specified network protocol. This method is public for protocol implementers +// and tests to use. +func (s *Stack) NetworkProtocolInstance(num tcpip.NetworkProtocolNumber) NetworkProtocol { + if p, ok := s.networkProtocols[num]; ok { + return p + } + return nil +} + +// TransportProtocolInstance returns the protocol instance in the stack for the +// specified transport protocol. This method is public for protocol implementers +// and tests to use. +func (s *Stack) TransportProtocolInstance(num tcpip.TransportProtocolNumber) TransportProtocol { + if pState, ok := s.transportProtocols[num]; ok { + return pState.proto + } + return nil +} + +// AddTCPProbe installs a probe function that will be invoked on every segment +// received by a given TCP endpoint. The probe function is passed a copy of the +// TCP endpoint state. +// +// NOTE: TCPProbe is added only to endpoints created after this call. Endpoints +// created prior to this call will not call the probe function. +// +// Further, installing two different probes back to back can result in some +// endpoints calling the first one and some the second one. There is no +// guarantee provided on which probe will be invoked. Ideally this should only +// be called once per stack. +func (s *Stack) AddTCPProbe(probe TCPProbeFunc) { + s.mu.Lock() + s.tcpProbeFunc = probe + s.mu.Unlock() +} + +// GetTCPProbe returns the TCPProbeFunc if installed with AddTCPProbe, nil +// otherwise. +func (s *Stack) GetTCPProbe() TCPProbeFunc { + s.mu.Lock() + p := s.tcpProbeFunc + s.mu.Unlock() + return p +} + +// RemoveTCPProbe removes an installed TCP probe. +// +// NOTE: This only ensures that endpoints created after this call do not +// have a probe attached. Endpoints already created will continue to invoke +// TCP probe. +func (s *Stack) RemoveTCPProbe() { + s.mu.Lock() + s.tcpProbeFunc = nil + s.mu.Unlock() +} diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go new file mode 100644 index 000000000..030ae98d1 --- /dev/null +++ b/pkg/tcpip/stack/stack_global_state.go @@ -0,0 +1,9 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stack + +// StackFromEnv is the global stack created in restore run. +// FIXME: remove this variable once tcpip S/R is fully supported. +var StackFromEnv *Stack diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go new file mode 100644 index 000000000..b416065d7 --- /dev/null +++ b/pkg/tcpip/stack/stack_test.go @@ -0,0 +1,760 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package stack_test contains tests for the stack. It is in its own package so +// that the tests can also validate that all definitions needed to implement +// transport and network protocols are properly exported by the stack package. +package stack_test + +import ( + "math" + "testing" + + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" +) + +const ( + fakeNetNumber tcpip.NetworkProtocolNumber = math.MaxUint32 + fakeNetHeaderLen = 12 + + // fakeControlProtocol is used for control packets that represent + // destination port unreachable. + fakeControlProtocol tcpip.TransportProtocolNumber = 2 + + // defaultMTU is the MTU, in bytes, used throughout the tests, except + // where another value is explicitly used. It is chosen to match the MTU + // of loopback interfaces on linux systems. + defaultMTU = 65536 +) + +// fakeNetworkEndpoint is a network-layer protocol endpoint. It counts sent and +// received packets; the counts of all endpoints are aggregated in the protocol +// descriptor. +// +// Headers of this protocol are fakeNetHeaderLen bytes, but we currently only +// use the first three: destination address, source address, and transport +// protocol. They're all one byte fields to simplify parsing. +type fakeNetworkEndpoint struct { + nicid tcpip.NICID + id stack.NetworkEndpointID + proto *fakeNetworkProtocol + dispatcher stack.TransportDispatcher + linkEP stack.LinkEndpoint +} + +func (f *fakeNetworkEndpoint) MTU() uint32 { + return f.linkEP.MTU() - uint32(f.MaxHeaderLength()) +} + +func (f *fakeNetworkEndpoint) NICID() tcpip.NICID { + return f.nicid +} + +func (f *fakeNetworkEndpoint) ID() *stack.NetworkEndpointID { + return &f.id +} + +func (f *fakeNetworkEndpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { + // Increment the received packet count in the protocol descriptor. + f.proto.packetCount[int(f.id.LocalAddress[0])%len(f.proto.packetCount)]++ + + // Consume the network header. + b := vv.First() + vv.TrimFront(fakeNetHeaderLen) + + // Handle control packets. + if b[2] == uint8(fakeControlProtocol) { + nb := vv.First() + if len(nb) < fakeNetHeaderLen { + return + } + + vv.TrimFront(fakeNetHeaderLen) + f.dispatcher.DeliverTransportControlPacket(tcpip.Address(nb[1:2]), tcpip.Address(nb[0:1]), fakeNetNumber, tcpip.TransportProtocolNumber(nb[2]), stack.ControlPortUnreachable, 0, vv) + return + } + + // Dispatch the packet to the transport protocol. + f.dispatcher.DeliverTransportPacket(r, tcpip.TransportProtocolNumber(b[2]), vv) +} + +func (f *fakeNetworkEndpoint) MaxHeaderLength() uint16 { + return f.linkEP.MaxHeaderLength() + fakeNetHeaderLen +} + +func (f *fakeNetworkEndpoint) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, dstAddr tcpip.Address) uint16 { + return 0 +} + +func (f *fakeNetworkEndpoint) Capabilities() stack.LinkEndpointCapabilities { + return f.linkEP.Capabilities() +} + +func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error { + // Increment the sent packet count in the protocol descriptor. + f.proto.sendPacketCount[int(r.RemoteAddress[0])%len(f.proto.sendPacketCount)]++ + + // Add the protocol's header to the packet and send it to the link + // endpoint. + b := hdr.Prepend(fakeNetHeaderLen) + b[0] = r.RemoteAddress[0] + b[1] = f.id.LocalAddress[0] + b[2] = byte(protocol) + return f.linkEP.WritePacket(r, hdr, payload, fakeNetNumber) +} + +func (*fakeNetworkEndpoint) Close() {} + +type fakeNetGoodOption bool + +type fakeNetBadOption bool + +type fakeNetInvalidValueOption int + +type fakeNetOptions struct { + good bool +} + +// fakeNetworkProtocol is a network-layer protocol descriptor. It aggregates the +// number of packets sent and received via endpoints of this protocol. The index +// where packets are added is given by the packet's destination address MOD 10. +type fakeNetworkProtocol struct { + packetCount [10]int + sendPacketCount [10]int + opts fakeNetOptions +} + +func (f *fakeNetworkProtocol) Number() tcpip.NetworkProtocolNumber { + return fakeNetNumber +} + +func (f *fakeNetworkProtocol) MinimumPacketSize() int { + return fakeNetHeaderLen +} + +func (*fakeNetworkProtocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { + return tcpip.Address(v[1:2]), tcpip.Address(v[0:1]) +} + +func (f *fakeNetworkProtocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { + return &fakeNetworkEndpoint{ + nicid: nicid, + id: stack.NetworkEndpointID{addr}, + proto: f, + dispatcher: dispatcher, + linkEP: linkEP, + }, nil +} + +func (f *fakeNetworkProtocol) SetOption(option interface{}) *tcpip.Error { + switch v := option.(type) { + case fakeNetGoodOption: + f.opts.good = bool(v) + return nil + case fakeNetInvalidValueOption: + return tcpip.ErrInvalidOptionValue + default: + return tcpip.ErrUnknownProtocolOption + } +} + +func (f *fakeNetworkProtocol) Option(option interface{}) *tcpip.Error { + switch v := option.(type) { + case *fakeNetGoodOption: + *v = fakeNetGoodOption(f.opts.good) + return nil + default: + return tcpip.ErrUnknownProtocolOption + } +} + +func TestNetworkReceive(t *testing.T) { + // Create a stack with the fake network protocol, one nic, and two + // addresses attached to it: 1 & 2. + id, linkEP := channel.New(10, defaultMTU, "") + s := stack.New([]string{"fakeNet"}, nil) + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x02"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) + var views [1]buffer.View + // Allocate the buffer containing the packet that will be injected into + // the stack. + buf := buffer.NewView(30) + + // Make sure packet with wrong address is not delivered. + buf[0] = 3 + vv := buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 0 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0) + } + if fakeNet.packetCount[2] != 0 { + t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 0) + } + + // Make sure packet is delivered to first endpoint. + buf[0] = 1 + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } + if fakeNet.packetCount[2] != 0 { + t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 0) + } + + // Make sure packet is delivered to second endpoint. + buf[0] = 2 + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } + if fakeNet.packetCount[2] != 1 { + t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1) + } + + // Make sure packet is not delivered if protocol number is wrong. + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber-1, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } + if fakeNet.packetCount[2] != 1 { + t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1) + } + + // Make sure packet that is too small is dropped. + buf.CapLength(2) + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } + if fakeNet.packetCount[2] != 1 { + t.Errorf("packetCount[2] = %d, want %d", fakeNet.packetCount[2], 1) + } +} + +func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address) { + r, err := s.FindRoute(0, "", addr, fakeNetNumber) + if err != nil { + t.Fatalf("FindRoute failed: %v", err) + } + defer r.Release() + + hdr := buffer.NewPrependable(int(r.MaxHeaderLength())) + err = r.WritePacket(&hdr, nil, fakeTransNumber) + if err != nil { + t.Errorf("WritePacket failed: %v", err) + return + } +} + +func TestNetworkSend(t *testing.T) { + // Create a stack with the fake network protocol, one nic, and one + // address: 1. The route table sends all packets through the only + // existing nic. + id, linkEP := channel.New(10, defaultMTU, "") + s := stack.New([]string{"fakeNet"}, nil) + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("NewNIC failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{{"\x00", "\x00", "\x00", 1}}) + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + // Make sure that the link-layer endpoint received the outbound packet. + sendTo(t, s, "\x03") + if c := linkEP.Drain(); c != 1 { + t.Errorf("packetCount = %d, want %d", c, 1) + } +} + +func TestNetworkSendMultiRoute(t *testing.T) { + // Create a stack with the fake network protocol, two nics, and two + // addresses per nic, the first nic has odd address, the second one has + // even addresses. + s := stack.New([]string{"fakeNet"}, nil) + + id1, linkEP1 := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id1); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x03"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + id2, linkEP2 := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(2, id2); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + if err := s.AddAddress(2, fakeNetNumber, "\x04"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + // Set a route table that sends all packets with odd destination + // addresses through the first NIC, and all even destination address + // through the second one. + s.SetRouteTable([]tcpip.Route{ + {"\x01", "\x01", "\x00", 1}, + {"\x00", "\x01", "\x00", 2}, + }) + + // Send a packet to an odd destination. + sendTo(t, s, "\x05") + + if c := linkEP1.Drain(); c != 1 { + t.Errorf("packetCount = %d, want %d", c, 1) + } + + // Send a packet to an even destination. + sendTo(t, s, "\x06") + + if c := linkEP2.Drain(); c != 1 { + t.Errorf("packetCount = %d, want %d", c, 1) + } +} + +func testRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr, expectedSrcAddr tcpip.Address) { + r, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber) + if err != nil { + t.Fatalf("FindRoute failed: %v", err) + } + + defer r.Release() + + if r.LocalAddress != expectedSrcAddr { + t.Fatalf("Bad source address: expected %v, got %v", expectedSrcAddr, r.LocalAddress) + } + + if r.RemoteAddress != dstAddr { + t.Fatalf("Bad destination address: expected %v, got %v", dstAddr, r.RemoteAddress) + } +} + +func testNoRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr tcpip.Address) { + _, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber) + if err != tcpip.ErrNoRoute { + t.Fatalf("FindRoute returned unexpected error, expected tcpip.ErrNoRoute, got %v", err) + } +} + +func TestRoutes(t *testing.T) { + // Create a stack with the fake network protocol, two nics, and two + // addresses per nic, the first nic has odd address, the second one has + // even addresses. + s := stack.New([]string{"fakeNet"}, nil) + + id1, _ := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id1); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x03"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + id2, _ := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(2, id2); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + if err := s.AddAddress(2, fakeNetNumber, "\x04"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + // Set a route table that sends all packets with odd destination + // addresses through the first NIC, and all even destination address + // through the second one. + s.SetRouteTable([]tcpip.Route{ + {"\x01", "\x01", "\x00", 1}, + {"\x00", "\x01", "\x00", 2}, + }) + + // Test routes to odd address. + testRoute(t, s, 0, "", "\x05", "\x01") + testRoute(t, s, 0, "\x01", "\x05", "\x01") + testRoute(t, s, 1, "\x01", "\x05", "\x01") + testRoute(t, s, 0, "\x03", "\x05", "\x03") + testRoute(t, s, 1, "\x03", "\x05", "\x03") + + // Test routes to even address. + testRoute(t, s, 0, "", "\x06", "\x02") + testRoute(t, s, 0, "\x02", "\x06", "\x02") + testRoute(t, s, 2, "\x02", "\x06", "\x02") + testRoute(t, s, 0, "\x04", "\x06", "\x04") + testRoute(t, s, 2, "\x04", "\x06", "\x04") + + // Try to send to odd numbered address from even numbered ones, then + // vice-versa. + testNoRoute(t, s, 0, "\x02", "\x05") + testNoRoute(t, s, 2, "\x02", "\x05") + testNoRoute(t, s, 0, "\x04", "\x05") + testNoRoute(t, s, 2, "\x04", "\x05") + + testNoRoute(t, s, 0, "\x01", "\x06") + testNoRoute(t, s, 1, "\x01", "\x06") + testNoRoute(t, s, 0, "\x03", "\x06") + testNoRoute(t, s, 1, "\x03", "\x06") +} + +func TestAddressRemoval(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil) + + id, linkEP := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + var views [1]buffer.View + buf := buffer.NewView(30) + + fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) + + // Write a packet, and check that it gets delivered. + fakeNet.packetCount[1] = 0 + buf[0] = 1 + vv := buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } + + // Remove the address, then check that packet doesn't get delivered + // anymore. + if err := s.RemoveAddress(1, "\x01"); err != nil { + t.Fatalf("RemoveAddress failed: %v", err) + } + + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } + + // Check that removing the same address fails. + if err := s.RemoveAddress(1, "\x01"); err != tcpip.ErrBadLocalAddress { + t.Fatalf("RemoveAddress failed: %v", err) + } +} + +func TestDelayedRemovalDueToRoute(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil) + + id, linkEP := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{ + {"\x00", "\x00", "\x00", 1}, + }) + + fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) + + var views [1]buffer.View + buf := buffer.NewView(30) + + // Write a packet, and check that it gets delivered. + fakeNet.packetCount[1] = 0 + buf[0] = 1 + vv := buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } + + // Get a route, check that packet is still deliverable. + r, err := s.FindRoute(0, "", "\x02", fakeNetNumber) + if err != nil { + t.Fatalf("FindRoute failed: %v", err) + } + + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 2 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 2) + } + + // Remove the address, then check that packet is still deliverable + // because the route is keeping the address alive. + if err := s.RemoveAddress(1, "\x01"); err != nil { + t.Fatalf("RemoveAddress failed: %v", err) + } + + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 3 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 3) + } + + // Check that removing the same address fails. + if err := s.RemoveAddress(1, "\x01"); err != tcpip.ErrBadLocalAddress { + t.Fatalf("RemoveAddress failed: %v", err) + } + + // Release the route, then check that packet is not deliverable anymore. + r.Release() + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 3 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 3) + } +} + +func TestPromiscuousMode(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil) + + id, linkEP := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{ + {"\x00", "\x00", "\x00", 1}, + }) + + fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) + + var views [1]buffer.View + buf := buffer.NewView(30) + + // Write a packet, and check that it doesn't get delivered as we don't + // have a matching endpoint. + fakeNet.packetCount[1] = 0 + buf[0] = 1 + vv := buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 0 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0) + } + + // Set promiscuous mode, then check that packet is delivered. + if err := s.SetPromiscuousMode(1, true); err != nil { + t.Fatalf("SetPromiscuousMode failed: %v", err) + } + + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } + + // Check that we can't get a route as there is no local address. + _, err := s.FindRoute(0, "", "\x02", fakeNetNumber) + if err != tcpip.ErrNoRoute { + t.Fatalf("FindRoute returned unexpected status: expected %v, got %v", tcpip.ErrNoRoute, err) + } + + // Set promiscuous mode to false, then check that packet can't be + // delivered anymore. + if err := s.SetPromiscuousMode(1, false); err != nil { + t.Fatalf("SetPromiscuousMode failed: %v", err) + } + + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } +} + +func TestAddressSpoofing(t *testing.T) { + srcAddr := tcpip.Address("\x01") + dstAddr := tcpip.Address("\x02") + + s := stack.New([]string{"fakeNet"}, nil) + + id, _ := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, dstAddr); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{ + {"\x00", "\x00", "\x00", 1}, + }) + + // With address spoofing disabled, FindRoute does not permit an address + // that was not added to the NIC to be used as the source. + r, err := s.FindRoute(0, srcAddr, dstAddr, fakeNetNumber) + if err == nil { + t.Errorf("FindRoute succeeded with route %+v when it should have failed", r) + } + + // With address spoofing enabled, FindRoute permits any address to be used + // as the source. + if err := s.SetSpoofing(1, true); err != nil { + t.Fatalf("SetSpoofing failed: %v", err) + } + r, err = s.FindRoute(0, srcAddr, dstAddr, fakeNetNumber) + if err != nil { + t.Fatalf("FindRoute failed: %v", err) + } + if r.LocalAddress != srcAddr { + t.Errorf("Route has wrong local address: got %v, wanted %v", r.LocalAddress, srcAddr) + } + if r.RemoteAddress != dstAddr { + t.Errorf("Route has wrong remote address: got %v, wanted %v", r.RemoteAddress, dstAddr) + } +} + +// Set the subnet, then check that packet is delivered. +func TestSubnetAcceptsMatchingPacket(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil) + + id, linkEP := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{ + {"\x00", "\x00", "\x00", 1}, + }) + + fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) + + var views [1]buffer.View + buf := buffer.NewView(30) + buf[0] = 1 + fakeNet.packetCount[1] = 0 + subnet, err := tcpip.NewSubnet(tcpip.Address("\x00"), tcpip.AddressMask("\xF0")) + if err != nil { + t.Fatalf("NewSubnet failed: %v", err) + } + if err := s.AddSubnet(1, fakeNetNumber, subnet); err != nil { + t.Fatalf("AddSubnet failed: %v", err) + } + + vv := buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 1 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) + } +} + +// Set destination outside the subnet, then check it doesn't get delivered. +func TestSubnetRejectsNonmatchingPacket(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil) + + id, linkEP := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{ + {"\x00", "\x00", "\x00", 1}, + }) + + fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) + + var views [1]buffer.View + buf := buffer.NewView(30) + buf[0] = 1 + fakeNet.packetCount[1] = 0 + subnet, err := tcpip.NewSubnet(tcpip.Address("\x10"), tcpip.AddressMask("\xF0")) + if err != nil { + t.Fatalf("NewSubnet failed: %v", err) + } + if err := s.AddSubnet(1, fakeNetNumber, subnet); err != nil { + t.Fatalf("AddSubnet failed: %v", err) + } + vv := buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeNet.packetCount[1] != 0 { + t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0) + } +} + +func TestNetworkOptions(t *testing.T) { + s := stack.New([]string{"fakeNet"}, []string{}) + + // Try an unsupported network protocol. + if err := s.SetNetworkProtocolOption(tcpip.NetworkProtocolNumber(99999), fakeNetGoodOption(false)); err != tcpip.ErrUnknownProtocol { + t.Fatalf("SetNetworkProtocolOption(fakeNet2, blah, false) = %v, want = tcpip.ErrUnknownProtocol", err) + } + + testCases := []struct { + option interface{} + wantErr *tcpip.Error + verifier func(t *testing.T, p stack.NetworkProtocol) + }{ + {fakeNetGoodOption(true), nil, func(t *testing.T, p stack.NetworkProtocol) { + t.Helper() + fakeNet := p.(*fakeNetworkProtocol) + if fakeNet.opts.good != true { + t.Fatalf("fakeNet.opts.good = false, want = true") + } + var v fakeNetGoodOption + if err := s.NetworkProtocolOption(fakeNetNumber, &v); err != nil { + t.Fatalf("s.NetworkProtocolOption(fakeNetNumber, &v) = %v, want = nil, where v is option %T", v, err) + } + if v != true { + t.Fatalf("s.NetworkProtocolOption(fakeNetNumber, &v) returned v = %v, want = true", v) + } + }}, + {fakeNetBadOption(true), tcpip.ErrUnknownProtocolOption, nil}, + {fakeNetInvalidValueOption(1), tcpip.ErrInvalidOptionValue, nil}, + } + for _, tc := range testCases { + if got := s.SetNetworkProtocolOption(fakeNetNumber, tc.option); got != tc.wantErr { + t.Errorf("s.SetNetworkProtocolOption(fakeNet, %v) = %v, want = %v", tc.option, got, tc.wantErr) + } + if tc.verifier != nil { + tc.verifier(t, s.NetworkProtocolInstance(fakeNetNumber)) + } + } +} + +func init() { + stack.RegisterNetworkProtocolFactory("fakeNet", func() stack.NetworkProtocol { + return &fakeNetworkProtocol{} + }) +} diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go new file mode 100644 index 000000000..3c0d7aa31 --- /dev/null +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -0,0 +1,166 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stack + +import ( + "sync" + + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" +) + +type protocolIDs struct { + network tcpip.NetworkProtocolNumber + transport tcpip.TransportProtocolNumber +} + +// transportEndpoints manages all endpoints of a given protocol. It has its own +// mutex so as to reduce interference between protocols. +type transportEndpoints struct { + mu sync.RWMutex + endpoints map[TransportEndpointID]TransportEndpoint +} + +// transportDemuxer demultiplexes packets targeted at a transport endpoint +// (i.e., after they've been parsed by the network layer). It does two levels +// of demultiplexing: first based on the network and transport protocols, then +// based on endpoints IDs. +type transportDemuxer struct { + protocol map[protocolIDs]*transportEndpoints +} + +func newTransportDemuxer(stack *Stack) *transportDemuxer { + d := &transportDemuxer{protocol: make(map[protocolIDs]*transportEndpoints)} + + // Add each network and transport pair to the demuxer. + for netProto := range stack.networkProtocols { + for proto := range stack.transportProtocols { + d.protocol[protocolIDs{netProto, proto}] = &transportEndpoints{endpoints: make(map[TransportEndpointID]TransportEndpoint)} + } + } + + return d +} + +// registerEndpoint registers the given endpoint with the dispatcher such that +// packets that match the endpoint ID are delivered to it. +func (d *transportDemuxer) registerEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint) *tcpip.Error { + for i, n := range netProtos { + if err := d.singleRegisterEndpoint(n, protocol, id, ep); err != nil { + d.unregisterEndpoint(netProtos[:i], protocol, id) + return err + } + } + + return nil +} + +func (d *transportDemuxer) singleRegisterEndpoint(netProto tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint) *tcpip.Error { + eps, ok := d.protocol[protocolIDs{netProto, protocol}] + if !ok { + return nil + } + + eps.mu.Lock() + defer eps.mu.Unlock() + + if _, ok := eps.endpoints[id]; ok { + return tcpip.ErrPortInUse + } + + eps.endpoints[id] = ep + + return nil +} + +// unregisterEndpoint unregisters the endpoint with the given id such that it +// won't receive any more packets. +func (d *transportDemuxer) unregisterEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID) { + for _, n := range netProtos { + if eps, ok := d.protocol[protocolIDs{n, protocol}]; ok { + eps.mu.Lock() + delete(eps.endpoints, id) + eps.mu.Unlock() + } + } +} + +// deliverPacket attempts to deliver the given packet. Returns true if it found +// an endpoint, false otherwise. +func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView, id TransportEndpointID) bool { + eps, ok := d.protocol[protocolIDs{r.NetProto, protocol}] + if !ok { + return false + } + + eps.mu.RLock() + ep := d.findEndpointLocked(eps, vv, id) + eps.mu.RUnlock() + + // Fail if we didn't find one. + if ep == nil { + return false + } + + // Deliver the packet. + ep.HandlePacket(r, id, vv) + + return true +} + +// deliverControlPacket attempts to deliver the given control packet. Returns +// true if it found an endpoint, false otherwise. +func (d *transportDemuxer) deliverControlPacket(net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv *buffer.VectorisedView, id TransportEndpointID) bool { + eps, ok := d.protocol[protocolIDs{net, trans}] + if !ok { + return false + } + + // Try to find the endpoint. + eps.mu.RLock() + ep := d.findEndpointLocked(eps, vv, id) + eps.mu.RUnlock() + + // Fail if we didn't find one. + if ep == nil { + return false + } + + // Deliver the packet. + ep.HandleControlPacket(id, typ, extra, vv) + + return true +} + +func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv *buffer.VectorisedView, id TransportEndpointID) TransportEndpoint { + // Try to find a match with the id as provided. + if ep := eps.endpoints[id]; ep != nil { + return ep + } + + // Try to find a match with the id minus the local address. + nid := id + + nid.LocalAddress = "" + if ep := eps.endpoints[nid]; ep != nil { + return ep + } + + // Try to find a match with the id minus the remote part. + nid.LocalAddress = id.LocalAddress + nid.RemoteAddress = "" + nid.RemotePort = 0 + if ep := eps.endpoints[nid]; ep != nil { + return ep + } + + // Try to find a match with only the local port. + nid.LocalAddress = "" + if ep := eps.endpoints[nid]; ep != nil { + return ep + } + + return nil +} diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go new file mode 100644 index 000000000..7e072e96e --- /dev/null +++ b/pkg/tcpip/stack/transport_test.go @@ -0,0 +1,420 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stack_test + +import ( + "testing" + + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +const ( + fakeTransNumber tcpip.TransportProtocolNumber = 1 + fakeTransHeaderLen = 3 +) + +// fakeTransportEndpoint is a transport-layer protocol endpoint. It counts +// received packets; the counts of all endpoints are aggregated in the protocol +// descriptor. +// +// Headers of this protocol are fakeTransHeaderLen bytes, but we currently don't +// use it. +type fakeTransportEndpoint struct { + id stack.TransportEndpointID + stack *stack.Stack + netProto tcpip.NetworkProtocolNumber + proto *fakeTransportProtocol + peerAddr tcpip.Address + route stack.Route +} + +func newFakeTransportEndpoint(stack *stack.Stack, proto *fakeTransportProtocol, netProto tcpip.NetworkProtocolNumber) tcpip.Endpoint { + return &fakeTransportEndpoint{stack: stack, netProto: netProto, proto: proto} +} + +func (f *fakeTransportEndpoint) Close() { + f.route.Release() +} + +func (*fakeTransportEndpoint) Readiness(mask waiter.EventMask) waiter.EventMask { + return mask +} + +func (*fakeTransportEndpoint) Read(*tcpip.FullAddress) (buffer.View, *tcpip.Error) { + return buffer.View{}, nil +} + +func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tcpip.Error) { + if len(f.route.RemoteAddress) == 0 { + return 0, tcpip.ErrNoRoute + } + + hdr := buffer.NewPrependable(int(f.route.MaxHeaderLength())) + v, err := p.Get(p.Size()) + if err != nil { + return 0, err + } + if err := f.route.WritePacket(&hdr, v, fakeTransNumber); err != nil { + return 0, err + } + + return uintptr(len(v)), nil +} + +func (f *fakeTransportEndpoint) Peek([][]byte) (uintptr, *tcpip.Error) { + return 0, nil +} + +// SetSockOpt sets a socket option. Currently not supported. +func (*fakeTransportEndpoint) SetSockOpt(interface{}) *tcpip.Error { + return tcpip.ErrInvalidEndpointState +} + +// GetSockOpt implements tcpip.Endpoint.GetSockOpt. +func (*fakeTransportEndpoint) GetSockOpt(opt interface{}) *tcpip.Error { + switch opt.(type) { + case tcpip.ErrorOption: + return nil + } + return tcpip.ErrInvalidEndpointState +} + +func (f *fakeTransportEndpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { + f.peerAddr = addr.Addr + + // Find the route. + r, err := f.stack.FindRoute(addr.NIC, "", addr.Addr, fakeNetNumber) + if err != nil { + return tcpip.ErrNoRoute + } + defer r.Release() + + // Try to register so that we can start receiving packets. + f.id.RemoteAddress = addr.Addr + err = f.stack.RegisterTransportEndpoint(0, []tcpip.NetworkProtocolNumber{fakeNetNumber}, fakeTransNumber, f.id, f) + if err != nil { + return err + } + + f.route = r.Clone() + + return nil +} + +func (f *fakeTransportEndpoint) ConnectEndpoint(e tcpip.Endpoint) *tcpip.Error { + return nil +} + +func (*fakeTransportEndpoint) Shutdown(tcpip.ShutdownFlags) *tcpip.Error { + return nil +} + +func (*fakeTransportEndpoint) Reset() { +} + +func (*fakeTransportEndpoint) Listen(int) *tcpip.Error { + return nil +} + +func (*fakeTransportEndpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) { + return nil, nil, nil +} + +func (*fakeTransportEndpoint) Bind(_ tcpip.FullAddress, commit func() *tcpip.Error) *tcpip.Error { + return commit() +} + +func (*fakeTransportEndpoint) GetLocalAddress() (tcpip.FullAddress, *tcpip.Error) { + return tcpip.FullAddress{}, nil +} + +func (*fakeTransportEndpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) { + return tcpip.FullAddress{}, nil +} + +func (f *fakeTransportEndpoint) HandlePacket(*stack.Route, stack.TransportEndpointID, *buffer.VectorisedView) { + // Increment the number of received packets. + f.proto.packetCount++ +} + +func (f *fakeTransportEndpoint) HandleControlPacket(stack.TransportEndpointID, stack.ControlType, uint32, *buffer.VectorisedView) { + // Increment the number of received control packets. + f.proto.controlCount++ +} + +type fakeTransportGoodOption bool + +type fakeTransportBadOption bool + +type fakeTransportInvalidValueOption int + +type fakeTransportProtocolOptions struct { + good bool +} + +// fakeTransportProtocol is a transport-layer protocol descriptor. It +// aggregates the number of packets received via endpoints of this protocol. +type fakeTransportProtocol struct { + packetCount int + controlCount int + opts fakeTransportProtocolOptions +} + +func (*fakeTransportProtocol) Number() tcpip.TransportProtocolNumber { + return fakeTransNumber +} + +func (f *fakeTransportProtocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, _ *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + return newFakeTransportEndpoint(stack, f, netProto), nil +} + +func (*fakeTransportProtocol) MinimumPacketSize() int { + return fakeTransHeaderLen +} + +func (*fakeTransportProtocol) ParsePorts(buffer.View) (src, dst uint16, err *tcpip.Error) { + return 0, 0, nil +} + +func (*fakeTransportProtocol) HandleUnknownDestinationPacket(*stack.Route, stack.TransportEndpointID, *buffer.VectorisedView) bool { + return true +} + +func (f *fakeTransportProtocol) SetOption(option interface{}) *tcpip.Error { + switch v := option.(type) { + case fakeTransportGoodOption: + f.opts.good = bool(v) + return nil + case fakeTransportInvalidValueOption: + return tcpip.ErrInvalidOptionValue + default: + return tcpip.ErrUnknownProtocolOption + } +} + +func (f *fakeTransportProtocol) Option(option interface{}) *tcpip.Error { + switch v := option.(type) { + case *fakeTransportGoodOption: + *v = fakeTransportGoodOption(f.opts.good) + return nil + default: + return tcpip.ErrUnknownProtocolOption + } +} + +func TestTransportReceive(t *testing.T) { + id, linkEP := channel.New(10, defaultMTU, "") + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}) + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{{"\x00", "\x00", "\x00", 1}}) + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + // Create endpoint and connect to remote address. + wq := waiter.Queue{} + ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + + if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil { + t.Fatalf("Connect failed: %v", err) + } + + fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol) + + var views [1]buffer.View + // Create buffer that will hold the packet. + buf := buffer.NewView(30) + + // Make sure packet with wrong protocol is not delivered. + buf[0] = 1 + buf[2] = 0 + vv := buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeTrans.packetCount != 0 { + t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0) + } + + // Make sure packet from the wrong source is not delivered. + buf[0] = 1 + buf[1] = 3 + buf[2] = byte(fakeTransNumber) + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeTrans.packetCount != 0 { + t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0) + } + + // Make sure packet is delivered. + buf[0] = 1 + buf[1] = 2 + buf[2] = byte(fakeTransNumber) + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeTrans.packetCount != 1 { + t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 1) + } +} + +func TestTransportControlReceive(t *testing.T) { + id, linkEP := channel.New(10, defaultMTU, "") + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}) + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{{"\x00", "\x00", "\x00", 1}}) + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + // Create endpoint and connect to remote address. + wq := waiter.Queue{} + ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + + if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil { + t.Fatalf("Connect failed: %v", err) + } + + fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol) + + var views [1]buffer.View + // Create buffer that will hold the control packet. + buf := buffer.NewView(2*fakeNetHeaderLen + 30) + + // Outer packet contains the control protocol number. + buf[0] = 1 + buf[1] = 0xfe + buf[2] = uint8(fakeControlProtocol) + + // Make sure packet with wrong protocol is not delivered. + buf[fakeNetHeaderLen+0] = 0 + buf[fakeNetHeaderLen+1] = 1 + buf[fakeNetHeaderLen+2] = 0 + vv := buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeTrans.controlCount != 0 { + t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0) + } + + // Make sure packet from the wrong source is not delivered. + buf[fakeNetHeaderLen+0] = 3 + buf[fakeNetHeaderLen+1] = 1 + buf[fakeNetHeaderLen+2] = byte(fakeTransNumber) + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeTrans.controlCount != 0 { + t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0) + } + + // Make sure packet is delivered. + buf[fakeNetHeaderLen+0] = 2 + buf[fakeNetHeaderLen+1] = 1 + buf[fakeNetHeaderLen+2] = byte(fakeTransNumber) + vv = buf.ToVectorisedView(views) + linkEP.Inject(fakeNetNumber, &vv) + if fakeTrans.controlCount != 1 { + t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 1) + } +} + +func TestTransportSend(t *testing.T) { + id, _ := channel.New(10, defaultMTU, "") + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}) + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{{"\x00", "\x00", "\x00", 1}}) + + // Create endpoint and bind it. + wq := waiter.Queue{} + ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + + if err := ep.Connect(tcpip.FullAddress{0, "\x02", 0}); err != nil { + t.Fatalf("Connect failed: %v", err) + } + + // Create buffer that will hold the payload. + view := buffer.NewView(30) + _, err = ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}) + if err != nil { + t.Fatalf("write failed: %v", err) + } + + fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) + + if fakeNet.sendPacketCount[2] != 1 { + t.Errorf("sendPacketCount = %d, want %d", fakeNet.sendPacketCount[2], 1) + } +} + +func TestTransportOptions(t *testing.T) { + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}) + + // Try an unsupported transport protocol. + if err := s.SetTransportProtocolOption(tcpip.TransportProtocolNumber(99999), fakeTransportGoodOption(false)); err != tcpip.ErrUnknownProtocol { + t.Fatalf("SetTransportProtocolOption(fakeTrans2, blah, false) = %v, want = tcpip.ErrUnknownProtocol", err) + } + + testCases := []struct { + option interface{} + wantErr *tcpip.Error + verifier func(t *testing.T, p stack.TransportProtocol) + }{ + {fakeTransportGoodOption(true), nil, func(t *testing.T, p stack.TransportProtocol) { + t.Helper() + fakeTrans := p.(*fakeTransportProtocol) + if fakeTrans.opts.good != true { + t.Fatalf("fakeTrans.opts.good = false, want = true") + } + var v fakeTransportGoodOption + if err := s.TransportProtocolOption(fakeTransNumber, &v); err != nil { + t.Fatalf("s.TransportProtocolOption(fakeTransNumber, &v) = %v, want = nil, where v is option %T", v, err) + } + if v != true { + t.Fatalf("s.TransportProtocolOption(fakeTransNumber, &v) returned v = %v, want = true", v) + } + + }}, + {fakeTransportBadOption(true), tcpip.ErrUnknownProtocolOption, nil}, + {fakeTransportInvalidValueOption(1), tcpip.ErrInvalidOptionValue, nil}, + } + for _, tc := range testCases { + if got := s.SetTransportProtocolOption(fakeTransNumber, tc.option); got != tc.wantErr { + t.Errorf("s.SetTransportProtocolOption(fakeTrans, %v) = %v, want = %v", tc.option, got, tc.wantErr) + } + if tc.verifier != nil { + tc.verifier(t, s.TransportProtocolInstance(fakeTransNumber)) + } + } +} + +func init() { + stack.RegisterTransportProtocolFactory("fakeTrans", func() stack.TransportProtocol { + return &fakeTransportProtocol{} + }) +} -- cgit v1.2.3 From 3d3deef573a54e031cb98038b9f617f5fac31044 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Tue, 1 May 2018 22:11:07 -0700 Subject: Implement SO_TIMESTAMP PiperOrigin-RevId: 195047018 Change-Id: I6d99528a00a2125f414e1e51e067205289ec9d3d --- pkg/dhcp/client.go | 4 +- pkg/dhcp/dhcp_test.go | 2 +- pkg/dhcp/server.go | 2 +- pkg/sentry/fs/host/socket_test.go | 2 +- pkg/sentry/kernel/kernel.go | 9 +++ pkg/sentry/socket/BUILD | 1 + pkg/sentry/socket/control/control.go | 35 +++++++++++ pkg/sentry/socket/epsocket/epsocket.go | 69 +++++++++++++++------- pkg/sentry/socket/hostinet/socket.go | 10 ++-- pkg/sentry/socket/netlink/socket.go | 16 ++--- pkg/sentry/socket/rpcinet/socket.go | 20 +++---- pkg/sentry/socket/socket.go | 12 +++- pkg/sentry/socket/unix/unix.go | 14 ++--- pkg/sentry/strace/socket.go | 29 ++++++++- pkg/sentry/syscalls/linux/sys_socket.go | 21 ++++--- pkg/tcpip/adapters/gonet/gonet.go | 4 +- pkg/tcpip/adapters/gonet/gonet_test.go | 2 +- pkg/tcpip/network/arp/arp_test.go | 2 +- pkg/tcpip/network/ipv4/icmp_test.go | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 4 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 4 +- pkg/tcpip/stack/stack.go | 17 +++++- pkg/tcpip/stack/stack_test.go | 22 +++---- pkg/tcpip/stack/transport_test.go | 16 ++--- pkg/tcpip/tcpip.go | 48 +++++++++++++-- pkg/tcpip/transport/tcp/endpoint.go | 22 +++---- pkg/tcpip/transport/tcp/tcp_test.go | 46 +++++++-------- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 4 +- pkg/tcpip/transport/tcp/testing/context/context.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 37 ++++++++++-- pkg/tcpip/transport/udp/udp_test.go | 10 ++-- runsc/boot/loader.go | 7 ++- 32 files changed, 345 insertions(+), 150 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 9a4fd7ae4..37deb69ff 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -162,7 +162,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) error // DHCPOFFER for { var addr tcpip.FullAddress - v, err := epin.Read(&addr) + v, _, err := epin.Read(&addr) if err == tcpip.ErrWouldBlock { select { case <-ch: @@ -216,7 +216,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) error // DHCPACK for { var addr tcpip.FullAddress - v, err := epin.Read(&addr) + v, _, err := epin.Read(&addr) if err == tcpip.ErrWouldBlock { select { case <-ch: diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index d56b93997..ed884fcb6 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -36,7 +36,7 @@ func TestDHCP(t *testing.T) { } }() - s := stack.New([]string{ipv4.ProtocolName}, []string{udp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{udp.ProtocolName}) const nicid tcpip.NICID = 1 if err := s.CreateNIC(nicid, id); err != nil { diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index d132d90b4..8816203a8 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -104,7 +104,7 @@ func (s *Server) reader(ctx context.Context) { for { var addr tcpip.FullAddress - v, err := s.ep.Read(&addr) + v, _, err := s.ep.Read(&addr) if err == tcpip.ErrWouldBlock { select { case <-ch: diff --git a/pkg/sentry/fs/host/socket_test.go b/pkg/sentry/fs/host/socket_test.go index 80c46dcfa..9b73c5173 100644 --- a/pkg/sentry/fs/host/socket_test.go +++ b/pkg/sentry/fs/host/socket_test.go @@ -142,7 +142,7 @@ func TestSocketSendMsgLen0(t *testing.T) { defer sfile.DecRef() s := sfile.FileOperations.(socket.Socket) - n, terr := s.SendMsg(nil, usermem.BytesIOSequence(nil), []byte{}, 0, unix.ControlMessages{}) + n, terr := s.SendMsg(nil, usermem.BytesIOSequence(nil), []byte{}, 0, socket.ControlMessages{}) if n != 0 { t.Fatalf("socket sendmsg() failed: %v wrote: %d", terr, n) } diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 0932965e0..25c8dd885 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -887,6 +887,15 @@ func (k *Kernel) SetExitError(err error) { } } +// NowNanoseconds implements tcpip.Clock.NowNanoseconds. +func (k *Kernel) NowNanoseconds() int64 { + now, err := k.timekeeper.GetTime(sentrytime.Realtime) + if err != nil { + panic("Kernel.NowNanoseconds: " + err.Error()) + } + return now +} + // SupervisorContext returns a Context with maximum privileges in k. It should // only be used by goroutines outside the control of the emulated kernel // defined by e. diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD index 87e32df37..5500a676e 100644 --- a/pkg/sentry/socket/BUILD +++ b/pkg/sentry/socket/BUILD @@ -32,6 +32,7 @@ go_library( "//pkg/sentry/usermem", "//pkg/state", "//pkg/syserr", + "//pkg/tcpip", "//pkg/tcpip/transport/unix", ], ) diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index cb34cbc85..17ecdd11c 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -208,6 +208,31 @@ func putCmsg(buf []byte, msgType uint32, align uint, data []int32) []byte { return alignSlice(buf, align) } +func putCmsgStruct(buf []byte, msgType uint32, align uint, data interface{}) []byte { + if cap(buf)-len(buf) < linux.SizeOfControlMessageHeader { + return buf + } + ob := buf + + buf = putUint64(buf, uint64(linux.SizeOfControlMessageHeader)) + buf = putUint32(buf, linux.SOL_SOCKET) + buf = putUint32(buf, msgType) + + hdrBuf := buf + + buf = binary.Marshal(buf, usermem.ByteOrder, data) + + // Check if we went over. + if cap(buf) != cap(ob) { + return hdrBuf + } + + // Fix up length. + putUint64(ob, uint64(len(buf)-len(ob))) + + return alignSlice(buf, align) +} + // Credentials implements SCMCredentials.Credentials. func (c *scmCredentials) Credentials(t *kernel.Task) (kernel.ThreadID, auth.UID, auth.GID) { // "When a process's user and group IDs are passed over a UNIX domain @@ -261,6 +286,16 @@ func alignSlice(buf []byte, align uint) []byte { return buf[:aligned] } +// PackTimestamp packs a SO_TIMESTAMP socket control message. +func PackTimestamp(t *kernel.Task, timestamp int64, buf []byte) []byte { + return putCmsgStruct( + buf, + linux.SO_TIMESTAMP, + t.Arch().Width(), + linux.NsecToTimeval(timestamp), + ) +} + // Parse parses a raw socket control message into portable objects. func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte) (unix.ControlMessages, error) { var ( diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 3fc3ea58f..5701ecfac 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -109,6 +109,7 @@ type SocketOperations struct { // readMu protects access to readView, control, and sender. readMu sync.Mutex `state:"nosave"` readView buffer.View + readCM tcpip.ControlMessages sender tcpip.FullAddress } @@ -210,12 +211,13 @@ func (s *SocketOperations) fetchReadView() *syserr.Error { s.readView = nil s.sender = tcpip.FullAddress{} - v, err := s.Endpoint.Read(&s.sender) + v, cms, err := s.Endpoint.Read(&s.sender) if err != nil { return syserr.TranslateNetstackError(err) } s.readView = v + s.readCM = cms return nil } @@ -230,7 +232,7 @@ func (s *SocketOperations) Read(ctx context.Context, _ *fs.File, dst usermem.IOS if dst.NumBytes() == 0 { return 0, nil } - n, _, _, err := s.nonBlockingRead(ctx, dst, false, false, false) + n, _, _, _, err := s.nonBlockingRead(ctx, dst, false, false, false) if err == syserr.ErrWouldBlock { return int64(n), syserror.ErrWouldBlock } @@ -552,6 +554,18 @@ func GetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, } return linux.NsecToTimeval(s.RecvTimeout()), nil + + case linux.SO_TIMESTAMP: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + + var v tcpip.TimestampOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + return int32(v), nil } case syscall.SOL_TCP: @@ -659,6 +673,14 @@ func SetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, level int, n binary.Unmarshal(optVal[:linux.SizeOfTimeval], usermem.ByteOrder, &v) s.SetRecvTimeout(v.ToNsecCapped()) return nil + + case linux.SO_TIMESTAMP: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.TimestampOption(v))) } case syscall.SOL_TCP: @@ -823,7 +845,9 @@ func (s *SocketOperations) coalescingRead(ctx context.Context, dst usermem.IOSeq } // nonBlockingRead issues a non-blocking read. -func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSequence, peek, trunc, senderRequested bool) (int, interface{}, uint32, *syserr.Error) { +// +// TODO: Support timestamps for stream sockets. +func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSequence, peek, trunc, senderRequested bool) (int, interface{}, uint32, socket.ControlMessages, *syserr.Error) { isPacket := s.isPacketBased() // Fast path for regular reads from stream (e.g., TCP) endpoints. Note @@ -839,14 +863,14 @@ func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSe s.readMu.Lock() n, err := s.coalescingRead(ctx, dst, trunc) s.readMu.Unlock() - return n, nil, 0, err + return n, nil, 0, socket.ControlMessages{}, err } s.readMu.Lock() defer s.readMu.Unlock() if err := s.fetchReadView(); err != nil { - return 0, nil, 0, err + return 0, nil, 0, socket.ControlMessages{}, err } if !isPacket && peek && trunc { @@ -854,14 +878,14 @@ func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSe // amount that could be read. var rql tcpip.ReceiveQueueSizeOption if err := s.Endpoint.GetSockOpt(&rql); err != nil { - return 0, nil, 0, syserr.TranslateNetstackError(err) + return 0, nil, 0, socket.ControlMessages{}, syserr.TranslateNetstackError(err) } available := len(s.readView) + int(rql) bufLen := int(dst.NumBytes()) if available < bufLen { - return available, nil, 0, nil + return available, nil, 0, socket.ControlMessages{}, nil } - return bufLen, nil, 0, nil + return bufLen, nil, 0, socket.ControlMessages{}, nil } n, err := dst.CopyOut(ctx, s.readView) @@ -874,17 +898,18 @@ func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSe if peek { if l := len(s.readView); trunc && l > n { // isPacket must be true. - return l, addr, addrLen, syserr.FromError(err) + return l, addr, addrLen, socket.ControlMessages{IP: s.readCM}, syserr.FromError(err) } if isPacket || err != nil { - return int(n), addr, addrLen, syserr.FromError(err) + return int(n), addr, addrLen, socket.ControlMessages{IP: s.readCM}, syserr.FromError(err) } // We need to peek beyond the first message. dst = dst.DropFirst(n) num, err := dst.CopyOutFrom(ctx, safemem.FromVecReaderFunc{func(dsts [][]byte) (int64, error) { - n, err := s.Endpoint.Peek(dsts) + n, _, err := s.Endpoint.Peek(dsts) + // TODO: Handle peek timestamp. if err != nil { return int64(n), syserr.TranslateNetstackError(err).ToError() } @@ -895,7 +920,7 @@ func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSe // We got some data, so no need to return an error. err = nil } - return int(n), nil, 0, syserr.FromError(err) + return int(n), nil, 0, socket.ControlMessages{IP: s.readCM}, syserr.FromError(err) } var msgLen int @@ -908,15 +933,15 @@ func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSe } if trunc { - return msgLen, addr, addrLen, syserr.FromError(err) + return msgLen, addr, addrLen, socket.ControlMessages{IP: s.readCM}, syserr.FromError(err) } - return int(n), addr, addrLen, syserr.FromError(err) + return int(n), addr, addrLen, socket.ControlMessages{IP: s.readCM}, syserr.FromError(err) } // RecvMsg implements the linux syscall recvmsg(2) for sockets backed by // tcpip.Endpoint. -func (s *SocketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (n int, senderAddr interface{}, senderAddrLen uint32, controlMessages unix.ControlMessages, err *syserr.Error) { +func (s *SocketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (n int, senderAddr interface{}, senderAddrLen uint32, controlMessages socket.ControlMessages, err *syserr.Error) { trunc := flags&linux.MSG_TRUNC != 0 peek := flags&linux.MSG_PEEK != 0 @@ -924,7 +949,7 @@ func (s *SocketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags // Stream sockets ignore the sender address. senderRequested = false } - n, senderAddr, senderAddrLen, err = s.nonBlockingRead(t, dst, peek, trunc, senderRequested) + n, senderAddr, senderAddrLen, controlMessages, err = s.nonBlockingRead(t, dst, peek, trunc, senderRequested) if err != syserr.ErrWouldBlock || flags&linux.MSG_DONTWAIT != 0 { return } @@ -936,25 +961,25 @@ func (s *SocketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags defer s.EventUnregister(&e) for { - n, senderAddr, senderAddrLen, err = s.nonBlockingRead(t, dst, peek, trunc, senderRequested) + n, senderAddr, senderAddrLen, controlMessages, err = s.nonBlockingRead(t, dst, peek, trunc, senderRequested) if err != syserr.ErrWouldBlock { return } if err := t.BlockWithDeadline(ch, haveDeadline, deadline); err != nil { if err == syserror.ETIMEDOUT { - return 0, nil, 0, unix.ControlMessages{}, syserr.ErrTryAgain + return 0, nil, 0, socket.ControlMessages{}, syserr.ErrTryAgain } - return 0, nil, 0, unix.ControlMessages{}, syserr.FromError(err) + return 0, nil, 0, socket.ControlMessages{}, syserr.FromError(err) } } } // SendMsg implements the linux syscall sendmsg(2) for sockets backed by // tcpip.Endpoint. -func (s *SocketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages unix.ControlMessages) (int, *syserr.Error) { - // Reject control messages. - if !controlMessages.Empty() { +func (s *SocketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages socket.ControlMessages) (int, *syserr.Error) { + // Reject Unix control messages. + if !controlMessages.Unix.Empty() { return 0, syserr.ErrInvalidArgument } diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index defa3db2c..02fad1c60 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -57,6 +57,8 @@ type socketOperations struct { queue waiter.Queue } +var _ = socket.Socket(&socketOperations{}) + func newSocketFile(ctx context.Context, fd int, nonblock bool) (*fs.File, *syserr.Error) { s := &socketOperations{fd: fd} if err := fdnotifier.AddFD(int32(fd), &s.queue); err != nil { @@ -339,14 +341,14 @@ func (s *socketOperations) SetSockOpt(t *kernel.Task, level int, name int, opt [ } // RecvMsg implements socket.Socket.RecvMsg. -func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (int, interface{}, uint32, unix.ControlMessages, *syserr.Error) { +func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (int, interface{}, uint32, socket.ControlMessages, *syserr.Error) { // Whitelist flags. // // FIXME: We can't support MSG_ERRQUEUE because it uses ancillary // messages that netstack/tcpip/transport/unix doesn't understand. Kill the // Socket interface's dependence on netstack. if flags&^(syscall.MSG_DONTWAIT|syscall.MSG_PEEK|syscall.MSG_TRUNC) != 0 { - return 0, nil, 0, unix.ControlMessages{}, syserr.ErrInvalidArgument + return 0, nil, 0, socket.ControlMessages{}, syserr.ErrInvalidArgument } var senderAddr []byte @@ -411,11 +413,11 @@ func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags } } - return int(n), senderAddr, uint32(len(senderAddr)), unix.ControlMessages{}, syserr.FromError(err) + return int(n), senderAddr, uint32(len(senderAddr)), socket.ControlMessages{}, syserr.FromError(err) } // SendMsg implements socket.Socket.SendMsg. -func (s *socketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages unix.ControlMessages) (int, *syserr.Error) { +func (s *socketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages socket.ControlMessages) (int, *syserr.Error) { // Whitelist flags. if flags&^(syscall.MSG_DONTWAIT|syscall.MSG_EOR|syscall.MSG_FASTOPEN|syscall.MSG_MORE|syscall.MSG_NOSIGNAL) != 0 { return 0, syserr.ErrInvalidArgument diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index 2d0e59ceb..0b8f528d0 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -305,7 +305,7 @@ func (s *Socket) GetPeerName(t *kernel.Task) (interface{}, uint32, *syserr.Error } // RecvMsg implements socket.Socket.RecvMsg. -func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (int, interface{}, uint32, unix.ControlMessages, *syserr.Error) { +func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (int, interface{}, uint32, socket.ControlMessages, *syserr.Error) { from := linux.SockAddrNetlink{ Family: linux.AF_NETLINK, PortID: 0, @@ -323,7 +323,7 @@ func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, have if trunc { n = int64(r.MsgSize) } - return int(n), from, fromLen, unix.ControlMessages{}, syserr.FromError(err) + return int(n), from, fromLen, socket.ControlMessages{}, syserr.FromError(err) } // We'll have to block. Register for notification and keep trying to @@ -337,14 +337,14 @@ func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, have if trunc { n = int64(r.MsgSize) } - return int(n), from, fromLen, unix.ControlMessages{}, syserr.FromError(err) + return int(n), from, fromLen, socket.ControlMessages{}, syserr.FromError(err) } if err := t.BlockWithDeadline(ch, haveDeadline, deadline); err != nil { if err == syserror.ETIMEDOUT { - return 0, nil, 0, unix.ControlMessages{}, syserr.ErrTryAgain + return 0, nil, 0, socket.ControlMessages{}, syserr.ErrTryAgain } - return 0, nil, 0, unix.ControlMessages{}, syserr.FromError(err) + return 0, nil, 0, socket.ControlMessages{}, syserr.FromError(err) } } } @@ -459,7 +459,7 @@ func (s *Socket) processMessages(ctx context.Context, buf []byte) *syserr.Error } // sendMsg is the core of message send, used for SendMsg and Write. -func (s *Socket) sendMsg(ctx context.Context, src usermem.IOSequence, to []byte, flags int, controlMessages unix.ControlMessages) (int, *syserr.Error) { +func (s *Socket) sendMsg(ctx context.Context, src usermem.IOSequence, to []byte, flags int, controlMessages socket.ControlMessages) (int, *syserr.Error) { dstPort := int32(0) if len(to) != 0 { @@ -506,12 +506,12 @@ func (s *Socket) sendMsg(ctx context.Context, src usermem.IOSequence, to []byte, } // SendMsg implements socket.Socket.SendMsg. -func (s *Socket) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages unix.ControlMessages) (int, *syserr.Error) { +func (s *Socket) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages socket.ControlMessages) (int, *syserr.Error) { return s.sendMsg(t, src, to, flags, controlMessages) } // Write implements fs.FileOperations.Write. func (s *Socket) Write(ctx context.Context, _ *fs.File, src usermem.IOSequence, _ int64) (int64, error) { - n, err := s.sendMsg(ctx, src, nil, 0, unix.ControlMessages{}) + n, err := s.sendMsg(ctx, src, nil, 0, socket.ControlMessages{}) return int64(n), err.ToError() } diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index 574d99ba5..15047df01 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -402,7 +402,7 @@ func rpcRecvMsg(t *kernel.Task, req *pb.SyscallRequest_Recvmsg) (*pb.RecvmsgResp } // RecvMsg implements socket.Socket.RecvMsg. -func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (int, interface{}, uint32, unix.ControlMessages, *syserr.Error) { +func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (int, interface{}, uint32, socket.ControlMessages, *syserr.Error) { req := &pb.SyscallRequest_Recvmsg{&pb.RecvmsgRequest{ Fd: s.fd, Length: uint32(dst.NumBytes()), @@ -414,10 +414,10 @@ func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags res, err := rpcRecvMsg(t, req) if err == nil { n, e := dst.CopyOut(t, res.Data) - return int(n), res.Address.GetAddress(), res.Address.GetLength(), unix.ControlMessages{}, syserr.FromError(e) + return int(n), res.Address.GetAddress(), res.Address.GetLength(), socket.ControlMessages{}, syserr.FromError(e) } if err != syserr.ErrWouldBlock || flags&linux.MSG_DONTWAIT != 0 { - return 0, nil, 0, unix.ControlMessages{}, err + return 0, nil, 0, socket.ControlMessages{}, err } // We'll have to block. Register for notifications and keep trying to @@ -430,17 +430,17 @@ func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags res, err := rpcRecvMsg(t, req) if err == nil { n, e := dst.CopyOut(t, res.Data) - return int(n), res.Address.GetAddress(), res.Address.GetLength(), unix.ControlMessages{}, syserr.FromError(e) + return int(n), res.Address.GetAddress(), res.Address.GetLength(), socket.ControlMessages{}, syserr.FromError(e) } if err != syserr.ErrWouldBlock { - return 0, nil, 0, unix.ControlMessages{}, err + return 0, nil, 0, socket.ControlMessages{}, err } if err := t.BlockWithDeadline(ch, haveDeadline, deadline); err != nil { if err == syserror.ETIMEDOUT { - return 0, nil, 0, unix.ControlMessages{}, syserr.ErrTryAgain + return 0, nil, 0, socket.ControlMessages{}, syserr.ErrTryAgain } - return 0, nil, 0, unix.ControlMessages{}, syserr.FromError(err) + return 0, nil, 0, socket.ControlMessages{}, syserr.FromError(err) } } } @@ -459,14 +459,14 @@ func rpcSendMsg(t *kernel.Task, req *pb.SyscallRequest_Sendmsg) (uint32, *syserr } // SendMsg implements socket.Socket.SendMsg. -func (s *socketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages unix.ControlMessages) (int, *syserr.Error) { +func (s *socketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages socket.ControlMessages) (int, *syserr.Error) { // Whitelist flags. if flags&^(syscall.MSG_DONTWAIT|syscall.MSG_EOR|syscall.MSG_FASTOPEN|syscall.MSG_MORE|syscall.MSG_NOSIGNAL) != 0 { return 0, syserr.ErrInvalidArgument } - // Reject control messages. - if !controlMessages.Empty() { + // Reject Unix control messages. + if !controlMessages.Unix.Empty() { return 0, syserr.ErrInvalidArgument } diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index be3026bfa..bd4858a34 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -31,9 +31,17 @@ import ( ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserr" + "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix" ) +// ControlMessages represents the union of unix control messages and tcpip +// control messages. +type ControlMessages struct { + Unix unix.ControlMessages + IP tcpip.ControlMessages +} + // Socket is the interface containing socket syscalls used by the syscall layer // to redirect them to the appropriate implementation. type Socket interface { @@ -78,11 +86,11 @@ type Socket interface { // // senderAddrLen is the address length to be returned to the application, // not necessarily the actual length of the address. - RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (n int, senderAddr interface{}, senderAddrLen uint32, controlMessages unix.ControlMessages, err *syserr.Error) + RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (n int, senderAddr interface{}, senderAddrLen uint32, controlMessages ControlMessages, err *syserr.Error) // SendMsg implements the sendmsg(2) linux syscall. SendMsg does not take // ownership of the ControlMessage on error. - SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages unix.ControlMessages) (n int, err *syserr.Error) + SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages ControlMessages) (n int, err *syserr.Error) // SetRecvTimeout sets the timeout (in ns) for recv operations. Zero means // no timeout. diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index a4b414851..f83156c8e 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -358,10 +358,10 @@ func (s *SocketOperations) Write(ctx context.Context, _ *fs.File, src usermem.IO // SendMsg implements the linux syscall sendmsg(2) for unix sockets backed by // a unix.Endpoint. -func (s *SocketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages unix.ControlMessages) (int, *syserr.Error) { +func (s *SocketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, controlMessages socket.ControlMessages) (int, *syserr.Error) { w := EndpointWriter{ Endpoint: s.ep, - Control: controlMessages, + Control: controlMessages.Unix, To: nil, } if len(to) > 0 { @@ -452,7 +452,7 @@ func (s *SocketOperations) Read(ctx context.Context, _ *fs.File, dst usermem.IOS // RecvMsg implements the linux syscall recvmsg(2) for sockets backed by // a unix.Endpoint. -func (s *SocketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (n int, senderAddr interface{}, senderAddrLen uint32, controlMessages unix.ControlMessages, err *syserr.Error) { +func (s *SocketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (n int, senderAddr interface{}, senderAddrLen uint32, controlMessages socket.ControlMessages, err *syserr.Error) { trunc := flags&linux.MSG_TRUNC != 0 peek := flags&linux.MSG_PEEK != 0 @@ -490,7 +490,7 @@ func (s *SocketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags if trunc { n = int64(r.MsgSize) } - return int(n), from, fromLen, r.Control, syserr.FromError(err) + return int(n), from, fromLen, socket.ControlMessages{Unix: r.Control}, syserr.FromError(err) } // We'll have to block. Register for notification and keep trying to @@ -509,14 +509,14 @@ func (s *SocketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags if trunc { n = int64(r.MsgSize) } - return int(n), from, fromLen, r.Control, syserr.FromError(err) + return int(n), from, fromLen, socket.ControlMessages{Unix: r.Control}, syserr.FromError(err) } if err := t.BlockWithDeadline(ch, haveDeadline, deadline); err != nil { if err == syserror.ETIMEDOUT { - return 0, nil, 0, unix.ControlMessages{}, syserr.ErrTryAgain + return 0, nil, 0, socket.ControlMessages{}, syserr.ErrTryAgain } - return 0, nil, 0, unix.ControlMessages{}, syserr.FromError(err) + return 0, nil, 0, socket.ControlMessages{}, syserr.FromError(err) } } } diff --git a/pkg/sentry/strace/socket.go b/pkg/sentry/strace/socket.go index 48c072e96..1a2e8573e 100644 --- a/pkg/sentry/strace/socket.go +++ b/pkg/sentry/strace/socket.go @@ -440,6 +440,7 @@ var SocketProtocol = map[int32]abi.ValueSet{ var controlMessageType = map[int32]string{ linux.SCM_RIGHTS: "SCM_RIGHTS", linux.SCM_CREDENTIALS: "SCM_CREDENTIALS", + linux.SO_TIMESTAMP: "SO_TIMESTAMP", } func cmsghdr(t *kernel.Task, addr usermem.Addr, length uint64, maxBytes uint64) string { @@ -477,7 +478,7 @@ func cmsghdr(t *kernel.Task, addr usermem.Addr, length uint64, maxBytes uint64) typ = fmt.Sprint(h.Type) } - if h.Length > uint64(len(buf)-i) { + if h.Length > uint64(len(buf)-i+linux.SizeOfControlMessageHeader) { strs = append(strs, fmt.Sprintf( "{level=%s, type=%s, length=%d, content extends beyond buffer}", level, @@ -546,6 +547,32 @@ func cmsghdr(t *kernel.Task, addr usermem.Addr, length uint64, maxBytes uint64) i += control.AlignUp(length, width) + case linux.SO_TIMESTAMP: + if length < linux.SizeOfTimeval { + strs = append(strs, fmt.Sprintf( + "{level=%s, type=%s, length=%d, content too short}", + level, + typ, + h.Length, + )) + i += control.AlignUp(length, width) + break + } + + var tv linux.Timeval + binary.Unmarshal(buf[i:i+linux.SizeOfTimeval], usermem.ByteOrder, &tv) + + strs = append(strs, fmt.Sprintf( + "{level=%s, type=%s, length=%d, Sec: %d, Usec: %d}", + level, + typ, + h.Length, + tv.Sec, + tv.Usec, + )) + + i += control.AlignUp(length, width) + default: panic("unreachable") } diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go index 70c618398..6258a1539 100644 --- a/pkg/sentry/syscalls/linux/sys_socket.go +++ b/pkg/sentry/syscalls/linux/sys_socket.go @@ -731,10 +731,11 @@ func recvSingleMsg(t *kernel.Task, s socket.Socket, msgPtr usermem.Addr, flags i // Fast path when no control message nor name buffers are provided. if msg.ControlLen == 0 && msg.NameLen == 0 { - n, _, _, _, err := s.RecvMsg(t, dst, int(flags), haveDeadline, deadline, false, 0) + n, _, _, cms, err := s.RecvMsg(t, dst, int(flags), haveDeadline, deadline, false, 0) if err != nil { return 0, syserror.ConvertIntr(err.ToError(), kernel.ERESTARTSYS) } + cms.Unix.Release() return uintptr(n), nil } @@ -745,17 +746,21 @@ func recvSingleMsg(t *kernel.Task, s socket.Socket, msgPtr usermem.Addr, flags i if e != nil { return 0, syserror.ConvertIntr(e.ToError(), kernel.ERESTARTSYS) } - defer cms.Release() + defer cms.Unix.Release() controlData := make([]byte, 0, msg.ControlLen) if cr, ok := s.(unix.Credentialer); ok && cr.Passcred() { - creds, _ := cms.Credentials.(control.SCMCredentials) + creds, _ := cms.Unix.Credentials.(control.SCMCredentials) controlData = control.PackCredentials(t, creds, controlData) } - if cms.Rights != nil { - controlData = control.PackRights(t, cms.Rights.(control.SCMRights), flags&linux.MSG_CMSG_CLOEXEC != 0, controlData) + if cms.IP.HasTimestamp { + controlData = control.PackTimestamp(t, cms.IP.Timestamp, controlData) + } + + if cms.Unix.Rights != nil { + controlData = control.PackRights(t, cms.Unix.Rights.(control.SCMRights), flags&linux.MSG_CMSG_CLOEXEC != 0, controlData) } // Copy the address to the caller. @@ -823,7 +828,7 @@ func recvFrom(t *kernel.Task, fd kdefs.FD, bufPtr usermem.Addr, bufLen uint64, f } n, sender, senderLen, cm, e := s.RecvMsg(t, dst, int(flags), haveDeadline, deadline, nameLenPtr != 0, 0) - cm.Release() + cm.Unix.Release() if e != nil { return 0, syserror.ConvertIntr(e.ToError(), kernel.ERESTARTSYS) } @@ -997,7 +1002,7 @@ func sendSingleMsg(t *kernel.Task, s socket.Socket, file *fs.File, msgPtr userme } // Call the syscall implementation. - n, e := s.SendMsg(t, src, to, int(flags), controlMessages) + n, e := s.SendMsg(t, src, to, int(flags), socket.ControlMessages{Unix: controlMessages}) err = handleIOError(t, n != 0, e.ToError(), kernel.ERESTARTSYS, "sendmsg", file) if err != nil { controlMessages.Release() @@ -1048,7 +1053,7 @@ func sendTo(t *kernel.Task, fd kdefs.FD, bufPtr usermem.Addr, bufLen uint64, fla } // Call the syscall implementation. - n, e := s.SendMsg(t, src, to, int(flags), control.New(t, s, nil)) + n, e := s.SendMsg(t, src, to, int(flags), socket.ControlMessages{Unix: control.New(t, s, nil)}) return uintptr(n), handleIOError(t, n != 0, e.ToError(), kernel.ERESTARTSYS, "sendto", file) } diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index 96a2d670d..5aa6b1aa2 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -268,7 +268,7 @@ type opErrorer interface { // commonRead implements the common logic between net.Conn.Read and // net.PacketConn.ReadFrom. func commonRead(ep tcpip.Endpoint, wq *waiter.Queue, deadline <-chan struct{}, addr *tcpip.FullAddress, errorer opErrorer) ([]byte, error) { - read, err := ep.Read(addr) + read, _, err := ep.Read(addr) if err == tcpip.ErrWouldBlock { // Create wait queue entry that notifies a channel. @@ -276,7 +276,7 @@ func commonRead(ep tcpip.Endpoint, wq *waiter.Queue, deadline <-chan struct{}, a wq.EventRegister(&waitEntry, waiter.EventIn) defer wq.EventUnregister(&waitEntry) for { - read, err = ep.Read(addr) + read, _, err = ep.Read(addr) if err != tcpip.ErrWouldBlock { break } diff --git a/pkg/tcpip/adapters/gonet/gonet_test.go b/pkg/tcpip/adapters/gonet/gonet_test.go index 2f86469eb..e3d0c6c84 100644 --- a/pkg/tcpip/adapters/gonet/gonet_test.go +++ b/pkg/tcpip/adapters/gonet/gonet_test.go @@ -47,7 +47,7 @@ func TestTimeouts(t *testing.T) { func newLoopbackStack() (*stack.Stack, *tcpip.Error) { // Create the stack and add a NIC. - s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName, udp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName, udp.ProtocolName}) if err := s.CreateNIC(NICID, loopback.New()); err != nil { return nil, err diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index 91ffdce4b..47b10e64e 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -32,7 +32,7 @@ type testContext struct { } func newTestContext(t *testing.T) *testContext { - s := stack.New([]string{ipv4.ProtocolName, arp.ProtocolName}, []string{ipv4.PingProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, arp.ProtocolName}, []string{ipv4.PingProtocolName}) const defaultMTU = 65536 id, linkEP := channel.New(256, defaultMTU, stackLinkAddr) diff --git a/pkg/tcpip/network/ipv4/icmp_test.go b/pkg/tcpip/network/ipv4/icmp_test.go index 378fba74b..c55aa1835 100644 --- a/pkg/tcpip/network/ipv4/icmp_test.go +++ b/pkg/tcpip/network/ipv4/icmp_test.go @@ -26,7 +26,7 @@ type testContext struct { } func newTestContext(t *testing.T) *testContext { - s := stack.New([]string{ipv4.ProtocolName}, []string{ipv4.PingProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{ipv4.PingProtocolName}) const defaultMTU = 65536 id, linkEP := channel.New(256, defaultMTU, "") diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index 332929c85..ef5c7ec60 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -113,7 +113,7 @@ func main() { // Create the stack with ipv4 and tcp protocols, then add a tun-based // NIC and ipv4 address. - s := stack.New([]string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) mtu, err := rawfile.GetMTU(tunName) if err != nil { @@ -183,7 +183,7 @@ func main() { // connection from its side. wq.EventRegister(&waitEntry, waiter.EventIn) for { - v, err := ep.Read(nil) + v, _, err := ep.Read(nil) if err != nil { if err == tcpip.ErrClosedForReceive { break diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index 10cd701af..8c166f643 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -42,7 +42,7 @@ func echo(wq *waiter.Queue, ep tcpip.Endpoint) { defer wq.EventUnregister(&waitEntry) for { - v, err := ep.Read(nil) + v, _, err := ep.Read(nil) if err != nil { if err == tcpip.ErrWouldBlock { <-notifyCh @@ -99,7 +99,7 @@ func main() { // Create the stack with ip and tcp protocols, then add a tun-based // NIC and address. - s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName}, []string{tcp.ProtocolName}) mtu, err := rawfile.GetMTU(tunName) if err != nil { diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 558ecdb72..b480bf812 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -270,6 +270,9 @@ type Stack struct { // If not nil, then any new endpoints will have this probe function // invoked everytime they receive a TCP segment. tcpProbeFunc TCPProbeFunc + + // clock is used to generate user-visible times. + clock tcpip.Clock } // New allocates a new networking stack with only the requested networking and @@ -279,7 +282,7 @@ type Stack struct { // SetNetworkProtocolOption/SetTransportProtocolOption methods provided by the // stack. Please refer to individual protocol implementations as to what options // are supported. -func New(network []string, transport []string) *Stack { +func New(clock tcpip.Clock, network []string, transport []string) *Stack { s := &Stack{ transportProtocols: make(map[tcpip.TransportProtocolNumber]*transportProtocolState), networkProtocols: make(map[tcpip.NetworkProtocolNumber]NetworkProtocol), @@ -287,6 +290,7 @@ func New(network []string, transport []string) *Stack { nics: make(map[tcpip.NICID]*NIC), linkAddrCache: newLinkAddrCache(ageLimit, resolutionTimeout, resolutionAttempts), PortManager: ports.NewPortManager(), + clock: clock, } // Add specified network protocols. @@ -388,6 +392,11 @@ func (s *Stack) SetTransportProtocolHandler(p tcpip.TransportProtocolNumber, h f } } +// NowNanoseconds implements tcpip.Clock.NowNanoseconds. +func (s *Stack) NowNanoseconds() int64 { + return s.clock.NowNanoseconds() +} + // Stats returns a snapshot of the current stats. // // NOTE: The underlying stats are updated using atomic instructions as a result @@ -474,6 +483,12 @@ func (s *Stack) CreateDisabledNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) * return s.createNIC(id, "", linkEP, false) } +// CreateDisabledNamedNIC is a combination of CreateNamedNIC and +// CreateDisabledNIC. +func (s *Stack) CreateDisabledNamedNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID) *tcpip.Error { + return s.createNIC(id, name, linkEP, false) +} + // EnableNIC enables the given NIC so that the link-layer endpoint can start // delivering packets to it. func (s *Stack) EnableNIC(id tcpip.NICID) *tcpip.Error { diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index b416065d7..ea7dccdc2 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -176,7 +176,7 @@ func TestNetworkReceive(t *testing.T) { // Create a stack with the fake network protocol, one nic, and two // addresses attached to it: 1 & 2. id, linkEP := channel.New(10, defaultMTU, "") - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("CreateNIC failed: %v", err) } @@ -270,7 +270,7 @@ func TestNetworkSend(t *testing.T) { // address: 1. The route table sends all packets through the only // existing nic. id, linkEP := channel.New(10, defaultMTU, "") - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("NewNIC failed: %v", err) } @@ -292,7 +292,7 @@ func TestNetworkSendMultiRoute(t *testing.T) { // Create a stack with the fake network protocol, two nics, and two // addresses per nic, the first nic has odd address, the second one has // even addresses. - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) id1, linkEP1 := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id1); err != nil { @@ -371,7 +371,7 @@ func TestRoutes(t *testing.T) { // Create a stack with the fake network protocol, two nics, and two // addresses per nic, the first nic has odd address, the second one has // even addresses. - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) id1, _ := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id1); err != nil { @@ -435,7 +435,7 @@ func TestRoutes(t *testing.T) { } func TestAddressRemoval(t *testing.T) { - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -479,7 +479,7 @@ func TestAddressRemoval(t *testing.T) { } func TestDelayedRemovalDueToRoute(t *testing.T) { - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -547,7 +547,7 @@ func TestDelayedRemovalDueToRoute(t *testing.T) { } func TestPromiscuousMode(t *testing.T) { - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -607,7 +607,7 @@ func TestAddressSpoofing(t *testing.T) { srcAddr := tcpip.Address("\x01") dstAddr := tcpip.Address("\x02") - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) id, _ := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -648,7 +648,7 @@ func TestAddressSpoofing(t *testing.T) { // Set the subnet, then check that packet is delivered. func TestSubnetAcceptsMatchingPacket(t *testing.T) { - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -682,7 +682,7 @@ func TestSubnetAcceptsMatchingPacket(t *testing.T) { // Set destination outside the subnet, then check it doesn't get delivered. func TestSubnetRejectsNonmatchingPacket(t *testing.T) { - s := stack.New([]string{"fakeNet"}, nil) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -714,7 +714,7 @@ func TestSubnetRejectsNonmatchingPacket(t *testing.T) { } func TestNetworkOptions(t *testing.T) { - s := stack.New([]string{"fakeNet"}, []string{}) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{}) // Try an unsupported network protocol. if err := s.SetNetworkProtocolOption(tcpip.NetworkProtocolNumber(99999), fakeNetGoodOption(false)); err != tcpip.ErrUnknownProtocol { diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 7e072e96e..b870ab375 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -46,8 +46,8 @@ func (*fakeTransportEndpoint) Readiness(mask waiter.EventMask) waiter.EventMask return mask } -func (*fakeTransportEndpoint) Read(*tcpip.FullAddress) (buffer.View, *tcpip.Error) { - return buffer.View{}, nil +func (*fakeTransportEndpoint) Read(*tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) { + return buffer.View{}, tcpip.ControlMessages{}, nil } func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tcpip.Error) { @@ -67,8 +67,8 @@ func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) return uintptr(len(v)), nil } -func (f *fakeTransportEndpoint) Peek([][]byte) (uintptr, *tcpip.Error) { - return 0, nil +func (f *fakeTransportEndpoint) Peek([][]byte) (uintptr, tcpip.ControlMessages, *tcpip.Error) { + return 0, tcpip.ControlMessages{}, nil } // SetSockOpt sets a socket option. Currently not supported. @@ -210,7 +210,7 @@ func (f *fakeTransportProtocol) Option(option interface{}) *tcpip.Error { func TestTransportReceive(t *testing.T) { id, linkEP := channel.New(10, defaultMTU, "") - s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{"fakeTrans"}) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("CreateNIC failed: %v", err) } @@ -270,7 +270,7 @@ func TestTransportReceive(t *testing.T) { func TestTransportControlReceive(t *testing.T) { id, linkEP := channel.New(10, defaultMTU, "") - s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{"fakeTrans"}) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("CreateNIC failed: %v", err) } @@ -336,7 +336,7 @@ func TestTransportControlReceive(t *testing.T) { func TestTransportSend(t *testing.T) { id, _ := channel.New(10, defaultMTU, "") - s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{"fakeTrans"}) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("CreateNIC failed: %v", err) } @@ -373,7 +373,7 @@ func TestTransportSend(t *testing.T) { } func TestTransportOptions(t *testing.T) { - s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}) + s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{"fakeTrans"}) // Try an unsupported transport protocol. if err := s.SetTransportProtocolOption(tcpip.TransportProtocolNumber(99999), fakeTransportGoodOption(false)); err != tcpip.ErrUnknownProtocol { diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index f3a94f353..f9df1d989 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -23,6 +23,7 @@ import ( "fmt" "strconv" "strings" + "time" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/waiter" @@ -80,6 +81,24 @@ var ( errSubnetAddressMasked = errors.New("subnet address has bits set outside the mask") ) +// A Clock provides the current time. +// +// Times returned by a Clock should always be used for application-visible +// time, but never for netstack internal timekeeping. +type Clock interface { + // NowNanoseconds returns the current real time as a number of + // nanoseconds since some epoch. + NowNanoseconds() int64 +} + +// StdClock implements Clock with the time package. +type StdClock struct{} + +// NowNanoseconds implements Clock.NowNanoseconds. +func (*StdClock) NowNanoseconds() int64 { + return time.Now().UnixNano() +} + // Address is a byte slice cast as a string that represents the address of a // network node. Or, in the case of unix endpoints, it may represent a path. type Address string @@ -210,6 +229,16 @@ func (s SlicePayload) Size() int { return len(s) } +// A ControlMessages contains socket control messages for IP sockets. +type ControlMessages struct { + // HasTimestamp indicates whether Timestamp is valid/set. + HasTimestamp bool + + // Timestamp is the time (in ns) that the last packed used to create + // the read data was received. + Timestamp int64 +} + // Endpoint is the interface implemented by transport protocols (e.g., tcp, udp) // that exposes functionality like read, write, connect, etc. to users of the // networking stack. @@ -219,9 +248,13 @@ type Endpoint interface { Close() // Read reads data from the endpoint and optionally returns the sender. - // This method does not block if there is no data pending. - // It will also either return an error or data, never both. - Read(*FullAddress) (buffer.View, *Error) + // + // This method does not block if there is no data pending. It will also + // either return an error or data, never both. + // + // A timestamp (in ns) is optionally returned. A zero value indicates + // that no timestamp was available. + Read(*FullAddress) (buffer.View, ControlMessages, *Error) // Write writes data to the endpoint's peer. This method does not block if // the data cannot be written. @@ -238,7 +271,10 @@ type Endpoint interface { // Peek reads data without consuming it from the endpoint. // // This method does not block if there is no data pending. - Peek([][]byte) (uintptr, *Error) + // + // A timestamp (in ns) is optionally returned. A zero value indicates + // that no timestamp was available. + Peek([][]byte) (uintptr, ControlMessages, *Error) // Connect connects the endpoint to its peer. Specifying a NIC is // optional. @@ -347,6 +383,10 @@ type ReuseAddressOption int // Only supported on Unix sockets. type PasscredOption int +// TimestampOption is used by SetSockOpt/GetSockOpt to specify whether +// SO_TIMESTAMP socket control messages are enabled. +type TimestampOption int + // TCPInfoOption is used by GetSockOpt to expose TCP statistics. // // TODO: Add and populate stat fields. diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 5d62589d8..d84171b0c 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -374,7 +374,7 @@ func (e *endpoint) cleanup() { } // Read reads data from the endpoint. -func (e *endpoint) Read(*tcpip.FullAddress) (buffer.View, *tcpip.Error) { +func (e *endpoint) Read(*tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) { e.mu.RLock() // The endpoint can be read if it's connected, or if it's already closed // but has some pending unread data. Also note that a RST being received @@ -383,9 +383,9 @@ func (e *endpoint) Read(*tcpip.FullAddress) (buffer.View, *tcpip.Error) { if s := e.state; s != stateConnected && s != stateClosed && e.rcvBufUsed == 0 { e.mu.RUnlock() if s == stateError { - return buffer.View{}, e.hardError + return buffer.View{}, tcpip.ControlMessages{}, e.hardError } - return buffer.View{}, tcpip.ErrInvalidEndpointState + return buffer.View{}, tcpip.ControlMessages{}, tcpip.ErrInvalidEndpointState } e.rcvListMu.Lock() @@ -394,7 +394,7 @@ func (e *endpoint) Read(*tcpip.FullAddress) (buffer.View, *tcpip.Error) { e.mu.RUnlock() - return v, err + return v, tcpip.ControlMessages{}, err } func (e *endpoint) readLocked() (buffer.View, *tcpip.Error) { @@ -498,7 +498,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // Peek reads data without consuming it from the endpoint. // // This method does not block if there is no data pending. -func (e *endpoint) Peek(vec [][]byte) (uintptr, *tcpip.Error) { +func (e *endpoint) Peek(vec [][]byte) (uintptr, tcpip.ControlMessages, *tcpip.Error) { e.mu.RLock() defer e.mu.RUnlock() @@ -506,9 +506,9 @@ func (e *endpoint) Peek(vec [][]byte) (uintptr, *tcpip.Error) { // but has some pending unread data. if s := e.state; s != stateConnected && s != stateClosed { if s == stateError { - return 0, e.hardError + return 0, tcpip.ControlMessages{}, e.hardError } - return 0, tcpip.ErrInvalidEndpointState + return 0, tcpip.ControlMessages{}, tcpip.ErrInvalidEndpointState } e.rcvListMu.Lock() @@ -516,9 +516,9 @@ func (e *endpoint) Peek(vec [][]byte) (uintptr, *tcpip.Error) { if e.rcvBufUsed == 0 { if e.rcvClosed || e.state != stateConnected { - return 0, tcpip.ErrClosedForReceive + return 0, tcpip.ControlMessages{}, tcpip.ErrClosedForReceive } - return 0, tcpip.ErrWouldBlock + return 0, tcpip.ControlMessages{}, tcpip.ErrWouldBlock } // Make a copy of vec so we can modify the slide headers. @@ -534,7 +534,7 @@ func (e *endpoint) Peek(vec [][]byte) (uintptr, *tcpip.Error) { for len(v) > 0 { if len(vec) == 0 { - return num, nil + return num, tcpip.ControlMessages{}, nil } if len(vec[0]) == 0 { vec = vec[1:] @@ -549,7 +549,7 @@ func (e *endpoint) Peek(vec [][]byte) (uintptr, *tcpip.Error) { } } - return num, nil + return num, tcpip.ControlMessages{}, nil } // zeroReceiveWindow checks if the receive window to be announced now would be diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index 118d861ba..3c21a1ec3 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -147,7 +147,7 @@ func TestSimpleReceive(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventIn) defer c.WQ.EventUnregister(&we) - if _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { + if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { t.Fatalf("Unexpected error from Read: %v", err) } @@ -169,7 +169,7 @@ func TestSimpleReceive(t *testing.T) { } // Receive data. - v, err := c.EP.Read(nil) + v, _, err := c.EP.Read(nil) if err != nil { t.Fatalf("Unexpected error from Read: %v", err) } @@ -199,7 +199,7 @@ func TestOutOfOrderReceive(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventIn) defer c.WQ.EventUnregister(&we) - if _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { + if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { t.Fatalf("Unexpected error from Read: %v", err) } @@ -226,7 +226,7 @@ func TestOutOfOrderReceive(t *testing.T) { // Wait 200ms and check that no data has been received. time.Sleep(200 * time.Millisecond) - if _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { + if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { t.Fatalf("Unexpected error from Read: %v", err) } @@ -243,7 +243,7 @@ func TestOutOfOrderReceive(t *testing.T) { // Receive data. read := make([]byte, 0, 6) for len(read) < len(data) { - v, err := c.EP.Read(nil) + v, _, err := c.EP.Read(nil) if err != nil { if err == tcpip.ErrWouldBlock { // Wait for receive to be notified. @@ -284,7 +284,7 @@ func TestOutOfOrderFlood(t *testing.T) { opt := tcpip.ReceiveBufferSizeOption(10) c.CreateConnected(789, 30000, &opt) - if _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { + if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { t.Fatalf("Unexpected error from Read: %v", err) } @@ -361,7 +361,7 @@ func TestRstOnCloseWithUnreadData(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventIn) defer c.WQ.EventUnregister(&we) - if _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { + if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { t.Fatalf("Unexpected error from Read: %v", err) } @@ -414,7 +414,7 @@ func TestFullWindowReceive(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventIn) defer c.WQ.EventUnregister(&we) - _, err := c.EP.Read(nil) + _, _, err := c.EP.Read(nil) if err != tcpip.ErrWouldBlock { t.Fatalf("Unexpected error from Read: %v", err) } @@ -449,7 +449,7 @@ func TestFullWindowReceive(t *testing.T) { ) // Receive data and check it. - v, err := c.EP.Read(nil) + v, _, err := c.EP.Read(nil) if err != nil { t.Fatalf("Unexpected error from Read: %v", err) } @@ -487,7 +487,7 @@ func TestNoWindowShrinking(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventIn) defer c.WQ.EventUnregister(&we) - _, err := c.EP.Read(nil) + _, _, err := c.EP.Read(nil) if err != tcpip.ErrWouldBlock { t.Fatalf("Unexpected error from Read: %v", err) } @@ -551,7 +551,7 @@ func TestNoWindowShrinking(t *testing.T) { // Receive data and check it. read := make([]byte, 0, 10) for len(read) < len(data) { - v, err := c.EP.Read(nil) + v, _, err := c.EP.Read(nil) if err != nil { t.Fatalf("Unexpected error from Read: %v", err) } @@ -954,7 +954,7 @@ func TestZeroScaledWindowReceive(t *testing.T) { } // Read some data. An ack should be sent in response to that. - v, err := c.EP.Read(nil) + v, _, err := c.EP.Read(nil) if err != nil { t.Fatalf("Unexpected error from Read: %v", err) } @@ -1337,7 +1337,7 @@ func TestReceiveOnResetConnection(t *testing.T) { loop: for { - switch _, err := c.EP.Read(nil); err { + switch _, _, err := c.EP.Read(nil); err { case nil: t.Fatalf("Unexpected success.") case tcpip.ErrWouldBlock: @@ -2293,7 +2293,7 @@ func TestReadAfterClosedState(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventIn) defer c.WQ.EventUnregister(&we) - if _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { + if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { t.Fatalf("Unexpected error from Read: %v", err) } @@ -2345,7 +2345,7 @@ func TestReadAfterClosedState(t *testing.T) { // Check that peek works. peekBuf := make([]byte, 10) - n, err := c.EP.Peek([][]byte{peekBuf}) + n, _, err := c.EP.Peek([][]byte{peekBuf}) if err != nil { t.Fatalf("Unexpected error from Peek: %v", err) } @@ -2356,7 +2356,7 @@ func TestReadAfterClosedState(t *testing.T) { } // Receive data. - v, err := c.EP.Read(nil) + v, _, err := c.EP.Read(nil) if err != nil { t.Fatalf("Unexpected error from Read: %v", err) } @@ -2367,11 +2367,11 @@ func TestReadAfterClosedState(t *testing.T) { // Now that we drained the queue, check that functions fail with the // right error code. - if _, err := c.EP.Read(nil); err != tcpip.ErrClosedForReceive { + if _, _, err := c.EP.Read(nil); err != tcpip.ErrClosedForReceive { t.Fatalf("Unexpected return from Read: got %v, want %v", err, tcpip.ErrClosedForReceive) } - if _, err := c.EP.Peek([][]byte{peekBuf}); err != tcpip.ErrClosedForReceive { + if _, _, err := c.EP.Peek([][]byte{peekBuf}); err != tcpip.ErrClosedForReceive { t.Fatalf("Unexpected return from Peek: got %v, want %v", err, tcpip.ErrClosedForReceive) } } @@ -2479,7 +2479,7 @@ func checkSendBufferSize(t *testing.T, ep tcpip.Endpoint, v int) { } func TestDefaultBufferSizes(t *testing.T) { - s := stack.New([]string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) // Check the default values. ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{}) @@ -2525,7 +2525,7 @@ func TestDefaultBufferSizes(t *testing.T) { } func TestMinMaxBufferSizes(t *testing.T) { - s := stack.New([]string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) // Check the default values. ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{}) @@ -2575,7 +2575,7 @@ func TestSelfConnect(t *testing.T) { // it checks that if an endpoint binds to say 127.0.0.1:1000 then // connects to 127.0.0.1:1000, then it will be connected to itself, and // is able to send and receive data through the same endpoint. - s := stack.New([]string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) id := loopback.New() if testing.Verbose() { @@ -2637,13 +2637,13 @@ func TestSelfConnect(t *testing.T) { // Read back what was written. wq.EventUnregister(&waitEntry) wq.EventRegister(&waitEntry, waiter.EventIn) - rd, err := ep.Read(nil) + rd, _, err := ep.Read(nil) if err != nil { if err != tcpip.ErrWouldBlock { t.Fatalf("Read failed: %v", err) } <-notifyCh - rd, err = ep.Read(nil) + rd, _, err = ep.Read(nil) if err != nil { t.Fatalf("Read failed: %v", err) } diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index d12081bb7..335262e43 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -95,7 +95,7 @@ func TestTimeStampEnabledConnect(t *testing.T) { // There should be 5 views to read and each of them should // contain the same data. for i := 0; i < 5; i++ { - got, err := c.EP.Read(nil) + got, _, err := c.EP.Read(nil) if err != nil { t.Fatalf("Unexpected error from Read: %v", err) } @@ -296,7 +296,7 @@ func TestSegmentDropWhenTimestampMissing(t *testing.T) { } // Issue a read and we should data. - got, err := c.EP.Read(nil) + got, _, err := c.EP.Read(nil) if err != nil { t.Fatalf("Unexpected error from Read: %v", err) } diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 6a402d150..eb928553f 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -129,7 +129,7 @@ type Context struct { // New allocates and initializes a test context containing a new // stack and a link-layer endpoint. func New(t *testing.T, mtu uint32) *Context { - s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName}) // Allow minimum send/receive buffer sizes to be 1 during tests. if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SendBufferSizeOption{1, tcp.DefaultBufferSize, tcp.DefaultBufferSize * 10}); err != nil { diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 80fa88c4c..f86fc6d5a 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -19,6 +19,8 @@ type udpPacket struct { udpPacketEntry senderAddress tcpip.FullAddress data buffer.VectorisedView `state:".(buffer.VectorisedView)"` + timestamp int64 + hasTimestamp bool // views is used as buffer for data when its length is large // enough to store a VectorisedView. views [8]buffer.View `state:"nosave"` @@ -52,6 +54,7 @@ type endpoint struct { rcvBufSizeMax int `state:".(int)"` rcvBufSize int rcvClosed bool + rcvTimestamp bool // The following fields are protected by the mu mutex. mu sync.RWMutex `state:"nosave"` @@ -134,7 +137,7 @@ func (e *endpoint) Close() { // Read reads data from the endpoint. This method does not block if // there is no data pending. -func (e *endpoint) Read(addr *tcpip.FullAddress) (buffer.View, *tcpip.Error) { +func (e *endpoint) Read(addr *tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) { e.rcvMu.Lock() if e.rcvList.Empty() { @@ -143,12 +146,13 @@ func (e *endpoint) Read(addr *tcpip.FullAddress) (buffer.View, *tcpip.Error) { err = tcpip.ErrClosedForReceive } e.rcvMu.Unlock() - return buffer.View{}, err + return buffer.View{}, tcpip.ControlMessages{}, err } p := e.rcvList.Front() e.rcvList.Remove(p) e.rcvBufSize -= p.data.Size() + ts := e.rcvTimestamp e.rcvMu.Unlock() @@ -156,7 +160,12 @@ func (e *endpoint) Read(addr *tcpip.FullAddress) (buffer.View, *tcpip.Error) { *addr = p.senderAddress } - return p.data.ToView(), nil + if ts && !p.hasTimestamp { + // Linux uses the current time. + p.timestamp = e.stack.NowNanoseconds() + } + + return p.data.ToView(), tcpip.ControlMessages{HasTimestamp: ts, Timestamp: p.timestamp}, nil } // prepareForWrite prepares the endpoint for sending data. In particular, it @@ -299,8 +308,8 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc } // Peek only returns data from a single datagram, so do nothing here. -func (e *endpoint) Peek([][]byte) (uintptr, *tcpip.Error) { - return 0, nil +func (e *endpoint) Peek([][]byte) (uintptr, tcpip.ControlMessages, *tcpip.Error) { + return 0, tcpip.ControlMessages{}, nil } // SetSockOpt sets a socket option. Currently not supported. @@ -322,6 +331,11 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { } e.v6only = v != 0 + + case tcpip.TimestampOption: + e.rcvMu.Lock() + e.rcvTimestamp = v != 0 + e.rcvMu.Unlock() } return nil } @@ -370,6 +384,14 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { } e.rcvMu.Unlock() return nil + + case *tcpip.TimestampOption: + e.rcvMu.Lock() + *o = 0 + if e.rcvTimestamp { + *o = 1 + } + e.rcvMu.Unlock() } return tcpip.ErrUnknownProtocolOption @@ -733,6 +755,11 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv e.rcvList.PushBack(pkt) e.rcvBufSize += vv.Size() + if e.rcvTimestamp { + pkt.timestamp = e.stack.NowNanoseconds() + pkt.hasTimestamp = true + } + e.rcvMu.Unlock() // Notify any waiters that there's data to be read now. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 65c567952..1eb9ecb80 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -56,7 +56,7 @@ type headers struct { } func newDualTestContext(t *testing.T, mtu uint32) *testContext { - s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{udp.ProtocolName}) + s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{udp.ProtocolName}) id, linkEP := channel.New(256, mtu, "") if testing.Verbose() { @@ -260,12 +260,12 @@ func testV4Read(c *testContext) { defer c.wq.EventUnregister(&we) var addr tcpip.FullAddress - v, err := c.ep.Read(&addr) + v, _, err := c.ep.Read(&addr) if err == tcpip.ErrWouldBlock { // Wait for data to become available. select { case <-ch: - v, err = c.ep.Read(&addr) + v, _, err = c.ep.Read(&addr) if err != nil { c.t.Fatalf("Read failed: %v", err) } @@ -355,12 +355,12 @@ func TestV6ReadOnV6(t *testing.T) { defer c.wq.EventUnregister(&we) var addr tcpip.FullAddress - v, err := c.ep.Read(&addr) + v, _, err := c.ep.Read(&addr) if err == tcpip.ErrWouldBlock { // Wait for data to become available. select { case <-ch: - v, err = c.ep.Read(&addr) + v, _, err = c.ep.Read(&addr) if err != nil { c.t.Fatalf("Read failed: %v", err) } diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index a470cb054..d63a9028e 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -37,6 +37,7 @@ import ( slinux "gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/time" "gvisor.googlesource.com/gvisor/pkg/sentry/watchdog" + "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/link/sniffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/network/arp" "gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv4" @@ -177,7 +178,7 @@ func New(spec *specs.Spec, conf *Config, controllerFD int, ioFDs []int, console // this point. Netns is configured before Run() is called. Netstack is // configured using a control uRPC message. Host network is configured inside // Run(). - networkStack := newEmptyNetworkStack(conf) + networkStack := newEmptyNetworkStack(conf, k) // Initiate the Kernel object, which is required by the Context passed // to createVFS in order to mount (among other things) procfs. @@ -337,7 +338,7 @@ func (l *Loader) WaitExit() kernel.ExitStatus { return l.k.GlobalInit().ExitStatus() } -func newEmptyNetworkStack(conf *Config) inet.Stack { +func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) inet.Stack { switch conf.Network { case NetworkHost: return hostinet.NewStack() @@ -346,7 +347,7 @@ func newEmptyNetworkStack(conf *Config) inet.Stack { // NetworkNone sets up loopback using netstack. netProtos := []string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName} protoNames := []string{tcp.ProtocolName, udp.ProtocolName} - return &epsocket.Stack{stack.New(netProtos, protoNames)} + return &epsocket.Stack{stack.New(clock, netProtos, protoNames)} default: panic(fmt.Sprintf("invalid network configuration: %v", conf.Network)) -- cgit v1.2.3 From 04b79137babed361fb227e3ad579adb2df4bb188 Mon Sep 17 00:00:00 2001 From: Cyrille Hemidy Date: Thu, 3 May 2018 14:05:25 -0700 Subject: Fix misspellings. PiperOrigin-RevId: 195307689 Change-Id: I499f19af49875a43214797d63376f20ae788d2f4 --- pkg/log/log.go | 2 +- pkg/sentry/fs/file.go | 2 +- pkg/sentry/fs/fsutil/file.go | 2 +- pkg/sentry/fs/ramfs/dir.go | 4 ++-- pkg/sentry/fs/tty/line_discipline.go | 4 ++-- pkg/sentry/kernel/semaphore/semaphore.go | 2 +- pkg/sentry/kernel/task_exit.go | 2 +- pkg/sentry/mm/vma.go | 2 +- pkg/sentry/socket/rpcinet/socket.go | 2 +- pkg/sentry/strace/syscalls.go | 2 +- pkg/tcpip/header/ipv6.go | 2 +- pkg/tcpip/stack/stack.go | 2 +- pkg/tcpip/transport/tcp/snd.go | 2 +- runsc/sandbox/sandbox.go | 4 ++-- 14 files changed, 17 insertions(+), 17 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/log/log.go b/pkg/log/log.go index 110e0e196..cdfc0601a 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -149,7 +149,7 @@ func (t TestEmitter) Emit(level Level, timestamp time.Time, format string, v ... // Logger is a high-level logging interface. It is in fact, not used within the // log package. Rather it is provided for others to provide contextual loggers // that may append some addition information to log statement. BasicLogger -// satifies this interface, and may be passed around as a Logger. +// satisfies this interface, and may be passed around as a Logger. type Logger interface { // Debugf logs a debug statement. Debugf(format string, v ...interface{}) diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index de2e80bf0..f2683bbd2 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -376,7 +376,7 @@ func (r *FileReader) Read(buf []byte) (int, error) { return int(n), err } -// ReadAt implementes io.Reader.ReadAt. +// ReadAt implements io.Reader.ReadAt. func (r *FileReader) ReadAt(buf []byte, offset int64) (int, error) { n, err := r.File.Preadv(r.Ctx, usermem.BytesIOSequence(buf), offset) return int(n), err diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go index a7329f1c9..b17f11a5a 100644 --- a/pkg/sentry/fs/fsutil/file.go +++ b/pkg/sentry/fs/fsutil/file.go @@ -34,7 +34,7 @@ func (NoopRelease) Release() {} // SeekWithDirCursor is used to implement fs.FileOperations.Seek. If dirCursor // is not nil and the seek was on a directory, the cursor will be updated. // -// Currenly only seeking to 0 on a directory is supported. +// Currently only seeking to 0 on a directory is supported. // // FIXME: Lift directory seeking limitations. func SeekWithDirCursor(ctx context.Context, file *fs.File, whence fs.SeekWhence, offset int64, dirCursor *string) (int64, error) { diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index bf4cd8dfd..19d5612ed 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -103,7 +103,7 @@ func (d *Dir) addChildLocked(name string, inode *fs.Inode) { } // Given we're now adding this inode to the directory we must also - // increase its link count. Similiarly we decremented it in removeChildLocked. + // increase its link count. Similarly we decremented it in removeChildLocked. inode.AddLink() } @@ -144,7 +144,7 @@ func (d *Dir) removeChildLocked(ctx context.Context, name string) (*fs.Inode, er inode.NotifyStatusChange(ctx) // Given we're now removing this inode to the directory we must also - // decrease its link count. Similiarly it is increased in addChildLocked. + // decrease its link count. Similarly it is increased in addChildLocked. inode.DropLink() return inode, nil diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index fde4e7941..a3aa95ece 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -244,8 +244,8 @@ func (l *lineDiscipline) queueWrite(ctx context.Context, src usermem.IOSequence, return int64(n), err } -// transformOutput does ouput processing for one end of the pty. See -// drivers/tty/n_tty.c:do_output_char for an analagous kernel function. +// transformOutput does output processing for one end of the pty. See +// drivers/tty/n_tty.c:do_output_char for an analogous kernel function. // // Precondition: l.termiosMu must be held. func (l *lineDiscipline) transformOutput(buf []byte) *bytes.Buffer { diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index 19ad5d537..fb8c2f98c 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -298,7 +298,7 @@ func (s *Set) GetVal(num int32, creds *auth.Credentials) (int16, error) { } // ExecuteOps attempts to execute a list of operations to the set. It only -// suceeds when all operations can be applied. No changes are made if it fails. +// succeeds when all operations can be applied. No changes are made if it fails. // // On failure, it may return an error (retries are hopeless) or it may return // a channel that can be waited on before attempting again. diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index 3d49ae350..d6604f37b 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -125,7 +125,7 @@ func (t *Task) killLocked() { Signo: int32(linux.SIGKILL), // Linux just sets SIGKILL in the pending signal bitmask without // enqueueing an actual siginfo, such that - // kernel/signal.c:collect_signal() initalizes si_code to SI_USER. + // kernel/signal.c:collect_signal() initializes si_code to SI_USER. Code: arch.SignalInfoUser, }) t.interrupt() diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index b6af48cb7..61aaa3195 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -243,7 +243,7 @@ func (mm *MemoryManager) getVMAsLocked(ctx context.Context, ar usermem.AddrRange } // getVecVMAsLocked ensures that vmas exist for all addresses in ars, and -// support access to type of (at, ignorePermissions). It retuns the subset of +// support access to type of (at, ignorePermissions). It returns the subset of // ars for which vmas exist. If this is not equal to ars, it returns a non-nil // error explaining why. // diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index 15047df01..2911d3fd6 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -530,7 +530,7 @@ func (p *socketProvider) Socket(t *kernel.Task, stypeflags unix.SockType, protoc // Only accept TCP and UDP. // // Try to restrict the flags we will accept to minimize backwards - // incompatability with netstack. + // incompatibility with netstack. stype := int(stypeflags) & linux.SOCK_TYPE_MASK switch stype { case syscall.SOCK_STREAM: diff --git a/pkg/sentry/strace/syscalls.go b/pkg/sentry/strace/syscalls.go index d0e661706..eccee733e 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -82,7 +82,7 @@ const ( // PipeFDs is an array of two FDs, formatted after syscall execution. PipeFDs - // Uname is a pointer to a struct uname, formatted after syscall exection. + // Uname is a pointer to a struct uname, formatted after syscall execution. Uname // Stat is a pointer to a struct stat, formatted after syscall execution. diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go index d8dc138b3..da0210539 100644 --- a/pkg/tcpip/header/ipv6.go +++ b/pkg/tcpip/header/ipv6.go @@ -60,7 +60,7 @@ const ( // IPv6ProtocolNumber is IPv6's network protocol number. IPv6ProtocolNumber tcpip.NetworkProtocolNumber = 0x86dd - // IPv6Version is the version of the ipv6 procotol. + // IPv6Version is the version of the ipv6 protocol. IPv6Version = 6 // IPv6MinimumMTU is the minimum MTU required by IPv6, per RFC 2460, diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index b480bf812..f0fbd8aad 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -165,7 +165,7 @@ type TCPSenderState struct { // window size from a segment. SndWndScale uint8 - // MaxSentAck is the highest acknowledgemnt number sent till now. + // MaxSentAck is the highest acknowledgement number sent till now. MaxSentAck seqnum.Value // FastRecovery holds the fast recovery state for the endpoint. diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index ad94aecd8..6c363a929 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -152,7 +152,7 @@ func newSender(ep *endpoint, iss, irs seqnum.Value, sndWnd seqnum.Size, mss uint // updateMaxPayloadSize updates the maximum payload size based on the given // MTU. If this is in response to "packet too big" control packets (indicated -// by the count argument), it also reduces the number of oustanding packets and +// by the count argument), it also reduces the number of outstanding packets and // attempts to retransmit the first packet above the MTU size. func (s *sender) updateMaxPayloadSize(mtu, count int) { m := mtu - header.TCPMinimumSize diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 64810b4ea..954824ada 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -58,7 +58,7 @@ func validateID(id string) error { // // Within a root directory, we maintain subdirectories for each sandbox named // with the sandbox id. The sandbox metadata is is stored as json within the -// sandbox directoy in a file named "meta.json". This metadata format is +// sandbox directory in a file named "meta.json". This metadata format is // defined by us, and is not part of the OCI spec. // // Sandboxes must write this metadata file after any change to their internal @@ -199,7 +199,7 @@ func Load(rootDir, id string) (*Sandbox, error) { // If the status is "Running" or "Created", check that the process // still exists, and set it to Stopped if it does not. // - // This is inherintly racey. + // This is inherently racey. if s.Status == Running || s.Status == Created { // Send signal 0 to check if process exists. if err := s.Signal(0); err != nil { -- cgit v1.2.3 From b4765f782d91443ab0415dc00e727d783632e2ad Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Tue, 8 May 2018 09:51:07 -0700 Subject: Fix warning: redundant if ...; err != nil check, just return error instead. This warning is produced by golint. PiperOrigin-RevId: 195833381 Change-Id: Idd6a7e57e3cfdf00819f2374b19fc113585dc1e1 --- pkg/bpf/decoder.go | 5 +---- pkg/compressio/compressio.go | 5 +---- pkg/p9/local_server/local_server.go | 6 +----- pkg/sentry/fs/fdpipe/pipe.go | 5 +---- pkg/sentry/fs/host/fs_test.go | 6 +----- pkg/sentry/fs/host/socket.go | 5 +---- pkg/sentry/kernel/task_signals.go | 10 ++-------- pkg/sentry/syscalls/linux/sys_file.go | 7 ++----- pkg/tcpip/stack/transport_demuxer.go | 6 +----- 9 files changed, 11 insertions(+), 44 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/bpf/decoder.go b/pkg/bpf/decoder.go index 6873ffa5c..ef41e9edc 100644 --- a/pkg/bpf/decoder.go +++ b/pkg/bpf/decoder.go @@ -161,10 +161,7 @@ func decodeAlu(inst linux.BPFInstruction, w *bytes.Buffer) error { default: return fmt.Errorf("invalid BPF ALU instruction: %v", inst) } - if err := decodeSource(inst, w); err != nil { - return err - } - return nil + return decodeSource(inst, w) } func decodeSource(inst linux.BPFInstruction, w *bytes.Buffer) error { diff --git a/pkg/compressio/compressio.go b/pkg/compressio/compressio.go index e0d36aee9..ef8cbd2a5 100644 --- a/pkg/compressio/compressio.go +++ b/pkg/compressio/compressio.go @@ -184,10 +184,7 @@ func handleResult(r result, callback func(*chunk) error) error { if r.err != nil { return r.err } - if err := callback(r.chunk); err != nil { - return err - } - return nil + return callback(r.chunk) } // schedule schedules the given buffers. diff --git a/pkg/p9/local_server/local_server.go b/pkg/p9/local_server/local_server.go index 5b1e97711..7a3e4cffe 100644 --- a/pkg/p9/local_server/local_server.go +++ b/pkg/p9/local_server/local_server.go @@ -246,11 +246,7 @@ func (l *local) Symlink(oldname string, newname string, _ p9.UID, _ p9.GID) (p9. // // Not properly implemented. func (l *local) Link(target p9.File, newname string) error { - if err := os.Link(target.(*local).path, path.Join(l.path, newname)); err != nil { - return err - } - - return nil + return os.Link(target.(*local).path, path.Join(l.path, newname)) } // Mknod implements p9.File.Mknod. diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index f7bbd4aff..7b318e35f 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -90,10 +90,7 @@ func (p *pipeOperations) init() error { if err := syscall.SetNonblock(p.file.FD(), true); err != nil { return err } - if err := fdnotifier.AddFD(int32(p.file.FD()), &p.Queue); err != nil { - return err - } - return nil + return fdnotifier.AddFD(int32(p.file.FD()), &p.Queue) } // EventRegister implements waiter.Waitable.EventRegister. diff --git a/pkg/sentry/fs/host/fs_test.go b/pkg/sentry/fs/host/fs_test.go index c000afc49..b08125ca8 100644 --- a/pkg/sentry/fs/host/fs_test.go +++ b/pkg/sentry/fs/host/fs_test.go @@ -141,11 +141,7 @@ func createTestDirs(ctx context.Context, t *testing.T, m *fs.MountNamespace) err return err } - if err := symlinks.CreateLink(ctx, r, "/symlinks", "recursive"); err != nil { - return err - } - - return nil + return symlinks.CreateLink(ctx, r, "/symlinks", "recursive") } // allPaths returns a slice of all paths of entries visible in the rootfs. diff --git a/pkg/sentry/fs/host/socket.go b/pkg/sentry/fs/host/socket.go index 8e36ed7ee..467633052 100644 --- a/pkg/sentry/fs/host/socket.go +++ b/pkg/sentry/fs/host/socket.go @@ -69,10 +69,7 @@ func (e *endpoint) init() error { } e.stype = unix.SockType(stype) - if err := fdnotifier.AddFD(int32(e.fd), &e.queue); err != nil { - return err - } - return nil + return fdnotifier.AddFD(int32(e.fd), &e.queue) } // newEndpoint creates a new host endpoint. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 2340256b0..e4ef7fd67 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -127,10 +127,7 @@ func (t *Task) dequeueSignalLocked() *arch.SignalInfo { if info := t.pendingSignals.dequeue(t.tr.SignalMask); info != nil { return info } - if info := t.tg.pendingSignals.dequeue(t.tr.SignalMask); info != nil { - return info - } - return nil + return t.tg.pendingSignals.dequeue(t.tr.SignalMask) } // TakeSignal returns a pending signal not blocked by mask. Signal handlers are @@ -144,10 +141,7 @@ func (t *Task) TakeSignal(mask linux.SignalSet) *arch.SignalInfo { if info := t.pendingSignals.dequeue(mask); info != nil { return info } - if info := t.tg.pendingSignals.dequeue(mask); info != nil { - return info - } - return nil + return t.tg.pendingSignals.dequeue(mask) } // discardSpecificLocked removes all instances of the given signal from all diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index a2dbba7e0..5fbacc15e 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -460,14 +460,11 @@ func accessAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, resolve bool, m creds: creds, } - if err := d.Inode.CheckPermission(ctx, fs.PermMask{ + return d.Inode.CheckPermission(ctx, fs.PermMask{ Read: mode&rOK != 0, Write: mode&wOK != 0, Execute: mode&xOK != 0, - }); err != nil { - return err - } - return nil + }) }) } diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index 3c0d7aa31..7bb853622 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -158,9 +158,5 @@ func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv *buffe // Try to find a match with only the local port. nid.LocalAddress = "" - if ep := eps.endpoints[nid]; ep != nil { - return ep - } - - return nil + return eps.endpoints[nid] } -- cgit v1.2.3 From 705605f9011cfbd58f407ca84bc4c2d8cf39d80b Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Tue, 22 May 2018 13:46:37 -0700 Subject: sentry: Add simple SIOCGIFFLAGS support (IFF_RUNNING and IFF_PROMIS). Establishes a way of communicating interface flags between netstack and epsocket. More flags can be added over time. PiperOrigin-RevId: 197616669 Change-Id: I230448c5fb5b7d2e8d69b41a451eb4e1096a0e30 --- pkg/sentry/socket/epsocket/epsocket.go | 57 ++++++++++++++++++++++++++++++-- pkg/tcpip/link/channel/channel.go | 5 +++ pkg/tcpip/link/fdbased/endpoint.go | 13 ++++++-- pkg/tcpip/link/loopback/loopback.go | 5 +++ pkg/tcpip/link/sharedmem/sharedmem.go | 7 ++++ pkg/tcpip/link/sniffer/sniffer.go | 5 +++ pkg/tcpip/link/waitable/waitable.go | 5 +++ pkg/tcpip/link/waitable/waitable_test.go | 5 +++ pkg/tcpip/network/ip_test.go | 5 +++ pkg/tcpip/stack/registration.go | 4 +++ pkg/tcpip/stack/stack.go | 33 ++++++++++++++++++ 11 files changed, 138 insertions(+), 6 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 2495ba459..9ff9af0bc 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -48,12 +48,15 @@ import ( "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + nstack "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix" "gvisor.googlesource.com/gvisor/pkg/waiter" ) const sizeOfInt32 int = 4 +var errStackType = syserr.New("expected but did not receive an epsocket.Stack", linux.EINVAL) + // ntohs converts a 16-bit number from network byte order to host byte order. It // assumes that the host is little endian. func ntohs(v uint16) uint16 { @@ -1177,9 +1180,11 @@ func interfaceIoctl(ctx context.Context, io usermem.IO, arg int, ifr *linux.IFRe usermem.ByteOrder.PutUint16(ifr.Data[:2], uint16(n)) case syscall.SIOCGIFFLAGS: - // TODO: Implement. For now, return only that the - // device is up so that ifconfig prints it. - usermem.ByteOrder.PutUint16(ifr.Data[:2], linux.IFF_UP) + f, err := interfaceStatusFlags(stack, iface.Name) + if err != nil { + return err + } + usermem.ByteOrder.PutUint16(ifr.Data[:2], f) case syscall.SIOCGIFADDR: // Copy the IPv4 address out. @@ -1288,3 +1293,49 @@ func ifconfIoctl(ctx context.Context, io usermem.IO, ifc *linux.IFConf) error { } return nil } + +// interfaceStatusFlags returns status flags for an interface in the stack. +// Flag values and meanings are described in greater detail in netdevice(7) in +// the SIOCGIFFLAGS section. +func interfaceStatusFlags(stack inet.Stack, name string) (uint16, *syserr.Error) { + // epsocket should only ever be passed an epsocket.Stack. + epstack, ok := stack.(*Stack) + if !ok { + return 0, errStackType + } + + // Find the NIC corresponding to this interface. + var ( + nicid tcpip.NICID + info nstack.NICInfo + found bool + ) + ns := epstack.Stack + for nicid, info = range ns.NICInfo() { + if info.Name == name { + found = true + break + } + } + if !found { + return 0, syserr.ErrNoDevice + } + + // Set flags based on NIC state. + nicFlags, err := ns.NICFlags(nicid) + if err != nil { + return 0, syserr.TranslateNetstackError(err) + } + + var retFlags uint16 + if nicFlags.Up { + retFlags |= linux.IFF_UP + } + if nicFlags.Running { + retFlags |= linux.IFF_RUNNING + } + if nicFlags.Promiscuous { + retFlags |= linux.IFF_PROMISC + } + return retFlags, nil +} diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index cebc34553..3f5440cc1 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -67,6 +67,11 @@ func (e *Endpoint) Attach(dispatcher stack.NetworkDispatcher) { e.dispatcher = dispatcher } +// IsAttached implements stack.LinkEndpoint.IsAttached. +func (e *Endpoint) IsAttached() bool { + return e.dispatcher != nil +} + // MTU implements stack.LinkEndpoint.MTU. It returns the value initialized // during construction. func (e *Endpoint) MTU() uint32 { diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index da74cd644..668514454 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -45,9 +45,10 @@ type endpoint struct { // its end of the communication pipe. closed func(*tcpip.Error) - vv *buffer.VectorisedView - iovecs []syscall.Iovec - views []buffer.View + vv *buffer.VectorisedView + iovecs []syscall.Iovec + views []buffer.View + attached bool } // Options specify the details about the fd-based endpoint to be created. @@ -96,9 +97,15 @@ func New(opts *Options) tcpip.LinkEndpointID { // Attach launches the goroutine that reads packets from the file descriptor and // dispatches them via the provided dispatcher. func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { + e.attached = true go e.dispatchLoop(dispatcher) // S/R-FIXME } +// IsAttached implements stack.LinkEndpoint.IsAttached. +func (e *endpoint) IsAttached() bool { + return e.attached +} + // MTU implements stack.LinkEndpoint.MTU. It returns the value initialized // during construction. func (e *endpoint) MTU() uint32 { diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 1a9cd09d7..f38847949 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -32,6 +32,11 @@ func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { e.dispatcher = dispatcher } +// IsAttached implements stack.LinkEndpoint.IsAttached. +func (e *endpoint) IsAttached() bool { + return e.dispatcher != nil +} + // MTU implements stack.LinkEndpoint.MTU. It returns a constant that matches the // linux loopback interface. func (*endpoint) MTU() uint32 { diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 2c0f1b294..5369ebc68 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -137,6 +137,13 @@ func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { e.mu.Unlock() } +// IsAttached implements stack.LinkEndpoint.IsAttached. +func (e *endpoint) IsAttached() bool { + e.mu.Lock() + defer e.mu.Unlock() + return e.workerStarted +} + // MTU implements stack.LinkEndpoint.MTU. It returns the value initialized // during construction. func (e *endpoint) MTU() uint32 { diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 72d9a0f1c..3a40081c0 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -143,6 +143,11 @@ func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { e.lower.Attach(e) } +// IsAttached implements stack.LinkEndpoint.IsAttached. +func (e *endpoint) IsAttached() bool { + return e.dispatcher != nil +} + // MTU implements stack.LinkEndpoint.MTU. It just forwards the request to the // lower endpoint. func (e *endpoint) MTU() uint32 { diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 2c6e73f22..91aed7a12 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -58,6 +58,11 @@ func (e *Endpoint) Attach(dispatcher stack.NetworkDispatcher) { e.lower.Attach(e) } +// IsAttached implements stack.LinkEndpoint.IsAttached. +func (e *Endpoint) IsAttached() bool { + return e.dispatcher != nil +} + // MTU implements stack.LinkEndpoint.MTU. It just forwards the request to the // lower endpoint. func (e *Endpoint) MTU() uint32 { diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index cb433dc19..188049322 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -34,6 +34,11 @@ func (e *countedEndpoint) Attach(dispatcher stack.NetworkDispatcher) { e.dispatcher = dispatcher } +// IsAttached implements stack.LinkEndpoint.IsAttached. +func (e *countedEndpoint) IsAttached() bool { + return e.dispatcher != nil +} + func (e *countedEndpoint) MTU() uint32 { return e.mtu } diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 797501858..c5f8714da 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -90,6 +90,11 @@ func (t *testObject) DeliverTransportControlPacket(local, remote tcpip.Address, // Attach is only implemented to satisfy the LinkEndpoint interface. func (*testObject) Attach(stack.NetworkDispatcher) {} +// IsAttached implements stack.LinkEndpoint.IsAttached. +func (*testObject) IsAttached() bool { + return true +} + // MTU implements stack.LinkEndpoint.MTU. It just returns a constant that // matches the linux loopback MTU. func (*testObject) MTU() uint32 { diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index e7e6381ac..15b2418ad 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -224,6 +224,10 @@ type LinkEndpoint interface { // Attach attaches the data link layer endpoint to the network-layer // dispatcher of the stack. Attach(dispatcher NetworkDispatcher) + + // IsAttached returns whether a NetworkDispatcher is attached to the + // endpoint. + IsAttached() bool } // A LinkAddressResolver is an extension to a NetworkProtocol that diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index f0fbd8aad..3976f585c 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -541,6 +541,39 @@ func (s *Stack) NICInfo() map[tcpip.NICID]NICInfo { return nics } +// NICStateFlags holds information about the state of an NIC. +type NICStateFlags struct { + // Up indicates whether the interface is running. + Up bool + + // Running indicates whether resources are allocated. + Running bool + + // Promiscuous indicates whether the interface is in promiscuous mode. + Promiscuous bool +} + +// NICFlags returns flags about the state of the NIC. It returns an error if +// the NIC corresponding to id cannot be found. +func (s *Stack) NICFlags(id tcpip.NICID) (NICStateFlags, *tcpip.Error) { + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[id] + if nic == nil { + return NICStateFlags{}, tcpip.ErrUnknownNICID + } + + ret := NICStateFlags{ + // Netstack interfaces are always up. + Up: true, + + Running: nic.linkEP.IsAttached(), + Promiscuous: nic.promiscuous, + } + return ret, nil +} + // AddAddress adds a new network-layer address to the specified NIC. func (s *Stack) AddAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error { s.mu.RLock() -- cgit v1.2.3 From 0e434b66a625b937d90e4ebe632de4546101be5a Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Thu, 21 Jun 2018 15:18:47 -0700 Subject: netstack: tcp socket connected state S/R support. PiperOrigin-RevId: 201596247 Change-Id: Id22f47b2cdcbe14aa0d930f7807ba75f91a56724 --- pkg/sentry/kernel/BUILD | 5 +- pkg/sentry/kernel/kernel.go | 6 + pkg/sentry/kernel/kernel_state.go | 31 +++++ pkg/tcpip/stack/stack_global_state.go | 2 +- pkg/tcpip/tcpip.go | 36 ++++++ pkg/tcpip/transport/tcp/BUILD | 7 ++ pkg/tcpip/transport/tcp/accept.go | 11 +- pkg/tcpip/transport/tcp/connect.go | 43 ++++++- pkg/tcpip/transport/tcp/endpoint.go | 72 +++++++++--- pkg/tcpip/transport/tcp/endpoint_state.go | 185 ++++++++++++++++++++---------- pkg/tcpip/transport/tcp/segment.go | 8 +- pkg/tcpip/transport/tcp/segment_queue.go | 4 +- pkg/tcpip/transport/tcp/segment_state.go | 41 +++++++ pkg/tcpip/transport/tcp/snd.go | 4 +- pkg/tcpip/transport/tcp/snd_state.go | 39 +++++++ 15 files changed, 403 insertions(+), 91 deletions(-) create mode 100644 pkg/sentry/kernel/kernel_state.go create mode 100644 pkg/tcpip/transport/tcp/segment_state.go create mode 100644 pkg/tcpip/transport/tcp/snd_state.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index b2a55ddff..07568b47c 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -12,6 +12,7 @@ go_stateify( "fs_context.go", "ipc_namespace.go", "kernel.go", + "kernel_state.go", "pending_signals.go", "pending_signals_state.go", "process_group_list.go", @@ -45,10 +46,11 @@ go_stateify( "vdso.go", "version.go", ], - out = "kernel_state.go", + out = "kernel_autogen_state.go", imports = [ "gvisor.googlesource.com/gvisor/pkg/sentry/arch", "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", + "gvisor.googlesource.com/gvisor/pkg/tcpip", ], package = "kernel", ) @@ -117,6 +119,7 @@ go_library( "fs_context.go", "ipc_namespace.go", "kernel.go", + "kernel_autogen_state.go", "kernel_state.go", "pending_signals.go", "pending_signals_list.go", diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 5662b8f08..64439cd9d 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -57,6 +57,7 @@ import ( sentrytime "gvisor.googlesource.com/gvisor/pkg/sentry/time" "gvisor.googlesource.com/gvisor/pkg/sentry/uniqueid" "gvisor.googlesource.com/gvisor/pkg/state" + "gvisor.googlesource.com/gvisor/pkg/tcpip" ) // Kernel represents an emulated Linux kernel. It must be initialized by calling @@ -158,6 +159,9 @@ type Kernel struct { // exitErr is the error causing the sandbox to exit, if any. It is // protected by extMu. exitErr error + + // danglingEndpoints is used to save / restore tcpip.DanglingEndpoints. + danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"` } // InitKernelArgs holds arguments to Init. @@ -422,6 +426,8 @@ func (k *Kernel) LoadFrom(r io.Reader, p platform.Platform, net inet.Stack) erro return err } + tcpip.AsyncLoading.Wait() + log.Infof("Overall load took [%s]", time.Since(loadStart)) // Applications may size per-cpu structures based on k.applicationCores, so diff --git a/pkg/sentry/kernel/kernel_state.go b/pkg/sentry/kernel/kernel_state.go new file mode 100644 index 000000000..bb2d5102d --- /dev/null +++ b/pkg/sentry/kernel/kernel_state.go @@ -0,0 +1,31 @@ +// Copyright 2018 Google Inc. +// +// 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 kernel + +import ( + "gvisor.googlesource.com/gvisor/pkg/tcpip" +) + +// saveDanglingEndpoints is invoked by stateify. +func (k *Kernel) saveDanglingEndpoints() []tcpip.Endpoint { + return tcpip.GetDanglingEndpoints() +} + +// loadDanglingEndpoints is invoked by stateify. +func (k *Kernel) loadDanglingEndpoints(es []tcpip.Endpoint) { + for _, e := range es { + tcpip.AddDanglingEndpoint(e) + } +} diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index 030ae98d1..260d7d05c 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -5,5 +5,5 @@ package stack // StackFromEnv is the global stack created in restore run. -// FIXME: remove this variable once tcpip S/R is fully supported. +// FIXME var StackFromEnv *Stack diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index cf25a086d..17fa0efb7 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -23,6 +23,7 @@ import ( "fmt" "strconv" "strings" + "sync" "time" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" @@ -552,3 +553,38 @@ type ProtocolAddress struct { // Address is a network address. Address Address } + +// danglingEndpointsMu protects access to danglingEndpoints. +var danglingEndpointsMu sync.Mutex + +// danglingEndpoints tracks all dangling endpoints no longer owned by the app. +var danglingEndpoints = make(map[Endpoint]struct{}) + +// GetDanglingEndpoints returns all dangling endpoints. +func GetDanglingEndpoints() []Endpoint { + es := make([]Endpoint, 0, len(danglingEndpoints)) + danglingEndpointsMu.Lock() + for e, _ := range danglingEndpoints { + es = append(es, e) + } + danglingEndpointsMu.Unlock() + return es +} + +// AddDanglingEndpoint adds a dangling endpoint. +func AddDanglingEndpoint(e Endpoint) { + danglingEndpointsMu.Lock() + danglingEndpoints[e] = struct{}{} + danglingEndpointsMu.Unlock() +} + +// DeleteDanglingEndpoint removes a dangling endpoint. +func DeleteDanglingEndpoint(e Endpoint) { + danglingEndpointsMu.Lock() + delete(danglingEndpoints, e) + danglingEndpointsMu.Unlock() +} + +// AsyncLoading is the global barrier for asynchronous endpoint loading +// activities. +var AsyncLoading sync.WaitGroup diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index f38f58e87..d129aa285 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -10,11 +10,16 @@ go_stateify( "endpoint.go", "endpoint_state.go", "rcv.go", + "segment.go", "segment_heap.go", + "segment_queue.go", + "segment_state.go", "snd.go", + "snd_state.go", "tcp_segment_list.go", ], out = "tcp_state.go", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], package = "tcp", ) @@ -43,7 +48,9 @@ go_library( "segment.go", "segment_heap.go", "segment_queue.go", + "segment_state.go", "snd.go", + "snd_state.go", "tcp_segment_list.go", "tcp_state.go", "timer.go", diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index 85adeef0e..410dfdad4 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -68,7 +68,8 @@ func encodeMSS(mss uint16) uint32 { // to go above a threshold. var synRcvdCount struct { sync.Mutex - value uint64 + value uint64 + pending sync.WaitGroup } // listenContext is used by a listening endpoint to store state used while @@ -102,6 +103,7 @@ func incSynRcvdCount() bool { return false } + synRcvdCount.pending.Add(1) synRcvdCount.value++ return true @@ -115,6 +117,7 @@ func decSynRcvdCount() { defer synRcvdCount.Unlock() synRcvdCount.value-- + synRcvdCount.pending.Done() } // newListenContext creates a new listen context. @@ -292,7 +295,7 @@ func (e *endpoint) handleListenSegment(ctx *listenContext, s *segment) { opts := parseSynSegmentOptions(s) if incSynRcvdCount() { s.incRef() - go e.handleSynSegment(ctx, s, &opts) // S/R-FIXME + go e.handleSynSegment(ctx, s, &opts) // S/R-SAFE: synRcvdCount is the barrier. } else { cookie := ctx.createCookie(s.id, s.sequenceNumber, encodeMSS(opts.MSS)) // Send SYN with window scaling because we currently @@ -381,10 +384,12 @@ func (e *endpoint) protocolListenLoop(rcvWnd seqnum.Size) *tcpip.Error { return nil } if n¬ifyDrain != 0 { - for s := e.segmentQueue.dequeue(); s != nil; s = e.segmentQueue.dequeue() { + for !e.segmentQueue.empty() { + s := e.segmentQueue.dequeue() e.handleListenSegment(ctx, s) s.decRef() } + synRcvdCount.pending.Wait() close(e.drainDone) <-e.undrain } diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 9aaabe0b1..d9f87c793 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -443,7 +443,8 @@ func (h *handshake) execute() *tcpip.Error { return tcpip.ErrAborted } if n¬ifyDrain != 0 { - for s := h.ep.segmentQueue.dequeue(); s != nil; s = h.ep.segmentQueue.dequeue() { + for !h.ep.segmentQueue.empty() { + s := h.ep.segmentQueue.dequeue() err := h.handleSegment(s) s.decRef() if err != nil { @@ -813,15 +814,13 @@ func (e *endpoint) handleSegments() *tcpip.Error { // protocolMainLoop is the main loop of the TCP protocol. It runs in its own // goroutine and is responsible for sending segments and handling received // segments. -func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { +func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error { var closeTimer *time.Timer var closeWaker sleep.Waker defer func() { // e.mu is expected to be hold upon entering this section. - e.completeWorkerLocked() - if e.snd != nil { e.snd.resendTimer.cleanup() } @@ -830,6 +829,8 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { closeTimer.Stop() } + e.completeWorkerLocked() + if e.drainDone != nil { close(e.drainDone) } @@ -840,7 +841,7 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.EventIn | waiter.EventOut) }() - if !passive { + if handshake { // This is an active connection, so we must initiate the 3-way // handshake, and then inform potential waiters about its // completion. @@ -945,6 +946,17 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { closeWaker.Assert() }) } + + if n¬ifyDrain != 0 { + for !e.segmentQueue.empty() { + if err := e.handleSegments(); err != nil { + return err + } + } + close(e.drainDone) + <-e.undrain + } + return nil }, }, @@ -956,6 +968,27 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { s.AddWaker(funcs[i].w, i) } + // The following assertions and notifications are needed for restored + // endpoints. Fresh newly created endpoints have empty states and should + // not invoke any. + e.segmentQueue.mu.Lock() + if !e.segmentQueue.list.Empty() { + e.newSegmentWaker.Assert() + } + e.segmentQueue.mu.Unlock() + + e.rcvListMu.Lock() + if !e.rcvList.Empty() { + e.waiterQueue.Notify(waiter.EventIn) + } + e.rcvListMu.Unlock() + + e.mu.RLock() + if e.workerCleanup { + e.notifyProtocolGoroutine(notifyClose) + } + e.mu.RUnlock() + // Main loop. Handle segments until both send and receive ends of the // connection have completed. for !e.rcv.closed || !e.snd.closed || e.snd.sndUna != e.snd.sndNxtList { diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index b21c2b4ab..706977618 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -69,7 +69,7 @@ type endpoint struct { // change throughout the lifetime of the endpoint. stack *stack.Stack `state:"manual"` netProto tcpip.NetworkProtocolNumber - waiterQueue *waiter.Queue + waiterQueue *waiter.Queue `state:"wait"` // lastError represents the last error that the endpoint reported; // access to it is protected by the following mutex. @@ -82,8 +82,8 @@ type endpoint struct { // // Once the peer has closed its send side, rcvClosed is set to true // to indicate to users that no more data is coming. - rcvListMu sync.Mutex `state:"nosave"` - rcvList segmentList + rcvListMu sync.Mutex `state:"nosave"` + rcvList segmentList `state:"wait"` rcvClosed bool rcvBufSize int rcvBufUsed int @@ -91,8 +91,8 @@ type endpoint struct { // The following fields are protected by the mutex. mu sync.RWMutex `state:"nosave"` id stack.TransportEndpointID - state endpointState - isPortReserved bool `state:"manual"` + state endpointState `state:".(endpointState)"` + isPortReserved bool `state:"manual"` isRegistered bool boundNICID tcpip.NICID `state:"manual"` route stack.Route `state:"manual"` @@ -118,7 +118,7 @@ type endpoint struct { // workerCleanup specifies if the worker goroutine must perform cleanup // before exitting. This can only be set to true when workerRunning is // also true, and they're both protected by the mutex. - workerCleanup bool `state:"zerovalue"` + workerCleanup bool // sendTSOk is used to indicate when the TS Option has been negotiated. // When sendTSOk is true every non-RST segment should carry a TS as per @@ -153,7 +153,7 @@ type endpoint struct { // segmentQueue is used to hand received segments to the protocol // goroutine. Segments are queued as long as the queue is not full, // and dropped when it is. - segmentQueue segmentQueue `state:"zerovalue"` + segmentQueue segmentQueue `state:"wait"` // The following fields are used to manage the send buffer. When // segments are ready to be sent, they are added to sndQueue and the @@ -166,7 +166,7 @@ type endpoint struct { sndBufUsed int sndClosed bool sndBufInQueue seqnum.Size - sndQueue segmentList + sndQueue segmentList `state:"wait"` sndWaker sleep.Waker `state:"manual"` sndCloseWaker sleep.Waker `state:"manual"` @@ -188,17 +188,21 @@ type endpoint struct { // notifyFlags is a bitmask of flags used to indicate to the protocol // goroutine what it was notified; this is only accessed atomically. - notifyFlags uint32 `state:"zerovalue"` + notifyFlags uint32 `state:"nosave"` // acceptedChan is used by a listening endpoint protocol goroutine to // send newly accepted connections to the endpoint so that they can be // read by Accept() calls. - acceptedChan chan *endpoint `state:".(endpointChan)"` + acceptedChan chan *endpoint `state:"manual"` + + // acceptedEndpoints is only used to save / restore the channel buffer. + // FIXME + acceptedEndpoints []*endpoint // The following are only used from the protocol goroutine, and // therefore don't need locks to protect them. - rcv *receiver - snd *sender + rcv *receiver `state:"wait"` + snd *sender `state:"wait"` // The goroutine drain completion notification channel. drainDone chan struct{} `state:"nosave"` @@ -211,6 +215,7 @@ type endpoint struct { probe stack.TCPProbeFunc `state:"nosave"` // The following are only used to assist the restore run to re-connect. + bindAddress tcpip.Address connectingAddress tcpip.Address } @@ -344,6 +349,7 @@ func (e *endpoint) Close() { // Either perform the local cleanup or kick the worker to make sure it // knows it needs to cleanup. + tcpip.AddDanglingEndpoint(e) if !e.workerRunning { e.cleanupLocked() } else { @@ -363,9 +369,12 @@ func (e *endpoint) cleanupLocked() { if e.acceptedChan != nil { close(e.acceptedChan) for n := range e.acceptedChan { + n.mu.Lock() n.resetConnectionLocked(tcpip.ErrConnectionAborted) + n.mu.Unlock() n.Close() } + e.acceptedChan = nil } e.workerCleanup = false @@ -374,6 +383,7 @@ func (e *endpoint) cleanupLocked() { } e.route.Release() + tcpip.DeleteDanglingEndpoint(e) } // Read reads data from the endpoint. @@ -786,6 +796,16 @@ func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress) (tcpip.NetworkProtocol // Connect connects the endpoint to its peer. func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { + return e.connect(addr, true, true) +} + +// connect connects the endpoint to its peer. In the normal non-S/R case, the +// new connection is expected to run the main goroutine and perform handshake. +// In restore of previously connected endpoints, both ends will be passively +// created (so no new handshaking is done); for stack-accepted connections not +// yet accepted by the app, they are restored without running the main goroutine +// here. +func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) *tcpip.Error { e.mu.Lock() defer e.mu.Unlock() @@ -897,9 +917,27 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { e.boundNICID = nicid e.effectiveNetProtos = netProtos e.connectingAddress = connectingAddr - e.workerRunning = true - go e.protocolMainLoop(false) // S/R-SAFE: will be drained before save. + // Connect in the restore phase does not perform handshake. Restore its + // connection setting here. + if !handshake { + e.segmentQueue.mu.Lock() + for _, l := range []segmentList{e.segmentQueue.list, e.sndQueue, e.snd.writeList} { + for s := l.Front(); s != nil; s = s.Next() { + s.id = e.id + s.route = r.Clone() + e.sndWaker.Assert() + } + } + e.segmentQueue.mu.Unlock() + e.snd.updateMaxPayloadSize(int(e.route.MTU()), 0) + e.state = stateConnected + } + + if run { + e.workerRunning = true + go e.protocolMainLoop(handshake) // S/R-SAFE: will be drained before save. + } return tcpip.ErrConnectStarted } @@ -971,6 +1009,9 @@ func (e *endpoint) Listen(backlog int) *tcpip.Error { if len(e.acceptedChan) > backlog { return tcpip.ErrInvalidEndpointState } + if cap(e.acceptedChan) == backlog { + return nil + } origChan := e.acceptedChan e.acceptedChan = make(chan *endpoint, backlog) close(origChan) @@ -1008,7 +1049,7 @@ func (e *endpoint) Listen(backlog int) *tcpip.Error { func (e *endpoint) startAcceptedLoop(waiterQueue *waiter.Queue) { e.waiterQueue = waiterQueue e.workerRunning = true - go e.protocolMainLoop(true) // S/R-FIXME + go e.protocolMainLoop(false) // S/R-SAFE: drained on save. } // Accept returns a new endpoint if a peer has established a connection @@ -1049,6 +1090,7 @@ func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) (ret return tcpip.ErrAlreadyBound } + e.bindAddress = addr.Addr netProto, err := e.checkV4Mapped(&addr) if err != nil { return err diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index b1e249bff..38c97c796 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -9,6 +9,7 @@ import ( "sync" "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" ) @@ -22,7 +23,7 @@ func (e *endpoint) drainSegmentLocked() { e.undrain = make(chan struct{}) e.mu.Unlock() - e.notificationWaker.Assert() + e.notifyProtocolGoroutine(notifyDrain) <-e.drainDone e.mu.Lock() @@ -38,37 +39,98 @@ func (e *endpoint) beforeSave() { switch e.state { case stateInitial, stateBound: - case stateListen: - if !e.segmentQueue.empty() { - e.drainSegmentLocked() + case stateListen, stateConnecting, stateConnected: + if e.state == stateConnected && !e.workerRunning { + // The endpoint must be in acceptedChan. + break } - case stateConnecting: e.drainSegmentLocked() - if e.state != stateConnected { + if e.state != stateClosed && e.state != stateError { + if !e.workerRunning { + panic("endpoint has no worker running in listen, connecting, or connected state") + } break } fallthrough - case stateConnected: - // FIXME - panic(tcpip.ErrSaveRejection{fmt.Errorf("endpoint cannot be saved in connected state: local %v:%v, remote %v:%v", e.id.LocalAddress, e.id.LocalPort, e.id.RemoteAddress, e.id.RemotePort)}) case stateClosed, stateError: if e.workerRunning { - panic(fmt.Sprintf("endpoint still has worker running in closed or error state")) + panic("endpoint still has worker running in closed or error state") } default: panic(fmt.Sprintf("endpoint in unknown state %v", e.state)) } + + if e.waiterQueue != nil && !e.waiterQueue.IsEmpty() { + panic("endpoint still has waiters upon save") + } + + if !((e.state == stateBound || e.state == stateListen) == e.isPortReserved) { + panic("endpoint port must and must only be reserved in bound or listen state") + } + + if e.acceptedChan != nil { + close(e.acceptedChan) + e.acceptedEndpoints = make([]*endpoint, len(e.acceptedChan), cap(e.acceptedChan)) + i := 0 + for ep := range e.acceptedChan { + e.acceptedEndpoints[i] = ep + i++ + } + if i != len(e.acceptedEndpoints) { + panic("endpoint acceptedChan buffer got consumed by background context") + } + } +} + +// saveState is invoked by stateify. +func (e *endpoint) saveState() endpointState { + return e.state +} + +// Endpoint loading must be done in the following ordering by their state, to +// avoid dangling connecting w/o listening peer, and to avoid conflicts in port +// reservation. +var connectedLoading sync.WaitGroup +var listenLoading sync.WaitGroup +var connectingLoading sync.WaitGroup + +// Bound endpoint loading happens last. + +// loadState is invoked by stateify. +func (e *endpoint) loadState(state endpointState) { + // This is to ensure that the loading wait groups include all applicable + // endpoints before any asynchronous calls to the Wait() methods. + switch state { + case stateConnected: + connectedLoading.Add(1) + case stateListen: + listenLoading.Add(1) + case stateConnecting: + connectingLoading.Add(1) + } + e.state = state } // afterLoad is invoked by stateify. func (e *endpoint) afterLoad() { + // We load acceptedChan buffer indirectly here. Note that closed + // endpoints might not need to allocate the channel. + // FIXME + if cap(e.acceptedEndpoints) > 0 { + e.acceptedChan = make(chan *endpoint, cap(e.acceptedEndpoints)) + for _, ep := range e.acceptedEndpoints { + e.acceptedChan <- ep + } + e.acceptedEndpoints = nil + } + e.stack = stack.StackFromEnv e.segmentQueue.setLimit(2 * e.rcvBufSize) e.workMu.Init() state := e.state switch state { - case stateInitial, stateBound, stateListen, stateConnecting: + case stateInitial, stateBound, stateListen, stateConnecting, stateConnected: var ss SendBufferSizeOption if err := e.stack.TransportProtocolOption(ProtocolNumber, &ss); err == nil { if e.sndBufSize < ss.Min || e.sndBufSize > ss.Max { @@ -80,65 +142,72 @@ func (e *endpoint) afterLoad() { } } - switch state { - case stateBound, stateListen, stateConnecting: + bind := func() { e.state = stateInitial - if err := e.Bind(tcpip.FullAddress{Addr: e.id.LocalAddress, Port: e.id.LocalPort}, nil); err != nil { + if len(e.bindAddress) == 0 { + e.bindAddress = e.id.LocalAddress + } + if err := e.Bind(tcpip.FullAddress{Addr: e.bindAddress, Port: e.id.LocalPort}, nil); err != nil { panic("endpoint binding failed: " + err.String()) } } switch state { - case stateListen: - backlog := cap(e.acceptedChan) - e.acceptedChan = nil - if err := e.Listen(backlog); err != nil { - panic("endpoint listening failed: " + err.String()) + case stateConnected: + bind() + if len(e.connectingAddress) == 0 { + // This endpoint is accepted by netstack but not yet by + // the app. If the endpoint is IPv6 but the remote + // address is IPv4, we need to connect as IPv6 so that + // dual-stack mode can be properly activated. + if e.netProto == header.IPv6ProtocolNumber && len(e.id.RemoteAddress) != header.IPv6AddressSize { + e.connectingAddress = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + e.id.RemoteAddress + } else { + e.connectingAddress = e.id.RemoteAddress + } } - } - - switch state { - case stateConnecting: - if err := e.Connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}); err != tcpip.ErrConnectStarted { + if err := e.connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}, false, e.workerRunning); err != tcpip.ErrConnectStarted { panic("endpoint connecting failed: " + err.String()) } + connectedLoading.Done() + case stateListen: + tcpip.AsyncLoading.Add(1) + go func() { + connectedLoading.Wait() + bind() + backlog := cap(e.acceptedChan) + if err := e.Listen(backlog); err != nil { + panic("endpoint listening failed: " + err.String()) + } + listenLoading.Done() + tcpip.AsyncLoading.Done() + }() + case stateConnecting: + tcpip.AsyncLoading.Add(1) + go func() { + connectedLoading.Wait() + listenLoading.Wait() + bind() + if err := e.Connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}); err != tcpip.ErrConnectStarted { + panic("endpoint connecting failed: " + err.String()) + } + connectingLoading.Done() + tcpip.AsyncLoading.Done() + }() + case stateBound: + tcpip.AsyncLoading.Add(1) + go func() { + connectedLoading.Wait() + listenLoading.Wait() + connectingLoading.Wait() + bind() + tcpip.AsyncLoading.Done() + }() + case stateClosed, stateError: + tcpip.DeleteDanglingEndpoint(e) } } -// saveAcceptedChan is invoked by stateify. -func (e *endpoint) saveAcceptedChan() endpointChan { - if e.acceptedChan == nil { - return endpointChan{} - } - close(e.acceptedChan) - buffer := make([]*endpoint, 0, len(e.acceptedChan)) - for ep := range e.acceptedChan { - buffer = append(buffer, ep) - } - if len(buffer) != cap(buffer) { - panic("endpoint.acceptedChan buffer got consumed by background context") - } - c := cap(e.acceptedChan) - e.acceptedChan = nil - return endpointChan{buffer: buffer, cap: c} -} - -// loadAcceptedChan is invoked by stateify. -func (e *endpoint) loadAcceptedChan(c endpointChan) { - if c.cap == 0 { - return - } - e.acceptedChan = make(chan *endpoint, c.cap) - for _, ep := range c.buffer { - e.acceptedChan <- ep - } -} - -type endpointChan struct { - buffer []*endpoint - cap int -} - // saveLastError is invoked by stateify. func (e *endpoint) saveLastError() string { if e.lastError == nil { diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 07e4bfd73..c5bff5f4f 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -29,9 +29,9 @@ const ( type segment struct { segmentEntry refCnt int32 - id stack.TransportEndpointID - route stack.Route `state:"manual"` - data buffer.VectorisedView + id stack.TransportEndpointID `state:"manual"` + route stack.Route `state:"manual"` + data buffer.VectorisedView `state:".(buffer.VectorisedView)"` // views is used as buffer for data when its length is large // enough to store a VectorisedView. views [8]buffer.View @@ -45,7 +45,7 @@ type segment struct { // parsedOptions stores the parsed values from the options in the segment. parsedOptions header.TCPOptions - options []byte + options []byte `state:".([]byte)"` } func newSegment(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) *segment { diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index c4a7f7d5b..a5e7b2ebf 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -12,8 +12,8 @@ import ( // segmentQueue is a bounded, thread-safe queue of TCP segments. type segmentQueue struct { - mu sync.Mutex - list segmentList + mu sync.Mutex `state:"nosave"` + list segmentList `state:"wait"` limit int used int } diff --git a/pkg/tcpip/transport/tcp/segment_state.go b/pkg/tcpip/transport/tcp/segment_state.go new file mode 100644 index 000000000..e5243200b --- /dev/null +++ b/pkg/tcpip/transport/tcp/segment_state.go @@ -0,0 +1,41 @@ +// Copyright 2018 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tcp + +import ( + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" +) + +// saveData is invoked by stateify. +func (s *segment) saveData() buffer.VectorisedView { + // We cannot save s.data directly as s.data.views may alias to s.views, + // which is not allowed by state framework (in-struct pointer). + return s.data.Clone(nil) +} + +// loadData is invoked by stateify. +func (s *segment) loadData(data buffer.VectorisedView) { + // NOTE: We cannot do the s.data = data.Clone(s.views[:]) optimization + // here because data.views is not guaranteed to be loaded by now. Plus, + // data.views will be allocated anyway so there really is little point + // of utilizing s.views for data.views. + s.data = data +} + +// saveOptions is invoked by stateify. +func (s *segment) saveOptions() []byte { + // We cannot save s.options directly as it may point to s.data's trimmed + // tail, which is not allowed by state framework (in-struct pointer). + b := make([]byte, 0, cap(s.options)) + return append(b, s.options...) +} + +// loadOptions is invoked by stateify. +func (s *segment) loadOptions(options []byte) { + // NOTE: We cannot point s.options back into s.data's trimmed tail. But + // it is OK as they do not need to aliased. Plus, options is already + // allocated so there is no cost here. + s.options = options +} diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index 95bea4d88..a98aca293 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -28,7 +28,7 @@ type sender struct { ep *endpoint // lastSendTime is the timestamp when the last packet was sent. - lastSendTime time.Time + lastSendTime time.Time `state:".(unixTime)"` // dupAckCount is the number of duplicated acks received. It is used for // fast retransmit. @@ -71,7 +71,7 @@ type sender struct { rttMeasureSeqNum seqnum.Value // rttMeasureTime is the time when the rttMeasureSeqNum was sent. - rttMeasureTime time.Time + rttMeasureTime time.Time `state:".(unixTime)"` closed bool writeNext *segment diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go new file mode 100644 index 000000000..d68773a7c --- /dev/null +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -0,0 +1,39 @@ +// Copyright 2018 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tcp + +import ( + "time" +) + +type unixTime struct { + second int64 + nano int64 +} + +// saveLastSendTime is invoked by stateify. +func (s *sender) saveLastSendTime() unixTime { + return unixTime{s.lastSendTime.Unix(), s.lastSendTime.UnixNano()} +} + +// loadLastSendTime is invoked by stateify. +func (s *sender) loadLastSendTime(unix unixTime) { + s.lastSendTime = time.Unix(unix.second, unix.nano) +} + +// saveRttMeasureTime is invoked by stateify. +func (s *sender) saveRttMeasureTime() unixTime { + return unixTime{s.rttMeasureTime.Unix(), s.rttMeasureTime.UnixNano()} +} + +// loadRttMeasureTime is invoked by stateify. +func (s *sender) loadRttMeasureTime(unix unixTime) { + s.rttMeasureTime = time.Unix(unix.second, unix.nano) +} + +// afterLoad is invoked by stateify. +func (s *sender) afterLoad() { + s.resendTimer.init(&s.resendWaker) +} -- cgit v1.2.3 From 51c1e510ab79607d80d6b81c2ae8ab308c323a58 Mon Sep 17 00:00:00 2001 From: Brian Geffon Date: Tue, 26 Jun 2018 10:32:22 -0700 Subject: Automated rollback of changelist 201596247 PiperOrigin-RevId: 202151720 Change-Id: I0491172c436bbb32b977f557953ba0bc41cfe299 --- pkg/sentry/kernel/BUILD | 5 +- pkg/sentry/kernel/kernel.go | 6 - pkg/sentry/kernel/kernel_state.go | 31 ----- pkg/tcpip/stack/stack_global_state.go | 2 +- pkg/tcpip/tcpip.go | 36 ------ pkg/tcpip/transport/tcp/BUILD | 7 -- pkg/tcpip/transport/tcp/accept.go | 11 +- pkg/tcpip/transport/tcp/connect.go | 43 +------ pkg/tcpip/transport/tcp/endpoint.go | 72 +++--------- pkg/tcpip/transport/tcp/endpoint_state.go | 185 ++++++++++-------------------- pkg/tcpip/transport/tcp/segment.go | 8 +- pkg/tcpip/transport/tcp/segment_queue.go | 4 +- pkg/tcpip/transport/tcp/segment_state.go | 41 ------- pkg/tcpip/transport/tcp/snd.go | 4 +- pkg/tcpip/transport/tcp/snd_state.go | 39 ------- 15 files changed, 91 insertions(+), 403 deletions(-) delete mode 100644 pkg/sentry/kernel/kernel_state.go delete mode 100644 pkg/tcpip/transport/tcp/segment_state.go delete mode 100644 pkg/tcpip/transport/tcp/snd_state.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 07568b47c..b2a55ddff 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -12,7 +12,6 @@ go_stateify( "fs_context.go", "ipc_namespace.go", "kernel.go", - "kernel_state.go", "pending_signals.go", "pending_signals_state.go", "process_group_list.go", @@ -46,11 +45,10 @@ go_stateify( "vdso.go", "version.go", ], - out = "kernel_autogen_state.go", + out = "kernel_state.go", imports = [ "gvisor.googlesource.com/gvisor/pkg/sentry/arch", "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", - "gvisor.googlesource.com/gvisor/pkg/tcpip", ], package = "kernel", ) @@ -119,7 +117,6 @@ go_library( "fs_context.go", "ipc_namespace.go", "kernel.go", - "kernel_autogen_state.go", "kernel_state.go", "pending_signals.go", "pending_signals_list.go", diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 64439cd9d..5662b8f08 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -57,7 +57,6 @@ import ( sentrytime "gvisor.googlesource.com/gvisor/pkg/sentry/time" "gvisor.googlesource.com/gvisor/pkg/sentry/uniqueid" "gvisor.googlesource.com/gvisor/pkg/state" - "gvisor.googlesource.com/gvisor/pkg/tcpip" ) // Kernel represents an emulated Linux kernel. It must be initialized by calling @@ -159,9 +158,6 @@ type Kernel struct { // exitErr is the error causing the sandbox to exit, if any. It is // protected by extMu. exitErr error - - // danglingEndpoints is used to save / restore tcpip.DanglingEndpoints. - danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"` } // InitKernelArgs holds arguments to Init. @@ -426,8 +422,6 @@ func (k *Kernel) LoadFrom(r io.Reader, p platform.Platform, net inet.Stack) erro return err } - tcpip.AsyncLoading.Wait() - log.Infof("Overall load took [%s]", time.Since(loadStart)) // Applications may size per-cpu structures based on k.applicationCores, so diff --git a/pkg/sentry/kernel/kernel_state.go b/pkg/sentry/kernel/kernel_state.go deleted file mode 100644 index bb2d5102d..000000000 --- a/pkg/sentry/kernel/kernel_state.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2018 Google Inc. -// -// 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 kernel - -import ( - "gvisor.googlesource.com/gvisor/pkg/tcpip" -) - -// saveDanglingEndpoints is invoked by stateify. -func (k *Kernel) saveDanglingEndpoints() []tcpip.Endpoint { - return tcpip.GetDanglingEndpoints() -} - -// loadDanglingEndpoints is invoked by stateify. -func (k *Kernel) loadDanglingEndpoints(es []tcpip.Endpoint) { - for _, e := range es { - tcpip.AddDanglingEndpoint(e) - } -} diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index 260d7d05c..030ae98d1 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -5,5 +5,5 @@ package stack // StackFromEnv is the global stack created in restore run. -// FIXME +// FIXME: remove this variable once tcpip S/R is fully supported. var StackFromEnv *Stack diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 17fa0efb7..cf25a086d 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -23,7 +23,6 @@ import ( "fmt" "strconv" "strings" - "sync" "time" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" @@ -553,38 +552,3 @@ type ProtocolAddress struct { // Address is a network address. Address Address } - -// danglingEndpointsMu protects access to danglingEndpoints. -var danglingEndpointsMu sync.Mutex - -// danglingEndpoints tracks all dangling endpoints no longer owned by the app. -var danglingEndpoints = make(map[Endpoint]struct{}) - -// GetDanglingEndpoints returns all dangling endpoints. -func GetDanglingEndpoints() []Endpoint { - es := make([]Endpoint, 0, len(danglingEndpoints)) - danglingEndpointsMu.Lock() - for e, _ := range danglingEndpoints { - es = append(es, e) - } - danglingEndpointsMu.Unlock() - return es -} - -// AddDanglingEndpoint adds a dangling endpoint. -func AddDanglingEndpoint(e Endpoint) { - danglingEndpointsMu.Lock() - danglingEndpoints[e] = struct{}{} - danglingEndpointsMu.Unlock() -} - -// DeleteDanglingEndpoint removes a dangling endpoint. -func DeleteDanglingEndpoint(e Endpoint) { - danglingEndpointsMu.Lock() - delete(danglingEndpoints, e) - danglingEndpointsMu.Unlock() -} - -// AsyncLoading is the global barrier for asynchronous endpoint loading -// activities. -var AsyncLoading sync.WaitGroup diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index d129aa285..f38f58e87 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -10,16 +10,11 @@ go_stateify( "endpoint.go", "endpoint_state.go", "rcv.go", - "segment.go", "segment_heap.go", - "segment_queue.go", - "segment_state.go", "snd.go", - "snd_state.go", "tcp_segment_list.go", ], out = "tcp_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], package = "tcp", ) @@ -48,9 +43,7 @@ go_library( "segment.go", "segment_heap.go", "segment_queue.go", - "segment_state.go", "snd.go", - "snd_state.go", "tcp_segment_list.go", "tcp_state.go", "timer.go", diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index 410dfdad4..85adeef0e 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -68,8 +68,7 @@ func encodeMSS(mss uint16) uint32 { // to go above a threshold. var synRcvdCount struct { sync.Mutex - value uint64 - pending sync.WaitGroup + value uint64 } // listenContext is used by a listening endpoint to store state used while @@ -103,7 +102,6 @@ func incSynRcvdCount() bool { return false } - synRcvdCount.pending.Add(1) synRcvdCount.value++ return true @@ -117,7 +115,6 @@ func decSynRcvdCount() { defer synRcvdCount.Unlock() synRcvdCount.value-- - synRcvdCount.pending.Done() } // newListenContext creates a new listen context. @@ -295,7 +292,7 @@ func (e *endpoint) handleListenSegment(ctx *listenContext, s *segment) { opts := parseSynSegmentOptions(s) if incSynRcvdCount() { s.incRef() - go e.handleSynSegment(ctx, s, &opts) // S/R-SAFE: synRcvdCount is the barrier. + go e.handleSynSegment(ctx, s, &opts) // S/R-FIXME } else { cookie := ctx.createCookie(s.id, s.sequenceNumber, encodeMSS(opts.MSS)) // Send SYN with window scaling because we currently @@ -384,12 +381,10 @@ func (e *endpoint) protocolListenLoop(rcvWnd seqnum.Size) *tcpip.Error { return nil } if n¬ifyDrain != 0 { - for !e.segmentQueue.empty() { - s := e.segmentQueue.dequeue() + for s := e.segmentQueue.dequeue(); s != nil; s = e.segmentQueue.dequeue() { e.handleListenSegment(ctx, s) s.decRef() } - synRcvdCount.pending.Wait() close(e.drainDone) <-e.undrain } diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index d9f87c793..9aaabe0b1 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -443,8 +443,7 @@ func (h *handshake) execute() *tcpip.Error { return tcpip.ErrAborted } if n¬ifyDrain != 0 { - for !h.ep.segmentQueue.empty() { - s := h.ep.segmentQueue.dequeue() + for s := h.ep.segmentQueue.dequeue(); s != nil; s = h.ep.segmentQueue.dequeue() { err := h.handleSegment(s) s.decRef() if err != nil { @@ -814,13 +813,15 @@ func (e *endpoint) handleSegments() *tcpip.Error { // protocolMainLoop is the main loop of the TCP protocol. It runs in its own // goroutine and is responsible for sending segments and handling received // segments. -func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error { +func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { var closeTimer *time.Timer var closeWaker sleep.Waker defer func() { // e.mu is expected to be hold upon entering this section. + e.completeWorkerLocked() + if e.snd != nil { e.snd.resendTimer.cleanup() } @@ -829,8 +830,6 @@ func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error { closeTimer.Stop() } - e.completeWorkerLocked() - if e.drainDone != nil { close(e.drainDone) } @@ -841,7 +840,7 @@ func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error { e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.EventIn | waiter.EventOut) }() - if handshake { + if !passive { // This is an active connection, so we must initiate the 3-way // handshake, and then inform potential waiters about its // completion. @@ -946,17 +945,6 @@ func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error { closeWaker.Assert() }) } - - if n¬ifyDrain != 0 { - for !e.segmentQueue.empty() { - if err := e.handleSegments(); err != nil { - return err - } - } - close(e.drainDone) - <-e.undrain - } - return nil }, }, @@ -968,27 +956,6 @@ func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error { s.AddWaker(funcs[i].w, i) } - // The following assertions and notifications are needed for restored - // endpoints. Fresh newly created endpoints have empty states and should - // not invoke any. - e.segmentQueue.mu.Lock() - if !e.segmentQueue.list.Empty() { - e.newSegmentWaker.Assert() - } - e.segmentQueue.mu.Unlock() - - e.rcvListMu.Lock() - if !e.rcvList.Empty() { - e.waiterQueue.Notify(waiter.EventIn) - } - e.rcvListMu.Unlock() - - e.mu.RLock() - if e.workerCleanup { - e.notifyProtocolGoroutine(notifyClose) - } - e.mu.RUnlock() - // Main loop. Handle segments until both send and receive ends of the // connection have completed. for !e.rcv.closed || !e.snd.closed || e.snd.sndUna != e.snd.sndNxtList { diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 706977618..b21c2b4ab 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -69,7 +69,7 @@ type endpoint struct { // change throughout the lifetime of the endpoint. stack *stack.Stack `state:"manual"` netProto tcpip.NetworkProtocolNumber - waiterQueue *waiter.Queue `state:"wait"` + waiterQueue *waiter.Queue // lastError represents the last error that the endpoint reported; // access to it is protected by the following mutex. @@ -82,8 +82,8 @@ type endpoint struct { // // Once the peer has closed its send side, rcvClosed is set to true // to indicate to users that no more data is coming. - rcvListMu sync.Mutex `state:"nosave"` - rcvList segmentList `state:"wait"` + rcvListMu sync.Mutex `state:"nosave"` + rcvList segmentList rcvClosed bool rcvBufSize int rcvBufUsed int @@ -91,8 +91,8 @@ type endpoint struct { // The following fields are protected by the mutex. mu sync.RWMutex `state:"nosave"` id stack.TransportEndpointID - state endpointState `state:".(endpointState)"` - isPortReserved bool `state:"manual"` + state endpointState + isPortReserved bool `state:"manual"` isRegistered bool boundNICID tcpip.NICID `state:"manual"` route stack.Route `state:"manual"` @@ -118,7 +118,7 @@ type endpoint struct { // workerCleanup specifies if the worker goroutine must perform cleanup // before exitting. This can only be set to true when workerRunning is // also true, and they're both protected by the mutex. - workerCleanup bool + workerCleanup bool `state:"zerovalue"` // sendTSOk is used to indicate when the TS Option has been negotiated. // When sendTSOk is true every non-RST segment should carry a TS as per @@ -153,7 +153,7 @@ type endpoint struct { // segmentQueue is used to hand received segments to the protocol // goroutine. Segments are queued as long as the queue is not full, // and dropped when it is. - segmentQueue segmentQueue `state:"wait"` + segmentQueue segmentQueue `state:"zerovalue"` // The following fields are used to manage the send buffer. When // segments are ready to be sent, they are added to sndQueue and the @@ -166,7 +166,7 @@ type endpoint struct { sndBufUsed int sndClosed bool sndBufInQueue seqnum.Size - sndQueue segmentList `state:"wait"` + sndQueue segmentList sndWaker sleep.Waker `state:"manual"` sndCloseWaker sleep.Waker `state:"manual"` @@ -188,21 +188,17 @@ type endpoint struct { // notifyFlags is a bitmask of flags used to indicate to the protocol // goroutine what it was notified; this is only accessed atomically. - notifyFlags uint32 `state:"nosave"` + notifyFlags uint32 `state:"zerovalue"` // acceptedChan is used by a listening endpoint protocol goroutine to // send newly accepted connections to the endpoint so that they can be // read by Accept() calls. - acceptedChan chan *endpoint `state:"manual"` - - // acceptedEndpoints is only used to save / restore the channel buffer. - // FIXME - acceptedEndpoints []*endpoint + acceptedChan chan *endpoint `state:".(endpointChan)"` // The following are only used from the protocol goroutine, and // therefore don't need locks to protect them. - rcv *receiver `state:"wait"` - snd *sender `state:"wait"` + rcv *receiver + snd *sender // The goroutine drain completion notification channel. drainDone chan struct{} `state:"nosave"` @@ -215,7 +211,6 @@ type endpoint struct { probe stack.TCPProbeFunc `state:"nosave"` // The following are only used to assist the restore run to re-connect. - bindAddress tcpip.Address connectingAddress tcpip.Address } @@ -349,7 +344,6 @@ func (e *endpoint) Close() { // Either perform the local cleanup or kick the worker to make sure it // knows it needs to cleanup. - tcpip.AddDanglingEndpoint(e) if !e.workerRunning { e.cleanupLocked() } else { @@ -369,12 +363,9 @@ func (e *endpoint) cleanupLocked() { if e.acceptedChan != nil { close(e.acceptedChan) for n := range e.acceptedChan { - n.mu.Lock() n.resetConnectionLocked(tcpip.ErrConnectionAborted) - n.mu.Unlock() n.Close() } - e.acceptedChan = nil } e.workerCleanup = false @@ -383,7 +374,6 @@ func (e *endpoint) cleanupLocked() { } e.route.Release() - tcpip.DeleteDanglingEndpoint(e) } // Read reads data from the endpoint. @@ -796,16 +786,6 @@ func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress) (tcpip.NetworkProtocol // Connect connects the endpoint to its peer. func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { - return e.connect(addr, true, true) -} - -// connect connects the endpoint to its peer. In the normal non-S/R case, the -// new connection is expected to run the main goroutine and perform handshake. -// In restore of previously connected endpoints, both ends will be passively -// created (so no new handshaking is done); for stack-accepted connections not -// yet accepted by the app, they are restored without running the main goroutine -// here. -func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) *tcpip.Error { e.mu.Lock() defer e.mu.Unlock() @@ -917,27 +897,9 @@ func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) *tc e.boundNICID = nicid e.effectiveNetProtos = netProtos e.connectingAddress = connectingAddr + e.workerRunning = true - // Connect in the restore phase does not perform handshake. Restore its - // connection setting here. - if !handshake { - e.segmentQueue.mu.Lock() - for _, l := range []segmentList{e.segmentQueue.list, e.sndQueue, e.snd.writeList} { - for s := l.Front(); s != nil; s = s.Next() { - s.id = e.id - s.route = r.Clone() - e.sndWaker.Assert() - } - } - e.segmentQueue.mu.Unlock() - e.snd.updateMaxPayloadSize(int(e.route.MTU()), 0) - e.state = stateConnected - } - - if run { - e.workerRunning = true - go e.protocolMainLoop(handshake) // S/R-SAFE: will be drained before save. - } + go e.protocolMainLoop(false) // S/R-SAFE: will be drained before save. return tcpip.ErrConnectStarted } @@ -1009,9 +971,6 @@ func (e *endpoint) Listen(backlog int) *tcpip.Error { if len(e.acceptedChan) > backlog { return tcpip.ErrInvalidEndpointState } - if cap(e.acceptedChan) == backlog { - return nil - } origChan := e.acceptedChan e.acceptedChan = make(chan *endpoint, backlog) close(origChan) @@ -1049,7 +1008,7 @@ func (e *endpoint) Listen(backlog int) *tcpip.Error { func (e *endpoint) startAcceptedLoop(waiterQueue *waiter.Queue) { e.waiterQueue = waiterQueue e.workerRunning = true - go e.protocolMainLoop(false) // S/R-SAFE: drained on save. + go e.protocolMainLoop(true) // S/R-FIXME } // Accept returns a new endpoint if a peer has established a connection @@ -1090,7 +1049,6 @@ func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) (ret return tcpip.ErrAlreadyBound } - e.bindAddress = addr.Addr netProto, err := e.checkV4Mapped(&addr) if err != nil { return err diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index 38c97c796..b1e249bff 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -9,7 +9,6 @@ import ( "sync" "gvisor.googlesource.com/gvisor/pkg/tcpip" - "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" ) @@ -23,7 +22,7 @@ func (e *endpoint) drainSegmentLocked() { e.undrain = make(chan struct{}) e.mu.Unlock() - e.notifyProtocolGoroutine(notifyDrain) + e.notificationWaker.Assert() <-e.drainDone e.mu.Lock() @@ -39,98 +38,37 @@ func (e *endpoint) beforeSave() { switch e.state { case stateInitial, stateBound: - case stateListen, stateConnecting, stateConnected: - if e.state == stateConnected && !e.workerRunning { - // The endpoint must be in acceptedChan. - break + case stateListen: + if !e.segmentQueue.empty() { + e.drainSegmentLocked() } + case stateConnecting: e.drainSegmentLocked() - if e.state != stateClosed && e.state != stateError { - if !e.workerRunning { - panic("endpoint has no worker running in listen, connecting, or connected state") - } + if e.state != stateConnected { break } fallthrough + case stateConnected: + // FIXME + panic(tcpip.ErrSaveRejection{fmt.Errorf("endpoint cannot be saved in connected state: local %v:%v, remote %v:%v", e.id.LocalAddress, e.id.LocalPort, e.id.RemoteAddress, e.id.RemotePort)}) case stateClosed, stateError: if e.workerRunning { - panic("endpoint still has worker running in closed or error state") + panic(fmt.Sprintf("endpoint still has worker running in closed or error state")) } default: panic(fmt.Sprintf("endpoint in unknown state %v", e.state)) } - - if e.waiterQueue != nil && !e.waiterQueue.IsEmpty() { - panic("endpoint still has waiters upon save") - } - - if !((e.state == stateBound || e.state == stateListen) == e.isPortReserved) { - panic("endpoint port must and must only be reserved in bound or listen state") - } - - if e.acceptedChan != nil { - close(e.acceptedChan) - e.acceptedEndpoints = make([]*endpoint, len(e.acceptedChan), cap(e.acceptedChan)) - i := 0 - for ep := range e.acceptedChan { - e.acceptedEndpoints[i] = ep - i++ - } - if i != len(e.acceptedEndpoints) { - panic("endpoint acceptedChan buffer got consumed by background context") - } - } -} - -// saveState is invoked by stateify. -func (e *endpoint) saveState() endpointState { - return e.state -} - -// Endpoint loading must be done in the following ordering by their state, to -// avoid dangling connecting w/o listening peer, and to avoid conflicts in port -// reservation. -var connectedLoading sync.WaitGroup -var listenLoading sync.WaitGroup -var connectingLoading sync.WaitGroup - -// Bound endpoint loading happens last. - -// loadState is invoked by stateify. -func (e *endpoint) loadState(state endpointState) { - // This is to ensure that the loading wait groups include all applicable - // endpoints before any asynchronous calls to the Wait() methods. - switch state { - case stateConnected: - connectedLoading.Add(1) - case stateListen: - listenLoading.Add(1) - case stateConnecting: - connectingLoading.Add(1) - } - e.state = state } // afterLoad is invoked by stateify. func (e *endpoint) afterLoad() { - // We load acceptedChan buffer indirectly here. Note that closed - // endpoints might not need to allocate the channel. - // FIXME - if cap(e.acceptedEndpoints) > 0 { - e.acceptedChan = make(chan *endpoint, cap(e.acceptedEndpoints)) - for _, ep := range e.acceptedEndpoints { - e.acceptedChan <- ep - } - e.acceptedEndpoints = nil - } - e.stack = stack.StackFromEnv e.segmentQueue.setLimit(2 * e.rcvBufSize) e.workMu.Init() state := e.state switch state { - case stateInitial, stateBound, stateListen, stateConnecting, stateConnected: + case stateInitial, stateBound, stateListen, stateConnecting: var ss SendBufferSizeOption if err := e.stack.TransportProtocolOption(ProtocolNumber, &ss); err == nil { if e.sndBufSize < ss.Min || e.sndBufSize > ss.Max { @@ -142,72 +80,65 @@ func (e *endpoint) afterLoad() { } } - bind := func() { + switch state { + case stateBound, stateListen, stateConnecting: e.state = stateInitial - if len(e.bindAddress) == 0 { - e.bindAddress = e.id.LocalAddress - } - if err := e.Bind(tcpip.FullAddress{Addr: e.bindAddress, Port: e.id.LocalPort}, nil); err != nil { + if err := e.Bind(tcpip.FullAddress{Addr: e.id.LocalAddress, Port: e.id.LocalPort}, nil); err != nil { panic("endpoint binding failed: " + err.String()) } } switch state { - case stateConnected: - bind() - if len(e.connectingAddress) == 0 { - // This endpoint is accepted by netstack but not yet by - // the app. If the endpoint is IPv6 but the remote - // address is IPv4, we need to connect as IPv6 so that - // dual-stack mode can be properly activated. - if e.netProto == header.IPv6ProtocolNumber && len(e.id.RemoteAddress) != header.IPv6AddressSize { - e.connectingAddress = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + e.id.RemoteAddress - } else { - e.connectingAddress = e.id.RemoteAddress - } + case stateListen: + backlog := cap(e.acceptedChan) + e.acceptedChan = nil + if err := e.Listen(backlog); err != nil { + panic("endpoint listening failed: " + err.String()) } - if err := e.connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}, false, e.workerRunning); err != tcpip.ErrConnectStarted { + } + + switch state { + case stateConnecting: + if err := e.Connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}); err != tcpip.ErrConnectStarted { panic("endpoint connecting failed: " + err.String()) } - connectedLoading.Done() - case stateListen: - tcpip.AsyncLoading.Add(1) - go func() { - connectedLoading.Wait() - bind() - backlog := cap(e.acceptedChan) - if err := e.Listen(backlog); err != nil { - panic("endpoint listening failed: " + err.String()) - } - listenLoading.Done() - tcpip.AsyncLoading.Done() - }() - case stateConnecting: - tcpip.AsyncLoading.Add(1) - go func() { - connectedLoading.Wait() - listenLoading.Wait() - bind() - if err := e.Connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}); err != tcpip.ErrConnectStarted { - panic("endpoint connecting failed: " + err.String()) - } - connectingLoading.Done() - tcpip.AsyncLoading.Done() - }() - case stateBound: - tcpip.AsyncLoading.Add(1) - go func() { - connectedLoading.Wait() - listenLoading.Wait() - connectingLoading.Wait() - bind() - tcpip.AsyncLoading.Done() - }() - case stateClosed, stateError: - tcpip.DeleteDanglingEndpoint(e) } } +// saveAcceptedChan is invoked by stateify. +func (e *endpoint) saveAcceptedChan() endpointChan { + if e.acceptedChan == nil { + return endpointChan{} + } + close(e.acceptedChan) + buffer := make([]*endpoint, 0, len(e.acceptedChan)) + for ep := range e.acceptedChan { + buffer = append(buffer, ep) + } + if len(buffer) != cap(buffer) { + panic("endpoint.acceptedChan buffer got consumed by background context") + } + c := cap(e.acceptedChan) + e.acceptedChan = nil + return endpointChan{buffer: buffer, cap: c} +} + +// loadAcceptedChan is invoked by stateify. +func (e *endpoint) loadAcceptedChan(c endpointChan) { + if c.cap == 0 { + return + } + e.acceptedChan = make(chan *endpoint, c.cap) + for _, ep := range c.buffer { + e.acceptedChan <- ep + } +} + +type endpointChan struct { + buffer []*endpoint + cap int +} + // saveLastError is invoked by stateify. func (e *endpoint) saveLastError() string { if e.lastError == nil { diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index c5bff5f4f..07e4bfd73 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -29,9 +29,9 @@ const ( type segment struct { segmentEntry refCnt int32 - id stack.TransportEndpointID `state:"manual"` - route stack.Route `state:"manual"` - data buffer.VectorisedView `state:".(buffer.VectorisedView)"` + id stack.TransportEndpointID + route stack.Route `state:"manual"` + data buffer.VectorisedView // views is used as buffer for data when its length is large // enough to store a VectorisedView. views [8]buffer.View @@ -45,7 +45,7 @@ type segment struct { // parsedOptions stores the parsed values from the options in the segment. parsedOptions header.TCPOptions - options []byte `state:".([]byte)"` + options []byte } func newSegment(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) *segment { diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index a5e7b2ebf..c4a7f7d5b 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -12,8 +12,8 @@ import ( // segmentQueue is a bounded, thread-safe queue of TCP segments. type segmentQueue struct { - mu sync.Mutex `state:"nosave"` - list segmentList `state:"wait"` + mu sync.Mutex + list segmentList limit int used int } diff --git a/pkg/tcpip/transport/tcp/segment_state.go b/pkg/tcpip/transport/tcp/segment_state.go deleted file mode 100644 index e5243200b..000000000 --- a/pkg/tcpip/transport/tcp/segment_state.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2018 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tcp - -import ( - "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" -) - -// saveData is invoked by stateify. -func (s *segment) saveData() buffer.VectorisedView { - // We cannot save s.data directly as s.data.views may alias to s.views, - // which is not allowed by state framework (in-struct pointer). - return s.data.Clone(nil) -} - -// loadData is invoked by stateify. -func (s *segment) loadData(data buffer.VectorisedView) { - // NOTE: We cannot do the s.data = data.Clone(s.views[:]) optimization - // here because data.views is not guaranteed to be loaded by now. Plus, - // data.views will be allocated anyway so there really is little point - // of utilizing s.views for data.views. - s.data = data -} - -// saveOptions is invoked by stateify. -func (s *segment) saveOptions() []byte { - // We cannot save s.options directly as it may point to s.data's trimmed - // tail, which is not allowed by state framework (in-struct pointer). - b := make([]byte, 0, cap(s.options)) - return append(b, s.options...) -} - -// loadOptions is invoked by stateify. -func (s *segment) loadOptions(options []byte) { - // NOTE: We cannot point s.options back into s.data's trimmed tail. But - // it is OK as they do not need to aliased. Plus, options is already - // allocated so there is no cost here. - s.options = options -} diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index a98aca293..95bea4d88 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -28,7 +28,7 @@ type sender struct { ep *endpoint // lastSendTime is the timestamp when the last packet was sent. - lastSendTime time.Time `state:".(unixTime)"` + lastSendTime time.Time // dupAckCount is the number of duplicated acks received. It is used for // fast retransmit. @@ -71,7 +71,7 @@ type sender struct { rttMeasureSeqNum seqnum.Value // rttMeasureTime is the time when the rttMeasureSeqNum was sent. - rttMeasureTime time.Time `state:".(unixTime)"` + rttMeasureTime time.Time closed bool writeNext *segment diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go deleted file mode 100644 index d68773a7c..000000000 --- a/pkg/tcpip/transport/tcp/snd_state.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2018 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tcp - -import ( - "time" -) - -type unixTime struct { - second int64 - nano int64 -} - -// saveLastSendTime is invoked by stateify. -func (s *sender) saveLastSendTime() unixTime { - return unixTime{s.lastSendTime.Unix(), s.lastSendTime.UnixNano()} -} - -// loadLastSendTime is invoked by stateify. -func (s *sender) loadLastSendTime(unix unixTime) { - s.lastSendTime = time.Unix(unix.second, unix.nano) -} - -// saveRttMeasureTime is invoked by stateify. -func (s *sender) saveRttMeasureTime() unixTime { - return unixTime{s.rttMeasureTime.Unix(), s.rttMeasureTime.UnixNano()} -} - -// loadRttMeasureTime is invoked by stateify. -func (s *sender) loadRttMeasureTime(unix unixTime) { - s.rttMeasureTime = time.Unix(unix.second, unix.nano) -} - -// afterLoad is invoked by stateify. -func (s *sender) afterLoad() { - s.resendTimer.init(&s.resendWaker) -} -- cgit v1.2.3 From 0ef606616732e1daf9d424658c31e5fed8f1ee4a Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Tue, 3 Jul 2018 11:38:08 -0700 Subject: Resend packets back to netstack if destined to itself Add option to redirect packet back to netstack if it's destined to itself. This fixes the problem where connecting to the local NIC address would not work, e.g.: echo bar | nc -l -p 8080 & echo foo | nc 192.168.0.2 8080 PiperOrigin-RevId: 203157739 Change-Id: I31c9f7c501e3f55007f25e1852c27893a16ac6c4 --- pkg/tcpip/link/fdbased/endpoint.go | 51 +++++++++++++++++++++++--------------- pkg/tcpip/stack/nic.go | 3 +-- pkg/tcpip/stack/route.go | 16 ++++++++---- pkg/tcpip/stack/stack.go | 2 +- runsc/boot/network.go | 9 +++---- 5 files changed, 48 insertions(+), 33 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 668514454..0c844c05b 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -45,10 +45,14 @@ type endpoint struct { // its end of the communication pipe. closed func(*tcpip.Error) - vv *buffer.VectorisedView - iovecs []syscall.Iovec - views []buffer.View - attached bool + vv *buffer.VectorisedView + iovecs []syscall.Iovec + views []buffer.View + dispatcher stack.NetworkDispatcher + + // egressLocal indicates whether packets destined to itself should be + // forwarded to the FD endpoint (true) or be sent back to netstack (false). + egressLocal bool } // Options specify the details about the fd-based endpoint to be created. @@ -59,6 +63,7 @@ type Options struct { ChecksumOffload bool ClosedFunc func(*tcpip.Error) Address tcpip.LinkAddress + EgressLocal bool } // New creates a new fd-based endpoint. @@ -80,14 +85,15 @@ func New(opts *Options) tcpip.LinkEndpointID { } e := &endpoint{ - fd: opts.FD, - mtu: opts.MTU, - caps: caps, - closed: opts.ClosedFunc, - addr: opts.Address, - hdrSize: hdrSize, - views: make([]buffer.View, len(BufConfig)), - iovecs: make([]syscall.Iovec, len(BufConfig)), + fd: opts.FD, + mtu: opts.MTU, + caps: caps, + closed: opts.ClosedFunc, + addr: opts.Address, + hdrSize: hdrSize, + views: make([]buffer.View, len(BufConfig)), + iovecs: make([]syscall.Iovec, len(BufConfig)), + egressLocal: opts.EgressLocal, } vv := buffer.NewVectorisedView(0, e.views) e.vv = &vv @@ -97,13 +103,13 @@ func New(opts *Options) tcpip.LinkEndpointID { // Attach launches the goroutine that reads packets from the file descriptor and // dispatches them via the provided dispatcher. func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { - e.attached = true - go e.dispatchLoop(dispatcher) // S/R-FIXME + e.dispatcher = dispatcher + go e.dispatchLoop() // S/R-FIXME } // IsAttached implements stack.LinkEndpoint.IsAttached. func (e *endpoint) IsAttached() bool { - return e.attached + return e.dispatcher != nil } // MTU implements stack.LinkEndpoint.MTU. It returns the value initialized @@ -130,6 +136,12 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { + if !e.egressLocal && r.LocalAddress != "" && r.LocalAddress == r.RemoteAddress { + hdrView := hdr.View() + vv := buffer.NewVectorisedView(len(hdrView)+len(payload), []buffer.View{hdrView, payload}) + e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, &vv) + return nil + } if e.hdrSize > 0 { // Add ethernet header if needed. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) @@ -142,7 +154,6 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload if len(payload) == 0 { return rawfile.NonBlockingWrite(e.fd, hdr.UsedBytes()) - } return rawfile.NonBlockingWrite2(e.fd, hdr.UsedBytes(), payload) @@ -175,7 +186,7 @@ func (e *endpoint) allocateViews(bufConfig []int) { } // dispatch reads one packet from the file descriptor and dispatches it. -func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool, *tcpip.Error) { +func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { e.allocateViews(BufConfig) n, err := rawfile.BlockingReadv(e.fd, e.iovecs) @@ -211,7 +222,7 @@ func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool e.vv.SetSize(n) e.vv.TrimFront(e.hdrSize) - d.DeliverNetworkPacket(e, addr, p, e.vv) + e.dispatcher.DeliverNetworkPacket(e, addr, p, e.vv) // Prepare e.views for another packet: release used views. for i := 0; i < used; i++ { @@ -223,10 +234,10 @@ func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool // dispatchLoop reads packets from the file descriptor in a loop and dispatches // them to the network stack. -func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) *tcpip.Error { +func (e *endpoint) dispatchLoop() *tcpip.Error { v := buffer.NewView(header.MaxIPPacketSize) for { - cont, err := e.dispatch(d, v) + cont, err := e.dispatch(v) if err != nil || !cont { if e.closed != nil { e.closed(err) diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 8ff4310d5..06bb5abc5 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -317,8 +317,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin return } - r := makeRoute(protocol, dst, src, ref) - r.LocalLinkAddress = linkEP.LinkAddress() + r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) r.RemoteLinkAddress = remoteLinkAddr ref.ep.HandlePacket(&r, vv) ref.decRef() diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 12f5efba5..e4f10cfa1 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -40,12 +40,13 @@ type Route struct { // makeRoute initializes a new route. It takes ownership of the provided // reference to a network endpoint. -func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, ref *referencedNetworkEndpoint) Route { +func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, localLinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint) Route { return Route{ - NetProto: netProto, - LocalAddress: localAddr, - RemoteAddress: remoteAddr, - ref: ref, + NetProto: netProto, + LocalAddress: localAddr, + LocalLinkAddress: localLinkAddr, + RemoteAddress: remoteAddr, + ref: ref, } } @@ -82,6 +83,11 @@ func (r *Route) Resolve(waker *sleep.Waker) *tcpip.Error { nextAddr := r.NextHop if nextAddr == "" { + // Local link address is already known. + if r.RemoteAddress == r.LocalAddress { + r.RemoteLinkAddress = r.LocalLinkAddress + return nil + } nextAddr = r.RemoteAddress } linkAddr, err := r.ref.linkCache.GetLinkAddress(r.ref.nic.ID(), nextAddr, r.LocalAddress, r.NetProto, waker) diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 3976f585c..d1d762a8e 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -647,7 +647,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n remoteAddr = ref.ep.ID().LocalAddress } - r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, ref) + r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref) r.NextHop = s.routeTable[i].Gateway return r, nil } diff --git a/runsc/boot/network.go b/runsc/boot/network.go index d2b52c823..df45218b9 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -134,11 +134,10 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct } linkEP := fdbased.New(&fdbased.Options{ - FD: newFD, - MTU: uint32(link.MTU), - ChecksumOffload: false, - EthernetHeader: true, - Address: tcpip.LinkAddress(generateRndMac()), + FD: newFD, + MTU: uint32(link.MTU), + EthernetHeader: true, + Address: tcpip.LinkAddress(generateRndMac()), }) log.Infof("Enabling interface %q with id %d on addresses %+v", link.Name, nicID, link.Addresses) -- cgit v1.2.3 From bf0fa0953763035df6af6fdf7eab3b8c163d90e0 Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Mon, 9 Jul 2018 14:03:03 -0700 Subject: Switch netstack licenses to Apache 2.0. Fixes #27 PiperOrigin-RevId: 203825288 Change-Id: Ie9f3a2b2c1e296b026b024f75c07da1a7e118633 --- pkg/dhcp/BUILD | 2 +- pkg/dhcp/client.go | 16 +++++++++++++--- pkg/dhcp/dhcp.go | 16 +++++++++++++--- pkg/dhcp/dhcp_test.go | 16 +++++++++++++--- pkg/dhcp/server.go | 16 +++++++++++++--- pkg/gate/BUILD | 2 +- pkg/gate/gate.go | 16 +++++++++++++--- pkg/gate/gate_test.go | 16 +++++++++++++--- pkg/ilist/BUILD | 2 +- pkg/ilist/list.go | 16 +++++++++++++--- pkg/ilist/list_test.go | 16 +++++++++++++--- pkg/sleep/BUILD | 2 +- pkg/sleep/commit_amd64.s | 16 +++++++++++++--- pkg/sleep/commit_arm64.s | 16 +++++++++++++--- pkg/sleep/commit_asm.go | 16 +++++++++++++--- pkg/sleep/commit_noasm.go | 16 +++++++++++++--- pkg/sleep/sleep_test.go | 16 +++++++++++++--- pkg/sleep/sleep_unsafe.go | 16 +++++++++++++--- pkg/tcpip/BUILD | 2 +- pkg/tcpip/adapters/gonet/BUILD | 2 +- pkg/tcpip/adapters/gonet/gonet.go | 16 +++++++++++++--- pkg/tcpip/adapters/gonet/gonet_test.go | 16 +++++++++++++--- pkg/tcpip/buffer/BUILD | 2 +- pkg/tcpip/buffer/prependable.go | 16 +++++++++++++--- pkg/tcpip/buffer/view.go | 16 +++++++++++++--- pkg/tcpip/buffer/view_test.go | 16 +++++++++++++--- pkg/tcpip/checker/BUILD | 2 +- pkg/tcpip/checker/checker.go | 16 +++++++++++++--- pkg/tcpip/header/BUILD | 2 +- pkg/tcpip/header/arp.go | 16 +++++++++++++--- pkg/tcpip/header/checksum.go | 16 +++++++++++++--- pkg/tcpip/header/eth.go | 16 +++++++++++++--- pkg/tcpip/header/gue.go | 16 +++++++++++++--- pkg/tcpip/header/icmpv4.go | 16 +++++++++++++--- pkg/tcpip/header/icmpv6.go | 16 +++++++++++++--- pkg/tcpip/header/interfaces.go | 16 +++++++++++++--- pkg/tcpip/header/ipv4.go | 16 +++++++++++++--- pkg/tcpip/header/ipv6.go | 16 +++++++++++++--- pkg/tcpip/header/ipv6_fragment.go | 16 +++++++++++++--- pkg/tcpip/header/ipversion_test.go | 16 +++++++++++++--- pkg/tcpip/header/tcp.go | 16 +++++++++++++--- pkg/tcpip/header/tcp_test.go | 16 +++++++++++++--- pkg/tcpip/header/udp.go | 16 +++++++++++++--- pkg/tcpip/link/channel/BUILD | 2 +- pkg/tcpip/link/channel/channel.go | 16 +++++++++++++--- pkg/tcpip/link/fdbased/BUILD | 2 +- pkg/tcpip/link/fdbased/endpoint.go | 16 +++++++++++++--- pkg/tcpip/link/fdbased/endpoint_test.go | 16 +++++++++++++--- pkg/tcpip/link/loopback/BUILD | 2 +- pkg/tcpip/link/loopback/loopback.go | 16 +++++++++++++--- pkg/tcpip/link/rawfile/BUILD | 2 +- pkg/tcpip/link/rawfile/blockingpoll_amd64.s | 16 +++++++++++++--- pkg/tcpip/link/rawfile/blockingpoll_unsafe.go | 16 +++++++++++++--- pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go | 16 +++++++++++++--- pkg/tcpip/link/rawfile/errors.go | 16 +++++++++++++--- pkg/tcpip/link/rawfile/rawfile_unsafe.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/BUILD | 2 +- pkg/tcpip/link/sharedmem/pipe/BUILD | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/pipe/pipe_test.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/pipe/rx.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/pipe/tx.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/queue/BUILD | 2 +- pkg/tcpip/link/sharedmem/queue/queue_test.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/queue/rx.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/queue/tx.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/rx.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/sharedmem.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/sharedmem_test.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/sharedmem_unsafe.go | 16 +++++++++++++--- pkg/tcpip/link/sharedmem/tx.go | 16 +++++++++++++--- pkg/tcpip/link/sniffer/BUILD | 2 +- pkg/tcpip/link/sniffer/pcap.go | 16 +++++++++++++--- pkg/tcpip/link/sniffer/sniffer.go | 16 +++++++++++++--- pkg/tcpip/link/tun/BUILD | 2 +- pkg/tcpip/link/tun/tun_unsafe.go | 16 +++++++++++++--- pkg/tcpip/link/waitable/BUILD | 2 +- pkg/tcpip/link/waitable/waitable.go | 16 +++++++++++++--- pkg/tcpip/link/waitable/waitable_test.go | 16 +++++++++++++--- pkg/tcpip/network/BUILD | 2 +- pkg/tcpip/network/arp/BUILD | 2 +- pkg/tcpip/network/arp/arp.go | 16 +++++++++++++--- pkg/tcpip/network/arp/arp_test.go | 16 +++++++++++++--- pkg/tcpip/network/fragmentation/BUILD | 2 +- pkg/tcpip/network/fragmentation/frag_heap.go | 16 +++++++++++++--- pkg/tcpip/network/fragmentation/frag_heap_test.go | 16 +++++++++++++--- pkg/tcpip/network/fragmentation/fragmentation.go | 16 +++++++++++++--- pkg/tcpip/network/fragmentation/fragmentation_test.go | 16 +++++++++++++--- pkg/tcpip/network/fragmentation/reassembler.go | 16 +++++++++++++--- pkg/tcpip/network/fragmentation/reassembler_test.go | 16 +++++++++++++--- pkg/tcpip/network/hash/BUILD | 2 +- pkg/tcpip/network/hash/hash.go | 16 +++++++++++++--- pkg/tcpip/network/ip_test.go | 16 +++++++++++++--- pkg/tcpip/network/ipv4/BUILD | 2 +- pkg/tcpip/network/ipv4/icmp.go | 16 +++++++++++++--- pkg/tcpip/network/ipv4/ipv4.go | 16 +++++++++++++--- pkg/tcpip/network/ipv6/BUILD | 2 +- pkg/tcpip/network/ipv6/icmp.go | 16 +++++++++++++--- pkg/tcpip/network/ipv6/ipv6.go | 16 +++++++++++++--- pkg/tcpip/ports/BUILD | 2 +- pkg/tcpip/ports/ports.go | 16 +++++++++++++--- pkg/tcpip/ports/ports_test.go | 16 +++++++++++++--- pkg/tcpip/sample/tun_tcp_connect/BUILD | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 16 +++++++++++++--- pkg/tcpip/sample/tun_tcp_echo/BUILD | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 16 +++++++++++++--- pkg/tcpip/seqnum/BUILD | 2 +- pkg/tcpip/seqnum/seqnum.go | 16 +++++++++++++--- pkg/tcpip/stack/BUILD | 2 +- pkg/tcpip/stack/linkaddrcache.go | 16 +++++++++++++--- pkg/tcpip/stack/linkaddrcache_test.go | 16 +++++++++++++--- pkg/tcpip/stack/nic.go | 16 +++++++++++++--- pkg/tcpip/stack/registration.go | 16 +++++++++++++--- pkg/tcpip/stack/route.go | 16 +++++++++++++--- pkg/tcpip/stack/stack.go | 16 +++++++++++++--- pkg/tcpip/stack/stack_global_state.go | 16 +++++++++++++--- pkg/tcpip/stack/stack_test.go | 16 +++++++++++++--- pkg/tcpip/stack/transport_demuxer.go | 16 +++++++++++++--- pkg/tcpip/stack/transport_test.go | 16 +++++++++++++--- pkg/tcpip/tcpip.go | 16 +++++++++++++--- pkg/tcpip/tcpip_test.go | 16 +++++++++++++--- pkg/tcpip/transport/ping/BUILD | 2 +- pkg/tcpip/transport/ping/endpoint.go | 16 +++++++++++++--- pkg/tcpip/transport/ping/endpoint_state.go | 16 +++++++++++++--- pkg/tcpip/transport/ping/protocol.go | 16 +++++++++++++--- pkg/tcpip/transport/queue/BUILD | 2 +- pkg/tcpip/transport/queue/queue.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/BUILD | 2 +- pkg/tcpip/transport/tcp/accept.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/connect.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/dual_stack_test.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/endpoint.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/endpoint_state.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/forwarder.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/protocol.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/rcv.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/sack.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/segment.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/segment_heap.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/segment_queue.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/snd.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/tcp_sack_test.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/tcp_test.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/testing/context/BUILD | 2 +- pkg/tcpip/transport/tcp/testing/context/context.go | 16 +++++++++++++--- pkg/tcpip/transport/tcp/timer.go | 16 +++++++++++++--- pkg/tcpip/transport/tcpconntrack/BUILD | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go | 16 +++++++++++++--- pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go | 16 +++++++++++++--- pkg/tcpip/transport/udp/BUILD | 2 +- pkg/tcpip/transport/udp/endpoint.go | 16 +++++++++++++--- pkg/tcpip/transport/udp/endpoint_state.go | 16 +++++++++++++--- pkg/tcpip/transport/udp/protocol.go | 16 +++++++++++++--- pkg/tcpip/transport/udp/udp_test.go | 16 +++++++++++++--- pkg/tcpip/transport/unix/BUILD | 2 +- pkg/tcpip/transport/unix/connectioned.go | 16 +++++++++++++--- pkg/tcpip/transport/unix/connectioned_state.go | 16 +++++++++++++--- pkg/tcpip/transport/unix/connectionless.go | 16 +++++++++++++--- pkg/tcpip/transport/unix/unix.go | 16 +++++++++++++--- pkg/tmutex/BUILD | 2 +- pkg/tmutex/tmutex.go | 16 +++++++++++++--- pkg/tmutex/tmutex_test.go | 16 +++++++++++++--- pkg/waiter/BUILD | 2 +- pkg/waiter/waiter.go | 16 +++++++++++++--- pkg/waiter/waiter_test.go | 16 +++++++++++++--- 167 files changed, 1703 insertions(+), 423 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/BUILD b/pkg/dhcp/BUILD index 3564da7e7..f56969ad8 100644 --- a/pkg/dhcp/BUILD +++ b/pkg/dhcp/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 09b724b48..8b5fc0452 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 dhcp diff --git a/pkg/dhcp/dhcp.go b/pkg/dhcp/dhcp.go index 762086853..18c318fc8 100644 --- a/pkg/dhcp/dhcp.go +++ b/pkg/dhcp/dhcp.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 dhcp implements a DHCP client and server as described in RFC 2131. package dhcp diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index ed884fcb6..565b64045 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 dhcp diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index 8816203a8..0beac7782 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 dhcp diff --git a/pkg/gate/BUILD b/pkg/gate/BUILD index 381474d9e..0b8b01da8 100644 --- a/pkg/gate/BUILD +++ b/pkg/gate/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/gate/gate.go b/pkg/gate/gate.go index 4b332a725..93808c9dd 100644 --- a/pkg/gate/gate.go +++ b/pkg/gate/gate.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 gate provides a usage Gate synchronization primitive. package gate diff --git a/pkg/gate/gate_test.go b/pkg/gate/gate_test.go index b7f6f54fb..06587339b 100644 --- a/pkg/gate/gate_test.go +++ b/pkg/gate/gate_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 gate_test diff --git a/pkg/ilist/BUILD b/pkg/ilist/BUILD index 937ac3876..16a738e89 100644 --- a/pkg/ilist/BUILD +++ b/pkg/ilist/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/pkg/ilist/list.go b/pkg/ilist/list.go index 739575f17..5efb6c072 100644 --- a/pkg/ilist/list.go +++ b/pkg/ilist/list.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ilist provides the implementation of intrusive linked lists. package ilist diff --git a/pkg/ilist/list_test.go b/pkg/ilist/list_test.go index 7f2b90e0c..2c56280f6 100644 --- a/pkg/ilist/list_test.go +++ b/pkg/ilist/list_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ilist diff --git a/pkg/sleep/BUILD b/pkg/sleep/BUILD index ab3f9ad99..f2b69b225 100644 --- a/pkg/sleep/BUILD +++ b/pkg/sleep/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/sleep/commit_amd64.s b/pkg/sleep/commit_amd64.s index 51d4f9189..d525e5b79 100644 --- a/pkg/sleep/commit_amd64.s +++ b/pkg/sleep/commit_amd64.s @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. #include "textflag.h" diff --git a/pkg/sleep/commit_arm64.s b/pkg/sleep/commit_arm64.s index 9d351d00a..8aca31bee 100644 --- a/pkg/sleep/commit_arm64.s +++ b/pkg/sleep/commit_arm64.s @@ -1,5 +1,15 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // Empty assembly file so empty func definitions work. diff --git a/pkg/sleep/commit_asm.go b/pkg/sleep/commit_asm.go index b7589dfef..39a55df7e 100644 --- a/pkg/sleep/commit_asm.go +++ b/pkg/sleep/commit_asm.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // +build amd64 diff --git a/pkg/sleep/commit_noasm.go b/pkg/sleep/commit_noasm.go index 22c734e1d..584866cd8 100644 --- a/pkg/sleep/commit_noasm.go +++ b/pkg/sleep/commit_noasm.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // +build !race // +build !amd64 diff --git a/pkg/sleep/sleep_test.go b/pkg/sleep/sleep_test.go index 281927d43..bc1738371 100644 --- a/pkg/sleep/sleep_test.go +++ b/pkg/sleep/sleep_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sleep diff --git a/pkg/sleep/sleep_unsafe.go b/pkg/sleep/sleep_unsafe.go index 5ecb7a3ac..b12cce681 100644 --- a/pkg/sleep/sleep_unsafe.go +++ b/pkg/sleep/sleep_unsafe.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sleep allows goroutines to efficiently sleep on multiple sources of // notifications (wakers). It offers O(1) complexity, which is different from diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index 5c38a4961..186a0d3bf 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_stateify:defs.bzl", "go_stateify") diff --git a/pkg/tcpip/adapters/gonet/BUILD b/pkg/tcpip/adapters/gonet/BUILD index 69cfc84ab..97da46776 100644 --- a/pkg/tcpip/adapters/gonet/BUILD +++ b/pkg/tcpip/adapters/gonet/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index 5aa6b1aa2..19491fb2c 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 gonet provides a Go net package compatible wrapper for a tcpip stack. package gonet diff --git a/pkg/tcpip/adapters/gonet/gonet_test.go b/pkg/tcpip/adapters/gonet/gonet_test.go index e3d0c6c84..4c0855854 100644 --- a/pkg/tcpip/adapters/gonet/gonet_test.go +++ b/pkg/tcpip/adapters/gonet/gonet_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 gonet diff --git a/pkg/tcpip/buffer/BUILD b/pkg/tcpip/buffer/BUILD index 055e4b953..08adf18cd 100644 --- a/pkg/tcpip/buffer/BUILD +++ b/pkg/tcpip/buffer/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_stateify:defs.bzl", "go_stateify") diff --git a/pkg/tcpip/buffer/prependable.go b/pkg/tcpip/buffer/prependable.go index fd84585f9..d2b26cf47 100644 --- a/pkg/tcpip/buffer/prependable.go +++ b/pkg/tcpip/buffer/prependable.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 buffer diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index 241ccc7a8..a5774a327 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 buffer provides the implementation of a buffer view. package buffer diff --git a/pkg/tcpip/buffer/view_test.go b/pkg/tcpip/buffer/view_test.go index ff8535ba5..57fe12360 100644 --- a/pkg/tcpip/buffer/view_test.go +++ b/pkg/tcpip/buffer/view_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 buffer_test contains tests for the VectorisedView type. package buffer diff --git a/pkg/tcpip/checker/BUILD b/pkg/tcpip/checker/BUILD index ac5203031..5447cfbf4 100644 --- a/pkg/tcpip/checker/BUILD +++ b/pkg/tcpip/checker/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go index 209f9d60b..518719de4 100644 --- a/pkg/tcpip/checker/checker.go +++ b/pkg/tcpip/checker/checker.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 checker provides helper functions to check networking packets for // validity. diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 167ea250d..859c2a106 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_stateify:defs.bzl", "go_stateify") diff --git a/pkg/tcpip/header/arp.go b/pkg/tcpip/header/arp.go index af7f988f3..ae373f112 100644 --- a/pkg/tcpip/header/arp.go +++ b/pkg/tcpip/header/arp.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/checksum.go b/pkg/tcpip/header/checksum.go index 6399b1b95..e67c50f50 100644 --- a/pkg/tcpip/header/checksum.go +++ b/pkg/tcpip/header/checksum.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header provides the implementation of the encoding and decoding of // network protocol headers. diff --git a/pkg/tcpip/header/eth.go b/pkg/tcpip/header/eth.go index 23b7efdfc..99c29b750 100644 --- a/pkg/tcpip/header/eth.go +++ b/pkg/tcpip/header/eth.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/gue.go b/pkg/tcpip/header/gue.go index a069fb669..aac4593c5 100644 --- a/pkg/tcpip/header/gue.go +++ b/pkg/tcpip/header/gue.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/icmpv4.go b/pkg/tcpip/header/icmpv4.go index 9f1ad38fc..af1e94b7f 100644 --- a/pkg/tcpip/header/icmpv4.go +++ b/pkg/tcpip/header/icmpv4.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/icmpv6.go b/pkg/tcpip/header/icmpv6.go index a061cd02b..7d35caff7 100644 --- a/pkg/tcpip/header/icmpv6.go +++ b/pkg/tcpip/header/icmpv6.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/interfaces.go b/pkg/tcpip/header/interfaces.go index a92286761..042006983 100644 --- a/pkg/tcpip/header/interfaces.go +++ b/pkg/tcpip/header/interfaces.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/ipv4.go b/pkg/tcpip/header/ipv4.go index 6e2a3d6f4..950c54f74 100644 --- a/pkg/tcpip/header/ipv4.go +++ b/pkg/tcpip/header/ipv4.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go index da0210539..58ebc3b06 100644 --- a/pkg/tcpip/header/ipv6.go +++ b/pkg/tcpip/header/ipv6.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/ipv6_fragment.go b/pkg/tcpip/header/ipv6_fragment.go index 04aa5c7b8..44b28b326 100644 --- a/pkg/tcpip/header/ipv6_fragment.go +++ b/pkg/tcpip/header/ipv6_fragment.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/ipversion_test.go b/pkg/tcpip/header/ipversion_test.go index 5f3956160..3ae9b7e4a 100644 --- a/pkg/tcpip/header/ipversion_test.go +++ b/pkg/tcpip/header/ipversion_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header_test diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index 995df4076..a95d282b0 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/header/tcp_test.go b/pkg/tcpip/header/tcp_test.go index b1dfd4dc5..7854d3523 100644 --- a/pkg/tcpip/header/tcp_test.go +++ b/pkg/tcpip/header/tcp_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header_test diff --git a/pkg/tcpip/header/udp.go b/pkg/tcpip/header/udp.go index 7c2548634..cf2602e50 100644 --- a/pkg/tcpip/header/udp.go +++ b/pkg/tcpip/header/udp.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 header diff --git a/pkg/tcpip/link/channel/BUILD b/pkg/tcpip/link/channel/BUILD index b58a76699..f2f0c8b6f 100644 --- a/pkg/tcpip/link/channel/BUILD +++ b/pkg/tcpip/link/channel/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 3f5440cc1..9d69f1d45 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 channel provides the implemention of channel-based data-link layer // endpoints. Such endpoints allow injection of inbound packets and store diff --git a/pkg/tcpip/link/fdbased/BUILD b/pkg/tcpip/link/fdbased/BUILD index b5ab1ea6a..aca3b14ca 100644 --- a/pkg/tcpip/link/fdbased/BUILD +++ b/pkg/tcpip/link/fdbased/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 0c844c05b..c6a5f6d5a 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 fdbased provides the implemention of data-link layer endpoints // backed by boundary-preserving file descriptors (e.g., TUN devices, diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index f7bbb28e1..e05e3aebd 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 fdbased diff --git a/pkg/tcpip/link/loopback/BUILD b/pkg/tcpip/link/loopback/BUILD index b454d0839..9714e93db 100644 --- a/pkg/tcpip/link/loopback/BUILD +++ b/pkg/tcpip/link/loopback/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index f38847949..aede1b4a2 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 loopback provides the implemention of loopback data-link layer // endpoints. Such endpoints just turn outbound packets into inbound ones. diff --git a/pkg/tcpip/link/rawfile/BUILD b/pkg/tcpip/link/rawfile/BUILD index b43de5530..4b30c7c1c 100644 --- a/pkg/tcpip/link/rawfile/BUILD +++ b/pkg/tcpip/link/rawfile/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s index 7635900a5..fc5231831 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s +++ b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. #include "textflag.h" diff --git a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go index 659bfbe03..a0a9d4acd 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go @@ -1,6 +1,16 @@ -// Copyright 2018 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // +build linux,!amd64 diff --git a/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go b/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go index 0d89ddc1d..1f143c0db 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go @@ -1,6 +1,16 @@ -// Copyright 2018 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // +build linux,amd64 diff --git a/pkg/tcpip/link/rawfile/errors.go b/pkg/tcpip/link/rawfile/errors.go index 8eae9252c..7f213793e 100644 --- a/pkg/tcpip/link/rawfile/errors.go +++ b/pkg/tcpip/link/rawfile/errors.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // +build linux diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go index 6e8d7f556..261d350d7 100644 --- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go +++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // +build linux diff --git a/pkg/tcpip/link/sharedmem/BUILD b/pkg/tcpip/link/sharedmem/BUILD index a4a965924..1bd79a3f4 100644 --- a/pkg/tcpip/link/sharedmem/BUILD +++ b/pkg/tcpip/link/sharedmem/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/link/sharedmem/pipe/BUILD b/pkg/tcpip/link/sharedmem/pipe/BUILD index e8d795500..e6c658071 100644 --- a/pkg/tcpip/link/sharedmem/pipe/BUILD +++ b/pkg/tcpip/link/sharedmem/pipe/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe.go b/pkg/tcpip/link/sharedmem/pipe/pipe.go index 1173a60da..1a0edbaba 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 pipe implements a shared memory ring buffer on which a single reader // and a single writer can operate (read/write) concurrently. The ring buffer diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go index 441ff5b25..db0737c98 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 pipe diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go index d536abedf..480dc4a23 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 pipe diff --git a/pkg/tcpip/link/sharedmem/pipe/rx.go b/pkg/tcpip/link/sharedmem/pipe/rx.go index 261e21f9e..ff778cecd 100644 --- a/pkg/tcpip/link/sharedmem/pipe/rx.go +++ b/pkg/tcpip/link/sharedmem/pipe/rx.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 pipe diff --git a/pkg/tcpip/link/sharedmem/pipe/tx.go b/pkg/tcpip/link/sharedmem/pipe/tx.go index 374f515ab..717f5a4b1 100644 --- a/pkg/tcpip/link/sharedmem/pipe/tx.go +++ b/pkg/tcpip/link/sharedmem/pipe/tx.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 pipe diff --git a/pkg/tcpip/link/sharedmem/queue/BUILD b/pkg/tcpip/link/sharedmem/queue/BUILD index 56ea4641d..80cedade1 100644 --- a/pkg/tcpip/link/sharedmem/queue/BUILD +++ b/pkg/tcpip/link/sharedmem/queue/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/link/sharedmem/queue/queue_test.go b/pkg/tcpip/link/sharedmem/queue/queue_test.go index b022c389c..3d5909cef 100644 --- a/pkg/tcpip/link/sharedmem/queue/queue_test.go +++ b/pkg/tcpip/link/sharedmem/queue/queue_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 queue diff --git a/pkg/tcpip/link/sharedmem/queue/rx.go b/pkg/tcpip/link/sharedmem/queue/rx.go index 91bb57190..c40d62c33 100644 --- a/pkg/tcpip/link/sharedmem/queue/rx.go +++ b/pkg/tcpip/link/sharedmem/queue/rx.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 queue provides the implementation of transmit and receive queues // based on shared memory ring buffers. diff --git a/pkg/tcpip/link/sharedmem/queue/tx.go b/pkg/tcpip/link/sharedmem/queue/tx.go index b04fb163b..39b595e56 100644 --- a/pkg/tcpip/link/sharedmem/queue/tx.go +++ b/pkg/tcpip/link/sharedmem/queue/tx.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 queue diff --git a/pkg/tcpip/link/sharedmem/rx.go b/pkg/tcpip/link/sharedmem/rx.go index 951ed966b..4c9aa3f64 100644 --- a/pkg/tcpip/link/sharedmem/rx.go +++ b/pkg/tcpip/link/sharedmem/rx.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sharedmem diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 5369ebc68..223eb3a1b 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sharedmem provides the implemention of data-link layer endpoints // backed by shared memory. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index f71e4751f..7bd8db6a4 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sharedmem diff --git a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go index 52f93f480..f0be2dc73 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sharedmem diff --git a/pkg/tcpip/link/sharedmem/tx.go b/pkg/tcpip/link/sharedmem/tx.go index bca1d79b4..42a21cb43 100644 --- a/pkg/tcpip/link/sharedmem/tx.go +++ b/pkg/tcpip/link/sharedmem/tx.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sharedmem diff --git a/pkg/tcpip/link/sniffer/BUILD b/pkg/tcpip/link/sniffer/BUILD index a912707c2..d14f150d1 100644 --- a/pkg/tcpip/link/sniffer/BUILD +++ b/pkg/tcpip/link/sniffer/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/link/sniffer/pcap.go b/pkg/tcpip/link/sniffer/pcap.go index 732a520dd..04f3d494e 100644 --- a/pkg/tcpip/link/sniffer/pcap.go +++ b/pkg/tcpip/link/sniffer/pcap.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sniffer diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 3a40081c0..22f009751 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 sniffer provides the implementation of data-link layer endpoints that // wrap another endpoint and logs inbound and outbound packets. diff --git a/pkg/tcpip/link/tun/BUILD b/pkg/tcpip/link/tun/BUILD index d627f00f1..21da7d57e 100644 --- a/pkg/tcpip/link/tun/BUILD +++ b/pkg/tcpip/link/tun/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/link/tun/tun_unsafe.go b/pkg/tcpip/link/tun/tun_unsafe.go index f2a2ec69e..d3d68b569 100644 --- a/pkg/tcpip/link/tun/tun_unsafe.go +++ b/pkg/tcpip/link/tun/tun_unsafe.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tun contains methods to open TAP and TUN devices. package tun diff --git a/pkg/tcpip/link/waitable/BUILD b/pkg/tcpip/link/waitable/BUILD index 63b648be7..3b513383a 100644 --- a/pkg/tcpip/link/waitable/BUILD +++ b/pkg/tcpip/link/waitable/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 91aed7a12..08b8d66e7 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 waitable provides the implementation of data-link layer endpoints // that wrap other endpoints, and can wait for inflight calls to WritePacket or diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 188049322..37efa60d6 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 waitable diff --git a/pkg/tcpip/network/BUILD b/pkg/tcpip/network/BUILD index 36ddaa692..963857f51 100644 --- a/pkg/tcpip/network/BUILD +++ b/pkg/tcpip/network/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_test") diff --git a/pkg/tcpip/network/arp/BUILD b/pkg/tcpip/network/arp/BUILD index 58d174965..689f66d6e 100644 --- a/pkg/tcpip/network/arp/BUILD +++ b/pkg/tcpip/network/arp/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 4e3d7f597..e7dfc6444 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 arp implements the ARP network protocol. It is used to resolve // IPv4 addresses into link-local MAC addresses, and advertises IPv4 diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index 6d61ff1d7..c35299f3f 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 arp_test diff --git a/pkg/tcpip/network/fragmentation/BUILD b/pkg/tcpip/network/fragmentation/BUILD index 78fe878ec..a173f87fb 100644 --- a/pkg/tcpip/network/fragmentation/BUILD +++ b/pkg/tcpip/network/fragmentation/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/tcpip/network/fragmentation/frag_heap.go b/pkg/tcpip/network/fragmentation/frag_heap.go index 2e8512909..073882e99 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap.go +++ b/pkg/tcpip/network/fragmentation/frag_heap.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 fragmentation diff --git a/pkg/tcpip/network/fragmentation/frag_heap_test.go b/pkg/tcpip/network/fragmentation/frag_heap_test.go index 218a24d7b..a2fe80264 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap_test.go +++ b/pkg/tcpip/network/fragmentation/frag_heap_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 fragmentation diff --git a/pkg/tcpip/network/fragmentation/fragmentation.go b/pkg/tcpip/network/fragmentation/fragmentation.go index a309a24c5..21497f876 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation.go +++ b/pkg/tcpip/network/fragmentation/fragmentation.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 fragmentation contains the implementation of IP fragmentation. // It is based on RFC 791 and RFC 815. diff --git a/pkg/tcpip/network/fragmentation/fragmentation_test.go b/pkg/tcpip/network/fragmentation/fragmentation_test.go index 2f0200d26..7320e594f 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation_test.go +++ b/pkg/tcpip/network/fragmentation/fragmentation_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 fragmentation diff --git a/pkg/tcpip/network/fragmentation/reassembler.go b/pkg/tcpip/network/fragmentation/reassembler.go index 0267a575d..7c465c1ac 100644 --- a/pkg/tcpip/network/fragmentation/reassembler.go +++ b/pkg/tcpip/network/fragmentation/reassembler.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 fragmentation diff --git a/pkg/tcpip/network/fragmentation/reassembler_test.go b/pkg/tcpip/network/fragmentation/reassembler_test.go index b64604383..4c137828f 100644 --- a/pkg/tcpip/network/fragmentation/reassembler_test.go +++ b/pkg/tcpip/network/fragmentation/reassembler_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 fragmentation diff --git a/pkg/tcpip/network/hash/BUILD b/pkg/tcpip/network/hash/BUILD index 1e76fed36..e1b5f26c4 100644 --- a/pkg/tcpip/network/hash/BUILD +++ b/pkg/tcpip/network/hash/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/network/hash/hash.go b/pkg/tcpip/network/hash/hash.go index 60227d515..eddf7ca4d 100644 --- a/pkg/tcpip/network/hash/hash.go +++ b/pkg/tcpip/network/hash/hash.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 hash contains utility functions for hashing. package hash diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index c5f8714da..f1edebe27 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ip_test diff --git a/pkg/tcpip/network/ipv4/BUILD b/pkg/tcpip/network/ipv4/BUILD index 02d55355c..ae42b662f 100644 --- a/pkg/tcpip/network/ipv4/BUILD +++ b/pkg/tcpip/network/ipv4/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index 3c382fdc2..d11938d6e 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ipv4 diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index 4cc2a2fd4..e5db44b5d 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ipv4 contains the implementation of the ipv4 network protocol. To use // it in the networking stack, this package must be added to the project, and diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index db7da0af3..d008ac7fb 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 0fc6dcce2..8b8539def 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ipv6 diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 15654cbbd..67d8cc670 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ipv6 contains the implementation of the ipv6 network protocol. To use // it in the networking stack, this package must be added to the project, and diff --git a/pkg/tcpip/ports/BUILD b/pkg/tcpip/ports/BUILD index e0140cea6..710c283f7 100644 --- a/pkg/tcpip/ports/BUILD +++ b/pkg/tcpip/ports/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/ports/ports.go b/pkg/tcpip/ports/ports.go index 24f3095d6..c963b36a2 100644 --- a/pkg/tcpip/ports/ports.go +++ b/pkg/tcpip/ports/ports.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ports provides PortManager that manages allocating, reserving and releasing ports. package ports diff --git a/pkg/tcpip/ports/ports_test.go b/pkg/tcpip/ports/ports_test.go index 372f77d55..825d5d314 100644 --- a/pkg/tcpip/ports/ports_test.go +++ b/pkg/tcpip/ports/ports_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ports diff --git a/pkg/tcpip/sample/tun_tcp_connect/BUILD b/pkg/tcpip/sample/tun_tcp_connect/BUILD index 870ee0433..21d32245d 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/BUILD +++ b/pkg/tcpip/sample/tun_tcp_connect/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_binary") diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index ef5c7ec60..8309ee3a0 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // This sample creates a stack with TCP and IPv4 protocols on top of a TUN // device, and connects to a peer. Similar to "nc
". While the diff --git a/pkg/tcpip/sample/tun_tcp_echo/BUILD b/pkg/tcpip/sample/tun_tcp_echo/BUILD index c51528a12..d7402aaa2 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/BUILD +++ b/pkg/tcpip/sample/tun_tcp_echo/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_binary") diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index 8c166f643..a4d955c7a 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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. // This sample creates a stack with TCP and IPv4 protocols on top of a TUN // device, and listens on a port. Data received by the server in the accepted diff --git a/pkg/tcpip/seqnum/BUILD b/pkg/tcpip/seqnum/BUILD index 0c717ec8d..6d28dbc3f 100644 --- a/pkg/tcpip/seqnum/BUILD +++ b/pkg/tcpip/seqnum/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_stateify:defs.bzl", "go_stateify") diff --git a/pkg/tcpip/seqnum/seqnum.go b/pkg/tcpip/seqnum/seqnum.go index f689be984..e507d02f7 100644 --- a/pkg/tcpip/seqnum/seqnum.go +++ b/pkg/tcpip/seqnum/seqnum.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 seqnum defines the types and methods for TCP sequence numbers such // that they fit in 32-bit words and work properly when overflows occur. diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD index 079ade2c8..6d201d0a2 100644 --- a/pkg/tcpip/stack/BUILD +++ b/pkg/tcpip/stack/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_stateify:defs.bzl", "go_stateify") diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index 789f97882..a1645c7bf 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go index e9897b2bd..f0988d6de 100644 --- a/pkg/tcpip/stack/linkaddrcache_test.go +++ b/pkg/tcpip/stack/linkaddrcache_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 06bb5abc5..c1480f97b 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 15b2418ad..70a123bbd 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index e4f10cfa1..423f428df 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index d1d762a8e..67a3cc95e 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 provides the glue between networking protocols and the // consumers of the networking stack. diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index 030ae98d1..6d261ce96 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index ea7dccdc2..04806865d 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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_test contains tests for the stack. It is in its own package so // that the tests can also validate that all definitions needed to implement diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index 7bb853622..dbaa9c829 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index b870ab375..bd0802ccb 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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_test diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index cf25a086d..4107c0f78 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcpip provides the interfaces and related types that users of the // tcpip stack will use in order to create endpoints used to send and receive diff --git a/pkg/tcpip/tcpip_test.go b/pkg/tcpip/tcpip_test.go index fd4d8346f..6bf82d632 100644 --- a/pkg/tcpip/tcpip_test.go +++ b/pkg/tcpip/tcpip_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcpip diff --git a/pkg/tcpip/transport/ping/BUILD b/pkg/tcpip/transport/ping/BUILD index c2ae9aea4..1febbf7f5 100644 --- a/pkg/tcpip/transport/ping/BUILD +++ b/pkg/tcpip/transport/ping/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index 2b80881bb..78e540727 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ping diff --git a/pkg/tcpip/transport/ping/endpoint_state.go b/pkg/tcpip/transport/ping/endpoint_state.go index 29fde2585..a16087304 100644 --- a/pkg/tcpip/transport/ping/endpoint_state.go +++ b/pkg/tcpip/transport/ping/endpoint_state.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ping diff --git a/pkg/tcpip/transport/ping/protocol.go b/pkg/tcpip/transport/ping/protocol.go index 1459b4d60..fb378286c 100644 --- a/pkg/tcpip/transport/ping/protocol.go +++ b/pkg/tcpip/transport/ping/protocol.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 ping contains the implementation of the ICMP and IPv6-ICMP transport // protocols for use in ping. To use it in the networking stack, this package diff --git a/pkg/tcpip/transport/queue/BUILD b/pkg/tcpip/transport/queue/BUILD index 162af574c..7e8ee1f66 100644 --- a/pkg/tcpip/transport/queue/BUILD +++ b/pkg/tcpip/transport/queue/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_stateify:defs.bzl", "go_stateify") diff --git a/pkg/tcpip/transport/queue/queue.go b/pkg/tcpip/transport/queue/queue.go index 0c90588ae..6a17441ae 100644 --- a/pkg/tcpip/transport/queue/queue.go +++ b/pkg/tcpip/transport/queue/queue.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 queue provides the implementation of buffer queue // and interface of queue entry with Length method. diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index f38f58e87..6cb0ebab2 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index 85adeef0e..ae4359ff4 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index b0cf0eaf6..980663675 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/dual_stack_test.go b/pkg/tcpip/transport/tcp/dual_stack_test.go index a89af4559..c88e98977 100644 --- a/pkg/tcpip/transport/tcp/dual_stack_test.go +++ b/pkg/tcpip/transport/tcp/dual_stack_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp_test diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 191dc1acc..9c937559c 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index b1e249bff..aa4ccea75 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index 657ac524f..71eb89795 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index e9748d8a6..cbe0e564e 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp contains the implementation of the TCP transport protocol. To use // it in the networking stack, this package must be added to the project, and diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index 574602105..b22a00ce1 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/sack.go b/pkg/tcpip/transport/tcp/sack.go index 000696455..05bac08cb 100644 --- a/pkg/tcpip/transport/tcp/sack.go +++ b/pkg/tcpip/transport/tcp/sack.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 07e4bfd73..a90f6661d 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/segment_heap.go b/pkg/tcpip/transport/tcp/segment_heap.go index 137ddbdd2..e3a3405ef 100644 --- a/pkg/tcpip/transport/tcp/segment_heap.go +++ b/pkg/tcpip/transport/tcp/segment_heap.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index c4a7f7d5b..83f554ebd 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index 085973c02..a9892eb64 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcp/tcp_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go index 2768958ee..a61d0ca64 100644 --- a/pkg/tcpip/transport/tcp/tcp_sack_test.go +++ b/pkg/tcpip/transport/tcp/tcp_sack_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp_test diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index e564af8c0..1b8463541 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp_test diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index 335262e43..4f6f1da18 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp_test diff --git a/pkg/tcpip/transport/tcp/testing/context/BUILD b/pkg/tcpip/transport/tcp/testing/context/BUILD index 40850c3e7..3caa38bcb 100644 --- a/pkg/tcpip/transport/tcp/testing/context/BUILD +++ b/pkg/tcpip/transport/tcp/testing/context/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index eb928553f..9deae09e3 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 context provides a test context for use in tcp tests. It also // provides helper methods to assert/check certain behaviours. diff --git a/pkg/tcpip/transport/tcp/timer.go b/pkg/tcpip/transport/tcp/timer.go index 7aa824d8f..938c0bcef 100644 --- a/pkg/tcpip/transport/tcp/timer.go +++ b/pkg/tcpip/transport/tcp/timer.go @@ -1,6 +1,16 @@ -// Copyright 2017 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcp diff --git a/pkg/tcpip/transport/tcpconntrack/BUILD b/pkg/tcpip/transport/tcpconntrack/BUILD index cf83ca134..3d748528e 100644 --- a/pkg/tcpip/transport/tcpconntrack/BUILD +++ b/pkg/tcpip/transport/tcpconntrack/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go index 194af772c..5f8f1a64d 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcpconntrack implements a TCP connection tracking object. It allows // users with access to a segment stream to figure out when a connection is diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go index 50cab3132..514722ab7 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tcpconntrack_test diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index ac34a932e..4f7a47973 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 6fcddd028..eb2f26189 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 udp diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index 93784fb05..30c16682b 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 udp diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index fa30e7201..dabc5bd13 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 udp contains the implementation of the UDP transport protocol. To use // it in the networking stack, this package must be added to the project, and diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index cc342c69b..3d5956145 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 udp_test diff --git a/pkg/tcpip/transport/unix/BUILD b/pkg/tcpip/transport/unix/BUILD index 47bc7a649..d58f06544 100644 --- a/pkg/tcpip/transport/unix/BUILD +++ b/pkg/tcpip/transport/unix/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_stateify:defs.bzl", "go_stateify") diff --git a/pkg/tcpip/transport/unix/connectioned.go b/pkg/tcpip/transport/unix/connectioned.go index def1b2c99..0e63186b2 100644 --- a/pkg/tcpip/transport/unix/connectioned.go +++ b/pkg/tcpip/transport/unix/connectioned.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 unix diff --git a/pkg/tcpip/transport/unix/connectioned_state.go b/pkg/tcpip/transport/unix/connectioned_state.go index 5d835c8b2..39e0ca2d6 100644 --- a/pkg/tcpip/transport/unix/connectioned_state.go +++ b/pkg/tcpip/transport/unix/connectioned_state.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 unix diff --git a/pkg/tcpip/transport/unix/connectionless.go b/pkg/tcpip/transport/unix/connectionless.go index 34d34f99a..3276ddcd0 100644 --- a/pkg/tcpip/transport/unix/connectionless.go +++ b/pkg/tcpip/transport/unix/connectionless.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 unix diff --git a/pkg/tcpip/transport/unix/unix.go b/pkg/tcpip/transport/unix/unix.go index 34bdb5877..190a1ccdb 100644 --- a/pkg/tcpip/transport/unix/unix.go +++ b/pkg/tcpip/transport/unix/unix.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 unix contains the implementation of Unix endpoints. package unix diff --git a/pkg/tmutex/BUILD b/pkg/tmutex/BUILD index 5d1614d35..d9a2c5ae5 100644 --- a/pkg/tmutex/BUILD +++ b/pkg/tmutex/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/pkg/tmutex/tmutex.go b/pkg/tmutex/tmutex.go index 61779654f..bd5c681dd 100644 --- a/pkg/tmutex/tmutex.go +++ b/pkg/tmutex/tmutex.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tmutex provides the implementation of a mutex that implements an // efficient TryLock function in addition to Lock and Unlock. diff --git a/pkg/tmutex/tmutex_test.go b/pkg/tmutex/tmutex_test.go index e1b5fd4e2..a9dc9972f 100644 --- a/pkg/tmutex/tmutex_test.go +++ b/pkg/tmutex/tmutex_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 tmutex diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index 7415dd325..032ec3237 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_stateify:defs.bzl", "go_stateify") diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index ab39fa002..9b189bb9e 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 waiter provides the implementation of a wait queue, where waiters can // be enqueued to be notified when an event of interest happens. diff --git a/pkg/waiter/waiter_test.go b/pkg/waiter/waiter_test.go index 1a203350b..c45f22889 100644 --- a/pkg/waiter/waiter_test.go +++ b/pkg/waiter/waiter_test.go @@ -1,6 +1,16 @@ -// Copyright 2016 The Netstack Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +// Copyright 2018 Google Inc. +// +// 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 waiter -- cgit v1.2.3 From b1683df90bf81974e9e309ed66edaff30537c1be Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Tue, 10 Jul 2018 09:22:37 -0700 Subject: netstack: tcp socket connected state S/R support. PiperOrigin-RevId: 203958972 Change-Id: Ia6fe16547539296d48e2c6731edacdd96bd6e93c --- pkg/sentry/kernel/BUILD | 5 +- pkg/sentry/kernel/kernel.go | 6 + pkg/sentry/kernel/kernel_state.go | 31 +++++ pkg/tcpip/stack/stack_global_state.go | 2 +- pkg/tcpip/tcpip.go | 36 ++++++ pkg/tcpip/transport/tcp/BUILD | 7 ++ pkg/tcpip/transport/tcp/accept.go | 11 +- pkg/tcpip/transport/tcp/connect.go | 43 ++++++- pkg/tcpip/transport/tcp/endpoint.go | 72 ++++++++--- pkg/tcpip/transport/tcp/endpoint_state.go | 193 +++++++++++++++++++++--------- pkg/tcpip/transport/tcp/segment.go | 8 +- pkg/tcpip/transport/tcp/segment_queue.go | 4 +- pkg/tcpip/transport/tcp/segment_state.go | 51 ++++++++ pkg/tcpip/transport/tcp/snd.go | 4 +- pkg/tcpip/transport/tcp/snd_state.go | 49 ++++++++ 15 files changed, 430 insertions(+), 92 deletions(-) create mode 100644 pkg/sentry/kernel/kernel_state.go create mode 100644 pkg/tcpip/transport/tcp/segment_state.go create mode 100644 pkg/tcpip/transport/tcp/snd_state.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index b2a55ddff..07568b47c 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -12,6 +12,7 @@ go_stateify( "fs_context.go", "ipc_namespace.go", "kernel.go", + "kernel_state.go", "pending_signals.go", "pending_signals_state.go", "process_group_list.go", @@ -45,10 +46,11 @@ go_stateify( "vdso.go", "version.go", ], - out = "kernel_state.go", + out = "kernel_autogen_state.go", imports = [ "gvisor.googlesource.com/gvisor/pkg/sentry/arch", "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", + "gvisor.googlesource.com/gvisor/pkg/tcpip", ], package = "kernel", ) @@ -117,6 +119,7 @@ go_library( "fs_context.go", "ipc_namespace.go", "kernel.go", + "kernel_autogen_state.go", "kernel_state.go", "pending_signals.go", "pending_signals_list.go", diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 5662b8f08..64439cd9d 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -57,6 +57,7 @@ import ( sentrytime "gvisor.googlesource.com/gvisor/pkg/sentry/time" "gvisor.googlesource.com/gvisor/pkg/sentry/uniqueid" "gvisor.googlesource.com/gvisor/pkg/state" + "gvisor.googlesource.com/gvisor/pkg/tcpip" ) // Kernel represents an emulated Linux kernel. It must be initialized by calling @@ -158,6 +159,9 @@ type Kernel struct { // exitErr is the error causing the sandbox to exit, if any. It is // protected by extMu. exitErr error + + // danglingEndpoints is used to save / restore tcpip.DanglingEndpoints. + danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"` } // InitKernelArgs holds arguments to Init. @@ -422,6 +426,8 @@ func (k *Kernel) LoadFrom(r io.Reader, p platform.Platform, net inet.Stack) erro return err } + tcpip.AsyncLoading.Wait() + log.Infof("Overall load took [%s]", time.Since(loadStart)) // Applications may size per-cpu structures based on k.applicationCores, so diff --git a/pkg/sentry/kernel/kernel_state.go b/pkg/sentry/kernel/kernel_state.go new file mode 100644 index 000000000..bb2d5102d --- /dev/null +++ b/pkg/sentry/kernel/kernel_state.go @@ -0,0 +1,31 @@ +// Copyright 2018 Google Inc. +// +// 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 kernel + +import ( + "gvisor.googlesource.com/gvisor/pkg/tcpip" +) + +// saveDanglingEndpoints is invoked by stateify. +func (k *Kernel) saveDanglingEndpoints() []tcpip.Endpoint { + return tcpip.GetDanglingEndpoints() +} + +// loadDanglingEndpoints is invoked by stateify. +func (k *Kernel) loadDanglingEndpoints(es []tcpip.Endpoint) { + for _, e := range es { + tcpip.AddDanglingEndpoint(e) + } +} diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index 6d261ce96..b6c095efb 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -15,5 +15,5 @@ package stack // StackFromEnv is the global stack created in restore run. -// FIXME: remove this variable once tcpip S/R is fully supported. +// FIXME var StackFromEnv *Stack diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 4107c0f78..eb1e4645d 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -33,6 +33,7 @@ import ( "fmt" "strconv" "strings" + "sync" "time" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" @@ -562,3 +563,38 @@ type ProtocolAddress struct { // Address is a network address. Address Address } + +// danglingEndpointsMu protects access to danglingEndpoints. +var danglingEndpointsMu sync.Mutex + +// danglingEndpoints tracks all dangling endpoints no longer owned by the app. +var danglingEndpoints = make(map[Endpoint]struct{}) + +// GetDanglingEndpoints returns all dangling endpoints. +func GetDanglingEndpoints() []Endpoint { + es := make([]Endpoint, 0, len(danglingEndpoints)) + danglingEndpointsMu.Lock() + for e, _ := range danglingEndpoints { + es = append(es, e) + } + danglingEndpointsMu.Unlock() + return es +} + +// AddDanglingEndpoint adds a dangling endpoint. +func AddDanglingEndpoint(e Endpoint) { + danglingEndpointsMu.Lock() + danglingEndpoints[e] = struct{}{} + danglingEndpointsMu.Unlock() +} + +// DeleteDanglingEndpoint removes a dangling endpoint. +func DeleteDanglingEndpoint(e Endpoint) { + danglingEndpointsMu.Lock() + delete(danglingEndpoints, e) + danglingEndpointsMu.Unlock() +} + +// AsyncLoading is the global barrier for asynchronous endpoint loading +// activities. +var AsyncLoading sync.WaitGroup diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 6cb0ebab2..6a2f42a12 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -10,11 +10,16 @@ go_stateify( "endpoint.go", "endpoint_state.go", "rcv.go", + "segment.go", "segment_heap.go", + "segment_queue.go", + "segment_state.go", "snd.go", + "snd_state.go", "tcp_segment_list.go", ], out = "tcp_state.go", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], package = "tcp", ) @@ -43,7 +48,9 @@ go_library( "segment.go", "segment_heap.go", "segment_queue.go", + "segment_state.go", "snd.go", + "snd_state.go", "tcp_segment_list.go", "tcp_state.go", "timer.go", diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index ae4359ff4..d6d2b4555 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -78,7 +78,8 @@ func encodeMSS(mss uint16) uint32 { // to go above a threshold. var synRcvdCount struct { sync.Mutex - value uint64 + value uint64 + pending sync.WaitGroup } // listenContext is used by a listening endpoint to store state used while @@ -112,6 +113,7 @@ func incSynRcvdCount() bool { return false } + synRcvdCount.pending.Add(1) synRcvdCount.value++ return true @@ -125,6 +127,7 @@ func decSynRcvdCount() { defer synRcvdCount.Unlock() synRcvdCount.value-- + synRcvdCount.pending.Done() } // newListenContext creates a new listen context. @@ -302,7 +305,7 @@ func (e *endpoint) handleListenSegment(ctx *listenContext, s *segment) { opts := parseSynSegmentOptions(s) if incSynRcvdCount() { s.incRef() - go e.handleSynSegment(ctx, s, &opts) // S/R-FIXME + go e.handleSynSegment(ctx, s, &opts) // S/R-SAFE: synRcvdCount is the barrier. } else { cookie := ctx.createCookie(s.id, s.sequenceNumber, encodeMSS(opts.MSS)) // Send SYN with window scaling because we currently @@ -391,10 +394,12 @@ func (e *endpoint) protocolListenLoop(rcvWnd seqnum.Size) *tcpip.Error { return nil } if n¬ifyDrain != 0 { - for s := e.segmentQueue.dequeue(); s != nil; s = e.segmentQueue.dequeue() { + for !e.segmentQueue.empty() { + s := e.segmentQueue.dequeue() e.handleListenSegment(ctx, s) s.decRef() } + synRcvdCount.pending.Wait() close(e.drainDone) <-e.undrain } diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index afdea2b53..33bf4fc0b 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -453,7 +453,8 @@ func (h *handshake) execute() *tcpip.Error { return tcpip.ErrAborted } if n¬ifyDrain != 0 { - for s := h.ep.segmentQueue.dequeue(); s != nil; s = h.ep.segmentQueue.dequeue() { + for !h.ep.segmentQueue.empty() { + s := h.ep.segmentQueue.dequeue() err := h.handleSegment(s) s.decRef() if err != nil { @@ -823,15 +824,13 @@ func (e *endpoint) handleSegments() *tcpip.Error { // protocolMainLoop is the main loop of the TCP protocol. It runs in its own // goroutine and is responsible for sending segments and handling received // segments. -func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { +func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error { var closeTimer *time.Timer var closeWaker sleep.Waker defer func() { // e.mu is expected to be hold upon entering this section. - e.completeWorkerLocked() - if e.snd != nil { e.snd.resendTimer.cleanup() } @@ -840,6 +839,8 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { closeTimer.Stop() } + e.completeWorkerLocked() + if e.drainDone != nil { close(e.drainDone) } @@ -850,7 +851,7 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.EventIn | waiter.EventOut) }() - if !passive { + if handshake { // This is an active connection, so we must initiate the 3-way // handshake, and then inform potential waiters about its // completion. @@ -960,6 +961,17 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { closeWaker.Assert() }) } + + if n¬ifyDrain != 0 { + for !e.segmentQueue.empty() { + if err := e.handleSegments(); err != nil { + return err + } + } + close(e.drainDone) + <-e.undrain + } + return nil }, }, @@ -971,6 +983,27 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error { s.AddWaker(funcs[i].w, i) } + // The following assertions and notifications are needed for restored + // endpoints. Fresh newly created endpoints have empty states and should + // not invoke any. + e.segmentQueue.mu.Lock() + if !e.segmentQueue.list.Empty() { + e.newSegmentWaker.Assert() + } + e.segmentQueue.mu.Unlock() + + e.rcvListMu.Lock() + if !e.rcvList.Empty() { + e.waiterQueue.Notify(waiter.EventIn) + } + e.rcvListMu.Unlock() + + e.mu.RLock() + if e.workerCleanup { + e.notifyProtocolGoroutine(notifyClose) + } + e.mu.RUnlock() + // Main loop. Handle segments until both send and receive ends of the // connection have completed. for !e.rcv.closed || !e.snd.closed || e.snd.sndUna != e.snd.sndNxtList { diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index cb105b863..8b9a81f6a 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -80,7 +80,7 @@ type endpoint struct { // change throughout the lifetime of the endpoint. stack *stack.Stack `state:"manual"` netProto tcpip.NetworkProtocolNumber - waiterQueue *waiter.Queue + waiterQueue *waiter.Queue `state:"wait"` // lastError represents the last error that the endpoint reported; // access to it is protected by the following mutex. @@ -95,8 +95,8 @@ type endpoint struct { // to indicate to users that no more data is coming. // // rcvListMu can be taken after the endpoint mu below. - rcvListMu sync.Mutex `state:"nosave"` - rcvList segmentList + rcvListMu sync.Mutex `state:"nosave"` + rcvList segmentList `state:"wait"` rcvClosed bool rcvBufSize int rcvBufUsed int @@ -104,8 +104,8 @@ type endpoint struct { // The following fields are protected by the mutex. mu sync.RWMutex `state:"nosave"` id stack.TransportEndpointID - state endpointState - isPortReserved bool `state:"manual"` + state endpointState `state:".(endpointState)"` + isPortReserved bool `state:"manual"` isRegistered bool boundNICID tcpip.NICID `state:"manual"` route stack.Route `state:"manual"` @@ -131,7 +131,7 @@ type endpoint struct { // workerCleanup specifies if the worker goroutine must perform cleanup // before exitting. This can only be set to true when workerRunning is // also true, and they're both protected by the mutex. - workerCleanup bool `state:"zerovalue"` + workerCleanup bool // sendTSOk is used to indicate when the TS Option has been negotiated. // When sendTSOk is true every non-RST segment should carry a TS as per @@ -166,7 +166,7 @@ type endpoint struct { // segmentQueue is used to hand received segments to the protocol // goroutine. Segments are queued as long as the queue is not full, // and dropped when it is. - segmentQueue segmentQueue `state:"zerovalue"` + segmentQueue segmentQueue `state:"wait"` // The following fields are used to manage the send buffer. When // segments are ready to be sent, they are added to sndQueue and the @@ -179,7 +179,7 @@ type endpoint struct { sndBufUsed int sndClosed bool sndBufInQueue seqnum.Size - sndQueue segmentList + sndQueue segmentList `state:"wait"` sndWaker sleep.Waker `state:"manual"` sndCloseWaker sleep.Waker `state:"manual"` @@ -201,17 +201,21 @@ type endpoint struct { // notifyFlags is a bitmask of flags used to indicate to the protocol // goroutine what it was notified; this is only accessed atomically. - notifyFlags uint32 `state:"zerovalue"` + notifyFlags uint32 `state:"nosave"` // acceptedChan is used by a listening endpoint protocol goroutine to // send newly accepted connections to the endpoint so that they can be // read by Accept() calls. - acceptedChan chan *endpoint `state:".(endpointChan)"` + acceptedChan chan *endpoint `state:"manual"` + + // acceptedEndpoints is only used to save / restore the channel buffer. + // FIXME + acceptedEndpoints []*endpoint // The following are only used from the protocol goroutine, and // therefore don't need locks to protect them. - rcv *receiver - snd *sender + rcv *receiver `state:"wait"` + snd *sender `state:"wait"` // The goroutine drain completion notification channel. drainDone chan struct{} `state:"nosave"` @@ -224,6 +228,7 @@ type endpoint struct { probe stack.TCPProbeFunc `state:"nosave"` // The following are only used to assist the restore run to re-connect. + bindAddress tcpip.Address connectingAddress tcpip.Address } @@ -357,6 +362,7 @@ func (e *endpoint) Close() { // Either perform the local cleanup or kick the worker to make sure it // knows it needs to cleanup. + tcpip.AddDanglingEndpoint(e) if !e.workerRunning { e.cleanupLocked() } else { @@ -376,9 +382,12 @@ func (e *endpoint) cleanupLocked() { if e.acceptedChan != nil { close(e.acceptedChan) for n := range e.acceptedChan { + n.mu.Lock() n.resetConnectionLocked(tcpip.ErrConnectionAborted) + n.mu.Unlock() n.Close() } + e.acceptedChan = nil } e.workerCleanup = false @@ -387,6 +396,7 @@ func (e *endpoint) cleanupLocked() { } e.route.Release() + tcpip.DeleteDanglingEndpoint(e) } // Read reads data from the endpoint. @@ -801,6 +811,16 @@ func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress) (tcpip.NetworkProtocol // Connect connects the endpoint to its peer. func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { + return e.connect(addr, true, true) +} + +// connect connects the endpoint to its peer. In the normal non-S/R case, the +// new connection is expected to run the main goroutine and perform handshake. +// In restore of previously connected endpoints, both ends will be passively +// created (so no new handshaking is done); for stack-accepted connections not +// yet accepted by the app, they are restored without running the main goroutine +// here. +func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) *tcpip.Error { e.mu.Lock() defer e.mu.Unlock() @@ -912,9 +932,27 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { e.boundNICID = nicid e.effectiveNetProtos = netProtos e.connectingAddress = connectingAddr - e.workerRunning = true - go e.protocolMainLoop(false) // S/R-SAFE: will be drained before save. + // Connect in the restore phase does not perform handshake. Restore its + // connection setting here. + if !handshake { + e.segmentQueue.mu.Lock() + for _, l := range []segmentList{e.segmentQueue.list, e.sndQueue, e.snd.writeList} { + for s := l.Front(); s != nil; s = s.Next() { + s.id = e.id + s.route = r.Clone() + e.sndWaker.Assert() + } + } + e.segmentQueue.mu.Unlock() + e.snd.updateMaxPayloadSize(int(e.route.MTU()), 0) + e.state = stateConnected + } + + if run { + e.workerRunning = true + go e.protocolMainLoop(handshake) // S/R-SAFE: will be drained before save. + } return tcpip.ErrConnectStarted } @@ -999,6 +1037,9 @@ func (e *endpoint) Listen(backlog int) *tcpip.Error { if len(e.acceptedChan) > backlog { return tcpip.ErrInvalidEndpointState } + if cap(e.acceptedChan) == backlog { + return nil + } origChan := e.acceptedChan e.acceptedChan = make(chan *endpoint, backlog) close(origChan) @@ -1036,7 +1077,7 @@ func (e *endpoint) Listen(backlog int) *tcpip.Error { func (e *endpoint) startAcceptedLoop(waiterQueue *waiter.Queue) { e.waiterQueue = waiterQueue e.workerRunning = true - go e.protocolMainLoop(true) // S/R-FIXME + go e.protocolMainLoop(false) // S/R-SAFE: drained on save. } // Accept returns a new endpoint if a peer has established a connection @@ -1077,6 +1118,7 @@ func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) (ret return tcpip.ErrAlreadyBound } + e.bindAddress = addr.Addr netProto, err := e.checkV4Mapped(&addr) if err != nil { return err diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index aa4ccea75..43765d425 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -17,8 +17,10 @@ package tcp import ( "fmt" "sync" + "time" "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" ) @@ -32,7 +34,7 @@ func (e *endpoint) drainSegmentLocked() { e.undrain = make(chan struct{}) e.mu.Unlock() - e.notificationWaker.Assert() + e.notifyProtocolGoroutine(notifyDrain) <-e.drainDone e.mu.Lock() @@ -48,37 +50,103 @@ func (e *endpoint) beforeSave() { switch e.state { case stateInitial, stateBound: - case stateListen: - if !e.segmentQueue.empty() { - e.drainSegmentLocked() + case stateListen, stateConnecting, stateConnected: + if e.state == stateConnected && !e.workerRunning { + // The endpoint must be in acceptedChan. + break } - case stateConnecting: e.drainSegmentLocked() - if e.state != stateConnected { + if e.state != stateClosed && e.state != stateError { + if !e.workerRunning { + panic("endpoint has no worker running in listen, connecting, or connected state") + } break } fallthrough - case stateConnected: - // FIXME - panic(tcpip.ErrSaveRejection{fmt.Errorf("endpoint cannot be saved in connected state: local %v:%v, remote %v:%v", e.id.LocalAddress, e.id.LocalPort, e.id.RemoteAddress, e.id.RemotePort)}) - case stateClosed, stateError: + case stateError, stateClosed: + for e.state == stateError && e.workerRunning { + e.mu.Unlock() + time.Sleep(100 * time.Millisecond) + e.mu.Lock() + } if e.workerRunning { - panic(fmt.Sprintf("endpoint still has worker running in closed or error state")) + panic("endpoint still has worker running in closed or error state") } default: panic(fmt.Sprintf("endpoint in unknown state %v", e.state)) } + + if e.waiterQueue != nil && !e.waiterQueue.IsEmpty() { + panic("endpoint still has waiters upon save") + } + + if !((e.state == stateBound || e.state == stateListen) == e.isPortReserved) { + panic("endpoint port must and must only be reserved in bound or listen state") + } + + if e.acceptedChan != nil { + close(e.acceptedChan) + e.acceptedEndpoints = make([]*endpoint, len(e.acceptedChan), cap(e.acceptedChan)) + i := 0 + for ep := range e.acceptedChan { + e.acceptedEndpoints[i] = ep + i++ + } + if i != len(e.acceptedEndpoints) { + panic("endpoint acceptedChan buffer got consumed by background context") + } + } +} + +// saveState is invoked by stateify. +func (e *endpoint) saveState() endpointState { + return e.state +} + +// Endpoint loading must be done in the following ordering by their state, to +// avoid dangling connecting w/o listening peer, and to avoid conflicts in port +// reservation. +var connectedLoading sync.WaitGroup +var listenLoading sync.WaitGroup +var connectingLoading sync.WaitGroup + +// Bound endpoint loading happens last. + +// loadState is invoked by stateify. +func (e *endpoint) loadState(state endpointState) { + // This is to ensure that the loading wait groups include all applicable + // endpoints before any asynchronous calls to the Wait() methods. + switch state { + case stateConnected: + connectedLoading.Add(1) + case stateListen: + listenLoading.Add(1) + case stateConnecting: + connectingLoading.Add(1) + } + e.state = state } // afterLoad is invoked by stateify. func (e *endpoint) afterLoad() { + // We load acceptedChan buffer indirectly here. Note that closed + // endpoints might not need to allocate the channel. + // FIXME + if cap(e.acceptedEndpoints) > 0 { + e.acceptedChan = make(chan *endpoint, cap(e.acceptedEndpoints)) + for _, ep := range e.acceptedEndpoints { + e.acceptedChan <- ep + } + e.acceptedEndpoints = nil + } + e.stack = stack.StackFromEnv e.segmentQueue.setLimit(2 * e.rcvBufSize) e.workMu.Init() state := e.state switch state { - case stateInitial, stateBound, stateListen, stateConnecting: + case stateInitial, stateBound, stateListen, stateConnecting, stateConnected: var ss SendBufferSizeOption if err := e.stack.TransportProtocolOption(ProtocolNumber, &ss); err == nil { if e.sndBufSize < ss.Min || e.sndBufSize > ss.Max { @@ -90,65 +158,72 @@ func (e *endpoint) afterLoad() { } } - switch state { - case stateBound, stateListen, stateConnecting: + bind := func() { e.state = stateInitial - if err := e.Bind(tcpip.FullAddress{Addr: e.id.LocalAddress, Port: e.id.LocalPort}, nil); err != nil { + if len(e.bindAddress) == 0 { + e.bindAddress = e.id.LocalAddress + } + if err := e.Bind(tcpip.FullAddress{Addr: e.bindAddress, Port: e.id.LocalPort}, nil); err != nil { panic("endpoint binding failed: " + err.String()) } } switch state { - case stateListen: - backlog := cap(e.acceptedChan) - e.acceptedChan = nil - if err := e.Listen(backlog); err != nil { - panic("endpoint listening failed: " + err.String()) + case stateConnected: + bind() + if len(e.connectingAddress) == 0 { + // This endpoint is accepted by netstack but not yet by + // the app. If the endpoint is IPv6 but the remote + // address is IPv4, we need to connect as IPv6 so that + // dual-stack mode can be properly activated. + if e.netProto == header.IPv6ProtocolNumber && len(e.id.RemoteAddress) != header.IPv6AddressSize { + e.connectingAddress = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + e.id.RemoteAddress + } else { + e.connectingAddress = e.id.RemoteAddress + } } - } - - switch state { - case stateConnecting: - if err := e.Connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}); err != tcpip.ErrConnectStarted { + if err := e.connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}, false, e.workerRunning); err != tcpip.ErrConnectStarted { panic("endpoint connecting failed: " + err.String()) } + connectedLoading.Done() + case stateListen: + tcpip.AsyncLoading.Add(1) + go func() { + connectedLoading.Wait() + bind() + backlog := cap(e.acceptedChan) + if err := e.Listen(backlog); err != nil { + panic("endpoint listening failed: " + err.String()) + } + listenLoading.Done() + tcpip.AsyncLoading.Done() + }() + case stateConnecting: + tcpip.AsyncLoading.Add(1) + go func() { + connectedLoading.Wait() + listenLoading.Wait() + bind() + if err := e.Connect(tcpip.FullAddress{NIC: e.boundNICID, Addr: e.connectingAddress, Port: e.id.RemotePort}); err != tcpip.ErrConnectStarted { + panic("endpoint connecting failed: " + err.String()) + } + connectingLoading.Done() + tcpip.AsyncLoading.Done() + }() + case stateBound: + tcpip.AsyncLoading.Add(1) + go func() { + connectedLoading.Wait() + listenLoading.Wait() + connectingLoading.Wait() + bind() + tcpip.AsyncLoading.Done() + }() + case stateClosed, stateError: + tcpip.DeleteDanglingEndpoint(e) } } -// saveAcceptedChan is invoked by stateify. -func (e *endpoint) saveAcceptedChan() endpointChan { - if e.acceptedChan == nil { - return endpointChan{} - } - close(e.acceptedChan) - buffer := make([]*endpoint, 0, len(e.acceptedChan)) - for ep := range e.acceptedChan { - buffer = append(buffer, ep) - } - if len(buffer) != cap(buffer) { - panic("endpoint.acceptedChan buffer got consumed by background context") - } - c := cap(e.acceptedChan) - e.acceptedChan = nil - return endpointChan{buffer: buffer, cap: c} -} - -// loadAcceptedChan is invoked by stateify. -func (e *endpoint) loadAcceptedChan(c endpointChan) { - if c.cap == 0 { - return - } - e.acceptedChan = make(chan *endpoint, c.cap) - for _, ep := range c.buffer { - e.acceptedChan <- ep - } -} - -type endpointChan struct { - buffer []*endpoint - cap int -} - // saveLastError is invoked by stateify. func (e *endpoint) saveLastError() string { if e.lastError == nil { diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index a90f6661d..40928ba2c 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -39,9 +39,9 @@ const ( type segment struct { segmentEntry refCnt int32 - id stack.TransportEndpointID - route stack.Route `state:"manual"` - data buffer.VectorisedView + id stack.TransportEndpointID `state:"manual"` + route stack.Route `state:"manual"` + data buffer.VectorisedView `state:".(buffer.VectorisedView)"` // views is used as buffer for data when its length is large // enough to store a VectorisedView. views [8]buffer.View @@ -55,7 +55,7 @@ type segment struct { // parsedOptions stores the parsed values from the options in the segment. parsedOptions header.TCPOptions - options []byte + options []byte `state:".([]byte)"` } func newSegment(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) *segment { diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 83f554ebd..2ddcf5f10 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -22,8 +22,8 @@ import ( // segmentQueue is a bounded, thread-safe queue of TCP segments. type segmentQueue struct { - mu sync.Mutex - list segmentList + mu sync.Mutex `state:"nosave"` + list segmentList `state:"wait"` limit int used int } diff --git a/pkg/tcpip/transport/tcp/segment_state.go b/pkg/tcpip/transport/tcp/segment_state.go new file mode 100644 index 000000000..22f0bbf18 --- /dev/null +++ b/pkg/tcpip/transport/tcp/segment_state.go @@ -0,0 +1,51 @@ +// Copyright 2018 Google Inc. +// +// 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 tcp + +import ( + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" +) + +// saveData is invoked by stateify. +func (s *segment) saveData() buffer.VectorisedView { + // We cannot save s.data directly as s.data.views may alias to s.views, + // which is not allowed by state framework (in-struct pointer). + return s.data.Clone(nil) +} + +// loadData is invoked by stateify. +func (s *segment) loadData(data buffer.VectorisedView) { + // NOTE: We cannot do the s.data = data.Clone(s.views[:]) optimization + // here because data.views is not guaranteed to be loaded by now. Plus, + // data.views will be allocated anyway so there really is little point + // of utilizing s.views for data.views. + s.data = data +} + +// saveOptions is invoked by stateify. +func (s *segment) saveOptions() []byte { + // We cannot save s.options directly as it may point to s.data's trimmed + // tail, which is not allowed by state framework (in-struct pointer). + b := make([]byte, 0, cap(s.options)) + return append(b, s.options...) +} + +// loadOptions is invoked by stateify. +func (s *segment) loadOptions(options []byte) { + // NOTE: We cannot point s.options back into s.data's trimmed tail. But + // it is OK as they do not need to aliased. Plus, options is already + // allocated so there is no cost here. + s.options = options +} diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index a9892eb64..7dfbf6384 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -38,7 +38,7 @@ type sender struct { ep *endpoint // lastSendTime is the timestamp when the last packet was sent. - lastSendTime time.Time + lastSendTime time.Time `state:".(unixTime)"` // dupAckCount is the number of duplicated acks received. It is used for // fast retransmit. @@ -81,7 +81,7 @@ type sender struct { rttMeasureSeqNum seqnum.Value // rttMeasureTime is the time when the rttMeasureSeqNum was sent. - rttMeasureTime time.Time + rttMeasureTime time.Time `state:".(unixTime)"` closed bool writeNext *segment diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go new file mode 100644 index 000000000..33c8867f4 --- /dev/null +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -0,0 +1,49 @@ +// Copyright 2018 Google Inc. +// +// 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 tcp + +import ( + "time" +) + +type unixTime struct { + second int64 + nano int64 +} + +// saveLastSendTime is invoked by stateify. +func (s *sender) saveLastSendTime() unixTime { + return unixTime{s.lastSendTime.Unix(), s.lastSendTime.UnixNano()} +} + +// loadLastSendTime is invoked by stateify. +func (s *sender) loadLastSendTime(unix unixTime) { + s.lastSendTime = time.Unix(unix.second, unix.nano) +} + +// saveRttMeasureTime is invoked by stateify. +func (s *sender) saveRttMeasureTime() unixTime { + return unixTime{s.rttMeasureTime.Unix(), s.rttMeasureTime.UnixNano()} +} + +// loadRttMeasureTime is invoked by stateify. +func (s *sender) loadRttMeasureTime(unix unixTime) { + s.rttMeasureTime = time.Unix(unix.second, unix.nano) +} + +// afterLoad is invoked by stateify. +func (s *sender) afterLoad() { + s.resendTimer.init(&s.resendWaker) +} -- cgit v1.2.3 From bf580cf64dbea1c70a3269914fad6490f7a4968d Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Tue, 10 Jul 2018 13:53:39 -0700 Subject: netstack: only do connected TCP S/R for loopback connections. PiperOrigin-RevId: 204006237 Change-Id: Ica8402ab54d9dd7d11cc41c6d74aacef51d140b7 --- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/stack/registration.go | 1 + pkg/tcpip/transport/tcp/endpoint_state.go | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index aede1b4a2..b4dc4833c 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -56,7 +56,7 @@ func (*endpoint) MTU() uint32 { // Capabilities implements stack.LinkEndpoint.Capabilities. Loopback advertises // itself as supporting checksum offload, but in reality it's just omitted. func (*endpoint) Capabilities() stack.LinkEndpointCapabilities { - return stack.CapabilityChecksumOffload + return stack.CapabilityChecksumOffload | stack.CapabilitySaveRestore } // MaxHeaderLength implements stack.LinkEndpoint.MaxHeaderLength. Given that the diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 70a123bbd..e9550a062 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -201,6 +201,7 @@ type LinkEndpointCapabilities uint const ( CapabilityChecksumOffload LinkEndpointCapabilities = 1 << iota CapabilityResolutionRequired + CapabilitySaveRestore ) // LinkEndpoint is the interface implemented by data link layer protocols (e.g., diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index 43765d425..ad20407fa 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -50,11 +50,16 @@ func (e *endpoint) beforeSave() { switch e.state { case stateInitial, stateBound: - case stateListen, stateConnecting, stateConnected: - if e.state == stateConnected && !e.workerRunning { + case stateConnected: + if e.route.Capabilities()&stack.CapabilitySaveRestore == 0 { + panic(tcpip.ErrSaveRejection{fmt.Errorf("endpoint cannot be saved in connected state: local %v:%d, remote %v:%d", e.id.LocalAddress, e.id.LocalPort, e.id.RemoteAddress, e.id.RemotePort)}) + } + if !e.workerRunning { // The endpoint must be in acceptedChan. break } + fallthrough + case stateListen, stateConnecting: e.drainSegmentLocked() if e.state != stateClosed && e.state != stateError { if !e.workerRunning { -- cgit v1.2.3 From c15cb8d432034e121497dbdc74d2842d5201552f Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Wed, 11 Jul 2018 15:06:29 -0700 Subject: Automated rollback of changelist 203157739 PiperOrigin-RevId: 204196916 Change-Id: If632750fc6368acb835e22cfcee0ae55c8a04d16 --- pkg/tcpip/link/fdbased/endpoint.go | 51 +++++++++++++++----------------------- pkg/tcpip/stack/nic.go | 3 ++- pkg/tcpip/stack/route.go | 16 ++++-------- pkg/tcpip/stack/stack.go | 2 +- runsc/boot/network.go | 9 ++++--- 5 files changed, 33 insertions(+), 48 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index c6a5f6d5a..413f77dcc 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -55,14 +55,10 @@ type endpoint struct { // its end of the communication pipe. closed func(*tcpip.Error) - vv *buffer.VectorisedView - iovecs []syscall.Iovec - views []buffer.View - dispatcher stack.NetworkDispatcher - - // egressLocal indicates whether packets destined to itself should be - // forwarded to the FD endpoint (true) or be sent back to netstack (false). - egressLocal bool + vv *buffer.VectorisedView + iovecs []syscall.Iovec + views []buffer.View + attached bool } // Options specify the details about the fd-based endpoint to be created. @@ -73,7 +69,6 @@ type Options struct { ChecksumOffload bool ClosedFunc func(*tcpip.Error) Address tcpip.LinkAddress - EgressLocal bool } // New creates a new fd-based endpoint. @@ -95,15 +90,14 @@ func New(opts *Options) tcpip.LinkEndpointID { } e := &endpoint{ - fd: opts.FD, - mtu: opts.MTU, - caps: caps, - closed: opts.ClosedFunc, - addr: opts.Address, - hdrSize: hdrSize, - views: make([]buffer.View, len(BufConfig)), - iovecs: make([]syscall.Iovec, len(BufConfig)), - egressLocal: opts.EgressLocal, + fd: opts.FD, + mtu: opts.MTU, + caps: caps, + closed: opts.ClosedFunc, + addr: opts.Address, + hdrSize: hdrSize, + views: make([]buffer.View, len(BufConfig)), + iovecs: make([]syscall.Iovec, len(BufConfig)), } vv := buffer.NewVectorisedView(0, e.views) e.vv = &vv @@ -113,13 +107,13 @@ func New(opts *Options) tcpip.LinkEndpointID { // Attach launches the goroutine that reads packets from the file descriptor and // dispatches them via the provided dispatcher. func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { - e.dispatcher = dispatcher - go e.dispatchLoop() // S/R-FIXME + e.attached = true + go e.dispatchLoop(dispatcher) // S/R-FIXME } // IsAttached implements stack.LinkEndpoint.IsAttached. func (e *endpoint) IsAttached() bool { - return e.dispatcher != nil + return e.attached } // MTU implements stack.LinkEndpoint.MTU. It returns the value initialized @@ -146,12 +140,6 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { - if !e.egressLocal && r.LocalAddress != "" && r.LocalAddress == r.RemoteAddress { - hdrView := hdr.View() - vv := buffer.NewVectorisedView(len(hdrView)+len(payload), []buffer.View{hdrView, payload}) - e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, &vv) - return nil - } if e.hdrSize > 0 { // Add ethernet header if needed. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) @@ -164,6 +152,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload if len(payload) == 0 { return rawfile.NonBlockingWrite(e.fd, hdr.UsedBytes()) + } return rawfile.NonBlockingWrite2(e.fd, hdr.UsedBytes(), payload) @@ -196,7 +185,7 @@ func (e *endpoint) allocateViews(bufConfig []int) { } // dispatch reads one packet from the file descriptor and dispatches it. -func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { +func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool, *tcpip.Error) { e.allocateViews(BufConfig) n, err := rawfile.BlockingReadv(e.fd, e.iovecs) @@ -232,7 +221,7 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { e.vv.SetSize(n) e.vv.TrimFront(e.hdrSize) - e.dispatcher.DeliverNetworkPacket(e, addr, p, e.vv) + d.DeliverNetworkPacket(e, addr, p, e.vv) // Prepare e.views for another packet: release used views. for i := 0; i < used; i++ { @@ -244,10 +233,10 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { // dispatchLoop reads packets from the file descriptor in a loop and dispatches // them to the network stack. -func (e *endpoint) dispatchLoop() *tcpip.Error { +func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) *tcpip.Error { v := buffer.NewView(header.MaxIPPacketSize) for { - cont, err := e.dispatch(v) + cont, err := e.dispatch(d, v) if err != nil || !cont { if e.closed != nil { e.closed(err) diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index c1480f97b..25c06cba5 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -327,7 +327,8 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin return } - r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) + r := makeRoute(protocol, dst, src, ref) + r.LocalLinkAddress = linkEP.LinkAddress() r.RemoteLinkAddress = remoteLinkAddr ref.ep.HandlePacket(&r, vv) ref.decRef() diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 423f428df..200c39289 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -50,13 +50,12 @@ type Route struct { // makeRoute initializes a new route. It takes ownership of the provided // reference to a network endpoint. -func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, localLinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint) Route { +func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, ref *referencedNetworkEndpoint) Route { return Route{ - NetProto: netProto, - LocalAddress: localAddr, - LocalLinkAddress: localLinkAddr, - RemoteAddress: remoteAddr, - ref: ref, + NetProto: netProto, + LocalAddress: localAddr, + RemoteAddress: remoteAddr, + ref: ref, } } @@ -93,11 +92,6 @@ func (r *Route) Resolve(waker *sleep.Waker) *tcpip.Error { nextAddr := r.NextHop if nextAddr == "" { - // Local link address is already known. - if r.RemoteAddress == r.LocalAddress { - r.RemoteLinkAddress = r.LocalLinkAddress - return nil - } nextAddr = r.RemoteAddress } linkAddr, err := r.ref.linkCache.GetLinkAddress(r.ref.nic.ID(), nextAddr, r.LocalAddress, r.NetProto, waker) diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 67a3cc95e..b9d0a1762 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -657,7 +657,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n remoteAddr = ref.ep.ID().LocalAddress } - r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref) + r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, ref) r.NextHop = s.routeTable[i].Gateway return r, nil } diff --git a/runsc/boot/network.go b/runsc/boot/network.go index df45218b9..d2b52c823 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -134,10 +134,11 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct } linkEP := fdbased.New(&fdbased.Options{ - FD: newFD, - MTU: uint32(link.MTU), - EthernetHeader: true, - Address: tcpip.LinkAddress(generateRndMac()), + FD: newFD, + MTU: uint32(link.MTU), + ChecksumOffload: false, + EthernetHeader: true, + Address: tcpip.LinkAddress(generateRndMac()), }) log.Infof("Enabling interface %q with id %d on addresses %+v", link.Name, nicID, link.Addresses) -- cgit v1.2.3 From beb89bb75749620969b0e1dea65240bf5d4324b2 Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Tue, 17 Jul 2018 10:13:57 -0700 Subject: netstack: update goroutine save / restore safety comments. PiperOrigin-RevId: 204930314 Change-Id: Ifc4c41ed28616cd57fafbf7c92e87141a945c41f --- pkg/tcpip/link/fdbased/endpoint.go | 5 ++++- pkg/tcpip/link/sharedmem/sharedmem.go | 5 ++++- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 2 +- pkg/tcpip/stack/linkaddrcache.go | 2 +- pkg/tcpip/transport/tcp/forwarder.go | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 413f77dcc..8fc009160 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -108,7 +108,10 @@ func New(opts *Options) tcpip.LinkEndpointID { // dispatches them via the provided dispatcher. func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { e.attached = true - go e.dispatchLoop(dispatcher) // S/R-FIXME + // Link endpoints are not savable. When transportation endpoints are + // saved, they stop sending outgoing packets and all incoming packets + // are rejected. + go e.dispatchLoop(dispatcher) // S/R-SAFE: See above. } // IsAttached implements stack.LinkEndpoint.IsAttached. diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 223eb3a1b..eabf35bd3 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -142,7 +142,10 @@ func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { if !e.workerStarted && atomic.LoadUint32(&e.stopRequested) == 0 { e.workerStarted = true e.completed.Add(1) - go e.dispatchLoop(dispatcher) // S/R-FIXME + // Link endpoints are not savable. When transportation endpoints + // are saved, they stop sending outgoing packets and all + // incoming packets are rejected. + go e.dispatchLoop(dispatcher) // S/R-SAFE: see above. } e.mu.Unlock() } diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index 8309ee3a0..1915f7ef9 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -187,7 +187,7 @@ func main() { // Start the writer in its own goroutine. writerCompletedCh := make(chan struct{}) - go writer(writerCompletedCh, ep) // S/R-FIXME + go writer(writerCompletedCh, ep) // S/R-SAFE: sample code. // Read data and write to standard output until the peer closes the // connection from its side. diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index a4d955c7a..e01adf635 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -187,6 +187,6 @@ func main() { log.Fatal("Accept() failed:", err) } - go echo(wq, n) // S/R-FIXME + go echo(wq, n) // S/R-SAFE: sample code. } } diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index a1645c7bf..04b8f251a 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -262,7 +262,7 @@ func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes Link e := c.makeAndAddEntry(k, "") e.addWaker(waker) - go func() { // S/R-FIXME + go func() { // S/R-SAFE: link non-savable; wakers dropped synchronously. for i := 0; ; i++ { // Send link request, then wait for the timeout limit and check // whether the request succeeded. diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index 71eb89795..8a873db73 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -90,7 +90,7 @@ func (f *Forwarder) HandlePacket(r *stack.Route, id stack.TransportEndpointID, v // Launch a new goroutine to handle the request. f.inFlight[id] = struct{}{} s.incRef() - go f.handler(&ForwarderRequest{ // S/R-FIXME + go f.handler(&ForwarderRequest{ // S/R-SAFE: not used by Sentry. forwarder: f, segment: s, synOptions: opts, -- cgit v1.2.3 From be7fcbc5582fe831b5ec63f773d867d7591e27a1 Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Fri, 27 Jul 2018 10:16:27 -0700 Subject: stateify: support explicit annotation mode; convert refs and stack packages. We have been unnecessarily creating too many savable types implicitly. PiperOrigin-RevId: 206334201 Change-Id: Idc5a3a14bfb7ee125c4f2bb2b1c53164e46f29a8 --- pkg/abi/BUILD | 3 +- pkg/abi/linux/BUILD | 3 +- pkg/amutex/BUILD | 2 +- pkg/atomicbitops/BUILD | 2 +- pkg/binary/BUILD | 2 +- pkg/bits/BUILD | 2 +- pkg/bpf/BUILD | 3 +- pkg/compressio/BUILD | 2 +- pkg/control/client/BUILD | 2 +- pkg/control/server/BUILD | 2 +- pkg/cpuid/BUILD | 3 +- pkg/dhcp/BUILD | 2 +- pkg/eventchannel/BUILD | 2 +- pkg/fd/BUILD | 2 +- pkg/gate/BUILD | 2 +- pkg/hashio/BUILD | 2 +- pkg/ilist/BUILD | 3 +- pkg/linewriter/BUILD | 2 +- pkg/log/BUILD | 2 +- pkg/metric/BUILD | 2 +- pkg/p9/BUILD | 2 +- pkg/p9/p9test/BUILD | 2 +- pkg/rand/BUILD | 2 +- pkg/refs/BUILD | 20 +------- pkg/refs/refcounter.go | 4 ++ pkg/refs/refcounter_state.go | 1 + pkg/seccomp/BUILD | 3 +- pkg/secio/BUILD | 2 +- pkg/segment/test/BUILD | 2 +- pkg/sentry/arch/BUILD | 3 +- pkg/sentry/context/BUILD | 2 +- pkg/sentry/context/contexttest/BUILD | 3 +- pkg/sentry/control/BUILD | 2 +- pkg/sentry/device/BUILD | 2 +- pkg/sentry/fs/BUILD | 3 +- pkg/sentry/fs/anon/BUILD | 2 +- pkg/sentry/fs/ashmem/BUILD | 3 +- pkg/sentry/fs/binder/BUILD | 3 +- pkg/sentry/fs/dev/BUILD | 3 +- pkg/sentry/fs/fdpipe/BUILD | 3 +- pkg/sentry/fs/filetest/BUILD | 3 +- pkg/sentry/fs/fsutil/BUILD | 3 +- pkg/sentry/fs/gofer/BUILD | 3 +- pkg/sentry/fs/host/BUILD | 3 +- pkg/sentry/fs/lock/BUILD | 3 +- pkg/sentry/fs/proc/BUILD | 3 +- pkg/sentry/fs/proc/device/BUILD | 2 +- pkg/sentry/fs/proc/seqfile/BUILD | 3 +- pkg/sentry/fs/ramfs/BUILD | 3 +- pkg/sentry/fs/ramfs/test/BUILD | 3 +- pkg/sentry/fs/sys/BUILD | 3 +- pkg/sentry/fs/timerfd/BUILD | 3 +- pkg/sentry/fs/tmpfs/BUILD | 3 +- pkg/sentry/fs/tty/BUILD | 3 +- pkg/sentry/hostcpu/BUILD | 2 +- pkg/sentry/inet/BUILD | 4 +- pkg/sentry/kernel/BUILD | 3 +- pkg/sentry/kernel/auth/BUILD | 3 +- pkg/sentry/kernel/epoll/BUILD | 3 +- pkg/sentry/kernel/eventfd/BUILD | 3 +- pkg/sentry/kernel/fasync/BUILD | 2 +- pkg/sentry/kernel/futex/BUILD | 3 +- pkg/sentry/kernel/kdefs/BUILD | 2 +- pkg/sentry/kernel/memevent/BUILD | 2 +- pkg/sentry/kernel/pipe/BUILD | 3 +- pkg/sentry/kernel/sched/BUILD | 2 +- pkg/sentry/kernel/semaphore/BUILD | 3 +- pkg/sentry/kernel/shm/BUILD | 3 +- pkg/sentry/kernel/time/BUILD | 3 +- pkg/sentry/limits/BUILD | 3 +- pkg/sentry/loader/BUILD | 4 +- pkg/sentry/memmap/BUILD | 3 +- pkg/sentry/memutil/BUILD | 2 +- pkg/sentry/mm/BUILD | 3 +- pkg/sentry/platform/BUILD | 3 +- pkg/sentry/platform/filemem/BUILD | 3 +- pkg/sentry/platform/interrupt/BUILD | 2 +- pkg/sentry/platform/kvm/BUILD | 2 +- pkg/sentry/platform/kvm/testutil/BUILD | 2 +- pkg/sentry/platform/procid/BUILD | 2 +- pkg/sentry/platform/ptrace/BUILD | 2 +- pkg/sentry/platform/ring0/BUILD | 2 +- pkg/sentry/platform/ring0/pagetables/BUILD | 2 +- pkg/sentry/platform/safecopy/BUILD | 2 +- pkg/sentry/safemem/BUILD | 2 +- pkg/sentry/sighandling/BUILD | 2 +- pkg/sentry/socket/BUILD | 3 +- pkg/sentry/socket/control/BUILD | 3 +- pkg/sentry/socket/epsocket/BUILD | 3 +- pkg/sentry/socket/hostinet/BUILD | 3 +- pkg/sentry/socket/netlink/BUILD | 3 +- pkg/sentry/socket/netlink/port/BUILD | 3 +- pkg/sentry/socket/netlink/route/BUILD | 3 +- pkg/sentry/socket/rpcinet/BUILD | 2 +- pkg/sentry/socket/rpcinet/conn/BUILD | 2 +- pkg/sentry/socket/rpcinet/notifier/BUILD | 2 +- pkg/sentry/socket/unix/BUILD | 3 +- pkg/sentry/state/BUILD | 2 +- pkg/sentry/strace/BUILD | 2 +- pkg/sentry/syscalls/BUILD | 2 +- pkg/sentry/syscalls/linux/BUILD | 3 +- pkg/sentry/time/BUILD | 2 +- pkg/sentry/uniqueid/BUILD | 2 +- pkg/sentry/usage/BUILD | 3 +- pkg/sentry/usermem/BUILD | 3 +- pkg/sentry/watchdog/BUILD | 2 +- pkg/sleep/BUILD | 2 +- pkg/state/BUILD | 2 +- pkg/state/statefile/BUILD | 2 +- pkg/sync/BUILD | 2 +- pkg/sync/seqatomictest/BUILD | 2 +- pkg/syserr/BUILD | 2 +- pkg/syserror/BUILD | 2 +- pkg/tcpip/BUILD | 3 +- pkg/tcpip/adapters/gonet/BUILD | 2 +- pkg/tcpip/buffer/BUILD | 3 +- pkg/tcpip/checker/BUILD | 2 +- pkg/tcpip/header/BUILD | 3 +- pkg/tcpip/link/channel/BUILD | 2 +- pkg/tcpip/link/fdbased/BUILD | 2 +- pkg/tcpip/link/loopback/BUILD | 2 +- pkg/tcpip/link/rawfile/BUILD | 2 +- pkg/tcpip/link/sharedmem/BUILD | 2 +- pkg/tcpip/link/sharedmem/pipe/BUILD | 2 +- pkg/tcpip/link/sharedmem/queue/BUILD | 2 +- pkg/tcpip/link/sniffer/BUILD | 2 +- pkg/tcpip/link/tun/BUILD | 2 +- pkg/tcpip/link/waitable/BUILD | 2 +- pkg/tcpip/network/BUILD | 2 +- pkg/tcpip/network/arp/BUILD | 2 +- pkg/tcpip/network/fragmentation/BUILD | 3 +- pkg/tcpip/network/hash/BUILD | 2 +- pkg/tcpip/network/ipv4/BUILD | 2 +- pkg/tcpip/network/ipv6/BUILD | 2 +- pkg/tcpip/ports/BUILD | 2 +- pkg/tcpip/seqnum/BUILD | 3 +- pkg/tcpip/stack/BUILD | 15 +----- pkg/tcpip/stack/registration.go | 2 + pkg/tcpip/transport/ping/BUILD | 3 +- pkg/tcpip/transport/queue/BUILD | 3 +- pkg/tcpip/transport/tcp/BUILD | 3 +- pkg/tcpip/transport/tcp/testing/context/BUILD | 2 +- pkg/tcpip/transport/tcpconntrack/BUILD | 2 +- pkg/tcpip/transport/udp/BUILD | 3 +- pkg/tcpip/transport/unix/BUILD | 3 +- pkg/tmutex/BUILD | 2 +- pkg/unet/BUILD | 2 +- pkg/urpc/BUILD | 2 +- pkg/waiter/BUILD | 3 +- pkg/waiter/fdnotifier/BUILD | 2 +- tools/go_stateify/defs.bzl | 58 ++++++++++++++++++----- tools/go_stateify/main.go | 66 +++++++++++++++++++++------ 152 files changed, 255 insertions(+), 267 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD index 4d507161f..f1e6bac67 100644 --- a/pkg/abi/BUILD +++ b/pkg/abi/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "abi_state", diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index ae7e4378c..38b4829c9 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -4,8 +4,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "linux_state", diff --git a/pkg/amutex/BUILD b/pkg/amutex/BUILD index 442096319..84e6b79a5 100644 --- a/pkg/amutex/BUILD +++ b/pkg/amutex/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "amutex", diff --git a/pkg/atomicbitops/BUILD b/pkg/atomicbitops/BUILD index f20a9f855..a8dd17825 100644 --- a/pkg/atomicbitops/BUILD +++ b/pkg/atomicbitops/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "atomicbitops", diff --git a/pkg/binary/BUILD b/pkg/binary/BUILD index 16f08b13f..586d05634 100644 --- a/pkg/binary/BUILD +++ b/pkg/binary/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "binary", diff --git a/pkg/bits/BUILD b/pkg/bits/BUILD index 9897e5dc3..8c943b615 100644 --- a/pkg/bits/BUILD +++ b/pkg/bits/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") go_library( diff --git a/pkg/bpf/BUILD b/pkg/bpf/BUILD index d4f12f13a..403270049 100644 --- a/pkg/bpf/BUILD +++ b/pkg/bpf/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "bpf_state", diff --git a/pkg/compressio/BUILD b/pkg/compressio/BUILD index 721b2d983..d70f982c1 100644 --- a/pkg/compressio/BUILD +++ b/pkg/compressio/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "compressio", diff --git a/pkg/control/client/BUILD b/pkg/control/client/BUILD index 9e1c058e4..d58cd1b71 100644 --- a/pkg/control/client/BUILD +++ b/pkg/control/client/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "client", diff --git a/pkg/control/server/BUILD b/pkg/control/server/BUILD index 2d0fdd8b8..c3f74a532 100644 --- a/pkg/control/server/BUILD +++ b/pkg/control/server/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "server", diff --git a/pkg/cpuid/BUILD b/pkg/cpuid/BUILD index a503b7ae8..9a0ca1b33 100644 --- a/pkg/cpuid/BUILD +++ b/pkg/cpuid/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "cpuid_state", diff --git a/pkg/dhcp/BUILD b/pkg/dhcp/BUILD index f56969ad8..bd9f592b4 100644 --- a/pkg/dhcp/BUILD +++ b/pkg/dhcp/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "dhcp", diff --git a/pkg/eventchannel/BUILD b/pkg/eventchannel/BUILD index ea0c587be..ac2ea869d 100644 --- a/pkg/eventchannel/BUILD +++ b/pkg/eventchannel/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "eventchannel", diff --git a/pkg/fd/BUILD b/pkg/fd/BUILD index e69d83d06..435b6fa34 100644 --- a/pkg/fd/BUILD +++ b/pkg/fd/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "fd", diff --git a/pkg/gate/BUILD b/pkg/gate/BUILD index 0b8b01da8..872eff531 100644 --- a/pkg/gate/BUILD +++ b/pkg/gate/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "gate", diff --git a/pkg/hashio/BUILD b/pkg/hashio/BUILD index aaa58b58f..5736e2e73 100644 --- a/pkg/hashio/BUILD +++ b/pkg/hashio/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "hashio", diff --git a/pkg/ilist/BUILD b/pkg/ilist/BUILD index 16a738e89..e32f26ffa 100644 --- a/pkg/ilist/BUILD +++ b/pkg/ilist/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "list_state", diff --git a/pkg/linewriter/BUILD b/pkg/linewriter/BUILD index 4a96c6f1d..6c3795432 100644 --- a/pkg/linewriter/BUILD +++ b/pkg/linewriter/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "linewriter", diff --git a/pkg/log/BUILD b/pkg/log/BUILD index 2530cfd18..fc9281079 100644 --- a/pkg/log/BUILD +++ b/pkg/log/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "log", diff --git a/pkg/metric/BUILD b/pkg/metric/BUILD index e3f50d528..c0cd40c7b 100644 --- a/pkg/metric/BUILD +++ b/pkg/metric/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "metric", diff --git a/pkg/p9/BUILD b/pkg/p9/BUILD index f348ff2e9..1cf5c6458 100644 --- a/pkg/p9/BUILD +++ b/pkg/p9/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:public"], diff --git a/pkg/p9/p9test/BUILD b/pkg/p9/p9test/BUILD index 339c86089..d6f428e11 100644 --- a/pkg/p9/p9test/BUILD +++ b/pkg/p9/p9test/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_test( name = "p9test_test", diff --git a/pkg/rand/BUILD b/pkg/rand/BUILD index 2bb59f895..12e6cf25a 100644 --- a/pkg/rand/BUILD +++ b/pkg/rand/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "rand", diff --git a/pkg/refs/BUILD b/pkg/refs/BUILD index 4b7c9345d..3ea877ccf 100644 --- a/pkg/refs/BUILD +++ b/pkg/refs/BUILD @@ -1,32 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") - -go_stateify( - name = "refs_state", - srcs = [ - "refcounter.go", - "refcounter_state.go", - ], - out = "refs_state.go", - package = "refs", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "refs", srcs = [ "refcounter.go", "refcounter_state.go", - "refs_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/refs", visibility = ["//:sandbox"], - deps = [ - "//pkg/ilist", - "//pkg/log", - "//pkg/state", - ], + deps = ["//pkg/ilist"], ) go_test( diff --git a/pkg/refs/refcounter.go b/pkg/refs/refcounter.go index 3162001e1..0d44c2499 100644 --- a/pkg/refs/refcounter.go +++ b/pkg/refs/refcounter.go @@ -58,6 +58,8 @@ type WeakRefUser interface { } // WeakRef is a weak reference. +// +// +stateify savable type WeakRef struct { ilist.Entry `state:"nosave"` @@ -177,6 +179,8 @@ func (w *WeakRef) zap() { // // N.B. To allow the zero-object to be initialized, the count is offset by // 1, that is, when refCount is n, there are really n+1 references. +// +// +stateify savable type AtomicRefCount struct { // refCount is composed of two fields: // diff --git a/pkg/refs/refcounter_state.go b/pkg/refs/refcounter_state.go index 1be67f951..093eae785 100644 --- a/pkg/refs/refcounter_state.go +++ b/pkg/refs/refcounter_state.go @@ -14,6 +14,7 @@ package refs +// +stateify savable type savedReference struct { obj interface{} } diff --git a/pkg/seccomp/BUILD b/pkg/seccomp/BUILD index cadd24505..b3e2f0b38 100644 --- a/pkg/seccomp/BUILD +++ b/pkg/seccomp/BUILD @@ -1,6 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_embed_data", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_embed_data") go_binary( name = "victim", diff --git a/pkg/secio/BUILD b/pkg/secio/BUILD index 9a28d2c1f..0ed38c64a 100644 --- a/pkg/secio/BUILD +++ b/pkg/secio/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "secio", diff --git a/pkg/segment/test/BUILD b/pkg/segment/test/BUILD index 9d398d71a..bdf53e24e 100644 --- a/pkg/segment/test/BUILD +++ b/pkg/segment/test/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:private"], diff --git a/pkg/sentry/arch/BUILD b/pkg/sentry/arch/BUILD index a88f57ac7..0a2a35400 100644 --- a/pkg/sentry/arch/BUILD +++ b/pkg/sentry/arch/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "arch_state", diff --git a/pkg/sentry/context/BUILD b/pkg/sentry/context/BUILD index ff39f94ba..2a7a6df23 100644 --- a/pkg/sentry/context/BUILD +++ b/pkg/sentry/context/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "context", diff --git a/pkg/sentry/context/contexttest/BUILD b/pkg/sentry/context/contexttest/BUILD index 5977344de..591b11a4d 100644 --- a/pkg/sentry/context/contexttest/BUILD +++ b/pkg/sentry/context/contexttest/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "contexttest_state", diff --git a/pkg/sentry/control/BUILD b/pkg/sentry/control/BUILD index 6169891f7..fbdde0721 100644 --- a/pkg/sentry/control/BUILD +++ b/pkg/sentry/control/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "control", diff --git a/pkg/sentry/device/BUILD b/pkg/sentry/device/BUILD index 1a8b461ba..69c99b0b3 100644 --- a/pkg/sentry/device/BUILD +++ b/pkg/sentry/device/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "device", diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 9b7264753..e3c9a9b70 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "fs_state", diff --git a/pkg/sentry/fs/anon/BUILD b/pkg/sentry/fs/anon/BUILD index 6b18aee47..ff4ab850a 100644 --- a/pkg/sentry/fs/anon/BUILD +++ b/pkg/sentry/fs/anon/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "anon", diff --git a/pkg/sentry/fs/ashmem/BUILD b/pkg/sentry/fs/ashmem/BUILD index e20e22a0f..9f166799a 100644 --- a/pkg/sentry/fs/ashmem/BUILD +++ b/pkg/sentry/fs/ashmem/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_stateify( diff --git a/pkg/sentry/fs/binder/BUILD b/pkg/sentry/fs/binder/BUILD index 15f91699f..ec3928baf 100644 --- a/pkg/sentry/fs/binder/BUILD +++ b/pkg/sentry/fs/binder/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "binder_state", diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD index d33a19c2f..ea41615fd 100644 --- a/pkg/sentry/fs/dev/BUILD +++ b/pkg/sentry/fs/dev/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "dev_state", diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index 9e1f65d3e..4fcb06f1f 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "pipe_state", diff --git a/pkg/sentry/fs/filetest/BUILD b/pkg/sentry/fs/filetest/BUILD index 51a390d77..f481c57fb 100644 --- a/pkg/sentry/fs/filetest/BUILD +++ b/pkg/sentry/fs/filetest/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "filetest_state", diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index 4fa6395f7..6eea64298 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "fsutil_state", diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD index e6f659c53..1277379e7 100644 --- a/pkg/sentry/fs/gofer/BUILD +++ b/pkg/sentry/fs/gofer/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "gofer_state", diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 97b64daed..23ec66f50 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "host_state", diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD index c15dde800..2607d7ed3 100644 --- a/pkg/sentry/fs/lock/BUILD +++ b/pkg/sentry/fs/lock/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "lock_state", diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index 21b5fc0c3..870df47b2 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "proc_state", diff --git a/pkg/sentry/fs/proc/device/BUILD b/pkg/sentry/fs/proc/device/BUILD index b62062bd7..34582f275 100644 --- a/pkg/sentry/fs/proc/device/BUILD +++ b/pkg/sentry/fs/proc/device/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "device", diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD index 48dd25e5b..c84f7e20d 100644 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ b/pkg/sentry/fs/proc/seqfile/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "seqfile_state", diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index 663a1aeb9..d84f2c624 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "ramfs_state", diff --git a/pkg/sentry/fs/ramfs/test/BUILD b/pkg/sentry/fs/ramfs/test/BUILD index 074b0f5ad..57fee45e2 100644 --- a/pkg/sentry/fs/ramfs/test/BUILD +++ b/pkg/sentry/fs/ramfs/test/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "test_state", diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD index 0ae2cbac8..095ff1f25 100644 --- a/pkg/sentry/fs/sys/BUILD +++ b/pkg/sentry/fs/sys/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "sys_state", diff --git a/pkg/sentry/fs/timerfd/BUILD b/pkg/sentry/fs/timerfd/BUILD index 7fddc29f4..8b1b7872e 100644 --- a/pkg/sentry/fs/timerfd/BUILD +++ b/pkg/sentry/fs/timerfd/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "timerfd_state", diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD index be4e695d3..473ab4296 100644 --- a/pkg/sentry/fs/tmpfs/BUILD +++ b/pkg/sentry/fs/tmpfs/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tmpfs_state", diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index fce327dfe..363897b2c 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tty_state", diff --git a/pkg/sentry/hostcpu/BUILD b/pkg/sentry/hostcpu/BUILD index 9457618d8..f362d15c8 100644 --- a/pkg/sentry/hostcpu/BUILD +++ b/pkg/sentry/hostcpu/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "hostcpu", diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD index 1150ced57..eaf8f15b2 100644 --- a/pkg/sentry/inet/BUILD +++ b/pkg/sentry/inet/BUILD @@ -1,11 +1,9 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - package( default_visibility = ["//:sandbox"], licenses = ["notice"], # Apache 2.0 ) -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "inet_state", diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 07568b47c..c4a7dacb2 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "kernel_state", diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index 7f0680b88..5b7b30557 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "auth_state", diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 04651d961..7d491efbc 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "epoll_autogen_state", diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index 561ced852..7ec179bd8 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "eventfd_state", diff --git a/pkg/sentry/kernel/fasync/BUILD b/pkg/sentry/kernel/fasync/BUILD index 8d06e1182..17749c0de 100644 --- a/pkg/sentry/kernel/fasync/BUILD +++ b/pkg/sentry/kernel/fasync/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "fasync", diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index de9897c58..a97a43549 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_template_instance( name = "waiter_list", diff --git a/pkg/sentry/kernel/kdefs/BUILD b/pkg/sentry/kernel/kdefs/BUILD index b6c00042a..fe6fa2260 100644 --- a/pkg/sentry/kernel/kdefs/BUILD +++ b/pkg/sentry/kernel/kdefs/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "kdefs", diff --git a/pkg/sentry/kernel/memevent/BUILD b/pkg/sentry/kernel/memevent/BUILD index c7779e1d5..66899910c 100644 --- a/pkg/sentry/kernel/memevent/BUILD +++ b/pkg/sentry/kernel/memevent/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "memevent", diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index ca9825f9d..4600d19bd 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "pipe_state", diff --git a/pkg/sentry/kernel/sched/BUILD b/pkg/sentry/kernel/sched/BUILD index b533c51c4..125792f39 100644 --- a/pkg/sentry/kernel/sched/BUILD +++ b/pkg/sentry/kernel/sched/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "sched", diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD index 1656ad126..969145fe1 100644 --- a/pkg/sentry/kernel/semaphore/BUILD +++ b/pkg/sentry/kernel/semaphore/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_template_instance( name = "waiter_list", diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD index 182cc1c76..0f88eb0ac 100644 --- a/pkg/sentry/kernel/shm/BUILD +++ b/pkg/sentry/kernel/shm/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "shm_state", diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD index 84f31b2dc..b3ed42aa4 100644 --- a/pkg/sentry/kernel/time/BUILD +++ b/pkg/sentry/kernel/time/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "time_state", diff --git a/pkg/sentry/limits/BUILD b/pkg/sentry/limits/BUILD index 06c3e72b0..3ce41cacc 100644 --- a/pkg/sentry/limits/BUILD +++ b/pkg/sentry/limits/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "limits_state", diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index 01a0ec426..e63052c6d 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_embed_data", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("@io_bazel_rules_go//go:def.bzl", "go_embed_data") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_embed_data( name = "vdso_bin", diff --git a/pkg/sentry/memmap/BUILD b/pkg/sentry/memmap/BUILD index 7525fea45..2e367e189 100644 --- a/pkg/sentry/memmap/BUILD +++ b/pkg/sentry/memmap/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "memmap_state", diff --git a/pkg/sentry/memutil/BUILD b/pkg/sentry/memutil/BUILD index a387a0c9f..341b30b98 100644 --- a/pkg/sentry/memutil/BUILD +++ b/pkg/sentry/memutil/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "memutil", diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 258389bb2..3f396986a 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "mm_state", diff --git a/pkg/sentry/platform/BUILD b/pkg/sentry/platform/BUILD index d5be81f8d..15a7fbbc3 100644 --- a/pkg/sentry/platform/BUILD +++ b/pkg/sentry/platform/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "platform_state", diff --git a/pkg/sentry/platform/filemem/BUILD b/pkg/sentry/platform/filemem/BUILD index 3c4d5b0b6..dadba1d38 100644 --- a/pkg/sentry/platform/filemem/BUILD +++ b/pkg/sentry/platform/filemem/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "filemem_autogen_state", diff --git a/pkg/sentry/platform/interrupt/BUILD b/pkg/sentry/platform/interrupt/BUILD index 33dde2a31..35121321a 100644 --- a/pkg/sentry/platform/interrupt/BUILD +++ b/pkg/sentry/platform/interrupt/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "interrupt", diff --git a/pkg/sentry/platform/kvm/BUILD b/pkg/sentry/platform/kvm/BUILD index 673393fad..4ef9e20d7 100644 --- a/pkg/sentry/platform/kvm/BUILD +++ b/pkg/sentry/platform/kvm/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( diff --git a/pkg/sentry/platform/kvm/testutil/BUILD b/pkg/sentry/platform/kvm/testutil/BUILD index 8533a8d89..e779e3893 100644 --- a/pkg/sentry/platform/kvm/testutil/BUILD +++ b/pkg/sentry/platform/kvm/testutil/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "testutil", diff --git a/pkg/sentry/platform/procid/BUILD b/pkg/sentry/platform/procid/BUILD index 5db4f6261..ba68d48f4 100644 --- a/pkg/sentry/platform/procid/BUILD +++ b/pkg/sentry/platform/procid/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "procid", diff --git a/pkg/sentry/platform/ptrace/BUILD b/pkg/sentry/platform/ptrace/BUILD index 16b0b3c69..ceee895dc 100644 --- a/pkg/sentry/platform/ptrace/BUILD +++ b/pkg/sentry/platform/ptrace/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "ptrace", diff --git a/pkg/sentry/platform/ring0/BUILD b/pkg/sentry/platform/ring0/BUILD index 2df232a64..2485eb2eb 100644 --- a/pkg/sentry/platform/ring0/BUILD +++ b/pkg/sentry/platform/ring0/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") go_template( diff --git a/pkg/sentry/platform/ring0/pagetables/BUILD b/pkg/sentry/platform/ring0/pagetables/BUILD index 023e298a0..7a86e2234 100644 --- a/pkg/sentry/platform/ring0/pagetables/BUILD +++ b/pkg/sentry/platform/ring0/pagetables/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") go_template( diff --git a/pkg/sentry/platform/safecopy/BUILD b/pkg/sentry/platform/safecopy/BUILD index 8b9f29403..7dcf6e561 100644 --- a/pkg/sentry/platform/safecopy/BUILD +++ b/pkg/sentry/platform/safecopy/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "safecopy", diff --git a/pkg/sentry/safemem/BUILD b/pkg/sentry/safemem/BUILD index dc4cfce41..e96509ce1 100644 --- a/pkg/sentry/safemem/BUILD +++ b/pkg/sentry/safemem/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "safemem", diff --git a/pkg/sentry/sighandling/BUILD b/pkg/sentry/sighandling/BUILD index daaad7c90..f480f0735 100644 --- a/pkg/sentry/sighandling/BUILD +++ b/pkg/sentry/sighandling/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "sighandling", diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD index 5500a676e..929787aa0 100644 --- a/pkg/sentry/socket/BUILD +++ b/pkg/sentry/socket/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "socket_state", diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD index 25de2f655..faf2b4c27 100644 --- a/pkg/sentry/socket/control/BUILD +++ b/pkg/sentry/socket/control/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "control_state", diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index 8430886cb..7ad5e88c5 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "epsocket_state", diff --git a/pkg/sentry/socket/hostinet/BUILD b/pkg/sentry/socket/hostinet/BUILD index 60ec265ba..227ca3926 100644 --- a/pkg/sentry/socket/hostinet/BUILD +++ b/pkg/sentry/socket/hostinet/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "hostinet_state", diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD index 9df3ab17c..b23a243f7 100644 --- a/pkg/sentry/socket/netlink/BUILD +++ b/pkg/sentry/socket/netlink/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "netlink_state", diff --git a/pkg/sentry/socket/netlink/port/BUILD b/pkg/sentry/socket/netlink/port/BUILD index 7340b95c9..ba6f686e4 100644 --- a/pkg/sentry/socket/netlink/port/BUILD +++ b/pkg/sentry/socket/netlink/port/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "port_state", diff --git a/pkg/sentry/socket/netlink/route/BUILD b/pkg/sentry/socket/netlink/route/BUILD index ff3f7b7a4..726469fc9 100644 --- a/pkg/sentry/socket/netlink/route/BUILD +++ b/pkg/sentry/socket/netlink/route/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "route_state", diff --git a/pkg/sentry/socket/rpcinet/BUILD b/pkg/sentry/socket/rpcinet/BUILD index 8973453f9..288199779 100644 --- a/pkg/sentry/socket/rpcinet/BUILD +++ b/pkg/sentry/socket/rpcinet/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "rpcinet", diff --git a/pkg/sentry/socket/rpcinet/conn/BUILD b/pkg/sentry/socket/rpcinet/conn/BUILD index 4923dee4b..c51ca14b1 100644 --- a/pkg/sentry/socket/rpcinet/conn/BUILD +++ b/pkg/sentry/socket/rpcinet/conn/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # BSD -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "conn", diff --git a/pkg/sentry/socket/rpcinet/notifier/BUILD b/pkg/sentry/socket/rpcinet/notifier/BUILD index 6f3b06a05..2ae902b3f 100644 --- a/pkg/sentry/socket/rpcinet/notifier/BUILD +++ b/pkg/sentry/socket/rpcinet/notifier/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # BSD -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "notifier", diff --git a/pkg/sentry/socket/unix/BUILD b/pkg/sentry/socket/unix/BUILD index 1ec6eb7ed..7d04d6b6b 100644 --- a/pkg/sentry/socket/unix/BUILD +++ b/pkg/sentry/socket/unix/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "unix_state", diff --git a/pkg/sentry/state/BUILD b/pkg/sentry/state/BUILD index 9bd98f445..a57a8298e 100644 --- a/pkg/sentry/state/BUILD +++ b/pkg/sentry/state/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "state", diff --git a/pkg/sentry/strace/BUILD b/pkg/sentry/strace/BUILD index c5946a564..e1c8db67a 100644 --- a/pkg/sentry/strace/BUILD +++ b/pkg/sentry/strace/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "strace", diff --git a/pkg/sentry/syscalls/BUILD b/pkg/sentry/syscalls/BUILD index d667b42c8..22a757095 100644 --- a/pkg/sentry/syscalls/BUILD +++ b/pkg/sentry/syscalls/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "syscalls", diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index d3f3cc459..574621ad2 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "linux_state", diff --git a/pkg/sentry/time/BUILD b/pkg/sentry/time/BUILD index cbcd699d5..9452787fb 100644 --- a/pkg/sentry/time/BUILD +++ b/pkg/sentry/time/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( diff --git a/pkg/sentry/uniqueid/BUILD b/pkg/sentry/uniqueid/BUILD index c8ab03c3d..8eba3609e 100644 --- a/pkg/sentry/uniqueid/BUILD +++ b/pkg/sentry/uniqueid/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "uniqueid", diff --git a/pkg/sentry/usage/BUILD b/pkg/sentry/usage/BUILD index a0fe0aa07..edee44d96 100644 --- a/pkg/sentry/usage/BUILD +++ b/pkg/sentry/usage/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "usage_state", diff --git a/pkg/sentry/usermem/BUILD b/pkg/sentry/usermem/BUILD index 36c0760dd..9dd1cd2b5 100644 --- a/pkg/sentry/usermem/BUILD +++ b/pkg/sentry/usermem/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "usermem_state", diff --git a/pkg/sentry/watchdog/BUILD b/pkg/sentry/watchdog/BUILD index 28fae4490..13bc33eb1 100644 --- a/pkg/sentry/watchdog/BUILD +++ b/pkg/sentry/watchdog/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "watchdog", diff --git a/pkg/sleep/BUILD b/pkg/sleep/BUILD index f2b69b225..05e4ca540 100644 --- a/pkg/sleep/BUILD +++ b/pkg/sleep/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "sleep", diff --git a/pkg/state/BUILD b/pkg/state/BUILD index bb6415d9b..012b0484e 100644 --- a/pkg/state/BUILD +++ b/pkg/state/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( diff --git a/pkg/state/statefile/BUILD b/pkg/state/statefile/BUILD index df2c6a578..16abe1930 100644 --- a/pkg/state/statefile/BUILD +++ b/pkg/state/statefile/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "statefile", diff --git a/pkg/sync/BUILD b/pkg/sync/BUILD index 1fc0c25b5..3959fea36 100644 --- a/pkg/sync/BUILD +++ b/pkg/sync/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//:sandbox"], diff --git a/pkg/sync/seqatomictest/BUILD b/pkg/sync/seqatomictest/BUILD index 9d6ee2dfb..07b4f85ab 100644 --- a/pkg/sync/seqatomictest/BUILD +++ b/pkg/sync/seqatomictest/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( diff --git a/pkg/syserr/BUILD b/pkg/syserr/BUILD index e5ce48412..c0850f3d9 100644 --- a/pkg/syserr/BUILD +++ b/pkg/syserr/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "syserr", diff --git a/pkg/syserror/BUILD b/pkg/syserror/BUILD index 68ddec786..e050c2043 100644 --- a/pkg/syserror/BUILD +++ b/pkg/syserror/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "syserror", diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index 186a0d3bf..391d801d0 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tcpip_state", diff --git a/pkg/tcpip/adapters/gonet/BUILD b/pkg/tcpip/adapters/gonet/BUILD index 97da46776..bf618831a 100644 --- a/pkg/tcpip/adapters/gonet/BUILD +++ b/pkg/tcpip/adapters/gonet/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "gonet", diff --git a/pkg/tcpip/buffer/BUILD b/pkg/tcpip/buffer/BUILD index 08adf18cd..efeb6a448 100644 --- a/pkg/tcpip/buffer/BUILD +++ b/pkg/tcpip/buffer/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "buffer_state", diff --git a/pkg/tcpip/checker/BUILD b/pkg/tcpip/checker/BUILD index 5447cfbf4..e8a524918 100644 --- a/pkg/tcpip/checker/BUILD +++ b/pkg/tcpip/checker/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "checker", diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 859c2a106..3aa2cfb24 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tcp_header_state", diff --git a/pkg/tcpip/link/channel/BUILD b/pkg/tcpip/link/channel/BUILD index f2f0c8b6f..9a6f49c45 100644 --- a/pkg/tcpip/link/channel/BUILD +++ b/pkg/tcpip/link/channel/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "channel", diff --git a/pkg/tcpip/link/fdbased/BUILD b/pkg/tcpip/link/fdbased/BUILD index aca3b14ca..6e75e9f47 100644 --- a/pkg/tcpip/link/fdbased/BUILD +++ b/pkg/tcpip/link/fdbased/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "fdbased", diff --git a/pkg/tcpip/link/loopback/BUILD b/pkg/tcpip/link/loopback/BUILD index 9714e93db..cc4247ffd 100644 --- a/pkg/tcpip/link/loopback/BUILD +++ b/pkg/tcpip/link/loopback/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "loopback", diff --git a/pkg/tcpip/link/rawfile/BUILD b/pkg/tcpip/link/rawfile/BUILD index 4b30c7c1c..10b35a37e 100644 --- a/pkg/tcpip/link/rawfile/BUILD +++ b/pkg/tcpip/link/rawfile/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "rawfile", diff --git a/pkg/tcpip/link/sharedmem/BUILD b/pkg/tcpip/link/sharedmem/BUILD index 1bd79a3f4..5390257c5 100644 --- a/pkg/tcpip/link/sharedmem/BUILD +++ b/pkg/tcpip/link/sharedmem/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "sharedmem", diff --git a/pkg/tcpip/link/sharedmem/pipe/BUILD b/pkg/tcpip/link/sharedmem/pipe/BUILD index e6c658071..ff798ae6f 100644 --- a/pkg/tcpip/link/sharedmem/pipe/BUILD +++ b/pkg/tcpip/link/sharedmem/pipe/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "pipe", diff --git a/pkg/tcpip/link/sharedmem/queue/BUILD b/pkg/tcpip/link/sharedmem/queue/BUILD index 80cedade1..c4a7879c4 100644 --- a/pkg/tcpip/link/sharedmem/queue/BUILD +++ b/pkg/tcpip/link/sharedmem/queue/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "queue", diff --git a/pkg/tcpip/link/sniffer/BUILD b/pkg/tcpip/link/sniffer/BUILD index d14f150d1..1e844f949 100644 --- a/pkg/tcpip/link/sniffer/BUILD +++ b/pkg/tcpip/link/sniffer/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "sniffer", diff --git a/pkg/tcpip/link/tun/BUILD b/pkg/tcpip/link/tun/BUILD index 21da7d57e..a8bb03661 100644 --- a/pkg/tcpip/link/tun/BUILD +++ b/pkg/tcpip/link/tun/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "tun", diff --git a/pkg/tcpip/link/waitable/BUILD b/pkg/tcpip/link/waitable/BUILD index 3b513383a..7582df32e 100644 --- a/pkg/tcpip/link/waitable/BUILD +++ b/pkg/tcpip/link/waitable/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "waitable", diff --git a/pkg/tcpip/network/BUILD b/pkg/tcpip/network/BUILD index 963857f51..9a26b46c4 100644 --- a/pkg/tcpip/network/BUILD +++ b/pkg/tcpip/network/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_test") +load("//tools/go_stateify:defs.bzl", "go_test") go_test( name = "ip_test", diff --git a/pkg/tcpip/network/arp/BUILD b/pkg/tcpip/network/arp/BUILD index 689f66d6e..44f2b66e5 100644 --- a/pkg/tcpip/network/arp/BUILD +++ b/pkg/tcpip/network/arp/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "arp", diff --git a/pkg/tcpip/network/fragmentation/BUILD b/pkg/tcpip/network/fragmentation/BUILD index a173f87fb..ac97ebe43 100644 --- a/pkg/tcpip/network/fragmentation/BUILD +++ b/pkg/tcpip/network/fragmentation/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "fragmentation_state", diff --git a/pkg/tcpip/network/hash/BUILD b/pkg/tcpip/network/hash/BUILD index e1b5f26c4..1c22c52fc 100644 --- a/pkg/tcpip/network/hash/BUILD +++ b/pkg/tcpip/network/hash/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "hash", diff --git a/pkg/tcpip/network/ipv4/BUILD b/pkg/tcpip/network/ipv4/BUILD index ae42b662f..19314e9bd 100644 --- a/pkg/tcpip/network/ipv4/BUILD +++ b/pkg/tcpip/network/ipv4/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "ipv4", diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index d008ac7fb..1c3eccae0 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "ipv6", diff --git a/pkg/tcpip/ports/BUILD b/pkg/tcpip/ports/BUILD index 710c283f7..3c3374275 100644 --- a/pkg/tcpip/ports/BUILD +++ b/pkg/tcpip/ports/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ports", diff --git a/pkg/tcpip/seqnum/BUILD b/pkg/tcpip/seqnum/BUILD index 6d28dbc3f..a75869dac 100644 --- a/pkg/tcpip/seqnum/BUILD +++ b/pkg/tcpip/seqnum/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "seqnum_state", diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD index 6d201d0a2..5e7355135 100644 --- a/pkg/tcpip/stack/BUILD +++ b/pkg/tcpip/stack/BUILD @@ -1,17 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") - -go_stateify( - name = "stack_state", - srcs = [ - "registration.go", - "stack.go", - ], - out = "stack_state.go", - package = "stack", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "stack", @@ -22,7 +11,6 @@ go_library( "route.go", "stack.go", "stack_global_state.go", - "stack_state.go", "transport_demuxer.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/stack", @@ -32,7 +20,6 @@ go_library( deps = [ "//pkg/ilist", "//pkg/sleep", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index e9550a062..c66f925a8 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -31,6 +31,8 @@ type NetworkEndpointID struct { } // TransportEndpointID is the identifier of a transport layer protocol endpoint. +// +// +stateify savable type TransportEndpointID struct { // LocalPort is the local port associated with the endpoint. LocalPort uint16 diff --git a/pkg/tcpip/transport/ping/BUILD b/pkg/tcpip/transport/ping/BUILD index 1febbf7f5..28e3e1700 100644 --- a/pkg/tcpip/transport/ping/BUILD +++ b/pkg/tcpip/transport/ping/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "ping_state", diff --git a/pkg/tcpip/transport/queue/BUILD b/pkg/tcpip/transport/queue/BUILD index 7e8ee1f66..fb878ad36 100644 --- a/pkg/tcpip/transport/queue/BUILD +++ b/pkg/tcpip/transport/queue/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "queue_state", diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 53623787d..6a7153e4d 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tcp_state", diff --git a/pkg/tcpip/transport/tcp/testing/context/BUILD b/pkg/tcpip/transport/tcp/testing/context/BUILD index 3caa38bcb..7a95594ef 100644 --- a/pkg/tcpip/transport/tcp/testing/context/BUILD +++ b/pkg/tcpip/transport/tcp/testing/context/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "context", diff --git a/pkg/tcpip/transport/tcpconntrack/BUILD b/pkg/tcpip/transport/tcpconntrack/BUILD index 3d748528e..46da3e6f1 100644 --- a/pkg/tcpip/transport/tcpconntrack/BUILD +++ b/pkg/tcpip/transport/tcpconntrack/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tcpconntrack", diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 4f7a47973..790dd55a3 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "udp_state", diff --git a/pkg/tcpip/transport/unix/BUILD b/pkg/tcpip/transport/unix/BUILD index d58f06544..676f2cf92 100644 --- a/pkg/tcpip/transport/unix/BUILD +++ b/pkg/tcpip/transport/unix/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "unix_state", diff --git a/pkg/tmutex/BUILD b/pkg/tmutex/BUILD index d9a2c5ae5..d18338fff 100644 --- a/pkg/tmutex/BUILD +++ b/pkg/tmutex/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tmutex", diff --git a/pkg/unet/BUILD b/pkg/unet/BUILD index e8e40315a..acdfd7cb6 100644 --- a/pkg/unet/BUILD +++ b/pkg/unet/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "unet", diff --git a/pkg/urpc/BUILD b/pkg/urpc/BUILD index b29b25637..d32c57d1a 100644 --- a/pkg/urpc/BUILD +++ b/pkg/urpc/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "urpc", diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index 032ec3237..8256acdb4 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "waiter_state", diff --git a/pkg/waiter/fdnotifier/BUILD b/pkg/waiter/fdnotifier/BUILD index d5b5ee82d..4e582755d 100644 --- a/pkg/waiter/fdnotifier/BUILD +++ b/pkg/waiter/fdnotifier/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "fdnotifier", diff --git a/tools/go_stateify/defs.bzl b/tools/go_stateify/defs.bzl index 60a9895ff..2b2582b7a 100644 --- a/tools/go_stateify/defs.bzl +++ b/tools/go_stateify/defs.bzl @@ -22,6 +22,8 @@ go_library( ) """ +load("@io_bazel_rules_go//go:def.bzl", _go_library = "go_library", _go_test = "go_test") + def _go_stateify_impl(ctx): """Implementation for the stateify tool.""" output = ctx.outputs.out @@ -33,6 +35,8 @@ def _go_stateify_impl(ctx): args += ["-statepkg=%s" % ctx.attr._statepkg] if ctx.attr.imports: args += ["-imports=%s" % ",".join(ctx.attr.imports)] + if ctx.attr.explicit: + args += ["-explicit=true"] args += ["--"] for src in ctx.attr.srcs: args += [f.path for f in src.files] @@ -45,17 +49,15 @@ def _go_stateify_impl(ctx): executable = ctx.executable._tool, ) -""" -Generates save and restore logic from a set of Go files. - - -Args: - name: the name of the rule. - srcs: the input source files. These files should include all structs in the package that need to be saved. - imports: an optional list of extra non-aliased, Go-style absolute import paths. - out: the name of the generated file output. This must not conflict with any other files and must be added to the srcs of the relevant go_library. - package: the package name for the input sources. -""" +# Generates save and restore logic from a set of Go files. +# +# Args: +# name: the name of the rule. +# srcs: the input source files. These files should include all structs in the package that need to be saved. +# imports: an optional list of extra non-aliased, Go-style absolute import paths. +# out: the name of the generated file output. This must not conflict with any other files and must be added to the srcs of the relevant go_library. +# package: the package name for the input sources. +# explicit: only generate for types explicitly annotated as savable. go_stateify = rule( implementation = _go_stateify_impl, attrs = { @@ -63,7 +65,41 @@ go_stateify = rule( "imports": attr.string_list(mandatory = False), "package": attr.string(mandatory = True), "out": attr.output(mandatory = True), + "explicit": attr.bool(default = False), "_tool": attr.label(executable = True, cfg = "host", default = Label("//tools/go_stateify:stateify")), "_statepkg": attr.string(default = "gvisor.googlesource.com/gvisor/pkg/state"), }, ) + +def go_library(name, srcs, deps = [], imports = [], **kwargs): + """wraps the standard go_library and does stateification.""" + if "encode_unsafe.go" not in srcs and (name + "_state_autogen.go") not in srcs: + # Only do stateification for non-state packages without manual autogen. + go_stateify( + name = name + "_state_autogen", + srcs = [src for src in srcs if src.endswith(".go")], + imports = imports, + package = name, + out = name + "_state_autogen.go", + explicit = True, + ) + all_srcs = srcs + [name + "_state_autogen.go"] + if "//pkg/state" not in deps: + all_deps = deps + ["//pkg/state"] + else: + all_deps = deps + else: + all_deps = deps + all_srcs = srcs + _go_library( + name = name, + srcs = all_srcs, + deps = all_deps, + **kwargs + ) + +def go_test(**kwargs): + """Wraps the standard go_test.""" + _go_test( + **kwargs + ) diff --git a/tools/go_stateify/main.go b/tools/go_stateify/main.go index 6c3583c62..231c6d80b 100644 --- a/tools/go_stateify/main.go +++ b/tools/go_stateify/main.go @@ -25,6 +25,7 @@ import ( "os" "reflect" "strings" + "sync" ) var ( @@ -32,6 +33,7 @@ var ( imports = flag.String("imports", "", "extra imports for the output file") output = flag.String("output", "", "output file") statePkg = flag.String("statepkg", "", "state import package; defaults to empty") + explicit = flag.Bool("explicit", false, "only generate for types explicitly tagged '// +stateify savable'") ) // resolveTypeName returns a qualified type name. @@ -224,16 +226,24 @@ func main() { // Emit the package name. fmt.Fprint(outputFile, "// automatically generated by stateify.\n\n") fmt.Fprintf(outputFile, "package %s\n\n", *pkg) - fmt.Fprint(outputFile, "import (\n") - if *statePkg != "" { - fmt.Fprintf(outputFile, " \"%s\"\n", *statePkg) - } - if *imports != "" { - for _, i := range strings.Split(*imports, ",") { - fmt.Fprintf(outputFile, " \"%s\"\n", i) - } + + // Emit the imports lazily. + var once sync.Once + maybeEmitImports := func() { + once.Do(func() { + // Emit the imports. + fmt.Fprint(outputFile, "import (\n") + if *statePkg != "" { + fmt.Fprintf(outputFile, " \"%s\"\n", *statePkg) + } + if *imports != "" { + for _, i := range strings.Split(*imports, ",") { + fmt.Fprintf(outputFile, " \"%s\"\n", i) + } + } + fmt.Fprint(outputFile, ")\n\n") + }) } - fmt.Fprint(outputFile, ")\n\n") files := make([]*ast.File, 0, len(flag.Args())) @@ -241,7 +251,7 @@ func main() { for _, filename := range flag.Args() { // Parse the file. fset := token.NewFileSet() - f, err := parser.ParseFile(fset, filename, nil, 0) + f, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) if err != nil { // Not a valid input file? fmt.Fprintf(os.Stderr, "Input %q can't be parsed: %v\n", filename, err) @@ -308,6 +318,26 @@ func main() { continue } + if *explicit { + // In explicit mode, only generate code for + // types explicitly marked + // "// +stateify savable" in one of the + // proceeding comment lines. + if d.Doc == nil { + continue + } + savable := false + for _, l := range d.Doc.List { + if l.Text == "// +stateify savable" { + savable = true + break + } + } + if !savable { + continue + } + } + for _, gs := range d.Specs { ts := gs.(*ast.TypeSpec) switch ts.Type.(type) { @@ -315,6 +345,8 @@ func main() { // Don't register. break case *ast.StructType: + maybeEmitImports() + ss := ts.Type.(*ast.StructType) // Define beforeSave if a definition was not found. This @@ -360,6 +392,8 @@ func main() { // Add to our registration. emitRegister(ts.Name.Name) case *ast.Ident, *ast.SelectorExpr, *ast.ArrayType: + maybeEmitImports() + _, val := resolveTypeName(ts.Name.Name, ts.Type) // Dispatch directly. @@ -377,10 +411,12 @@ func main() { } } - // Emit the init() function. - fmt.Fprintf(outputFile, "func init() {\n") - for _, ic := range initCalls { - fmt.Fprintf(outputFile, " %s\n", ic) + if len(initCalls) > 0 { + // Emit the init() function. + fmt.Fprintf(outputFile, "func init() {\n") + for _, ic := range initCalls { + fmt.Fprintf(outputFile, " %s\n", ic) + } + fmt.Fprintf(outputFile, "}\n") } - fmt.Fprintf(outputFile, "}\n") } -- cgit v1.2.3 From 0a55f8c1c11dc6d2dfb1bed02489f92bab437ea1 Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Mon, 30 Jul 2018 15:42:01 -0700 Subject: netstack: support disconnect-on-save option per fdbased link. PiperOrigin-RevId: 206659972 Change-Id: I5e0e035f97743b6525ad36bed2c802791609beaf --- pkg/tcpip/link/fdbased/endpoint.go | 10 ++++++++++ pkg/tcpip/stack/registration.go | 1 + pkg/tcpip/transport/tcp/connect.go | 4 +++- pkg/tcpip/transport/tcp/endpoint_state.go | 11 +++++++++-- 4 files changed, 23 insertions(+), 3 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 8fc009160..4e20cfbf8 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -69,6 +69,8 @@ type Options struct { ChecksumOffload bool ClosedFunc func(*tcpip.Error) Address tcpip.LinkAddress + SaveRestore bool + DisconnectOk bool } // New creates a new fd-based endpoint. @@ -89,6 +91,14 @@ func New(opts *Options) tcpip.LinkEndpointID { caps |= stack.CapabilityResolutionRequired } + if opts.SaveRestore { + caps |= stack.CapabilitySaveRestore + } + + if opts.DisconnectOk { + caps |= stack.CapabilityDisconnectOk + } + e := &endpoint{ fd: opts.FD, mtu: opts.MTU, diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index c66f925a8..01a29689d 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -204,6 +204,7 @@ const ( CapabilityChecksumOffload LinkEndpointCapabilities = 1 << iota CapabilityResolutionRequired CapabilitySaveRestore + CapabilityDisconnectOk ) // LinkEndpoint is the interface implemented by data link layer protocols (e.g., diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 8d70eb45a..b90d3fe48 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -1023,7 +1023,9 @@ func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error { // Mark endpoint as closed. e.mu.Lock() - e.state = stateClosed + if e.state != stateError { + e.state = stateClosed + } // Lock released below. epilogue() diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index 9c2e8878f..6143390b3 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -52,10 +52,17 @@ func (e *endpoint) beforeSave() { case stateInitial, stateBound: case stateConnected: if e.route.Capabilities()&stack.CapabilitySaveRestore == 0 { - panic(tcpip.ErrSaveRejection{fmt.Errorf("endpoint cannot be saved in connected state: local %v:%d, remote %v:%d", e.id.LocalAddress, e.id.LocalPort, e.id.RemoteAddress, e.id.RemotePort)}) + if e.route.Capabilities()&stack.CapabilityDisconnectOk == 0 { + panic(tcpip.ErrSaveRejection{fmt.Errorf("endpoint cannot be saved in connected state: local %v:%d, remote %v:%d", e.id.LocalAddress, e.id.LocalPort, e.id.RemoteAddress, e.id.RemotePort)}) + } + e.resetConnectionLocked(tcpip.ErrConnectionAborted) + e.mu.Unlock() + e.Close() + e.mu.Lock() } if !e.workerRunning { - // The endpoint must be in acceptedChan. + // The endpoint must be in acceptedChan or has been just + // disconnected and closed. break } fallthrough -- cgit v1.2.3 From 3cd7824410302da00d1c8c8323db8959a124814a Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Wed, 1 Aug 2018 20:21:00 -0700 Subject: Move stack clock to options struct PiperOrigin-RevId: 207039273 Change-Id: Ib8f55a6dc302052ab4a10ccd70b07f0d73b373df --- pkg/dhcp/dhcp_test.go | 2 +- pkg/tcpip/adapters/gonet/gonet_test.go | 2 +- pkg/tcpip/network/arp/arp_test.go | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 2 +- pkg/tcpip/stack/stack.go | 15 ++++++++++++++- pkg/tcpip/stack/stack_test.go | 22 +++++++++++----------- pkg/tcpip/stack/transport_test.go | 8 ++++---- pkg/tcpip/transport/tcp/tcp_test.go | 6 +++--- pkg/tcpip/transport/tcp/testing/context/context.go | 2 +- pkg/tcpip/transport/udp/udp_test.go | 2 +- runsc/boot/loader.go | 2 +- 12 files changed, 40 insertions(+), 27 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index 565b64045..731ed61a5 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -46,7 +46,7 @@ func TestDHCP(t *testing.T) { } }() - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{udp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName}, []string{udp.ProtocolName}, stack.Options{}) const nicid tcpip.NICID = 1 if err := s.CreateNIC(nicid, id); err != nil { diff --git a/pkg/tcpip/adapters/gonet/gonet_test.go b/pkg/tcpip/adapters/gonet/gonet_test.go index 4c0855854..86a82f21d 100644 --- a/pkg/tcpip/adapters/gonet/gonet_test.go +++ b/pkg/tcpip/adapters/gonet/gonet_test.go @@ -57,7 +57,7 @@ func TestTimeouts(t *testing.T) { func newLoopbackStack() (*stack.Stack, *tcpip.Error) { // Create the stack and add a NIC. - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName, udp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName, udp.ProtocolName}, stack.Options{}) if err := s.CreateNIC(NICID, loopback.New()); err != nil { return nil, err diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index c35299f3f..8fc79dc94 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -43,7 +43,7 @@ type testContext struct { } func newTestContext(t *testing.T) *testContext { - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, arp.ProtocolName}, []string{ping.ProtocolName4}) + s := stack.New([]string{ipv4.ProtocolName, arp.ProtocolName}, []string{ping.ProtocolName4}, stack.Options{}) const defaultMTU = 65536 id, linkEP := channel.New(256, defaultMTU, stackLinkAddr) diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index 1915f7ef9..3030e84a7 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -123,7 +123,7 @@ func main() { // Create the stack with ipv4 and tcp protocols, then add a tun-based // NIC and ipv4 address. - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName}, []string{tcp.ProtocolName}, stack.Options{}) mtu, err := rawfile.GetMTU(tunName) if err != nil { diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index e01adf635..9cced35eb 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -109,7 +109,7 @@ func main() { // Create the stack with ip and tcp protocols, then add a tun-based // NIC and address. - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName}, []string{tcp.ProtocolName}, stack.Options{}) mtu, err := rawfile.GetMTU(tunName) if err != nil { diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index b9d0a1762..9cdc7b6d8 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -285,6 +285,14 @@ type Stack struct { clock tcpip.Clock } +// Options contains optional Stack configuration. +type Options struct { + // Clock is an optional clock source used for timestampping packets. + // + // If no Clock is specified, the clock source will be time.Now. + Clock tcpip.Clock +} + // New allocates a new networking stack with only the requested networking and // transport protocols configured with default options. // @@ -292,7 +300,12 @@ type Stack struct { // SetNetworkProtocolOption/SetTransportProtocolOption methods provided by the // stack. Please refer to individual protocol implementations as to what options // are supported. -func New(clock tcpip.Clock, network []string, transport []string) *Stack { +func New(network []string, transport []string, opts Options) *Stack { + clock := opts.Clock + if clock == nil { + clock = &tcpip.StdClock{} + } + s := &Stack{ transportProtocols: make(map[tcpip.TransportProtocolNumber]*transportProtocolState), networkProtocols: make(map[tcpip.NetworkProtocolNumber]NetworkProtocol), diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 04806865d..57de5b93a 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -186,7 +186,7 @@ func TestNetworkReceive(t *testing.T) { // Create a stack with the fake network protocol, one nic, and two // addresses attached to it: 1 & 2. id, linkEP := channel.New(10, defaultMTU, "") - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("CreateNIC failed: %v", err) } @@ -280,7 +280,7 @@ func TestNetworkSend(t *testing.T) { // address: 1. The route table sends all packets through the only // existing nic. id, linkEP := channel.New(10, defaultMTU, "") - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("NewNIC failed: %v", err) } @@ -302,7 +302,7 @@ func TestNetworkSendMultiRoute(t *testing.T) { // Create a stack with the fake network protocol, two nics, and two // addresses per nic, the first nic has odd address, the second one has // even addresses. - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id1, linkEP1 := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id1); err != nil { @@ -381,7 +381,7 @@ func TestRoutes(t *testing.T) { // Create a stack with the fake network protocol, two nics, and two // addresses per nic, the first nic has odd address, the second one has // even addresses. - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id1, _ := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id1); err != nil { @@ -445,7 +445,7 @@ func TestRoutes(t *testing.T) { } func TestAddressRemoval(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -489,7 +489,7 @@ func TestAddressRemoval(t *testing.T) { } func TestDelayedRemovalDueToRoute(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -557,7 +557,7 @@ func TestDelayedRemovalDueToRoute(t *testing.T) { } func TestPromiscuousMode(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -617,7 +617,7 @@ func TestAddressSpoofing(t *testing.T) { srcAddr := tcpip.Address("\x01") dstAddr := tcpip.Address("\x02") - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id, _ := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -658,7 +658,7 @@ func TestAddressSpoofing(t *testing.T) { // Set the subnet, then check that packet is delivered. func TestSubnetAcceptsMatchingPacket(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -692,7 +692,7 @@ func TestSubnetAcceptsMatchingPacket(t *testing.T) { // Set destination outside the subnet, then check it doesn't get delivered. func TestSubnetRejectsNonmatchingPacket(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, nil) + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id, linkEP := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { @@ -724,7 +724,7 @@ func TestSubnetRejectsNonmatchingPacket(t *testing.T) { } func TestNetworkOptions(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{}) + s := stack.New([]string{"fakeNet"}, []string{}, stack.Options{}) // Try an unsupported network protocol. if err := s.SetNetworkProtocolOption(tcpip.NetworkProtocolNumber(99999), fakeNetGoodOption(false)); err != tcpip.ErrUnknownProtocol { diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index bd0802ccb..98d2f9d99 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -220,7 +220,7 @@ func (f *fakeTransportProtocol) Option(option interface{}) *tcpip.Error { func TestTransportReceive(t *testing.T) { id, linkEP := channel.New(10, defaultMTU, "") - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{"fakeTrans"}) + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}, stack.Options{}) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("CreateNIC failed: %v", err) } @@ -280,7 +280,7 @@ func TestTransportReceive(t *testing.T) { func TestTransportControlReceive(t *testing.T) { id, linkEP := channel.New(10, defaultMTU, "") - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{"fakeTrans"}) + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}, stack.Options{}) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("CreateNIC failed: %v", err) } @@ -346,7 +346,7 @@ func TestTransportControlReceive(t *testing.T) { func TestTransportSend(t *testing.T) { id, _ := channel.New(10, defaultMTU, "") - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{"fakeTrans"}) + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}, stack.Options{}) if err := s.CreateNIC(1, id); err != nil { t.Fatalf("CreateNIC failed: %v", err) } @@ -383,7 +383,7 @@ func TestTransportSend(t *testing.T) { } func TestTransportOptions(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{"fakeNet"}, []string{"fakeTrans"}) + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}, stack.Options{}) // Try an unsupported transport protocol. if err := s.SetTransportProtocolOption(tcpip.TransportProtocolNumber(99999), fakeTransportGoodOption(false)); err != tcpip.ErrUnknownProtocol { diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index 1b8463541..45ebca5b1 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -2579,7 +2579,7 @@ func checkSendBufferSize(t *testing.T, ep tcpip.Endpoint, v int) { } func TestDefaultBufferSizes(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName}, []string{tcp.ProtocolName}, stack.Options{}) // Check the default values. ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{}) @@ -2625,7 +2625,7 @@ func TestDefaultBufferSizes(t *testing.T) { } func TestMinMaxBufferSizes(t *testing.T) { - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName}, []string{tcp.ProtocolName}, stack.Options{}) // Check the default values. ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{}) @@ -2675,7 +2675,7 @@ func TestSelfConnect(t *testing.T) { // it checks that if an endpoint binds to say 127.0.0.1:1000 then // connects to 127.0.0.1:1000, then it will be connected to itself, and // is able to send and receive data through the same endpoint. - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName}, []string{tcp.ProtocolName}, stack.Options{}) id := loopback.New() if testing.Verbose() { diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 9deae09e3..e44979527 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -139,7 +139,7 @@ type Context struct { // New allocates and initializes a test context containing a new // stack and a link-layer endpoint. func New(t *testing.T, mtu uint32) *Context { - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName}, stack.Options{}) // Allow minimum send/receive buffer sizes to be 1 during tests. if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SendBufferSizeOption{1, tcp.DefaultBufferSize, tcp.DefaultBufferSize * 10}); err != nil { diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 3d5956145..7203d7705 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -66,7 +66,7 @@ type headers struct { } func newDualTestContext(t *testing.T, mtu uint32) *testContext { - s := stack.New(&tcpip.StdClock{}, []string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{udp.ProtocolName}) + s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{udp.ProtocolName}, stack.Options{}) id, linkEP := channel.New(256, mtu, "") if testing.Verbose() { diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 66394cdf8..2f976cd52 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -534,7 +534,7 @@ func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) inet.Stack { // NetworkNone sets up loopback using netstack. netProtos := []string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName} protoNames := []string{tcp.ProtocolName, udp.ProtocolName, ping.ProtocolName4} - return &epsocket.Stack{stack.New(clock, netProtos, protoNames)} + return &epsocket.Stack{stack.New(netProtos, protoNames, stack.Options{Clock: clock})} default: panic(fmt.Sprintf("invalid network configuration: %v", conf.Network)) -- cgit v1.2.3 From 7d3684aadf71255d3d8442ae1ed0b0f0048f95a3 Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Tue, 7 Aug 2018 11:48:37 -0700 Subject: Adds support to dump out cubic internal state. PiperOrigin-RevId: 207754087 Change-Id: I83abce64348ea93f8692da81a881b364dae2158b --- pkg/tcpip/stack/stack.go | 17 +++++++++++++++++ pkg/tcpip/transport/tcp/endpoint.go | 14 ++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 9cdc7b6d8..fa7aeb051 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -56,6 +56,20 @@ type transportProtocolState struct { // passed to stack.AddTCPProbe. type TCPProbeFunc func(s TCPEndpointState) +// TCPCubicState is used to hold a copy of the internal cubic state when the +// TCPProbeFunc is invoked. +type TCPCubicState struct { + WLastMax float64 + WMax float64 + T time.Time + TimeSinceLastCongestion time.Duration + C float64 + K float64 + Beta float64 + WC float64 + WEst float64 +} + // TCPEndpointID is the unique 4 tuple that identifies a given endpoint. type TCPEndpointID struct { // LocalPort is the local port associated with the endpoint. @@ -180,6 +194,9 @@ type TCPSenderState struct { // FastRecovery holds the fast recovery state for the endpoint. FastRecovery TCPFastRecoveryState + + // Cubic holds the state related to CUBIC congestion control. + Cubic TCPCubicState } // TCPSACKInfo holds TCP SACK related information for a given TCP endpoint. diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index e1b71e423..3fcbf6502 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1452,5 +1452,19 @@ func (e *endpoint) completeState() stack.TCPEndpointState { SndWndScale: e.snd.sndWndScale, MaxSentAck: e.snd.maxSentAck, } + + if cubic, ok := e.snd.cc.(*cubicState); ok { + s.Sender.Cubic = stack.TCPCubicState{ + WMax: cubic.wMax, + WLastMax: cubic.wLastMax, + T: cubic.t, + TimeSinceLastCongestion: time.Since(cubic.t), + C: cubic.c, + K: cubic.k, + Beta: cubic.beta, + WC: cubic.wC, + WEst: cubic.wEst, + } + } return s } -- cgit v1.2.3 From ea1e39a314d3a248d8b682a9f63e686530597d61 Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Wed, 8 Aug 2018 22:02:09 -0700 Subject: Resend packets back to netstack if destined to itself Add option to redirect packet back to netstack if it's destined to itself. This fixes the problem where connecting to the local NIC address would not work, e.g.: echo bar | nc -l -p 8080 & echo foo | nc 192.168.0.2 8080 PiperOrigin-RevId: 207995083 Change-Id: I17adc2a04df48bfea711011a5df206326a1fb8ef --- pkg/tcpip/link/fdbased/endpoint.go | 52 ++++++++++++++--------- pkg/tcpip/stack/nic.go | 3 +- pkg/tcpip/stack/route.go | 16 +++++--- pkg/tcpip/stack/stack.go | 2 +- runsc/boot/network.go | 10 ++--- runsc/test/integration/integration_test.go | 66 ++++++++++++++++++++++-------- runsc/test/testutil/docker.go | 7 ++++ 7 files changed, 107 insertions(+), 49 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 4e20cfbf8..152d8f0b2 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -55,10 +55,15 @@ type endpoint struct { // its end of the communication pipe. closed func(*tcpip.Error) - vv *buffer.VectorisedView - iovecs []syscall.Iovec - views []buffer.View - attached bool + vv *buffer.VectorisedView + iovecs []syscall.Iovec + views []buffer.View + dispatcher stack.NetworkDispatcher + + // handleLocal indicates whether packets destined to itself should be + // handled by the netstack internally (true) or be forwarded to the FD + // endpoint (false). + handleLocal bool } // Options specify the details about the fd-based endpoint to be created. @@ -71,6 +76,7 @@ type Options struct { Address tcpip.LinkAddress SaveRestore bool DisconnectOk bool + HandleLocal bool } // New creates a new fd-based endpoint. @@ -100,14 +106,15 @@ func New(opts *Options) tcpip.LinkEndpointID { } e := &endpoint{ - fd: opts.FD, - mtu: opts.MTU, - caps: caps, - closed: opts.ClosedFunc, - addr: opts.Address, - hdrSize: hdrSize, - views: make([]buffer.View, len(BufConfig)), - iovecs: make([]syscall.Iovec, len(BufConfig)), + fd: opts.FD, + mtu: opts.MTU, + caps: caps, + closed: opts.ClosedFunc, + addr: opts.Address, + hdrSize: hdrSize, + views: make([]buffer.View, len(BufConfig)), + iovecs: make([]syscall.Iovec, len(BufConfig)), + handleLocal: opts.HandleLocal, } vv := buffer.NewVectorisedView(0, e.views) e.vv = &vv @@ -117,16 +124,16 @@ func New(opts *Options) tcpip.LinkEndpointID { // Attach launches the goroutine that reads packets from the file descriptor and // dispatches them via the provided dispatcher. func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { - e.attached = true + e.dispatcher = dispatcher // Link endpoints are not savable. When transportation endpoints are // saved, they stop sending outgoing packets and all incoming packets // are rejected. - go e.dispatchLoop(dispatcher) // S/R-SAFE: See above. + go e.dispatchLoop() // S/R-SAFE: See above. } // IsAttached implements stack.LinkEndpoint.IsAttached. func (e *endpoint) IsAttached() bool { - return e.attached + return e.dispatcher != nil } // MTU implements stack.LinkEndpoint.MTU. It returns the value initialized @@ -153,6 +160,12 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { + if e.handleLocal && r.LocalAddress != "" && r.LocalAddress == r.RemoteAddress { + hdrView := hdr.View() + vv := buffer.NewVectorisedView(len(hdrView)+len(payload), []buffer.View{hdrView, payload}) + e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, &vv) + return nil + } if e.hdrSize > 0 { // Add ethernet header if needed. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) @@ -165,7 +178,6 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload if len(payload) == 0 { return rawfile.NonBlockingWrite(e.fd, hdr.UsedBytes()) - } return rawfile.NonBlockingWrite2(e.fd, hdr.UsedBytes(), payload) @@ -198,7 +210,7 @@ func (e *endpoint) allocateViews(bufConfig []int) { } // dispatch reads one packet from the file descriptor and dispatches it. -func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool, *tcpip.Error) { +func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { e.allocateViews(BufConfig) n, err := rawfile.BlockingReadv(e.fd, e.iovecs) @@ -234,7 +246,7 @@ func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool e.vv.SetSize(n) e.vv.TrimFront(e.hdrSize) - d.DeliverNetworkPacket(e, addr, p, e.vv) + e.dispatcher.DeliverNetworkPacket(e, addr, p, e.vv) // Prepare e.views for another packet: release used views. for i := 0; i < used; i++ { @@ -246,10 +258,10 @@ func (e *endpoint) dispatch(d stack.NetworkDispatcher, largeV buffer.View) (bool // dispatchLoop reads packets from the file descriptor in a loop and dispatches // them to the network stack. -func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) *tcpip.Error { +func (e *endpoint) dispatchLoop() *tcpip.Error { v := buffer.NewView(header.MaxIPPacketSize) for { - cont, err := e.dispatch(d, v) + cont, err := e.dispatch(v) if err != nil || !cont { if e.closed != nil { e.closed(err) diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 25c06cba5..c1480f97b 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -327,8 +327,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin return } - r := makeRoute(protocol, dst, src, ref) - r.LocalLinkAddress = linkEP.LinkAddress() + r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) r.RemoteLinkAddress = remoteLinkAddr ref.ep.HandlePacket(&r, vv) ref.decRef() diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 200c39289..423f428df 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -50,12 +50,13 @@ type Route struct { // makeRoute initializes a new route. It takes ownership of the provided // reference to a network endpoint. -func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, ref *referencedNetworkEndpoint) Route { +func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, localLinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint) Route { return Route{ - NetProto: netProto, - LocalAddress: localAddr, - RemoteAddress: remoteAddr, - ref: ref, + NetProto: netProto, + LocalAddress: localAddr, + LocalLinkAddress: localLinkAddr, + RemoteAddress: remoteAddr, + ref: ref, } } @@ -92,6 +93,11 @@ func (r *Route) Resolve(waker *sleep.Waker) *tcpip.Error { nextAddr := r.NextHop if nextAddr == "" { + // Local link address is already known. + if r.RemoteAddress == r.LocalAddress { + r.RemoteLinkAddress = r.LocalLinkAddress + return nil + } nextAddr = r.RemoteAddress } linkAddr, err := r.ref.linkCache.GetLinkAddress(r.ref.nic.ID(), nextAddr, r.LocalAddress, r.NetProto, waker) diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index fa7aeb051..6c4aa7cc5 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -687,7 +687,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n remoteAddr = ref.ep.ID().LocalAddress } - r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, ref) + r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref) r.NextHop = s.routeTable[i].Gateway return r, nil } diff --git a/runsc/boot/network.go b/runsc/boot/network.go index d2b52c823..d702ae74e 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -134,11 +134,11 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct } linkEP := fdbased.New(&fdbased.Options{ - FD: newFD, - MTU: uint32(link.MTU), - ChecksumOffload: false, - EthernetHeader: true, - Address: tcpip.LinkAddress(generateRndMac()), + FD: newFD, + MTU: uint32(link.MTU), + EthernetHeader: true, + HandleLocal: true, + Address: tcpip.LinkAddress(generateRndMac()), }) log.Infof("Enabling interface %q with id %d on addresses %+v", link.Name, nicID, link.Addresses) diff --git a/runsc/test/integration/integration_test.go b/runsc/test/integration/integration_test.go index 67b58523d..c286e48d2 100644 --- a/runsc/test/integration/integration_test.go +++ b/runsc/test/integration/integration_test.go @@ -31,6 +31,7 @@ import ( "net" "net/http" "os" + "strings" "testing" "time" @@ -54,36 +55,36 @@ func httpRequestSucceeds(client http.Client, server string, port int) error { // TestLifeCycle tests a basic Create/Start/Stop docker container life cycle. func TestLifeCycle(t *testing.T) { if err := testutil.Pull("nginx"); err != nil { - t.Fatalf("docker pull failed: %v", err) + t.Fatal("docker pull failed:", err) } d := testutil.MakeDocker("lifecycle-test") if err := d.Create("-p", "80", "nginx"); err != nil { - t.Fatalf("docker create failed: %v", err) + t.Fatal("docker create failed:", err) } if err := d.Start(); err != nil { d.CleanUp() - t.Fatalf("docker start failed: %v", err) + t.Fatal("docker start failed:", err) } // Test that container is working port, err := d.FindPort(80) if err != nil { - t.Fatalf("docker.FindPort(80) failed: %v", err) + t.Fatal("docker.FindPort(80) failed: ", err) } if err := testutil.WaitForHTTP(port, 5*time.Second); err != nil { - t.Fatalf("WaitForHTTP() timeout: %v", err) + t.Fatal("WaitForHTTP() timeout:", err) } client := http.Client{Timeout: time.Duration(2 * time.Second)} if err := httpRequestSucceeds(client, "localhost", port); err != nil { - t.Errorf("http request failed: %v", err) + t.Error("http request failed:", err) } if err := d.Stop(); err != nil { d.CleanUp() - t.Fatalf("docker stop failed: %v", err) + t.Fatal("docker stop failed:", err) } if err := d.Remove(); err != nil { - t.Fatalf("docker rm failed: %v", err) + t.Fatal("docker rm failed:", err) } } @@ -94,7 +95,7 @@ func TestPauseResume(t *testing.T) { } if err := testutil.Pull("google/python-hello"); err != nil { - t.Fatalf("docker pull failed: %v", err) + t.Fatal("docker pull failed:", err) } d := testutil.MakeDocker("pause-resume-test") if out, err := d.Run("-p", "8080", "google/python-hello"); err != nil { @@ -105,22 +106,22 @@ func TestPauseResume(t *testing.T) { // Find where port 8080 is mapped to. port, err := d.FindPort(8080) if err != nil { - t.Fatalf("docker.FindPort(8080) failed: %v", err) + t.Fatal("docker.FindPort(8080) failed:", err) } // Wait until it's up and running. if err := testutil.WaitForHTTP(port, 20*time.Second); err != nil { - t.Fatalf("WaitForHTTP() timeout: %v", err) + t.Fatal("WaitForHTTP() timeout:", err) } // Check that container is working. client := http.Client{Timeout: time.Duration(2 * time.Second)} if err := httpRequestSucceeds(client, "localhost", port); err != nil { - t.Errorf("http request failed: %v", err) + t.Error("http request failed:", err) } if err := d.Pause(); err != nil { - t.Fatalf("docker pause failed: %v", err) + t.Fatal("docker pause failed:", err) } // Check if container is paused. @@ -136,17 +137,50 @@ func TestPauseResume(t *testing.T) { } if err := d.Unpause(); err != nil { - t.Fatalf("docker unpause failed: %v", err) + t.Fatal("docker unpause failed:", err) } // Wait until it's up and running. if err := testutil.WaitForHTTP(port, 20*time.Second); err != nil { - t.Fatalf("WaitForHTTP() timeout: %v", err) + t.Fatal("WaitForHTTP() timeout:", err) } // Check if container is working again. if err := httpRequestSucceeds(client, "localhost", port); err != nil { - t.Errorf("http request failed: %v", err) + t.Error("http request failed:", err) + } +} + +// Create client and server that talk to each other using the local IP. +func TestConnectToSelf(t *testing.T) { + d := testutil.MakeDocker("connect-to-self-test") + + // Creates server that replies "server" and exists. Sleeps at the end because + // 'docker exec' gets killed if the init process exists before it can finish. + if _, err := d.Run("ubuntu:trusty", "/bin/sh", "-c", "echo server | nc -l -p 8080 && sleep 1"); err != nil { + t.Fatal("docker run failed:", err) + } + defer d.CleanUp() + + // Finds IP address for eth0. + ip, err := d.Exec("/bin/sh", "-c", "ifconfig eth0 | grep -E -o \".*inet [^ ]+\" | cut -d: -f2") + if err != nil { + t.Fatal("docker exec failed:", err) + } + ip = strings.TrimRight(ip, "\n") + + // Runs client that sends "client" to the server and exits. + reply, err := d.Exec("/bin/sh", "-c", fmt.Sprintf("echo client | nc %s 8080", ip)) + if err != nil { + t.Fatal("docker exec failed:", err) + } + + // Ensure both client and server got the message from each other. + if want := "server\n"; reply != want { + t.Errorf("Error on server, want: %q, got: %q", want, reply) + } + if err := d.WaitForOutput("^client\n$", 1*time.Second); err != nil { + t.Fatal("docker.WaitForOutput(client) timeout:", err) } } diff --git a/runsc/test/testutil/docker.go b/runsc/test/testutil/docker.go index 6825ed9ec..b7d60e712 100644 --- a/runsc/test/testutil/docker.go +++ b/runsc/test/testutil/docker.go @@ -162,6 +162,13 @@ func (d *Docker) Run(args ...string) (string, error) { return do(a...) } +// Exec calls 'docker exec' with the arguments provided. +func (d *Docker) Exec(args ...string) (string, error) { + a := []string{"exec", d.Name} + a = append(a, args...) + return do(a...) +} + // Pause calls 'docker pause'. func (d *Docker) Pause() error { if _, err := do("pause", d.Name); err != nil { -- cgit v1.2.3 From 4e171f7590284c1f4cedf90c92204873961b2e97 Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Wed, 8 Aug 2018 22:38:41 -0700 Subject: Basic support for ip link/addr and ifconfig Closes #94 PiperOrigin-RevId: 207997580 Change-Id: I19b426f1586b5ec12f8b0cd5884d5b401d334924 --- pkg/abi/linux/netlink_route.go | 5 +++ pkg/sentry/inet/inet.go | 3 ++ pkg/sentry/socket/epsocket/epsocket.go | 52 ++++++++++------------- pkg/sentry/socket/epsocket/stack.go | 12 ++++-- pkg/sentry/socket/netlink/route/protocol.go | 15 ++++++- pkg/sentry/socket/netlink/socket.go | 64 ++++++++++++++++++++++++++--- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/stack/nic.go | 7 ++++ pkg/tcpip/stack/registration.go | 1 + pkg/tcpip/stack/stack.go | 36 ++++++++-------- runsc/boot/network.go | 5 ++- 11 files changed, 138 insertions(+), 64 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/abi/linux/netlink_route.go b/pkg/abi/linux/netlink_route.go index 0d88bc5c5..a5d778748 100644 --- a/pkg/abi/linux/netlink_route.go +++ b/pkg/abi/linux/netlink_route.go @@ -184,3 +184,8 @@ const ( IFA_MULTICAST = 7 IFA_FLAGS = 8 ) + +// Device types, from uapi/linux/if_arp.h. +const ( + ARPHRD_LOOPBACK = 772 +) diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index e54a61196..30ca4e0c0 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -67,6 +67,9 @@ type Interface struct { // Addr is the hardware device address. Addr []byte + + // MTU is the maximum transmission unit. + MTU uint32 } // InterfaceAddr contains information about a network interface address. diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index f969a1d7c..b32eda96f 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -48,7 +48,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" - nstack "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix" "gvisor.googlesource.com/gvisor/pkg/waiter" ) @@ -452,7 +452,7 @@ func (s *SocketOperations) GetSockOpt(t *kernel.Task, level, name, outLen int) ( // sockets backed by a commonEndpoint. func GetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, skType unix.SockType, level, name, outLen int) (interface{}, *syserr.Error) { switch level { - case syscall.SOL_SOCKET: + case linux.SOL_SOCKET: switch name { case linux.SO_TYPE: if outLen < sizeOfInt32 { @@ -634,7 +634,7 @@ func (s *SocketOperations) SetSockOpt(t *kernel.Task, level int, name int, optVa // sockets backed by a commonEndpoint. func SetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, level int, name int, optVal []byte) *syserr.Error { switch level { - case syscall.SOL_SOCKET: + case linux.SOL_SOCKET: switch name { case linux.SO_SNDBUF: if len(optVal) < sizeOfInt32 { @@ -1191,7 +1191,9 @@ func interfaceIoctl(ctx context.Context, io usermem.IO, arg int, ifr *linux.IFRe if err != nil { return err } - usermem.ByteOrder.PutUint16(ifr.Data[:2], f) + // Drop the flags that don't fit in the size that we need to return. This + // matches Linux behavior. + usermem.ByteOrder.PutUint16(ifr.Data[:2], uint16(f)) case syscall.SIOCGIFADDR: // Copy the IPv4 address out. @@ -1304,7 +1306,7 @@ func ifconfIoctl(ctx context.Context, io usermem.IO, ifc *linux.IFConf) error { // interfaceStatusFlags returns status flags for an interface in the stack. // Flag values and meanings are described in greater detail in netdevice(7) in // the SIOCGIFFLAGS section. -func interfaceStatusFlags(stack inet.Stack, name string) (uint16, *syserr.Error) { +func interfaceStatusFlags(stack inet.Stack, name string) (uint32, *syserr.Error) { // epsocket should only ever be passed an epsocket.Stack. epstack, ok := stack.(*Stack) if !ok { @@ -1312,37 +1314,27 @@ func interfaceStatusFlags(stack inet.Stack, name string) (uint16, *syserr.Error) } // Find the NIC corresponding to this interface. - var ( - nicid tcpip.NICID - info nstack.NICInfo - found bool - ) - ns := epstack.Stack - for nicid, info = range ns.NICInfo() { + for _, info := range epstack.Stack.NICInfo() { if info.Name == name { - found = true - break + return nicStateFlagsToLinux(info.Flags), nil } } - if !found { - return 0, syserr.ErrNoDevice - } + return 0, syserr.ErrNoDevice +} - // Set flags based on NIC state. - nicFlags, err := ns.NICFlags(nicid) - if err != nil { - return 0, syserr.TranslateNetstackError(err) +func nicStateFlagsToLinux(f stack.NICStateFlags) uint32 { + var rv uint32 + if f.Up { + rv |= linux.IFF_UP | linux.IFF_LOWER_UP } - - var retFlags uint16 - if nicFlags.Up { - retFlags |= linux.IFF_UP + if f.Running { + rv |= linux.IFF_RUNNING } - if nicFlags.Running { - retFlags |= linux.IFF_RUNNING + if f.Promiscuous { + rv |= linux.IFF_PROMISC } - if nicFlags.Promiscuous { - retFlags |= linux.IFF_PROMISC + if f.Loopback { + rv |= linux.IFF_LOOPBACK } - return retFlags, nil + return rv } diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index 12b4b4767..e4ed52fc8 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -41,10 +41,16 @@ func (s *Stack) SupportsIPv6() bool { func (s *Stack) Interfaces() map[int32]inet.Interface { is := make(map[int32]inet.Interface) for id, ni := range s.Stack.NICInfo() { + var devType uint16 + if ni.Flags.Loopback { + devType = linux.ARPHRD_LOOPBACK + } is[int32(id)] = inet.Interface{ - Name: ni.Name, - Addr: []byte(ni.LinkAddress), - // TODO: Other fields. + Name: ni.Name, + Addr: []byte(ni.LinkAddress), + Flags: uint32(nicStateFlagsToLinux(ni.Flags)), + DeviceType: devType, + MTU: ni.MTU, } } return is diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index 55a76e916..70322b9ed 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -16,6 +16,8 @@ package route import ( + "bytes" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/inet" @@ -97,9 +99,18 @@ func (p *Protocol) dumpLinks(ctx context.Context, hdr linux.NetlinkMessageHeader }) m.PutAttrString(linux.IFLA_IFNAME, i.Name) + m.PutAttr(linux.IFLA_MTU, i.MTU) + + mac := make([]byte, 6) + brd := mac + if len(i.Addr) > 0 { + mac = i.Addr + brd = bytes.Repeat([]byte{0xff}, len(i.Addr)) + } + m.PutAttr(linux.IFLA_ADDRESS, mac) + m.PutAttr(linux.IFLA_BROADCAST, brd) - // TODO: There are many more attributes, such as - // MAC address. + // TODO: There are many more attributes. } return nil diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index e15d1546c..f3b2c7256 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -16,6 +16,7 @@ package netlink import ( + "math" "sync" "gvisor.googlesource.com/gvisor/pkg/abi/linux" @@ -39,8 +40,18 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// defaultSendBufferSize is the default size for the send buffer. -const defaultSendBufferSize = 16 * 1024 +const sizeOfInt32 int = 4 + +const ( + // minBufferSize is the smallest size of a send buffer. + minSendBufferSize = 4 << 10 // 4096 bytes. + + // defaultSendBufferSize is the default size for the send buffer. + defaultSendBufferSize = 16 * 1024 + + // maxBufferSize is the largest size a send buffer can grow to. + maxSendBufferSize = 4 << 20 // 4MB +) // netlinkSocketDevice is the netlink socket virtual device. var netlinkSocketDevice = device.NewAnonDevice() @@ -86,7 +97,7 @@ type Socket struct { // sendBufferSize is the send buffer "size". We don't actually have a // fixed buffer but only consume this many bytes. - sendBufferSize uint64 + sendBufferSize uint32 } var _ socket.Socket = (*Socket)(nil) @@ -273,13 +284,54 @@ func (s *Socket) Shutdown(t *kernel.Task, how int) *syserr.Error { // GetSockOpt implements socket.Socket.GetSockOpt. func (s *Socket) GetSockOpt(t *kernel.Task, level int, name int, outLen int) (interface{}, *syserr.Error) { - // TODO: no sockopts supported. + switch level { + case linux.SOL_SOCKET: + switch name { + case linux.SO_SNDBUF: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + return int32(s.sendBufferSize), nil + + case linux.SO_RCVBUF: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + // We don't have limit on receiving size. + return math.MaxInt32, nil + } + } + // TODO: other sockopts are not supported. return nil, syserr.ErrProtocolNotAvailable } // SetSockOpt implements socket.Socket.SetSockOpt. func (s *Socket) SetSockOpt(t *kernel.Task, level int, name int, opt []byte) *syserr.Error { - // TODO: no sockopts supported. + switch level { + case linux.SOL_SOCKET: + switch name { + case linux.SO_SNDBUF: + if len(opt) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + size := usermem.ByteOrder.Uint32(opt) + if size < minSendBufferSize { + size = minSendBufferSize + } else if size > maxSendBufferSize { + size = maxSendBufferSize + } + s.sendBufferSize = size + return nil + case linux.SO_RCVBUF: + if len(opt) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + // We don't have limit on receiving size. So just accept anything as + // valid for compatibility. + return nil + } + } + // TODO: other sockopts are not supported. return syserr.ErrProtocolNotAvailable } @@ -489,7 +541,7 @@ func (s *Socket) sendMsg(ctx context.Context, src usermem.IOSequence, to []byte, // For simplicity, and consistency with Linux, we copy in the entire // message up front. - if uint64(src.NumBytes()) > s.sendBufferSize { + if src.NumBytes() > int64(s.sendBufferSize) { return 0, syserr.ErrMessageTooLong } diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index b4dc4833c..015275721 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -56,7 +56,7 @@ func (*endpoint) MTU() uint32 { // Capabilities implements stack.LinkEndpoint.Capabilities. Loopback advertises // itself as supporting checksum offload, but in reality it's just omitted. func (*endpoint) Capabilities() stack.LinkEndpointCapabilities { - return stack.CapabilityChecksumOffload | stack.CapabilitySaveRestore + return stack.CapabilityChecksumOffload | stack.CapabilitySaveRestore | stack.CapabilityLoopback } // MaxHeaderLength implements stack.LinkEndpoint.MaxHeaderLength. Given that the diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index c1480f97b..592006a32 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -67,6 +67,13 @@ func (n *NIC) setPromiscuousMode(enable bool) { n.mu.Unlock() } +func (n *NIC) isPromiscuousMode() bool { + n.mu.RLock() + rv := n.promiscuous + n.mu.RUnlock() + return rv +} + // setSpoofing enables or disables address spoofing. func (n *NIC) setSpoofing(enable bool) { n.mu.Lock() diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 01a29689d..bbe887144 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -205,6 +205,7 @@ const ( CapabilityResolutionRequired CapabilitySaveRestore CapabilityDisconnectOk + CapabilityLoopback ) // LinkEndpoint is the interface implemented by data link layer protocols (e.g., diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 6c4aa7cc5..e2b9dc2c0 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -563,6 +563,12 @@ type NICInfo struct { Name string LinkAddress tcpip.LinkAddress ProtocolAddresses []tcpip.ProtocolAddress + + // Flags indicate the state of the NIC. + Flags NICStateFlags + + // MTU is the maximum transmission unit. + MTU uint32 } // NICInfo returns a map of NICIDs to their associated information. @@ -572,10 +578,18 @@ func (s *Stack) NICInfo() map[tcpip.NICID]NICInfo { nics := make(map[tcpip.NICID]NICInfo) for id, nic := range s.nics { + flags := NICStateFlags{ + Up: true, // Netstack interfaces are always up. + Running: nic.linkEP.IsAttached(), + Promiscuous: nic.isPromiscuousMode(), + Loopback: nic.linkEP.Capabilities()&CapabilityLoopback != 0, + } nics[id] = NICInfo{ Name: nic.name, LinkAddress: nic.linkEP.LinkAddress(), ProtocolAddresses: nic.Addresses(), + Flags: flags, + MTU: nic.linkEP.MTU(), } } return nics @@ -591,27 +605,9 @@ type NICStateFlags struct { // Promiscuous indicates whether the interface is in promiscuous mode. Promiscuous bool -} - -// NICFlags returns flags about the state of the NIC. It returns an error if -// the NIC corresponding to id cannot be found. -func (s *Stack) NICFlags(id tcpip.NICID) (NICStateFlags, *tcpip.Error) { - s.mu.RLock() - defer s.mu.RUnlock() - nic := s.nics[id] - if nic == nil { - return NICStateFlags{}, tcpip.ErrUnknownNICID - } - - ret := NICStateFlags{ - // Netstack interfaces are always up. - Up: true, - - Running: nic.linkEP.IsAttached(), - Promiscuous: nic.promiscuous, - } - return ret, nil + // Loopback indicates whether the interface is a loopback. + Loopback bool } // AddAddress adds a new network-layer address to the specified NIC. diff --git a/runsc/boot/network.go b/runsc/boot/network.go index d702ae74e..0e43c91be 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -133,15 +133,16 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct return fmt.Errorf("failed to dup FD %v: %v", oldFD, err) } + mac := tcpip.LinkAddress(generateRndMac()) linkEP := fdbased.New(&fdbased.Options{ FD: newFD, MTU: uint32(link.MTU), EthernetHeader: true, HandleLocal: true, - Address: tcpip.LinkAddress(generateRndMac()), + Address: mac, }) - log.Infof("Enabling interface %q with id %d on addresses %+v", link.Name, nicID, link.Addresses) + log.Infof("Enabling interface %q with id %d on addresses %+v (%v)", link.Name, nicID, link.Addresses, mac) if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses); err != nil { return err } -- cgit v1.2.3 From a316f83977e2a8d0b2746985342fb400472645ae Mon Sep 17 00:00:00 2001 From: Googler Date: Tue, 21 Aug 2018 15:25:50 -0700 Subject: Expose route table PiperOrigin-RevId: 209670528 Change-Id: I2890bcdef36f0b5f24b372b42cf628b38dd5764e --- pkg/tcpip/stack/stack.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index e2b9dc2c0..e09c7efda 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -469,6 +469,13 @@ func (s *Stack) SetRouteTable(table []tcpip.Route) { s.routeTable = table } +// GetRouteTable returns the route table which is currently in use. +func (s *Stack) GetRouteTable() []tcpip.Route { + s.mu.Lock() + defer s.mu.Unlock() + return append([]tcpip.Route(nil), s.routeTable...) +} + // NewEndpoint creates a new transport layer endpoint of the given protocol. func (s *Stack) NewEndpoint(transport tcpip.TransportProtocolNumber, network tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { t, ok := s.transportProtocols[transport] -- cgit v1.2.3 From abe7764928bb18fe417c53c8ea8aa9fb970114b7 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Thu, 23 Aug 2018 08:54:09 -0700 Subject: Encapsulate netstack metrics PiperOrigin-RevId: 209943212 Change-Id: I96dcbc7c2ab2426e510b94a564436505256c5c79 --- pkg/tcpip/stack/nic.go | 14 ++++---- pkg/tcpip/stack/stack.go | 26 ++++----------- pkg/tcpip/tcpip.go | 48 ++++++++++++++++++++++++--- pkg/tcpip/transport/tcp/connect.go | 5 ++- pkg/tcpip/transport/tcp/endpoint.go | 4 +-- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 9 ++--- 6 files changed, 67 insertions(+), 39 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 592006a32..284732874 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -282,12 +282,12 @@ func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error { func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { netProto, ok := n.stack.networkProtocols[protocol] if !ok { - atomic.AddUint64(&n.stack.stats.UnknownProtocolRcvdPackets, 1) + n.stack.stats.UnknownProtocolRcvdPackets.Increment() return } if len(vv.First()) < netProto.MinimumPacketSize() { - atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1) + n.stack.stats.MalformedRcvdPackets.Increment() return } @@ -330,7 +330,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin } if ref == nil { - atomic.AddUint64(&n.stack.stats.UnknownNetworkEndpointRcvdPackets, 1) + n.stack.stats.UnknownNetworkEndpointRcvdPackets.Increment() return } @@ -345,19 +345,19 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) { state, ok := n.stack.transportProtocols[protocol] if !ok { - atomic.AddUint64(&n.stack.stats.UnknownProtocolRcvdPackets, 1) + n.stack.stats.UnknownProtocolRcvdPackets.Increment() return } transProto := state.proto if len(vv.First()) < transProto.MinimumPacketSize() { - atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1) + n.stack.stats.MalformedRcvdPackets.Increment() return } srcPort, dstPort, err := transProto.ParsePorts(vv.First()) if err != nil { - atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1) + n.stack.stats.MalformedRcvdPackets.Increment() return } @@ -379,7 +379,7 @@ func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolN // We could not find an appropriate destination for this packet, so // deliver it to the global handler. if !transProto.HandleUnknownDestinationPacket(r, id, vv) { - atomic.AddUint64(&n.stack.stats.MalformedRcvdPackets, 1) + n.stack.stats.MalformedRcvdPackets.Increment() } } diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index e09c7efda..cc5427cf9 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -26,7 +26,6 @@ package stack import ( "sync" - "sync/atomic" "time" "gvisor.googlesource.com/gvisor/pkg/sleep" @@ -308,6 +307,9 @@ type Options struct { // // If no Clock is specified, the clock source will be time.Now. Clock tcpip.Clock + + // Stats are optional statistic counters. + Stats tcpip.Stats } // New allocates a new networking stack with only the requested networking and @@ -331,6 +333,7 @@ func New(network []string, transport []string, opts Options) *Stack { linkAddrCache: newLinkAddrCache(ageLimit, resolutionTimeout, resolutionAttempts), PortManager: ports.NewPortManager(), clock: clock, + stats: opts.Stats.FillIn(), } // Add specified network protocols. @@ -437,27 +440,12 @@ func (s *Stack) NowNanoseconds() int64 { return s.clock.NowNanoseconds() } -// Stats returns a snapshot of the current stats. -// -// NOTE: The underlying stats are updated using atomic instructions as a result -// the snapshot returned does not represent the value of all the stats at any -// single given point of time. -// TODO: Make stats available in sentry for debugging/diag. -func (s *Stack) Stats() tcpip.Stats { - return tcpip.Stats{ - UnknownProtocolRcvdPackets: atomic.LoadUint64(&s.stats.UnknownProtocolRcvdPackets), - UnknownNetworkEndpointRcvdPackets: atomic.LoadUint64(&s.stats.UnknownNetworkEndpointRcvdPackets), - MalformedRcvdPackets: atomic.LoadUint64(&s.stats.MalformedRcvdPackets), - DroppedPackets: atomic.LoadUint64(&s.stats.DroppedPackets), - } -} - -// MutableStats returns a mutable copy of the current stats. +// Stats returns a mutable copy of the current stats. // // This is not generally exported via the public interface, but is available // internally. -func (s *Stack) MutableStats() *tcpip.Stats { - return &s.stats +func (s *Stack) Stats() tcpip.Stats { + return s.stats } // SetRouteTable assigns the route table to be used by this stack. It diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index bea73def9..e323aea8c 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -34,6 +34,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" @@ -465,23 +466,62 @@ type TransportProtocolNumber uint32 // NetworkProtocolNumber is the number of a network protocol. type NetworkProtocolNumber uint32 +// A StatCounter keeps track of a statistic. +type StatCounter struct { + count uint64 +} + +// Increment adds one to the counter. +func (s *StatCounter) Increment() { + atomic.AddUint64(&s.count, 1) +} + +// Value returns the current value of the counter. +func (s *StatCounter) Value() uint64 { + return atomic.LoadUint64(&s.count) +} + +// IncrementBy increments the counter by v. +func (s *StatCounter) IncrementBy(v uint64) { + atomic.AddUint64(&s.count, v) +} + // Stats holds statistics about the networking stack. +// +// All fields are optional. type Stats struct { // UnknownProtocolRcvdPackets is the number of packets received by the // stack that were for an unknown or unsupported protocol. - UnknownProtocolRcvdPackets uint64 + UnknownProtocolRcvdPackets *StatCounter // UnknownNetworkEndpointRcvdPackets is the number of packets received // by the stack that were for a supported network protocol, but whose // destination address didn't having a matching endpoint. - UnknownNetworkEndpointRcvdPackets uint64 + UnknownNetworkEndpointRcvdPackets *StatCounter // MalformedRcvPackets is the number of packets received by the stack // that were deemed malformed. - MalformedRcvdPackets uint64 + MalformedRcvdPackets *StatCounter // DroppedPackets is the number of packets dropped due to full queues. - DroppedPackets uint64 + DroppedPackets *StatCounter +} + +// FillIn returns a copy of s with nil fields initialized to new StatCounters. +func (s Stats) FillIn() Stats { + if s.UnknownProtocolRcvdPackets == nil { + s.UnknownProtocolRcvdPackets = &StatCounter{} + } + if s.UnknownNetworkEndpointRcvdPackets == nil { + s.UnknownNetworkEndpointRcvdPackets = &StatCounter{} + } + if s.MalformedRcvdPackets == nil { + s.MalformedRcvdPackets = &StatCounter{} + } + if s.DroppedPackets == nil { + s.DroppedPackets = &StatCounter{} + } + return s } // String implements the fmt.Stringer interface. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index b90d3fe48..58d7942f3 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -16,7 +16,6 @@ package tcp import ( "sync" - "sync/atomic" "time" "gvisor.googlesource.com/gvisor/pkg/rand" @@ -292,7 +291,7 @@ func (h *handshake) synRcvdState(s *segment) *tcpip.Error { // not carry a timestamp option then the segment must be dropped // as per https://tools.ietf.org/html/rfc7323#section-3.2. if h.ep.sendTSOk && !s.parsedOptions.TS { - atomic.AddUint64(&h.ep.stack.MutableStats().DroppedPackets, 1) + h.ep.stack.Stats().DroppedPackets.Increment() return nil } @@ -793,7 +792,7 @@ func (e *endpoint) handleSegments() *tcpip.Error { // must be dropped as per // https://tools.ietf.org/html/rfc7323#section-3.2. if e.sendTSOk && !s.parsedOptions.TS { - atomic.AddUint64(&e.stack.MutableStats().DroppedPackets, 1) + e.stack.Stats().DroppedPackets.Increment() s.decRef() continue } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 3fcbf6502..bdcba39c6 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1225,7 +1225,7 @@ func (e *endpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) { func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) { s := newSegment(r, id, vv) if !s.parse() { - atomic.AddUint64(&e.stack.MutableStats().MalformedRcvdPackets, 1) + e.stack.Stats().MalformedRcvdPackets.Increment() s.decRef() return } @@ -1235,7 +1235,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv e.newSegmentWaker.Assert() } else { // The queue is full, so we drop the segment. - atomic.AddUint64(&e.stack.MutableStats().DroppedPackets, 1) + e.stack.Stats().DroppedPackets.Increment() s.decRef() } } diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index 4f6f1da18..a529d9e72 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -268,7 +268,8 @@ func TestSegmentDropWhenTimestampMissing(t *testing.T) { defer c.WQ.EventUnregister(&we) stk := c.Stack() - droppedPackets := stk.Stats().DroppedPackets + droppedPacketsStat := stk.Stats().DroppedPackets + droppedPackets := droppedPacketsStat.Value() data := []byte{1, 2, 3} // Save the sequence number as we will reset it later down // in the test. @@ -283,11 +284,11 @@ func TestSegmentDropWhenTimestampMissing(t *testing.T) { } // Assert that DroppedPackets was incremented by 1. - if got, want := stk.Stats().DroppedPackets, droppedPackets+1; got != want { + if got, want := droppedPacketsStat.Value(), droppedPackets+1; got != want { t.Fatalf("incorrect number of dropped packets, got: %v, want: %v", got, want) } - droppedPackets = stk.Stats().DroppedPackets + droppedPackets = droppedPacketsStat.Value() // Reset the sequence number so that the other endpoint accepts // this segment and does not treat it like an out of order delivery. rep.NextSeqNum = savedSeqNum @@ -301,7 +302,7 @@ func TestSegmentDropWhenTimestampMissing(t *testing.T) { } // Assert that DroppedPackets was not incremented by 1. - if got, want := stk.Stats().DroppedPackets, droppedPackets; got != want { + if got, want := droppedPacketsStat.Value(), droppedPackets; got != want { t.Fatalf("incorrect number of dropped packets, got: %v, want: %v", got, want) } -- cgit v1.2.3 From b17e80ef5a44e773e9032e7dbcb7438ff851ab7c Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 25 Aug 2018 06:16:34 -0700 Subject: Upstreaming DHCP changes from Fuchsia PiperOrigin-RevId: 210221388 Change-Id: Ic82d592b8c4778855fa55ba913f6b9a10b2d511f --- pkg/dhcp/BUILD | 3 + pkg/dhcp/client.go | 285 +++++++++++++++++++++++++++++------------------ pkg/dhcp/dhcp.go | 99 ++++++++-------- pkg/dhcp/dhcp_string.go | 115 +++++++++++++++++++ pkg/dhcp/dhcp_test.go | 246 ++++++++++++++++++++++++++++++++++++---- pkg/dhcp/server.go | 154 ++++++++++++++++++------- pkg/tcpip/stack/stack.go | 5 +- 7 files changed, 687 insertions(+), 220 deletions(-) create mode 100644 pkg/dhcp/dhcp_string.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/BUILD b/pkg/dhcp/BUILD index bd9f592b4..711a72c99 100644 --- a/pkg/dhcp/BUILD +++ b/pkg/dhcp/BUILD @@ -7,12 +7,14 @@ go_library( srcs = [ "client.go", "dhcp.go", + "dhcp_string.go", "server.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/dhcp", deps = [ "//pkg/rand", "//pkg/tcpip", + "//pkg/tcpip/buffer", "//pkg/tcpip/network/ipv4", "//pkg/tcpip/stack", "//pkg/tcpip/transport/udp", @@ -33,5 +35,6 @@ go_test( "//pkg/tcpip/network/ipv4", "//pkg/tcpip/stack", "//pkg/tcpip/transport/udp", + "//pkg/waiter", ], ) diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 8b5fc0452..909040e79 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -18,7 +18,6 @@ import ( "bytes" "context" "fmt" - "log" "sync" "time" @@ -32,9 +31,10 @@ import ( // Client is a DHCP client. type Client struct { - stack *stack.Stack - nicid tcpip.NICID - linkAddr tcpip.LinkAddress + stack *stack.Stack + nicid tcpip.NICID + linkAddr tcpip.LinkAddress + acquiredFunc func(old, new tcpip.Address, cfg Config) mu sync.Mutex addr tcpip.Address @@ -46,29 +46,57 @@ type Client struct { // NewClient creates a DHCP client. // // TODO: add s.LinkAddr(nicid) to *stack.Stack. -func NewClient(s *stack.Stack, nicid tcpip.NICID, linkAddr tcpip.LinkAddress) *Client { +func NewClient(s *stack.Stack, nicid tcpip.NICID, linkAddr tcpip.LinkAddress, acquiredFunc func(old, new tcpip.Address, cfg Config)) *Client { return &Client{ - stack: s, - nicid: nicid, - linkAddr: linkAddr, + stack: s, + nicid: nicid, + linkAddr: linkAddr, + acquiredFunc: acquiredFunc, } } -// Start starts the DHCP client. +// Run starts the DHCP client. // It will periodically search for an IP address using the Request method. -func (c *Client) Start() { - go func() { - for { - log.Print("DHCP request") - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) - err := c.Request(ctx, "") - cancel() - if err == nil { - break - } +func (c *Client) Run(ctx context.Context) { + go c.run(ctx) +} + +func (c *Client) run(ctx context.Context) { + defer func() { + c.mu.Lock() + defer c.mu.Unlock() + if c.addr != "" { + c.stack.RemoveAddress(c.nicid, c.addr) } - log.Printf("DHCP acquired IP %s for %s", c.Address(), c.Config().LeaseLength) }() + + var renewAddr tcpip.Address + for { + reqCtx, cancel := context.WithTimeout(ctx, 3*time.Second) + cfg, err := c.Request(reqCtx, renewAddr) + cancel() + if err != nil { + select { + case <-time.After(1 * time.Second): + // loop and try again + case <-ctx.Done(): + return + } + } + + c.mu.Lock() + renewAddr = c.addr + c.mu.Unlock() + + timer := time.NewTimer(cfg.LeaseLength) + select { + case <-ctx.Done(): + timer.Stop() + return + case <-timer.C: + // loop and make a renewal request + } + } } // Address reports the IP address acquired by the DHCP client. @@ -85,56 +113,53 @@ func (c *Client) Config() Config { return c.cfg } -// Shutdown relinquishes any lease and ends any outstanding renewal timers. -func (c *Client) Shutdown() { - c.mu.Lock() - defer c.mu.Unlock() - if c.addr != "" { - c.stack.RemoveAddress(c.nicid, c.addr) - } - if c.cancelRenew != nil { - c.cancelRenew() - } -} - // Request executes a DHCP request session. // // On success, it adds a new address to this client's TCPIP stack. // If the server sets a lease limit a timer is set to automatically // renew it. -func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) error { +func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg Config, reterr error) { + if err := c.stack.AddAddress(c.nicid, ipv4.ProtocolNumber, "\xff\xff\xff\xff"); err != nil && err != tcpip.ErrDuplicateAddress { + return Config{}, fmt.Errorf("dhcp: %v", err) + } + if err := c.stack.AddAddress(c.nicid, ipv4.ProtocolNumber, "\x00\x00\x00\x00"); err != nil && err != tcpip.ErrDuplicateAddress { + return Config{}, fmt.Errorf("dhcp: %v", err) + } + defer c.stack.RemoveAddress(c.nicid, "\xff\xff\xff\xff") + defer c.stack.RemoveAddress(c.nicid, "\x00\x00\x00\x00") + var wq waiter.Queue ep, err := c.stack.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq) if err != nil { - return fmt.Errorf("dhcp: outbound endpoint: %v", err) + return Config{}, fmt.Errorf("dhcp: outbound endpoint: %v", err) } - err = ep.Bind(tcpip.FullAddress{ - Addr: "\x00\x00\x00\x00", - Port: clientPort, - }, nil) defer ep.Close() - if err != nil { - return fmt.Errorf("dhcp: connect failed: %v", err) + if err := ep.Bind(tcpip.FullAddress{ + Addr: "\x00\x00\x00\x00", + Port: ClientPort, + NIC: c.nicid, + }, nil); err != nil { + return Config{}, fmt.Errorf("dhcp: connect failed: %v", err) } epin, err := c.stack.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq) if err != nil { - return fmt.Errorf("dhcp: inbound endpoint: %v", err) + return Config{}, fmt.Errorf("dhcp: inbound endpoint: %v", err) } - err = epin.Bind(tcpip.FullAddress{ - Addr: "\xff\xff\xff\xff", - Port: clientPort, - }, nil) defer epin.Close() - if err != nil { - return fmt.Errorf("dhcp: connect failed: %v", err) + if err := epin.Bind(tcpip.FullAddress{ + Addr: "\xff\xff\xff\xff", + Port: ClientPort, + NIC: c.nicid, + }, nil); err != nil { + return Config{}, fmt.Errorf("dhcp: connect failed: %v", err) } var xid [4]byte rand.Read(xid[:]) // DHCPDISCOVERY - options := options{ + discOpts := options{ {optDHCPMsgType, []byte{byte(dhcpDISCOVER)}}, {optParamReq, []byte{ 1, // request subnet mask @@ -144,25 +169,34 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) error }}, } if requestedAddr != "" { - options = append(options, option{optReqIPAddr, []byte(requestedAddr)}) + discOpts = append(discOpts, option{optReqIPAddr, []byte(requestedAddr)}) } - h := make(header, headerBaseSize+options.len()) + var clientID []byte + if len(c.linkAddr) == 6 { + clientID = append( + []byte{1}, // RFC 1700: Hardware Type [Ethernet = 1] + c.linkAddr..., + ) + discOpts = append(discOpts, option{optClientID, clientID}) + } + h := make(header, headerBaseSize+discOpts.len()+1) h.init() h.setOp(opRequest) copy(h.xidbytes(), xid[:]) h.setBroadcast() copy(h.chaddr(), c.linkAddr) - h.setOptions(options) + h.setOptions(discOpts) serverAddr := &tcpip.FullAddress{ Addr: "\xff\xff\xff\xff", - Port: serverPort, + Port: ServerPort, + NIC: c.nicid, } wopts := tcpip.WriteOptions{ To: serverAddr, } if _, err := ep.Write(tcpip.SlicePayload(h), wopts); err != nil { - return fmt.Errorf("dhcp discovery write: %v", err) + return Config{}, fmt.Errorf("dhcp discovery write: %v", err) } we, ch := waiter.NewChannelEntry(nil) @@ -170,6 +204,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) error defer wq.EventUnregister(&we) // DHCPOFFER + var opts options for { var addr tcpip.FullAddress v, _, err := epin.Read(&addr) @@ -178,49 +213,84 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) error case <-ch: continue case <-ctx.Done(): - return fmt.Errorf("reading dhcp offer: %v", tcpip.ErrAborted) + return Config{}, fmt.Errorf("reading dhcp offer: %v", tcpip.ErrAborted) } } h = header(v) - if h.isValid() && h.op() == opReply && bytes.Equal(h.xidbytes(), xid[:]) { - break + var valid bool + var e error + opts, valid, e = loadDHCPReply(h, dhcpOFFER, xid[:]) + if !valid { + if e != nil { + // TODO: handle all the errors? + // TODO: report malformed server responses + } + continue } - } - if _, err := h.options(); err != nil { - return fmt.Errorf("dhcp offer: %v", err) + break } var ack bool - var cfg Config + if err := cfg.decode(opts); err != nil { + return Config{}, fmt.Errorf("dhcp offer: %v", err) + } // DHCPREQUEST addr := tcpip.Address(h.yiaddr()) if err := c.stack.AddAddress(c.nicid, ipv4.ProtocolNumber, addr); err != nil { if err != tcpip.ErrDuplicateAddress { - return fmt.Errorf("adding address: %v", err) + return Config{}, fmt.Errorf("adding address: %v", err) } } defer func() { - if ack { - c.mu.Lock() - c.addr = addr - c.cfg = cfg - c.mu.Unlock() - } else { + if !ack || reterr != nil { c.stack.RemoveAddress(c.nicid, addr) + addr = "" + cfg = Config{Error: reterr} + } + + c.mu.Lock() + oldAddr := c.addr + c.addr = addr + c.cfg = cfg + c.mu.Unlock() + + // Clean up broadcast addresses before calling acquiredFunc + // so nothing else uses them by mistake. + // + // (The deferred RemoveAddress calls above silently error.) + c.stack.RemoveAddress(c.nicid, "\xff\xff\xff\xff") + c.stack.RemoveAddress(c.nicid, "\x00\x00\x00\x00") + + if c.acquiredFunc != nil { + c.acquiredFunc(oldAddr, addr, cfg) + } + if requestedAddr != "" && requestedAddr != addr { + c.stack.RemoveAddress(c.nicid, requestedAddr) } }() + h.init() h.setOp(opRequest) for i, b := 0, h.yiaddr(); i < len(b); i++ { b[i] = 0 } - h.setOptions([]option{ + for i, b := 0, h.siaddr(); i < len(b); i++ { + b[i] = 0 + } + for i, b := 0, h.giaddr(); i < len(b); i++ { + b[i] = 0 + } + reqOpts := []option{ {optDHCPMsgType, []byte{byte(dhcpREQUEST)}}, {optReqIPAddr, []byte(addr)}, - {optDHCPServer, h.siaddr()}, - }) + {optDHCPServer, []byte(cfg.ServerAddress)}, + } + if len(clientID) != 0 { + reqOpts = append(reqOpts, option{optClientID, clientID}) + } + h.setOptions(reqOpts) if _, err := ep.Write(tcpip.SlicePayload(h), wopts); err != nil { - return fmt.Errorf("dhcp discovery write: %v", err) + return Config{}, fmt.Errorf("dhcp discovery write: %v", err) } // DHCPACK @@ -232,53 +302,46 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) error case <-ch: continue case <-ctx.Done(): - return fmt.Errorf("reading dhcp ack: %v", tcpip.ErrAborted) + return Config{}, fmt.Errorf("reading dhcp ack: %v", tcpip.ErrAborted) } } h = header(v) - if h.isValid() && h.op() == opReply && bytes.Equal(h.xidbytes(), xid[:]) { - break + var valid bool + var e error + opts, valid, e = loadDHCPReply(h, dhcpACK, xid[:]) + if !valid { + if e != nil { + // TODO: handle all the errors? + // TODO: report malformed server responses + } + if opts, valid, _ = loadDHCPReply(h, dhcpNAK, xid[:]); valid { + if msg := opts.message(); msg != "" { + return Config{}, fmt.Errorf("dhcp: NAK %q", msg) + } + return Config{}, fmt.Errorf("dhcp: NAK with no message") + } + continue } + break } - opts, e := h.options() - if e != nil { - return fmt.Errorf("dhcp ack: %v", e) - } - if err := cfg.decode(opts); err != nil { - return fmt.Errorf("dhcp ack bad options: %v", err) + ack = true + return cfg, nil +} + +func loadDHCPReply(h header, typ dhcpMsgType, xid []byte) (opts options, valid bool, err error) { + if !h.isValid() || h.op() != opReply || !bytes.Equal(h.xidbytes(), xid[:]) { + return nil, false, nil } - msgtype, e := opts.dhcpMsgType() - if e != nil { - return fmt.Errorf("dhcp ack: %v", e) + opts, err = h.options() + if err != nil { + return nil, false, err } - ack = msgtype == dhcpACK - if !ack { - return fmt.Errorf("dhcp: request not acknowledged") + msgtype, err := opts.dhcpMsgType() + if err != nil { + return nil, false, err } - if cfg.LeaseLength != 0 { - go c.renewAfter(cfg.LeaseLength) + if msgtype != typ { + return nil, false, nil } - return nil -} - -func (c *Client) renewAfter(d time.Duration) { - c.mu.Lock() - defer c.mu.Unlock() - if c.cancelRenew != nil { - c.cancelRenew() - } - ctx, cancel := context.WithCancel(context.Background()) - c.cancelRenew = cancel - go func() { - timer := time.NewTimer(d) - defer timer.Stop() - select { - case <-ctx.Done(): - case <-timer.C: - if err := c.Request(ctx, c.addr); err != nil { - log.Printf("address renewal failed: %v", err) - go c.renewAfter(1 * time.Minute) - } - } - }() + return opts, true, nil } diff --git a/pkg/dhcp/dhcp.go b/pkg/dhcp/dhcp.go index 18c318fc8..ceaba34c3 100644 --- a/pkg/dhcp/dhcp.go +++ b/pkg/dhcp/dhcp.go @@ -26,19 +26,21 @@ import ( // Config is standard DHCP configuration. type Config struct { - ServerAddress tcpip.Address // address of the server - SubnetMask tcpip.AddressMask // client address subnet mask - Gateway tcpip.Address // client default gateway - DomainNameServer tcpip.Address // client domain name server - LeaseLength time.Duration // length of the address lease + Error error + ServerAddress tcpip.Address // address of the server + SubnetMask tcpip.AddressMask // client address subnet mask + Gateway tcpip.Address // client default gateway + DNS []tcpip.Address // client DNS server addresses + LeaseLength time.Duration // length of the address lease } func (cfg *Config) decode(opts []option) error { *cfg = Config{} for _, opt := range opts { b := opt.body - if l := opt.code.len(); l != -1 && l != len(b) { - return fmt.Errorf("%s bad length: %d", opt.code, len(b)) + if !opt.code.lenValid(len(b)) { + // TODO: s/%v/%s/ when `go vet` is smarter. + return fmt.Errorf("%v: bad length: %d", opt.code, len(b)) } switch opt.code { case optLeaseTime: @@ -51,7 +53,12 @@ func (cfg *Config) decode(opts []option) error { case optDefaultGateway: cfg.Gateway = tcpip.Address(b) case optDomainNameServer: - cfg.DomainNameServer = tcpip.Address(b) + for ; len(b) > 0; b = b[4:] { + if len(b) < 4 { + return fmt.Errorf("DNS bad length: %d", len(b)) + } + cfg.DNS = append(cfg.DNS, tcpip.Address(b[:4])) + } } } return nil @@ -67,8 +74,12 @@ func (cfg Config) encode() (opts []option) { if cfg.Gateway != "" { opts = append(opts, option{optDefaultGateway, []byte(cfg.Gateway)}) } - if cfg.DomainNameServer != "" { - opts = append(opts, option{optDomainNameServer, []byte(cfg.DomainNameServer)}) + if len(cfg.DNS) > 0 { + dns := make([]byte, 0, 4*len(cfg.DNS)) + for _, addr := range cfg.DNS { + dns = append(dns, addr...) + } + opts = append(opts, option{optDomainNameServer, dns}) } if l := cfg.LeaseLength / time.Second; l != 0 { v := make([]byte, 4) @@ -82,8 +93,10 @@ func (cfg Config) encode() (opts []option) { } const ( - serverPort = 67 - clientPort = 68 + // ServerPort is the well-known UDP port number for a DHCP server. + ServerPort = 67 + // ClientPort is the well-known UDP port number for a DHCP client. + ClientPort = 68 ) var magicCookie = []byte{99, 130, 83, 99} // RFC 1497 @@ -107,10 +120,10 @@ func (h header) isValid() bool { if o := h.op(); o != opRequest && o != opReply { return false } - if h[1] != 0x01 || h[2] != 0x06 || h[3] != 0x00 { + if h[1] != 0x01 || h[2] != 0x06 { return false } - return bytes.Equal(h[236:240], magicCookie) && h[len(h)-1] == 0 + return bytes.Equal(h[236:240], magicCookie) } func (h header) op() op { return op(h[0]) } @@ -141,7 +154,7 @@ func (h header) options() (opts options, err error) { } optlen := int(h[i+1]) if len(h) < i+2+optlen { - return nil, fmt.Errorf("option too long") + return nil, fmt.Errorf("option %v too long i=%d, optlen=%d", optionCode(h[i]), i, optlen) } opts = append(opts, option{ code: optionCode(h[i]), @@ -160,6 +173,8 @@ func (h header) setOptions(opts []option) { copy(h[i+2:i+2+len(opt.body)], opt.body) i += 2 + len(opt.body) } + h[i] = 255 // End option + i++ for ; i < len(h); i++ { h[i] = 0 } @@ -182,47 +197,31 @@ const ( optSubnetMask optionCode = 1 optDefaultGateway optionCode = 3 optDomainNameServer optionCode = 6 + optDomainName optionCode = 15 optReqIPAddr optionCode = 50 optLeaseTime optionCode = 51 optDHCPMsgType optionCode = 53 // dhcpMsgType optDHCPServer optionCode = 54 optParamReq optionCode = 55 + optMessage optionCode = 56 + optClientID optionCode = 61 ) -func (code optionCode) len() int { +func (code optionCode) lenValid(l int) bool { switch code { - case optSubnetMask, optDefaultGateway, optDomainNameServer, + case optSubnetMask, optDefaultGateway, optReqIPAddr, optLeaseTime, optDHCPServer: - return 4 + return l == 4 case optDHCPMsgType: - return 1 - case optParamReq: - return -1 // no fixed length - default: - return -1 - } -} - -func (code optionCode) String() string { - switch code { - case optSubnetMask: - return "option(subnet-mask)" - case optDefaultGateway: - return "option(default-gateway)" + return l == 1 case optDomainNameServer: - return "option(dns)" - case optReqIPAddr: - return "option(request-ip-address)" - case optLeaseTime: - return "option(least-time)" - case optDHCPMsgType: - return "option(message-type)" - case optDHCPServer: - return "option(server)" + return l%4 == 0 + case optMessage, optDomainName, optClientID: + return l >= 1 case optParamReq: - return "option(parameter-request)" + return true // no fixed length default: - return fmt.Sprintf("option(%d)", code) + return true // unknown option, assume ok } } @@ -232,11 +231,12 @@ func (opts options) dhcpMsgType() (dhcpMsgType, error) { for _, opt := range opts { if opt.code == optDHCPMsgType { if len(opt.body) != 1 { - return 0, fmt.Errorf("%s: bad length: %d", optDHCPMsgType, len(opt.body)) + // TODO: s/%v/%s/ when `go vet` is smarter. + return 0, fmt.Errorf("%v: bad length: %d", opt.code, len(opt.body)) } v := opt.body[0] if v <= 0 || v >= 8 { - return 0, fmt.Errorf("%s: unknown value: %d", optDHCPMsgType, v) + return 0, fmt.Errorf("DHCP bad length: %d", len(opt.body)) } return dhcpMsgType(v), nil } @@ -244,6 +244,15 @@ func (opts options) dhcpMsgType() (dhcpMsgType, error) { return 0, nil } +func (opts options) message() string { + for _, opt := range opts { + if opt.code == optMessage { + return string(opt.body) + } + } + return "" +} + func (opts options) len() int { l := 0 for _, opt := range opts { diff --git a/pkg/dhcp/dhcp_string.go b/pkg/dhcp/dhcp_string.go new file mode 100644 index 000000000..7cabed29e --- /dev/null +++ b/pkg/dhcp/dhcp_string.go @@ -0,0 +1,115 @@ +// Copyright 2018 Google Inc. +// +// 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 dhcp + +import ( + "bytes" + "fmt" + + "gvisor.googlesource.com/gvisor/pkg/tcpip" +) + +func (h header) String() string { + opts, err := h.options() + var msgtype dhcpMsgType + if err == nil { + msgtype, err = opts.dhcpMsgType() + } + if !h.isValid() || err != nil { + return fmt.Sprintf("DHCP invalid, %v %v h[1:4]=%x cookie=%x len=%d (%v)", h.op(), h.xid(), []byte(h[1:4]), []byte(h[236:240]), len(h), err) + } + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "%v %v len=%d\n", msgtype, h.xid(), len(h)) + fmt.Fprintf(buf, "\tciaddr:%v yiaddr:%v siaddr:%v giaddr:%v\n", + tcpip.Address(h.ciaddr()), + tcpip.Address(h.yiaddr()), + tcpip.Address(h.siaddr()), + tcpip.Address(h.giaddr())) + fmt.Fprintf(buf, "\tchaddr:%x", h.chaddr()) + for _, opt := range opts { + fmt.Fprintf(buf, "\n\t%v", opt) + } + return buf.String() +} + +func (opt option) String() string { + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "%v: ", opt.code) + fmt.Fprintf(buf, "%x", opt.body) + return buf.String() +} + +func (code optionCode) String() string { + switch code { + case optSubnetMask: + return "option(subnet-mask)" + case optDefaultGateway: + return "option(default-gateway)" + case optDomainNameServer: + return "option(dns)" + case optDomainName: + return "option(domain-name)" + case optReqIPAddr: + return "option(request-ip-address)" + case optLeaseTime: + return "option(lease-time)" + case optDHCPMsgType: + return "option(message-type)" + case optDHCPServer: + return "option(server)" + case optParamReq: + return "option(parameter-request)" + case optMessage: + return "option(message)" + case optClientID: + return "option(client-id)" + default: + return fmt.Sprintf("option(%d)", code) + } +} + +func (o op) String() string { + switch o { + case opRequest: + return "op(request)" + case opReply: + return "op(reply)" + } + return fmt.Sprintf("op(UNKNOWN:%d)", int(o)) +} + +func (t dhcpMsgType) String() string { + switch t { + case dhcpDISCOVER: + return "DHCPDISCOVER" + case dhcpOFFER: + return "DHCPOFFER" + case dhcpREQUEST: + return "DHCPREQUEST" + case dhcpDECLINE: + return "DHCPDECLINE" + case dhcpACK: + return "DHCPACK" + case dhcpNAK: + return "DHCPNAK" + case dhcpRELEASE: + return "DHCPRELEASE" + } + return fmt.Sprintf("DHCP(%d)", int(t)) +} + +func (v xid) String() string { + return fmt.Sprintf("xid:%x", uint32(v)) +} diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index 731ed61a5..67814683a 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -27,9 +27,13 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv4" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/udp" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) -func TestDHCP(t *testing.T) { +const nicid = tcpip.NICID(1) +const serverAddr = tcpip.Address("\xc0\xa8\x03\x01") + +func createStack(t *testing.T) *stack.Stack { const defaultMTU = 65536 id, linkEP := channel.New(256, defaultMTU, "") if testing.Verbose() { @@ -48,17 +52,9 @@ func TestDHCP(t *testing.T) { s := stack.New([]string{ipv4.ProtocolName}, []string{udp.ProtocolName}, stack.Options{}) - const nicid tcpip.NICID = 1 if err := s.CreateNIC(nicid, id); err != nil { t.Fatal(err) } - if err := s.AddAddress(nicid, ipv4.ProtocolNumber, "\x00\x00\x00\x00"); err != nil { - t.Fatal(err) - } - if err := s.AddAddress(nicid, ipv4.ProtocolNumber, "\xff\xff\xff\xff"); err != nil { - t.Fatal(err) - } - const serverAddr = tcpip.Address("\xc0\xa8\x03\x01") if err := s.AddAddress(nicid, ipv4.ProtocolNumber, serverAddr); err != nil { t.Fatal(err) } @@ -70,31 +66,38 @@ func TestDHCP(t *testing.T) { NIC: nicid, }}) - var clientAddrs = []tcpip.Address{"\xc0\xa8\x03\x02", "\xc0\xa8\x03\x03"} + return s +} + +func TestDHCP(t *testing.T) { + s := createStack(t) + clientAddrs := []tcpip.Address{"\xc0\xa8\x03\x02", "\xc0\xa8\x03\x03"} serverCfg := Config{ - ServerAddress: serverAddr, - SubnetMask: "\xff\xff\xff\x00", - Gateway: "\xc0\xa8\x03\xF0", - DomainNameServer: "\x08\x08\x08\x08", - LeaseLength: 24 * time.Hour, + ServerAddress: serverAddr, + SubnetMask: "\xff\xff\xff\x00", + Gateway: "\xc0\xa8\x03\xF0", + DNS: []tcpip.Address{ + "\x08\x08\x08\x08", "\x08\x08\x04\x04", + }, + LeaseLength: 24 * time.Hour, } serverCtx, cancel := context.WithCancel(context.Background()) defer cancel() - _, err := NewServer(serverCtx, s, clientAddrs, serverCfg) + _, err := newEPConnServer(serverCtx, s, clientAddrs, serverCfg) if err != nil { t.Fatal(err) } const clientLinkAddr0 = tcpip.LinkAddress("\x52\x11\x22\x33\x44\x52") - c0 := NewClient(s, nicid, clientLinkAddr0) - if err := c0.Request(context.Background(), ""); err != nil { + c0 := NewClient(s, nicid, clientLinkAddr0, nil) + if _, err := c0.Request(context.Background(), ""); err != nil { t.Fatal(err) } if got, want := c0.Address(), clientAddrs[0]; got != want { t.Errorf("c.Addr()=%s, want=%s", got, want) } - if err := c0.Request(context.Background(), ""); err != nil { + if _, err := c0.Request(context.Background(), ""); err != nil { t.Fatal(err) } if got, want := c0.Address(), clientAddrs[0]; got != want { @@ -102,22 +105,219 @@ func TestDHCP(t *testing.T) { } const clientLinkAddr1 = tcpip.LinkAddress("\x52\x11\x22\x33\x44\x53") - c1 := NewClient(s, nicid, clientLinkAddr1) - if err := c1.Request(context.Background(), ""); err != nil { + c1 := NewClient(s, nicid, clientLinkAddr1, nil) + if _, err := c1.Request(context.Background(), ""); err != nil { t.Fatal(err) } if got, want := c1.Address(), clientAddrs[1]; got != want { t.Errorf("c.Addr()=%s, want=%s", got, want) } - if err := c0.Request(context.Background(), ""); err != nil { + if _, err := c0.Request(context.Background(), ""); err != nil { t.Fatal(err) } if got, want := c0.Address(), clientAddrs[0]; got != want { t.Errorf("c.Addr()=%s, want=%s", got, want) } - if got, want := c0.Config(), serverCfg; got != want { + if got, want := c0.Config(), serverCfg; !equalConfig(got, want) { t.Errorf("client config:\n\t%#+v\nwant:\n\t%#+v", got, want) } } + +func equalConfig(c0, c1 Config) bool { + if c0.Error != c1.Error || c0.ServerAddress != c1.ServerAddress || c0.SubnetMask != c1.SubnetMask || c0.Gateway != c1.Gateway || c0.LeaseLength != c1.LeaseLength { + return false + } + if len(c0.DNS) != len(c1.DNS) { + return false + } + for i := 0; i < len(c0.DNS); i++ { + if c0.DNS[i] != c1.DNS[i] { + return false + } + } + return true +} + +func TestRenew(t *testing.T) { + s := createStack(t) + clientAddrs := []tcpip.Address{"\xc0\xa8\x03\x02"} + + serverCfg := Config{ + ServerAddress: serverAddr, + SubnetMask: "\xff\xff\xff\x00", + Gateway: "\xc0\xa8\x03\xF0", + DNS: []tcpip.Address{"\x08\x08\x08\x08"}, + LeaseLength: 1 * time.Second, + } + serverCtx, cancel := context.WithCancel(context.Background()) + defer cancel() + _, err := newEPConnServer(serverCtx, s, clientAddrs, serverCfg) + if err != nil { + t.Fatal(err) + } + + count := 0 + var curAddr tcpip.Address + addrCh := make(chan tcpip.Address) + acquiredFunc := func(oldAddr, newAddr tcpip.Address, cfg Config) { + if err := cfg.Error; err != nil { + t.Fatalf("acquisition %d failed: %v", count, err) + } + if oldAddr != curAddr { + t.Fatalf("aquisition %d: curAddr=%v, oldAddr=%v", count, curAddr, oldAddr) + } + if cfg.LeaseLength != time.Second { + t.Fatalf("aquisition %d: lease length: %v, want %v", count, cfg.LeaseLength, time.Second) + } + count++ + curAddr = newAddr + addrCh <- newAddr + } + + clientCtx, cancel := context.WithCancel(context.Background()) + const clientLinkAddr0 = tcpip.LinkAddress("\x52\x11\x22\x33\x44\x52") + c := NewClient(s, nicid, clientLinkAddr0, acquiredFunc) + c.Run(clientCtx) + + var addr tcpip.Address + select { + case addr = <-addrCh: + t.Logf("got first address: %v", addr) + case <-time.After(5 * time.Second): + t.Fatal("timeout acquiring initial address") + } + + select { + case newAddr := <-addrCh: + t.Logf("got renewal: %v", newAddr) + if newAddr != addr { + t.Fatalf("renewal address is %v, want %v", newAddr, addr) + } + case <-time.After(5 * time.Second): + t.Fatal("timeout waiting for address renewal") + } + + cancel() +} + +// Regression test for https://fuchsia.atlassian.net/browse/NET-17 +func TestNoNullTerminator(t *testing.T) { + v := "\x02\x01\x06\x00" + + "\xc8\x37\xbe\x73\x00\x00\x80\x00\x00\x00\x00\x00\xc0\xa8\x2b\x92" + + "\xc0\xa8\x2b\x01\x00\x00\x00\x00\x00\x0f\x60\x0a\x23\x93\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x63\x82\x53\x63\x35\x01\x02\x36" + + "\x04\xc0\xa8\x2b\x01\x33\x04\x00\x00\x0e\x10\x3a\x04\x00\x00\x07" + + "\x08\x3b\x04\x00\x00\x0c\x4e\x01\x04\xff\xff\xff\x00\x1c\x04\xc0" + + "\xa8\x2b\xff\x03\x04\xc0\xa8\x2b\x01\x06\x04\xc0\xa8\x2b\x01\x2b" + + "\x0f\x41\x4e\x44\x52\x4f\x49\x44\x5f\x4d\x45\x54\x45\x52\x45\x44" + + "\xff" + h := header(v) + if !h.isValid() { + t.Error("failed to decode header") + } + + if got, want := h.op(), opReply; got != want { + t.Errorf("h.op()=%v, want=%v", got, want) + } + + if _, err := h.options(); err != nil { + t.Errorf("bad options: %v", err) + } +} + +func teeConn(c conn) (conn, conn) { + dup1 := &dupConn{ + c: c, + dup: make(chan connMsg, 8), + } + dup2 := &chConn{ + c: c, + ch: dup1.dup, + } + return dup1, dup2 +} + +type connMsg struct { + buf buffer.View + addr tcpip.FullAddress + err error +} + +type dupConn struct { + c conn + dup chan connMsg +} + +func (c *dupConn) Read() (buffer.View, tcpip.FullAddress, error) { + v, addr, err := c.c.Read() + c.dup <- connMsg{v, addr, err} + return v, addr, err +} +func (c *dupConn) Write(b []byte, addr *tcpip.FullAddress) error { return c.c.Write(b, addr) } + +type chConn struct { + ch chan connMsg + c conn +} + +func (c *chConn) Read() (buffer.View, tcpip.FullAddress, error) { + msg := <-c.ch + return msg.buf, msg.addr, msg.err +} +func (c *chConn) Write(b []byte, addr *tcpip.FullAddress) error { return c.c.Write(b, addr) } + +func TestTwoServers(t *testing.T) { + s := createStack(t) + + wq := new(waiter.Queue) + ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, wq) + if err != nil { + t.Fatalf("dhcp: server endpoint: %v", err) + } + if err = ep.Bind(tcpip.FullAddress{Port: ServerPort}, nil); err != nil { + t.Fatalf("dhcp: server bind: %v", err) + } + + serverCtx, cancel := context.WithCancel(context.Background()) + defer cancel() + c1, c2 := teeConn(newEPConn(serverCtx, wq, ep)) + + if _, err := NewServer(serverCtx, c1, []tcpip.Address{"\xc0\xa8\x03\x02"}, Config{ + ServerAddress: "\xc0\xa8\x03\x01", + SubnetMask: "\xff\xff\xff\x00", + Gateway: "\xc0\xa8\x03\xF0", + DNS: []tcpip.Address{"\x08\x08\x08\x08"}, + LeaseLength: 30 * time.Minute, + }); err != nil { + t.Fatal(err) + } + if _, err := NewServer(serverCtx, c2, []tcpip.Address{"\xc0\xa8\x04\x02"}, Config{ + ServerAddress: "\xc0\xa8\x04\x01", + SubnetMask: "\xff\xff\xff\x00", + Gateway: "\xc0\xa8\x03\xF0", + DNS: []tcpip.Address{"\x08\x08\x08\x08"}, + LeaseLength: 30 * time.Minute, + }); err != nil { + t.Fatal(err) + } + + const clientLinkAddr0 = tcpip.LinkAddress("\x52\x11\x22\x33\x44\x52") + c := NewClient(s, nicid, clientLinkAddr0, nil) + if _, err := c.Request(context.Background(), ""); err != nil { + t.Fatal(err) + } +} diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index 0beac7782..003e272b2 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -17,11 +17,13 @@ package dhcp import ( "context" "fmt" + "io" "log" "sync" "time" "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv4" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/udp" @@ -30,10 +32,8 @@ import ( // Server is a DHCP server. type Server struct { - stack *stack.Stack + conn conn broadcast tcpip.FullAddress - wq waiter.Queue - ep tcpip.Endpoint addrs []tcpip.Address // TODO: use a tcpip.AddressMask or range structure cfg Config cfgopts []option // cfg to send to client @@ -44,36 +44,96 @@ type Server struct { leases map[tcpip.LinkAddress]serverLease } +// conn is a blocking read/write network endpoint. +type conn interface { + Read() (buffer.View, tcpip.FullAddress, error) + Write([]byte, *tcpip.FullAddress) error +} + +type epConn struct { + ctx context.Context + wq *waiter.Queue + ep tcpip.Endpoint + we waiter.Entry + inCh chan struct{} +} + +func newEPConn(ctx context.Context, wq *waiter.Queue, ep tcpip.Endpoint) *epConn { + c := &epConn{ + ctx: ctx, + wq: wq, + ep: ep, + } + c.we, c.inCh = waiter.NewChannelEntry(nil) + wq.EventRegister(&c.we, waiter.EventIn) + + go func() { + <-ctx.Done() + wq.EventUnregister(&c.we) + }() + + return c +} + +func (c *epConn) Read() (buffer.View, tcpip.FullAddress, error) { + for { + var addr tcpip.FullAddress + v, _, err := c.ep.Read(&addr) + if err == tcpip.ErrWouldBlock { + select { + case <-c.inCh: + continue + case <-c.ctx.Done(): + return nil, tcpip.FullAddress{}, io.EOF + } + } + if err != nil { + return v, addr, fmt.Errorf("read: %v", err) + } + return v, addr, nil + } +} + +func (c *epConn) Write(b []byte, addr *tcpip.FullAddress) error { + if _, err := c.ep.Write(tcpip.SlicePayload(b), tcpip.WriteOptions{To: addr}); err != nil { + return fmt.Errorf("write: %v", err) + } + return nil +} + +func newEPConnServer(ctx context.Context, stack *stack.Stack, addrs []tcpip.Address, cfg Config) (*Server, error) { + wq := new(waiter.Queue) + ep, err := stack.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, wq) + if err != nil { + return nil, fmt.Errorf("dhcp: server endpoint: %v", err) + } + if err := ep.Bind(tcpip.FullAddress{Port: ServerPort}, nil); err != nil { + return nil, fmt.Errorf("dhcp: server bind: %v", err) + } + c := newEPConn(ctx, wq, ep) + return NewServer(ctx, c, addrs, cfg) +} + // NewServer creates a new DHCP server and begins serving. // The server continues serving until ctx is done. -func NewServer(ctx context.Context, stack *stack.Stack, addrs []tcpip.Address, cfg Config) (*Server, error) { +func NewServer(ctx context.Context, c conn, addrs []tcpip.Address, cfg Config) (*Server, error) { + if cfg.ServerAddress == "" { + return nil, fmt.Errorf("dhcp: server requires explicit server address") + } s := &Server{ - stack: stack, + conn: c, addrs: addrs, cfg: cfg, cfgopts: cfg.encode(), broadcast: tcpip.FullAddress{ Addr: "\xff\xff\xff\xff", - Port: clientPort, + Port: ClientPort, }, handlers: make([]chan header, 8), leases: make(map[tcpip.LinkAddress]serverLease), } - var err *tcpip.Error - s.ep, err = s.stack.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &s.wq) - if err != nil { - return nil, fmt.Errorf("dhcp: server endpoint: %v", err) - } - serverBroadcast := tcpip.FullAddress{ - Addr: "", - Port: serverPort, - } - if err := s.ep.Bind(serverBroadcast, nil); err != nil { - return nil, fmt.Errorf("dhcp: server bind: %v", err) - } - for i := 0; i < len(s.handlers); i++ { ch := make(chan header, 8) s.handlers[i] = ch @@ -108,20 +168,10 @@ func (s *Server) expirer(ctx context.Context) { // reader listens for all incoming DHCP packets and fans them out to // handling goroutines based on XID as session identifiers. func (s *Server) reader(ctx context.Context) { - we, ch := waiter.NewChannelEntry(nil) - s.wq.EventRegister(&we, waiter.EventIn) - defer s.wq.EventUnregister(&we) - for { - var addr tcpip.FullAddress - v, _, err := s.ep.Read(&addr) - if err == tcpip.ErrWouldBlock { - select { - case <-ch: - continue - case <-ctx.Done(): - return - } + v, _, err := s.conn.Read() + if err != nil { + return } h := header(v) @@ -234,21 +284,50 @@ func (s *Server) handleDiscover(hreq header, opts options) { // DHCPOFFER opts = options{{optDHCPMsgType, []byte{byte(dhcpOFFER)}}} opts = append(opts, s.cfgopts...) - h := make(header, headerBaseSize+opts.len()) + h := make(header, headerBaseSize+opts.len()+1) h.init() h.setOp(opReply) copy(h.xidbytes(), hreq.xidbytes()) copy(h.yiaddr(), lease.addr) - copy(h.siaddr(), s.cfg.ServerAddress) copy(h.chaddr(), hreq.chaddr()) h.setOptions(opts) - s.ep.Write(tcpip.SlicePayload(h), tcpip.WriteOptions{To: &s.broadcast}) + s.conn.Write([]byte(h), &s.broadcast) +} + +func (s *Server) nack(hreq header) { + // DHCPNACK + opts := options([]option{ + {optDHCPMsgType, []byte{byte(dhcpNAK)}}, + {optDHCPServer, []byte(s.cfg.ServerAddress)}, + }) + h := make(header, headerBaseSize+opts.len()+1) + h.init() + h.setOp(opReply) + copy(h.xidbytes(), hreq.xidbytes()) + copy(h.chaddr(), hreq.chaddr()) + h.setOptions(opts) + s.conn.Write([]byte(h), &s.broadcast) } func (s *Server) handleRequest(hreq header, opts options) { linkAddr := tcpip.LinkAddress(hreq.chaddr()[:6]) xid := hreq.xid() + reqopts, err := hreq.options() + if err != nil { + s.nack(hreq) + return + } + var reqcfg Config + if err := reqcfg.decode(reqopts); err != nil { + s.nack(hreq) + return + } + if reqcfg.ServerAddress != s.cfg.ServerAddress { + // This request is for a different DHCP server. Ignore it. + return + } + s.mu.Lock() lease := s.leases[linkAddr] switch lease.state { @@ -271,15 +350,14 @@ func (s *Server) handleRequest(hreq header, opts options) { // DHCPACK opts = []option{{optDHCPMsgType, []byte{byte(dhcpACK)}}} opts = append(opts, s.cfgopts...) - h := make(header, headerBaseSize+opts.len()) + h := make(header, headerBaseSize+opts.len()+1) h.init() h.setOp(opReply) copy(h.xidbytes(), hreq.xidbytes()) copy(h.yiaddr(), lease.addr) - copy(h.siaddr(), s.cfg.ServerAddress) copy(h.chaddr(), hreq.chaddr()) h.setOptions(opts) - s.ep.Write(tcpip.SlicePayload(h), tcpip.WriteOptions{To: &s.broadcast}) + s.conn.Write([]byte(h), &s.broadcast) } type leaseState int diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index cc5427cf9..2c8c4aa31 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -764,9 +764,8 @@ func (s *Stack) SetSpoofing(nicID tcpip.NICID, enable bool) *tcpip.Error { func (s *Stack) AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress) { fullAddr := tcpip.FullAddress{NIC: nicid, Addr: addr} s.linkAddrCache.add(fullAddr, linkAddr) - // TODO: provide a way for a - // transport endpoint to receive a signal that AddLinkAddress - // for a particular address has been called. + // TODO: provide a way for a transport endpoint to receive a signal + // that AddLinkAddress for a particular address has been called. } // GetLinkAddress implements LinkAddressCache.GetLinkAddress. -- cgit v1.2.3 From 0923bcf06bffe0216cd685f49e83a07201d48cc3 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 27 Aug 2018 15:28:38 -0700 Subject: Add various statistics PiperOrigin-RevId: 210442599 Change-Id: I9498351f461dc69c77b7f815d526c5693bec8e4a --- pkg/tcpip/link/sniffer/sniffer.go | 20 +- pkg/tcpip/network/BUILD | 3 + pkg/tcpip/network/ip_test.go | 149 ++++--- pkg/tcpip/network/ipv4/ipv4.go | 2 + pkg/tcpip/network/ipv6/ipv6.go | 2 + pkg/tcpip/stack/nic.go | 7 +- pkg/tcpip/stack/route.go | 11 +- pkg/tcpip/stack/transport_demuxer.go | 5 + pkg/tcpip/tcpip.go | 198 +++++++--- pkg/tcpip/transport/tcp/connect.go | 10 + pkg/tcpip/transport/tcp/endpoint.go | 22 +- pkg/tcpip/transport/tcp/tcp_test.go | 428 ++++++++++++++++----- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 3 +- pkg/tcpip/transport/tcp/testing/context/context.go | 19 +- pkg/tcpip/transport/udp/endpoint.go | 11 +- pkg/tcpip/transport/udp/udp_test.go | 38 ++ 16 files changed, 703 insertions(+), 225 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 3836cebb7..414a7edb4 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -118,7 +118,7 @@ func NewWithFile(lower tcpip.LinkEndpointID, file *os.File, snapLen uint32) (tcp // logs the packet before forwarding to the actual dispatcher. func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { - LogPacket("recv", protocol, vv.First(), nil) + logPacket("recv", protocol, vv.First(), nil) } if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 { vs := vv.Views() @@ -190,7 +190,7 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // the request to the lower endpoint. func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { - LogPacket("send", protocol, hdr.UsedBytes(), payload) + logPacket("send", protocol, hdr.UsedBytes(), payload) } if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 { hdrBuf := hdr.UsedBytes() @@ -226,8 +226,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload return e.lower.WritePacket(r, hdr, payload, protocol) } -// LogPacket logs the given packet. -func LogPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byte) { +func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byte) { // Figure out the network layer info. var transProto uint8 src := tcpip.Address("unknown") @@ -316,9 +315,19 @@ func LogPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byt case header.TCPProtocolNumber: transName = "tcp" tcp := header.TCP(b) + offset := int(tcp.DataOffset()) + if offset < header.TCPMinimumSize { + details += fmt.Sprintf("invalid packet: tcp data offset too small %d", offset) + break + } + if offset > len(tcp) { + details += fmt.Sprintf("invalid packet: tcp data offset %d larger than packet buffer length %d", offset, len(tcp)) + break + } + srcPort = tcp.SourcePort() dstPort = tcp.DestinationPort() - size -= uint16(tcp.DataOffset()) + size -= uint16(offset) // Initialize the TCP flags. flags := tcp.Flags() @@ -334,6 +343,7 @@ func LogPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byt } else { details += fmt.Sprintf(" options: %+v", tcp.ParsedOptions()) } + default: log.Infof("%s %v -> %v unknown transport protocol: %d", prefix, src, dst, transProto) return diff --git a/pkg/tcpip/network/BUILD b/pkg/tcpip/network/BUILD index 9a26b46c4..25a3c98b6 100644 --- a/pkg/tcpip/network/BUILD +++ b/pkg/tcpip/network/BUILD @@ -12,8 +12,11 @@ go_test( "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", + "//pkg/tcpip/link/loopback", "//pkg/tcpip/network/ipv4", "//pkg/tcpip/network/ipv6", "//pkg/tcpip/stack", + "//pkg/tcpip/transport/tcp", + "//pkg/tcpip/transport/udp", ], ) diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index f1edebe27..4475a75cf 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -20,9 +20,25 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/loopback" "gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv4" "gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv6" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/tcp" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/udp" +) + +const ( + localIpv4Addr = "\x0a\x00\x00\x01" + remoteIpv4Addr = "\x0a\x00\x00\x02" + ipv4SubnetAddr = "\x0a\x00\x00\x00" + ipv4SubnetMask = "\xff\xff\xff\x00" + ipv4Gateway = "\x0a\x00\x00\x03" + localIpv6Addr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + remoteIpv6Addr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" + ipv6SubnetAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + ipv6SubnetMask = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00" + ipv6Gateway = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03" ) // testObject implements two interfaces: LinkEndpoint and TransportDispatcher. @@ -152,10 +168,38 @@ func (t *testObject) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payloa return nil } +func buildIPv4Route(local, remote tcpip.Address) (stack.Route, *tcpip.Error) { + s := stack.New([]string{ipv4.ProtocolName}, []string{udp.ProtocolName, tcp.ProtocolName}, stack.Options{}) + s.CreateNIC(1, loopback.New()) + s.AddAddress(1, ipv4.ProtocolNumber, local) + s.SetRouteTable([]tcpip.Route{{ + Destination: ipv4SubnetAddr, + Mask: ipv4SubnetMask, + Gateway: ipv4Gateway, + NIC: 1, + }}) + + return s.FindRoute(1, local, remote, ipv4.ProtocolNumber) +} + +func buildIPv6Route(local, remote tcpip.Address) (stack.Route, *tcpip.Error) { + s := stack.New([]string{ipv6.ProtocolName}, []string{udp.ProtocolName, tcp.ProtocolName}, stack.Options{}) + s.CreateNIC(1, loopback.New()) + s.AddAddress(1, ipv6.ProtocolNumber, local) + s.SetRouteTable([]tcpip.Route{{ + Destination: ipv6SubnetAddr, + Mask: ipv6SubnetMask, + Gateway: ipv6Gateway, + NIC: 1, + }}) + + return s.FindRoute(1, local, remote, ipv6.ProtocolNumber) +} + func TestIPv4Send(t *testing.T) { o := testObject{t: t, v4: true} proto := ipv4.NewProtocol() - ep, err := proto.NewEndpoint(1, "\x0a\x00\x00\x01", nil, nil, &o) + ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, nil, &o) if err != nil { t.Fatalf("NewEndpoint failed: %v", err) } @@ -171,13 +215,13 @@ func TestIPv4Send(t *testing.T) { // Issue the write. o.protocol = 123 - o.srcAddr = "\x0a\x00\x00\x01" - o.dstAddr = "\x0a\x00\x00\x02" + o.srcAddr = localIpv4Addr + o.dstAddr = remoteIpv4Addr o.contents = payload - r := stack.Route{ - RemoteAddress: o.dstAddr, - LocalAddress: o.srcAddr, + r, err := buildIPv4Route(localIpv4Addr, remoteIpv4Addr) + if err != nil { + t.Fatalf("could not find route: %v", err) } if err := ep.WritePacket(&r, &hdr, payload, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) @@ -187,7 +231,7 @@ func TestIPv4Send(t *testing.T) { func TestIPv4Receive(t *testing.T) { o := testObject{t: t, v4: true} proto := ipv4.NewProtocol() - ep, err := proto.NewEndpoint(1, "\x0a\x00\x00\x01", nil, &o, nil) + ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, &o, nil) if err != nil { t.Fatalf("NewEndpoint failed: %v", err) } @@ -200,8 +244,8 @@ func TestIPv4Receive(t *testing.T) { TotalLength: uint16(totalLen), TTL: 20, Protocol: 10, - SrcAddr: "\x0a\x00\x00\x02", - DstAddr: "\x0a\x00\x00\x01", + SrcAddr: remoteIpv4Addr, + DstAddr: localIpv4Addr, }) // Make payload be non-zero. @@ -211,13 +255,13 @@ func TestIPv4Receive(t *testing.T) { // Give packet to ipv4 endpoint, dispatcher will validate that it's ok. o.protocol = 10 - o.srcAddr = "\x0a\x00\x00\x02" - o.dstAddr = "\x0a\x00\x00\x01" + o.srcAddr = remoteIpv4Addr + o.dstAddr = localIpv4Addr o.contents = view[header.IPv4MinimumSize:totalLen] - r := stack.Route{ - LocalAddress: o.dstAddr, - RemoteAddress: o.srcAddr, + r, err := buildIPv4Route(localIpv4Addr, remoteIpv4Addr) + if err != nil { + t.Fatalf("could not find route: %v", err) } var views [1]buffer.View vv := view.ToVectorisedView(views) @@ -248,7 +292,7 @@ func TestIPv4ReceiveControl(t *testing.T) { {"Zero-length packet", 0, 0, header.ICMPv4PortUnreachable, stack.ControlPortUnreachable, 0, 2*header.IPv4MinimumSize + header.ICMPv4DstUnreachableMinimumSize + 8}, } r := stack.Route{ - LocalAddress: "\x0a\x00\x00\x01", + LocalAddress: localIpv4Addr, RemoteAddress: "\x0a\x00\x00\xbb", } for _, c := range cases { @@ -256,7 +300,7 @@ func TestIPv4ReceiveControl(t *testing.T) { var views [1]buffer.View o := testObject{t: t} proto := ipv4.NewProtocol() - ep, err := proto.NewEndpoint(1, "\x0a\x00\x00\x01", nil, &o, nil) + ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, &o, nil) if err != nil { t.Fatalf("NewEndpoint failed: %v", err) } @@ -273,7 +317,7 @@ func TestIPv4ReceiveControl(t *testing.T) { TTL: 20, Protocol: uint8(header.ICMPv4ProtocolNumber), SrcAddr: "\x0a\x00\x00\xbb", - DstAddr: "\x0a\x00\x00\x01", + DstAddr: localIpv4Addr, }) // Create the ICMP header. @@ -290,8 +334,8 @@ func TestIPv4ReceiveControl(t *testing.T) { TTL: 20, Protocol: 10, FragmentOffset: c.fragmentOffset, - SrcAddr: "\x0a\x00\x00\x01", - DstAddr: "\x0a\x00\x00\x02", + SrcAddr: localIpv4Addr, + DstAddr: remoteIpv4Addr, }) // Make payload be non-zero. @@ -302,8 +346,8 @@ func TestIPv4ReceiveControl(t *testing.T) { // Give packet to IPv4 endpoint, dispatcher will validate that // it's ok. o.protocol = 10 - o.srcAddr = "\x0a\x00\x00\x02" - o.dstAddr = "\x0a\x00\x00\x01" + o.srcAddr = remoteIpv4Addr + o.dstAddr = localIpv4Addr o.contents = view[dataOffset:] o.typ = c.expectedTyp o.extra = c.expectedExtra @@ -321,7 +365,7 @@ func TestIPv4ReceiveControl(t *testing.T) { func TestIPv4FragmentationReceive(t *testing.T) { o := testObject{t: t, v4: true} proto := ipv4.NewProtocol() - ep, err := proto.NewEndpoint(1, "\x0a\x00\x00\x01", nil, &o, nil) + ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, &o, nil) if err != nil { t.Fatalf("NewEndpoint failed: %v", err) } @@ -337,8 +381,8 @@ func TestIPv4FragmentationReceive(t *testing.T) { Protocol: 10, FragmentOffset: 0, Flags: header.IPv4FlagMoreFragments, - SrcAddr: "\x0a\x00\x00\x02", - DstAddr: "\x0a\x00\x00\x01", + SrcAddr: remoteIpv4Addr, + DstAddr: localIpv4Addr, }) // Make payload be non-zero. for i := header.IPv4MinimumSize; i < totalLen; i++ { @@ -353,8 +397,8 @@ func TestIPv4FragmentationReceive(t *testing.T) { TTL: 20, Protocol: 10, FragmentOffset: 24, - SrcAddr: "\x0a\x00\x00\x02", - DstAddr: "\x0a\x00\x00\x01", + SrcAddr: remoteIpv4Addr, + DstAddr: localIpv4Addr, }) // Make payload be non-zero. for i := header.IPv4MinimumSize; i < totalLen; i++ { @@ -363,13 +407,13 @@ func TestIPv4FragmentationReceive(t *testing.T) { // Give packet to ipv4 endpoint, dispatcher will validate that it's ok. o.protocol = 10 - o.srcAddr = "\x0a\x00\x00\x02" - o.dstAddr = "\x0a\x00\x00\x01" + o.srcAddr = remoteIpv4Addr + o.dstAddr = localIpv4Addr o.contents = append(frag1[header.IPv4MinimumSize:totalLen], frag2[header.IPv4MinimumSize:totalLen]...) - r := stack.Route{ - LocalAddress: o.dstAddr, - RemoteAddress: o.srcAddr, + r, err := buildIPv4Route(localIpv4Addr, remoteIpv4Addr) + if err != nil { + t.Fatalf("could not find route: %v", err) } // Send first segment. @@ -393,7 +437,7 @@ func TestIPv4FragmentationReceive(t *testing.T) { func TestIPv6Send(t *testing.T) { o := testObject{t: t} proto := ipv6.NewProtocol() - ep, err := proto.NewEndpoint(1, "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", nil, nil, &o) + ep, err := proto.NewEndpoint(1, localIpv6Addr, nil, nil, &o) if err != nil { t.Fatalf("NewEndpoint failed: %v", err) } @@ -409,13 +453,13 @@ func TestIPv6Send(t *testing.T) { // Issue the write. o.protocol = 123 - o.srcAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" - o.dstAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" + o.srcAddr = localIpv6Addr + o.dstAddr = remoteIpv6Addr o.contents = payload - r := stack.Route{ - RemoteAddress: o.dstAddr, - LocalAddress: o.srcAddr, + r, err := buildIPv6Route(localIpv6Addr, remoteIpv6Addr) + if err != nil { + t.Fatalf("could not find route: %v", err) } if err := ep.WritePacket(&r, &hdr, payload, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) @@ -425,7 +469,7 @@ func TestIPv6Send(t *testing.T) { func TestIPv6Receive(t *testing.T) { o := testObject{t: t} proto := ipv6.NewProtocol() - ep, err := proto.NewEndpoint(1, "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", nil, &o, nil) + ep, err := proto.NewEndpoint(1, localIpv6Addr, nil, &o, nil) if err != nil { t.Fatalf("NewEndpoint failed: %v", err) } @@ -437,8 +481,8 @@ func TestIPv6Receive(t *testing.T) { PayloadLength: uint16(totalLen - header.IPv6MinimumSize), NextHeader: 10, HopLimit: 20, - SrcAddr: "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", - DstAddr: "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + SrcAddr: remoteIpv6Addr, + DstAddr: localIpv6Addr, }) // Make payload be non-zero. @@ -448,14 +492,15 @@ func TestIPv6Receive(t *testing.T) { // Give packet to ipv6 endpoint, dispatcher will validate that it's ok. o.protocol = 10 - o.srcAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" - o.dstAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + o.srcAddr = remoteIpv6Addr + o.dstAddr = localIpv6Addr o.contents = view[header.IPv6MinimumSize:totalLen] - r := stack.Route{ - LocalAddress: o.dstAddr, - RemoteAddress: o.srcAddr, + r, err := buildIPv6Route(localIpv6Addr, remoteIpv6Addr) + if err != nil { + t.Fatalf("could not find route: %v", err) } + var views [1]buffer.View vv := view.ToVectorisedView(views) ep.HandlePacket(&r, &vv) @@ -491,7 +536,7 @@ func TestIPv6ReceiveControl(t *testing.T) { {"Zero-length packet", 0, nil, header.ICMPv6DstUnreachable, header.ICMPv6PortUnreachable, stack.ControlPortUnreachable, 0, 2*header.IPv6MinimumSize + header.ICMPv6DstUnreachableMinimumSize + 8}, } r := stack.Route{ - LocalAddress: "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + LocalAddress: localIpv6Addr, RemoteAddress: "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa", } for _, c := range cases { @@ -499,7 +544,7 @@ func TestIPv6ReceiveControl(t *testing.T) { var views [1]buffer.View o := testObject{t: t} proto := ipv6.NewProtocol() - ep, err := proto.NewEndpoint(1, "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", nil, &o, nil) + ep, err := proto.NewEndpoint(1, localIpv6Addr, nil, &o, nil) if err != nil { t.Fatalf("NewEndpoint failed: %v", err) } @@ -519,7 +564,7 @@ func TestIPv6ReceiveControl(t *testing.T) { NextHeader: uint8(header.ICMPv6ProtocolNumber), HopLimit: 20, SrcAddr: "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa", - DstAddr: "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + DstAddr: localIpv6Addr, }) // Create the ICMP header. @@ -534,8 +579,8 @@ func TestIPv6ReceiveControl(t *testing.T) { PayloadLength: 100, NextHeader: 10, HopLimit: 20, - SrcAddr: "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", - DstAddr: "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", + SrcAddr: localIpv6Addr, + DstAddr: remoteIpv6Addr, }) // Build the fragmentation header if needed. @@ -558,8 +603,8 @@ func TestIPv6ReceiveControl(t *testing.T) { // Give packet to IPv6 endpoint, dispatcher will validate that // it's ok. o.protocol = 10 - o.srcAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" - o.dstAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + o.srcAddr = remoteIpv6Addr + o.dstAddr = localIpv6Addr o.contents = view[dataOffset:] o.typ = c.expectedTyp o.extra = c.expectedExtra diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index e5db44b5d..e6b1f5128 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -121,6 +121,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload DstAddr: r.RemoteAddress, }) ip.SetChecksum(^ip.CalculateChecksum()) + r.Stats().IP.PacketsSent.Increment() return e.linkEP.WritePacket(r, hdr, payload, ProtocolNumber) } @@ -153,6 +154,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { e.handleICMP(r, vv) return } + r.Stats().IP.PacketsDelivered.Increment() e.dispatcher.DeliverTransportPacket(r, p, vv) } diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 67d8cc670..f48d120c5 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -97,6 +97,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload SrcAddr: tcpip.Address(e.address[:]), DstAddr: r.RemoteAddress, }) + r.Stats().IP.PacketsSent.Increment() return e.linkEP.WritePacket(r, hdr, payload, ProtocolNumber) } @@ -118,6 +119,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { return } + r.Stats().IP.PacketsDelivered.Increment() e.dispatcher.DeliverTransportPacket(r, p, vv) } diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 284732874..c158e2005 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/ilist" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" ) // NIC represents a "network interface card" to which the networking stack is @@ -286,6 +287,10 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin return } + if netProto.Number() == header.IPv4ProtocolNumber || netProto.Number() == header.IPv6ProtocolNumber { + n.stack.stats.IP.PacketsReceived.Increment() + } + if len(vv.First()) < netProto.MinimumPacketSize() { n.stack.stats.MalformedRcvdPackets.Increment() return @@ -330,7 +335,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin } if ref == nil { - n.stack.stats.UnknownNetworkEndpointRcvdPackets.Increment() + n.stack.stats.IP.InvalidAddressesReceived.Increment() return } diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 423f428df..63a20e031 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -70,6 +70,11 @@ func (r *Route) MaxHeaderLength() uint16 { return r.ref.ep.MaxHeaderLength() } +// Stats returns a mutable copy of current stats. +func (r *Route) Stats() tcpip.Stats { + return r.ref.nic.stack.Stats() +} + // PseudoHeaderChecksum forwards the call to the network endpoint's // implementation. func (r *Route) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber) uint16 { @@ -125,7 +130,11 @@ func (r *Route) IsResolutionRequired() bool { // WritePacket writes the packet through the given route. func (r *Route) WritePacket(hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error { - return r.ref.ep.WritePacket(r, hdr, payload, protocol) + err := r.ref.ep.WritePacket(r, hdr, payload, protocol) + if err == tcpip.ErrNoRoute { + r.Stats().IP.OutgoingPacketErrors.Increment() + } + return err } // MTU returns the MTU of the underlying network endpoint. diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index dbaa9c829..862afa693 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -19,6 +19,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" ) type protocolIDs struct { @@ -111,6 +112,10 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto // Fail if we didn't find one. if ep == nil { + // UDP packet could not be delivered to an unknown destination port. + if protocol == header.UDPProtocolNumber { + r.Stats().UDP.UnknownPortErrors.Increment() + } return false } diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index e323aea8c..166d37004 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -31,6 +31,7 @@ package tcpip import ( "errors" "fmt" + "reflect" "strconv" "strings" "sync" @@ -47,48 +48,56 @@ import ( // Note: to support save / restore, it is important that all tcpip errors have // distinct error messages. type Error struct { - string + msg string + + ignoreStats bool } // String implements fmt.Stringer.String. func (e *Error) String() string { - return e.string + return e.msg +} + +// IgnoreStats indicates whether this error type should be included in failure +// counts in tcpip.Stats structs. +func (e *Error) IgnoreStats() bool { + return e.ignoreStats } // Errors that can be returned by the network stack. var ( - ErrUnknownProtocol = &Error{"unknown protocol"} - ErrUnknownNICID = &Error{"unknown nic id"} - ErrUnknownProtocolOption = &Error{"unknown option for protocol"} - ErrDuplicateNICID = &Error{"duplicate nic id"} - ErrDuplicateAddress = &Error{"duplicate address"} - ErrNoRoute = &Error{"no route"} - ErrBadLinkEndpoint = &Error{"bad link layer endpoint"} - ErrAlreadyBound = &Error{"endpoint already bound"} - ErrInvalidEndpointState = &Error{"endpoint is in invalid state"} - ErrAlreadyConnecting = &Error{"endpoint is already connecting"} - ErrAlreadyConnected = &Error{"endpoint is already connected"} - ErrNoPortAvailable = &Error{"no ports are available"} - ErrPortInUse = &Error{"port is in use"} - ErrBadLocalAddress = &Error{"bad local address"} - ErrClosedForSend = &Error{"endpoint is closed for send"} - ErrClosedForReceive = &Error{"endpoint is closed for receive"} - ErrWouldBlock = &Error{"operation would block"} - ErrConnectionRefused = &Error{"connection was refused"} - ErrTimeout = &Error{"operation timed out"} - ErrAborted = &Error{"operation aborted"} - ErrConnectStarted = &Error{"connection attempt started"} - ErrDestinationRequired = &Error{"destination address is required"} - ErrNotSupported = &Error{"operation not supported"} - ErrQueueSizeNotSupported = &Error{"queue size querying not supported"} - ErrNotConnected = &Error{"endpoint not connected"} - ErrConnectionReset = &Error{"connection reset by peer"} - ErrConnectionAborted = &Error{"connection aborted"} - ErrNoSuchFile = &Error{"no such file"} - ErrInvalidOptionValue = &Error{"invalid option value specified"} - ErrNoLinkAddress = &Error{"no remote link address"} - ErrBadAddress = &Error{"bad address"} - ErrNetworkUnreachable = &Error{"network is unreachable"} + ErrUnknownProtocol = &Error{msg: "unknown protocol"} + ErrUnknownNICID = &Error{msg: "unknown nic id"} + ErrUnknownProtocolOption = &Error{msg: "unknown option for protocol"} + ErrDuplicateNICID = &Error{msg: "duplicate nic id"} + ErrDuplicateAddress = &Error{msg: "duplicate address"} + ErrNoRoute = &Error{msg: "no route"} + ErrBadLinkEndpoint = &Error{msg: "bad link layer endpoint"} + ErrAlreadyBound = &Error{msg: "endpoint already bound", ignoreStats: true} + ErrInvalidEndpointState = &Error{msg: "endpoint is in invalid state"} + ErrAlreadyConnecting = &Error{msg: "endpoint is already connecting", ignoreStats: true} + ErrAlreadyConnected = &Error{msg: "endpoint is already connected", ignoreStats: true} + ErrNoPortAvailable = &Error{msg: "no ports are available"} + ErrPortInUse = &Error{msg: "port is in use"} + ErrBadLocalAddress = &Error{msg: "bad local address"} + ErrClosedForSend = &Error{msg: "endpoint is closed for send"} + ErrClosedForReceive = &Error{msg: "endpoint is closed for receive"} + ErrWouldBlock = &Error{msg: "operation would block", ignoreStats: true} + ErrConnectionRefused = &Error{msg: "connection was refused"} + ErrTimeout = &Error{msg: "operation timed out"} + ErrAborted = &Error{msg: "operation aborted"} + ErrConnectStarted = &Error{msg: "connection attempt started", ignoreStats: true} + ErrDestinationRequired = &Error{msg: "destination address is required"} + ErrNotSupported = &Error{msg: "operation not supported"} + ErrQueueSizeNotSupported = &Error{msg: "queue size querying not supported"} + ErrNotConnected = &Error{msg: "endpoint not connected"} + ErrConnectionReset = &Error{msg: "connection reset by peer"} + ErrConnectionAborted = &Error{msg: "connection aborted"} + ErrNoSuchFile = &Error{msg: "no such file"} + ErrInvalidOptionValue = &Error{msg: "invalid option value specified"} + ErrNoLinkAddress = &Error{msg: "no remote link address"} + ErrBadAddress = &Error{msg: "bad address"} + ErrNetworkUnreachable = &Error{msg: "network is unreachable"} ) // Errors related to Subnet @@ -473,7 +482,7 @@ type StatCounter struct { // Increment adds one to the counter. func (s *StatCounter) Increment() { - atomic.AddUint64(&s.count, 1) + s.IncrementBy(1) } // Value returns the current value of the counter. @@ -486,6 +495,82 @@ func (s *StatCounter) IncrementBy(v uint64) { atomic.AddUint64(&s.count, v) } +// IPStats collects IP-specific stats (both v4 and v6). +type IPStats struct { + // PacketsReceived is the total number of IP packets received from the link + // layer in nic.DeliverNetworkPacket. + PacketsReceived *StatCounter + + // InvalidAddressesReceived is the total number of IP packets received + // with an unknown or invalid destination address. + InvalidAddressesReceived *StatCounter + + // PacketsDelivered is the total number of incoming IP packets that + // are successfully delivered to the transport layer via HandlePacket. + PacketsDelivered *StatCounter + + // PacketsSent is the total number of IP packets sent via WritePacket. + PacketsSent *StatCounter + + // OutgoingPacketErrors is the total number of IP packets which failed + // to write to a link-layer endpoint. + OutgoingPacketErrors *StatCounter +} + +// TCPStats collects TCP-specific stats. +type TCPStats struct { + // ActiveConnectionOpenings is the number of connections opened successfully + // via Connect. + ActiveConnectionOpenings *StatCounter + + // PassiveConnectionOpenings is the number of connections opened + // successfully via Listen. + PassiveConnectionOpenings *StatCounter + + // FailedConnectionAttempts is the number of calls to Connect or Listen + // (active and passive openings, respectively) that end in an error. + FailedConnectionAttempts *StatCounter + + // ValidSegmentsReceived is the number of TCP segments received that the + // transport layer successfully parsed. + ValidSegmentsReceived *StatCounter + + // InvalidSegmentsReceived is the number of TCP segments received that + // the transport layer could not parse. + InvalidSegmentsReceived *StatCounter + + // SegmentsSent is the number of TCP segments sent. + SegmentsSent *StatCounter + + // ResetsSent is the number of TCP resets sent. + ResetsSent *StatCounter + + // ResetsReceived is the number of TCP resets received. + ResetsReceived *StatCounter +} + +// UDPStats collects UDP-specific stats. +type UDPStats struct { + // PacketsReceived is the number of UDP datagrams received via + // HandlePacket. + PacketsReceived *StatCounter + + // UnknownPortErrors is the number of incoming UDP datagrams dropped + // because they did not have a known destination port. + UnknownPortErrors *StatCounter + + // ReceiveBufferErrors is the number of incoming UDP datagrams dropped + // due to the receiving buffer being in an invalid state. + ReceiveBufferErrors *StatCounter + + // MalformedPacketsReceived is the number of incoming UDP datagrams + // dropped due to the UDP header being in a malformed state. + MalformedPacketsReceived *StatCounter + + // PacketsSent is the number of UDP datagrams sent via sendUDP. + PacketsSent *StatCounter +} + // Stats holds statistics about the networking stack. // // All fields are optional. @@ -494,33 +579,42 @@ type Stats struct { // stack that were for an unknown or unsupported protocol. UnknownProtocolRcvdPackets *StatCounter - // UnknownNetworkEndpointRcvdPackets is the number of packets received - // by the stack that were for a supported network protocol, but whose - // destination address didn't having a matching endpoint. - UnknownNetworkEndpointRcvdPackets *StatCounter - // MalformedRcvPackets is the number of packets received by the stack // that were deemed malformed. MalformedRcvdPackets *StatCounter // DroppedPackets is the number of packets dropped due to full queues. DroppedPackets *StatCounter + + // IP breaks out IP-specific stats (both v4 and v6). + IP IPStats + + // TCP breaks out TCP-specific stats. + TCP TCPStats + + // UDP breaks out UDP-specific stats. + UDP UDPStats +} + +func fillIn(v reflect.Value) { + for i := 0; i < v.NumField(); i++ { + v := v.Field(i) + switch v.Kind() { + case reflect.Ptr: + if s, ok := v.Addr().Interface().(**StatCounter); ok { + if *s == nil { + *s = &StatCounter{} + } + } + case reflect.Struct: + fillIn(v) + } + } } // FillIn returns a copy of s with nil fields initialized to new StatCounters. func (s Stats) FillIn() Stats { - if s.UnknownProtocolRcvdPackets == nil { - s.UnknownProtocolRcvdPackets = &StatCounter{} - } - if s.UnknownNetworkEndpointRcvdPackets == nil { - s.UnknownNetworkEndpointRcvdPackets = &StatCounter{} - } - if s.MalformedRcvdPackets == nil { - s.MalformedRcvdPackets = &StatCounter{} - } - if s.DroppedPackets == nil { - s.DroppedPackets = &StatCounter{} - } + fillIn(reflect.ValueOf(&s).Elem()) return s } diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 58d7942f3..14282d399 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -604,6 +604,11 @@ func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffe tcp.SetChecksum(^tcp.CalculateChecksum(xsum, length)) } + r.Stats().TCP.SegmentsSent.Increment() + if (flags & flagRst) != 0 { + r.Stats().TCP.ResetsSent.Increment() + } + return r.WritePacket(&hdr, data, ProtocolNumber) } @@ -641,6 +646,11 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.View, fla tcp.SetChecksum(^tcp.CalculateChecksum(xsum, length)) } + r.Stats().TCP.SegmentsSent.Increment() + if (flags & flagRst) != 0 { + r.Stats().TCP.ResetsSent.Increment() + } + return r.WritePacket(&hdr, data, ProtocolNumber) } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index bdcba39c6..cbbbbc084 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -829,9 +829,14 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { // created (so no new handshaking is done); for stack-accepted connections not // yet accepted by the app, they are restored without running the main goroutine // here. -func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) *tcpip.Error { +func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) (err *tcpip.Error) { e.mu.Lock() defer e.mu.Unlock() + defer func() { + if err != nil && !err.IgnoreStats() { + e.stack.Stats().TCP.FailedConnectionAttempts.Increment() + } + }() connectingAddr := addr.Addr @@ -960,6 +965,7 @@ func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) *tc if run { e.workerRunning = true + e.stack.Stats().TCP.ActiveConnectionOpenings.Increment() go e.protocolMainLoop(handshake) // S/R-SAFE: will be drained before save. } @@ -1032,9 +1038,14 @@ func (e *endpoint) Shutdown(flags tcpip.ShutdownFlags) *tcpip.Error { // Listen puts the endpoint in "listen" mode, which allows it to accept // new connections. -func (e *endpoint) Listen(backlog int) *tcpip.Error { +func (e *endpoint) Listen(backlog int) (err *tcpip.Error) { e.mu.Lock() defer e.mu.Unlock() + defer func() { + if err != nil && !err.IgnoreStats() { + e.stack.Stats().TCP.FailedConnectionAttempts.Increment() + } + }() // Allow the backlog to be adjusted if the endpoint is not shutting down. // When the endpoint shuts down, it sets workerCleanup to true, and from @@ -1075,6 +1086,7 @@ func (e *endpoint) Listen(backlog int) *tcpip.Error { } e.workerRunning = true + e.stack.Stats().TCP.PassiveConnectionOpenings.Increment() go e.protocolListenLoop( // S/R-SAFE: drained on save. seqnum.Size(e.receiveBufferAvailable())) @@ -1226,10 +1238,16 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv s := newSegment(r, id, vv) if !s.parse() { e.stack.Stats().MalformedRcvdPackets.Increment() + e.stack.Stats().TCP.InvalidSegmentsReceived.Increment() s.decRef() return } + e.stack.Stats().TCP.ValidSegmentsReceived.Increment() + if (s.flags & flagRst) != 0 { + e.stack.Stats().TCP.ResetsReceived.Increment() + } + // Send packet to worker goroutine. if e.segmentQueue.enqueue(s) { e.newSegmentWaker.Assert() diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index 74318c012..71d70a597 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -62,7 +62,7 @@ func TestGiveUpConnect(t *testing.T) { defer wq.EventUnregister(&waitEntry) if err := ep.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted { - t.Fatalf("Unexpected return value from Connect: %v", err) + t.Fatalf("got ep.Connect(...) = %v, want = %v", err, tcpip.ErrConnectStarted) } // Close the connection, wait for completion. @@ -75,6 +75,187 @@ func TestGiveUpConnect(t *testing.T) { } } +func TestConnectIncrementActiveConnection(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + + stats := c.Stack().Stats() + want := stats.TCP.ActiveConnectionOpenings.Value() + 1 + + c.CreateConnected(789, 30000, nil) + if got := stats.TCP.ActiveConnectionOpenings.Value(); got != want { + t.Errorf("got stats.TCP.ActtiveConnectionOpenings.Value() = %v, want = %v", got, want) + } +} + +func TestConnectDoesNotIncrementFailedConnectionAttempts(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + + stats := c.Stack().Stats() + want := stats.TCP.FailedConnectionAttempts.Value() + + c.CreateConnected(789, 30000, nil) + if got := stats.TCP.FailedConnectionAttempts.Value(); got != want { + t.Errorf("got stats.TCP.FailedConnectionOpenings.Value() = %v, want = %v", got, want) + } +} + +func TestActiveFailedConnectionAttemptIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + + stats := c.Stack().Stats() + ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + c.EP = ep + want := stats.TCP.FailedConnectionAttempts.Value() + 1 + + if err := c.EP.Connect(tcpip.FullAddress{NIC: 2, Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrNoRoute { + t.Errorf("got c.EP.Connect(...) = %v, want = %v", err, tcpip.ErrNoRoute) + } + + if got := stats.TCP.FailedConnectionAttempts.Value(); got != want { + t.Errorf("got stats.TCP.FailedConnectionAttempts.Value() = %v, want = %v", got, want) + } +} + +func TestPassiveConnectionAttemptIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + + stats := c.Stack().Stats() + want := stats.TCP.PassiveConnectionOpenings.Value() + 1 + ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + + if err := ep.Bind(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}, nil); err != nil { + t.Fatalf("Bind failed: %v", err) + } + if err := ep.Listen(1); err != nil { + t.Fatalf("Listen failed: %v", err) + } + + if got := stats.TCP.PassiveConnectionOpenings.Value(); got != want { + t.Errorf("got stats.TCP.PassiveConnectionOpenings.Value() = %v, want = %v", got, want) + } +} + +func TestPassiveFailedConnectionAttemptIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + + stats := c.Stack().Stats() + ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + c.EP = ep + want := stats.TCP.FailedConnectionAttempts.Value() + 1 + + if err := ep.Listen(1); err != tcpip.ErrInvalidEndpointState { + t.Errorf("got ep.Listen(1) = %v, want = %v", err, tcpip.ErrInvalidEndpointState) + } + + if got := stats.TCP.FailedConnectionAttempts.Value(); got != want { + t.Errorf("got stats.TCP.FailedConnectionAttempts.Value() = %v, want = %v", got, want) + } +} + +func TestTCPSegmentsSentIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + + stats := c.Stack().Stats() + // SYN and ACK + want := stats.TCP.SegmentsSent.Value() + 2 + c.CreateConnected(789, 30000, nil) + + if got := stats.TCP.SegmentsSent.Value(); got != want { + t.Errorf("got stats.TCP.SegmentsSent.Value() = %v, want = %v", got, want) + } +} + +func TestTCPResetsSentIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + stats := c.Stack().Stats() + wq := &waiter.Queue{} + ep, err := c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + want := stats.TCP.SegmentsSent.Value() + 1 + + if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + t.Fatalf("Bind failed: %v", err) + } + + if err := ep.Listen(10); err != nil { + t.Fatalf("Listen failed: %v", err) + } + + // Send a SYN request. + iss := seqnum.Value(789) + c.SendPacket(nil, &context.Headers{ + SrcPort: context.TestPort, + DstPort: context.StackPort, + Flags: header.TCPFlagSyn, + SeqNum: iss, + }) + + // Receive the SYN-ACK reply. + b := c.GetPacket() + tcp := header.TCP(header.IPv4(b).Payload()) + c.IRS = seqnum.Value(tcp.SequenceNumber()) + + ackHeaders := &context.Headers{ + SrcPort: context.TestPort, + DstPort: context.StackPort, + Flags: header.TCPFlagAck, + SeqNum: iss + 1, + // If the AckNum is not the increment of the last sequence number, a RST + // segment is sent back in response. + AckNum: c.IRS + 2, + } + + // Send ACK. + c.SendPacket(nil, ackHeaders) + + c.GetPacket() + if got := stats.TCP.ResetsSent.Value(); got != want { + t.Errorf("got stats.TCP.ResetsSent.Value() = %v, want = %v", got, want) + } +} + +func TestTCPResetsReceivedIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + + stats := c.Stack().Stats() + want := stats.TCP.ResetsReceived.Value() + 1 + ackNum := seqnum.Value(789) + rcvWnd := seqnum.Size(30000) + c.CreateConnected(ackNum, rcvWnd, nil) + + c.SendPacket(nil, &context.Headers{ + SrcPort: context.TestPort, + DstPort: c.Port, + SeqNum: c.IRS.Add(2), + AckNum: ackNum.Add(2), + RcvWnd: rcvWnd, + Flags: header.TCPFlagRst, + }) + + if got := stats.TCP.ResetsReceived.Value(); got != want { + t.Errorf("got stats.TCP.ResetsReceived.Value() = %v, want = %v", got, want) + } +} + func TestActiveHandshake(t *testing.T) { c := context.New(t, defaultMTU) defer c.Cleanup() @@ -159,7 +340,7 @@ func TestSimpleReceive(t *testing.T) { defer c.WQ.EventUnregister(&we) if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock) } data := []byte{1, 2, 3} @@ -182,11 +363,11 @@ func TestSimpleReceive(t *testing.T) { // Receive data. v, _, err := c.EP.Read(nil) if err != nil { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("Read failed: %v", err) } - if bytes.Compare(data, v) != 0 { - t.Fatalf("Data is different: expected %v, got %v", data, v) + if !bytes.Equal(data, v) { + t.Fatalf("got data = %v, want = %v", v, data) } // Check that ACK is received. @@ -211,7 +392,7 @@ func TestOutOfOrderReceive(t *testing.T) { defer c.WQ.EventUnregister(&we) if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock) } // Send second half of data first, with seqnum 3 ahead of expected. @@ -238,7 +419,7 @@ func TestOutOfOrderReceive(t *testing.T) { // Wait 200ms and check that no data has been received. time.Sleep(200 * time.Millisecond) if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock) } // Send the first 3 bytes now. @@ -265,15 +446,15 @@ func TestOutOfOrderReceive(t *testing.T) { } continue } - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("Read failed: %v", err) } read = append(read, v...) } // Check that we received the data in proper order. - if bytes.Compare(data, read) != 0 { - t.Fatalf("Data is different: expected %v, got %v", data, read) + if !bytes.Equal(data, read) { + t.Fatalf("got data = %v, want = %v", read, data) } // Check that the whole data is acknowledged. @@ -296,7 +477,7 @@ func TestOutOfOrderFlood(t *testing.T) { c.CreateConnected(789, 30000, &opt) if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock) } // Send 100 packets before the actual one that is expected. @@ -373,7 +554,7 @@ func TestRstOnCloseWithUnreadData(t *testing.T) { defer c.WQ.EventUnregister(&we) if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock) } data := []byte{1, 2, 3} @@ -438,7 +619,7 @@ func TestRstOnCloseWithUnreadDataFinConvertRst(t *testing.T) { defer c.WQ.EventUnregister(&we) if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock) } data := []byte{1, 2, 3} @@ -517,7 +698,7 @@ func TestFullWindowReceive(t *testing.T) { _, _, err := c.EP.Read(nil) if err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("Read failed: %v", err) } // Fill up the window. @@ -552,11 +733,11 @@ func TestFullWindowReceive(t *testing.T) { // Receive data and check it. v, _, err := c.EP.Read(nil) if err != nil { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("Read failed: %v", err) } - if bytes.Compare(data, v) != 0 { - t.Fatalf("Data is different: expected %v, got %v", data, v) + if !bytes.Equal(data, v) { + t.Fatalf("got data = %v, want = %v", v, data) } // Check that we get an ACK for the newly non-zero window. @@ -588,9 +769,8 @@ func TestNoWindowShrinking(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventIn) defer c.WQ.EventUnregister(&we) - _, _, err := c.EP.Read(nil) - if err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock) } // Send 3 bytes, check that the peer acknowledges them. @@ -654,14 +834,14 @@ func TestNoWindowShrinking(t *testing.T) { for len(read) < len(data) { v, _, err := c.EP.Read(nil) if err != nil { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("Read failed: %v", err) } read = append(read, v...) } - if bytes.Compare(data, read) != 0 { - t.Fatalf("Data is different: expected %v, got %v", data, read) + if !bytes.Equal(data, read) { + t.Fatalf("got data = %v, want = %v", read, data) } // Check that we get an ACK for the newly non-zero window, which is the @@ -688,7 +868,7 @@ func TestSimpleSend(t *testing.T) { copy(view, data) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Check that data is received. @@ -703,8 +883,8 @@ func TestSimpleSend(t *testing.T) { ), ) - if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; bytes.Compare(data, p) != 0 { - t.Fatalf("Data is different: expected %v, got %v", data, p) + if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(data, p) { + t.Fatalf("got data = %v, want = %v", p, data) } // Acknowledge the data. @@ -730,7 +910,7 @@ func TestZeroWindowSend(t *testing.T) { _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}) if err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Since the window is currently zero, check that no packet is received. @@ -758,8 +938,8 @@ func TestZeroWindowSend(t *testing.T) { ), ) - if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; bytes.Compare(data, p) != 0 { - t.Fatalf("Data is different: expected %v, got %v", data, p) + if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; !bytes.Equal(data, p) { + t.Fatalf("got data = %v, want = %v", p, data) } // Acknowledge the data. @@ -790,7 +970,7 @@ func TestScaledWindowConnect(t *testing.T) { copy(view, data) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Check that data is received, and that advertised window is 0xbfff, @@ -823,7 +1003,7 @@ func TestNonScaledWindowConnect(t *testing.T) { copy(view, data) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Check that data is received, and that advertised window is 0xffff, @@ -896,7 +1076,7 @@ func TestScaledWindowAccept(t *testing.T) { copy(view, data) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Check that data is received, and that advertised window is 0xbfff, @@ -969,7 +1149,7 @@ func TestNonScaledWindowAccept(t *testing.T) { copy(view, data) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Check that data is received, and that advertised window is 0xffff, @@ -1057,7 +1237,7 @@ func TestZeroScaledWindowReceive(t *testing.T) { // Read some data. An ack should be sent in response to that. v, _, err := c.EP.Read(nil) if err != nil { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("Read failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1084,7 +1264,7 @@ func testBrokenUpWrite(t *testing.T, c *context.Context, maxPayload int) { copy(view, data) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Check that data is received in chunks. @@ -1105,8 +1285,8 @@ func testBrokenUpWrite(t *testing.T, c *context.Context, maxPayload int) { ) pdata := data[bytesReceived : bytesReceived+payloadLen] - if p := tcp.Payload(); bytes.Compare(pdata, p) != 0 { - t.Fatalf("Data is different: expected %v, got %v", pdata, p) + if p := tcp.Payload(); !bytes.Equal(pdata, p) { + t.Fatalf("got data = %v, want = %v", p, pdata) } bytesReceived += payloadLen var options []byte @@ -1325,9 +1505,8 @@ func TestSynOptionsOnActiveConnect(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventOut) defer c.WQ.EventUnregister(&we) - err = c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}) - if err != tcpip.ErrConnectStarted { - t.Fatalf("Unexpected return value from Connect: %v", err) + if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted { + t.Fatalf("got c.EP.Connect(...) = %v, want = %v", err, tcpip.ErrConnectStarted) } // Receive SYN packet. @@ -1380,9 +1559,8 @@ func TestSynOptionsOnActiveConnect(t *testing.T) { // Wait for connection to be established. select { case <-ch: - err = c.EP.GetSockOpt(tcpip.ErrorOption{}) - if err != nil { - t.Fatalf("Unexpected error when connecting: %v", err) + if err := c.EP.GetSockOpt(tcpip.ErrorOption{}); err != nil { + t.Fatalf("GetSockOpt failed: %v", err) } case <-time.After(1 * time.Second): t.Fatalf("Timed out waiting for connection") @@ -1439,8 +1617,6 @@ func TestReceiveOnResetConnection(t *testing.T) { loop: for { switch _, _, err := c.EP.Read(nil); err { - case nil: - t.Fatalf("Unexpected success.") case tcpip.ErrWouldBlock: select { case <-ch: @@ -1450,7 +1626,7 @@ loop: case tcpip.ErrConnectionReset: break loop default: - t.Fatalf("Unexpected error: want %v, got %v", tcpip.ErrConnectionReset, err) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrConnectionReset) } } } @@ -1475,9 +1651,8 @@ func TestSendOnResetConnection(t *testing.T) { // Try to write. view := buffer.NewView(10) - _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}) - if err != tcpip.ErrConnectionReset { - t.Fatalf("Unexpected error from Write: want %v, got %v", tcpip.ErrConnectionReset, err) + if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != tcpip.ErrConnectionReset { + t.Fatalf("got c.EP.Write(...) = %v, want = %v", err, tcpip.ErrConnectionReset) } } @@ -1489,7 +1664,7 @@ func TestFinImmediately(t *testing.T) { // Shutdown immediately, check that we get a FIN. if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil { - t.Fatalf("Unexpected error from Shutdown: %v", err) + t.Fatalf("Shutdown failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1532,7 +1707,7 @@ func TestFinRetransmit(t *testing.T) { // Shutdown immediately, check that we get a FIN. if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil { - t.Fatalf("Unexpected error from Shutdown: %v", err) + t.Fatalf("Shutdown failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1587,7 +1762,7 @@ func TestFinWithNoPendingData(t *testing.T) { // Write something out, and have it acknowledged. view := buffer.NewView(10) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } next := uint32(c.IRS) + 1 @@ -1613,7 +1788,7 @@ func TestFinWithNoPendingData(t *testing.T) { // Shutdown, check that we get a FIN. if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil { - t.Fatalf("Unexpected error from Shutdown: %v", err) + t.Fatalf("Shutdown failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1660,7 +1835,7 @@ func TestFinWithPendingDataCwndFull(t *testing.T) { view := buffer.NewView(10) for i := tcp.InitialCwnd; i > 0; i-- { if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } } @@ -1682,7 +1857,7 @@ func TestFinWithPendingDataCwndFull(t *testing.T) { // because the congestion window doesn't allow it. Wait until a // retransmit is received. if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil { - t.Fatalf("Unexpected error from Shutdown: %v", err) + t.Fatalf("Shutdown failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1746,7 +1921,7 @@ func TestFinWithPendingData(t *testing.T) { // Write something out, and acknowledge it to get cwnd to 2. view := buffer.NewView(10) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } next := uint32(c.IRS) + 1 @@ -1772,7 +1947,7 @@ func TestFinWithPendingData(t *testing.T) { // Write new data, but don't acknowledge it. if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1788,7 +1963,7 @@ func TestFinWithPendingData(t *testing.T) { // Shutdown the connection, check that we do get a FIN. if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil { - t.Fatalf("Unexpected error from Shutdown: %v", err) + t.Fatalf("Shutdown failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1833,7 +2008,7 @@ func TestFinWithPartialAck(t *testing.T) { // FIN from the test side. view := buffer.NewView(10) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } next := uint32(c.IRS) + 1 @@ -1870,7 +2045,7 @@ func TestFinWithPartialAck(t *testing.T) { // Write new data, but don't acknowledge it. if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1886,7 +2061,7 @@ func TestFinWithPartialAck(t *testing.T) { // Shutdown the connection, check that we do get a FIN. if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil { - t.Fatalf("Unexpected error from Shutdown: %v", err) + t.Fatalf("Shutdown failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -1940,7 +2115,7 @@ func TestExponentialIncreaseDuringSlowStart(t *testing.T) { // Write all the data in one shot. Packets will only be written at the // MTU size though. if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } expected := tcp.InitialCwnd @@ -1982,7 +2157,7 @@ func TestCongestionAvoidance(t *testing.T) { // Write all the data in one shot. Packets will only be written at the // MTU size though. if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Do slow start for a few iterations. @@ -2087,7 +2262,7 @@ func TestCubicCongestionAvoidance(t *testing.T) { // Write all the data in one shot. Packets will only be written at the // MTU size though. if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Do slow start for a few iterations. @@ -2157,18 +2332,18 @@ func TestCubicCongestionAvoidance(t *testing.T) { // If our estimate was correct there should be no more pending packets. // We attempt to read a packet a few times with a short sleep in between // to ensure that we don't see the sender send any unexpected packets. - packetsUnexpected := 0 + unexpectedPackets := 0 for { gotPacket := c.ReceiveNonBlockingAndCheckPacket(data, bytesRead, maxPayload) if !gotPacket { break } bytesRead += maxPayload - packetsUnexpected++ + unexpectedPackets++ time.Sleep(1 * time.Millisecond) } - if packetsUnexpected != 0 { - t.Fatalf("received %d unexpected packets for iteration %d", packetsUnexpected, i) + if unexpectedPackets != 0 { + t.Fatalf("received %d unexpected packets for iteration %d", unexpectedPackets, i) } // Check we don't receive any more packets on this iteration. // The timeout can't be too high or we'll trigger a timeout. @@ -2195,7 +2370,7 @@ func TestFastRecovery(t *testing.T) { // Write all the data in one shot. Packets will only be written at the // MTU size though. if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Do slow start for a few iterations. @@ -2327,11 +2502,11 @@ func TestRetransmit(t *testing.T) { // MTU size though. half := data[:len(data)/2] if _, err := c.EP.Write(tcpip.SlicePayload(half), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } half = data[len(data)/2:] if _, err := c.EP.Write(tcpip.SlicePayload(half), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Do slow start for a few iterations. @@ -2429,7 +2604,7 @@ func scaledSendWindow(t *testing.T, scale uint8) { // Send some data. Check that it's capped by the window size. view := buffer.NewView(65535) if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { - t.Fatalf("Unexpected error from Write: %v", err) + t.Fatalf("Write failed: %v", err) } // Check that only data that fits in the scaled window is sent. @@ -2458,6 +2633,52 @@ func TestScaledSendWindow(t *testing.T) { } } +func TestReceivedValidSegmentCountIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + c.CreateConnected(789, 30000, nil) + stats := c.Stack().Stats() + want := stats.TCP.ValidSegmentsReceived.Value() + 1 + + c.SendPacket(nil, &context.Headers{ + SrcPort: context.TestPort, + DstPort: c.Port, + Flags: header.TCPFlagAck, + SeqNum: seqnum.Value(790), + AckNum: c.IRS.Add(1), + RcvWnd: 30000, + }) + + if got := stats.TCP.ValidSegmentsReceived.Value(); got != want { + t.Errorf("got stats.TCP.ValidSegmentsReceived.Value() = %v, want = %v", got, want) + } +} + +func TestReceivedInvalidSegmentCountIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + c.CreateConnected(789, 30000, nil) + stats := c.Stack().Stats() + want := stats.TCP.InvalidSegmentsReceived.Value() + 1 + vv := c.BuildSegment(nil, &context.Headers{ + SrcPort: context.TestPort, + DstPort: c.Port, + Flags: header.TCPFlagAck, + SeqNum: seqnum.Value(790), + AckNum: c.IRS.Add(1), + RcvWnd: 30000, + }) + tcpbuf := vv.ByteSlice()[0][header.IPv4MinimumSize:] + // 12 is the TCP header data offset. + tcpbuf[12] = ((header.TCPMinimumSize - 1) / 4) << 4 + + c.SendSegment(&vv) + + if got := stats.TCP.InvalidSegmentsReceived.Value(); got != want { + t.Errorf("got stats.TCP.InvalidSegmentsReceived.Value() = %v, want = %v", got, want) + } +} + func TestReceivedSegmentQueuing(t *testing.T) { // This test sends 200 segments containing a few bytes each to an // endpoint and checks that they're all received and acknowledged by @@ -2519,12 +2740,12 @@ func TestReadAfterClosedState(t *testing.T) { defer c.WQ.EventUnregister(&we) if _, _, err := c.EP.Read(nil); err != tcpip.ErrWouldBlock { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrWouldBlock) } // Shutdown immediately for write, check that we get a FIN. if err := c.EP.Shutdown(tcpip.ShutdownWrite); err != nil { - t.Fatalf("Unexpected error from Shutdown: %v", err) + t.Fatalf("Shutdown failed: %v", err) } checker.IPv4(t, c.GetPacket(), @@ -2572,32 +2793,32 @@ func TestReadAfterClosedState(t *testing.T) { peekBuf := make([]byte, 10) n, _, err := c.EP.Peek([][]byte{peekBuf}) if err != nil { - t.Fatalf("Unexpected error from Peek: %v", err) + t.Fatalf("Peek failed: %v", err) } peekBuf = peekBuf[:n] - if bytes.Compare(data, peekBuf) != 0 { - t.Fatalf("Data is different: expected %v, got %v", data, peekBuf) + if !bytes.Equal(data, peekBuf) { + t.Fatalf("got data = %v, want = %v", peekBuf, data) } // Receive data. v, _, err := c.EP.Read(nil) if err != nil { - t.Fatalf("Unexpected error from Read: %v", err) + t.Fatalf("Read failed: %v", err) } - if bytes.Compare(data, v) != 0 { - t.Fatalf("Data is different: expected %v, got %v", data, v) + if !bytes.Equal(data, v) { + t.Fatalf("got data = %v, want = %v", v, data) } // Now that we drained the queue, check that functions fail with the // right error code. if _, _, err := c.EP.Read(nil); err != tcpip.ErrClosedForReceive { - t.Fatalf("Unexpected return from Read: got %v, want %v", err, tcpip.ErrClosedForReceive) + t.Fatalf("got c.EP.Read(nil) = %v, want = %v", err, tcpip.ErrClosedForReceive) } if _, _, err := c.EP.Peek([][]byte{peekBuf}); err != tcpip.ErrClosedForReceive { - t.Fatalf("Unexpected return from Peek: got %v, want %v", err, tcpip.ErrClosedForReceive) + t.Fatalf("got c.EP.Peek(...) = %v, want = %v", err, tcpip.ErrClosedForReceive) } } @@ -2635,9 +2856,8 @@ func TestReusePort(t *testing.T) { if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { t.Fatalf("Bind failed: %v", err) } - err = c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}) - if err != tcpip.ErrConnectStarted { - t.Fatalf("Unexpected return value from Connect: %v", err) + if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted { + t.Fatalf("got c.EP.Connect(...) = %v, want = %v", err, tcpip.ErrConnectStarted) } c.EP.Close() @@ -2658,8 +2878,7 @@ func TestReusePort(t *testing.T) { if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { t.Fatalf("Bind failed: %v", err) } - err = c.EP.Listen(10) - if err != nil { + if err := c.EP.Listen(10); err != nil { t.Fatalf("Listen failed: %v", err) } c.EP.Close() @@ -2671,8 +2890,7 @@ func TestReusePort(t *testing.T) { if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { t.Fatalf("Bind failed: %v", err) } - err = c.EP.Listen(10) - if err != nil { + if err := c.EP.Listen(10); err != nil { t.Fatalf("Listen failed: %v", err) } } @@ -2686,7 +2904,7 @@ func checkRecvBufferSize(t *testing.T, ep tcpip.Endpoint, v int) { } if int(s) != v { - t.Fatalf("Bad receive buffer size: want=%v, got=%v", v, s) + t.Fatalf("got receive buffer size = %v, want = %v", s, v) } } @@ -2699,7 +2917,7 @@ func checkSendBufferSize(t *testing.T, ep tcpip.Endpoint, v int) { } if int(s) != v { - t.Fatalf("Bad send buffer size: want=%v, got=%v", v, s) + t.Fatalf("got send buffer size = %v, want = %v", s, v) } } @@ -2840,14 +3058,12 @@ func TestSelfConnect(t *testing.T) { wq.EventRegister(&waitEntry, waiter.EventOut) defer wq.EventUnregister(&waitEntry) - err = ep.Connect(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}) - if err != tcpip.ErrConnectStarted { - t.Fatalf("Unexpected return value from Connect: %v", err) + if err := ep.Connect(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}); err != tcpip.ErrConnectStarted { + t.Fatalf("got ep.Connect(...) = %v, want = %v", err, tcpip.ErrConnectStarted) } <-notifyCh - err = ep.GetSockOpt(tcpip.ErrorOption{}) - if err != nil { + if err := ep.GetSockOpt(tcpip.ErrorOption{}); err != nil { t.Fatalf("Connect failed: %v", err) } @@ -2855,7 +3071,7 @@ func TestSelfConnect(t *testing.T) { data := []byte{1, 2, 3} view := buffer.NewView(len(data)) copy(view, data) - if _, err = ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, err := ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2874,8 +3090,8 @@ func TestSelfConnect(t *testing.T) { } } - if bytes.Compare(data, rd) != 0 { - t.Fatalf("Data is different: want=%v, got=%v", data, rd) + if !bytes.Equal(data, rd) { + t.Fatalf("got data = %v, want = %v", rd, data) } } @@ -2949,16 +3165,16 @@ func TestTCPEndpointProbe(t *testing.T) { // We don't do an extensive validation of every field but a // basic sanity test. if got, want := state.ID.LocalAddress, tcpip.Address(context.StackAddr); got != want { - t.Fatalf("unexpected LocalAddress got: %q, want: %q", got, want) + t.Fatalf("got LocalAddress: %q, want: %q", got, want) } if got, want := state.ID.LocalPort, c.Port; got != want { - t.Fatalf("unexpected LocalPort got: %d, want: %d", got, want) + t.Fatalf("got LocalPort: %d, want: %d", got, want) } if got, want := state.ID.RemoteAddress, tcpip.Address(context.TestAddr); got != want { - t.Fatalf("unexpected RemoteAddress got: %q, want: %q", got, want) + t.Fatalf("got RemoteAddress: %q, want: %q", got, want) } if got, want := state.ID.RemotePort, uint16(context.TestPort); got != want { - t.Fatalf("unexpected RemotePort got: %d, want: %d", got, want) + t.Fatalf("got RemotePort: %d, want: %d", got, want) } invoked <- struct{}{} @@ -3008,7 +3224,7 @@ func TestSetCongestionControl(t *testing.T) { t.Fatalf("s.TransportProtocolOption(%v, %v) = %v", tcp.ProtocolNumber, &cc, err) } if got, want := cc, tc.cc; got != want { - t.Fatalf("unexpected value for congestion control got: %v, want: %v", got, want) + t.Fatalf("got congestion control: %v, want: %v", got, want) } }) } @@ -3026,7 +3242,7 @@ func TestAvailableCongestionControl(t *testing.T) { t.Fatalf("s.TransportProtocolOption(%v, %v) = %v", tcp.ProtocolNumber, &aCC, err) } if got, want := aCC, tcp.AvailableCongestionControlOption("reno cubic"); got != want { - t.Fatalf("unexpected value for AvailableCongestionControlOption: got: %v, want: %v", got, want) + t.Fatalf("got tcp.AvailableCongestionControlOption: %v, want: %v", got, want) } } @@ -3048,7 +3264,7 @@ func TestSetAvailableCongestionControl(t *testing.T) { t.Fatalf("s.TransportProtocolOption(%v, %v) = %v", tcp.ProtocolNumber, &cc, err) } if got, want := cc, tcp.AvailableCongestionControlOption("reno cubic"); got != want { - t.Fatalf("unexpected value for available congestion control got: %v, want: %v", got, want) + t.Fatalf("got tcp.AvailableCongestionControlOption: %v, want: %v", got, want) } } diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index a529d9e72..894ead507 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -267,8 +267,7 @@ func TestSegmentDropWhenTimestampMissing(t *testing.T) { c.WQ.EventRegister(&we, waiter.EventIn) defer c.WQ.EventUnregister(&we) - stk := c.Stack() - droppedPacketsStat := stk.Stats().DroppedPackets + droppedPacketsStat := c.Stack().Stats().DroppedPackets droppedPackets := droppedPacketsStat.Value() data := []byte{1, 2, 3} // Save the sequence number as we will reset it later down diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 6b5786140..c46af4b8b 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -295,9 +295,8 @@ func (c *Context) SendICMPPacket(typ header.ICMPv4Type, code uint8, p1, p2 []byt c.linkEP.Inject(ipv4.ProtocolNumber, &vv) } -// SendPacket builds and sends a TCP segment(with the provided payload & TCP -// headers) in an IPv4 packet via the link layer endpoint. -func (c *Context) SendPacket(payload []byte, h *Headers) { +// BuildSegment builds a TCP segment based on the given Headers and payload. +func (c *Context) BuildSegment(payload []byte, h *Headers) buffer.VectorisedView { // Allocate a buffer for data and headers. buf := buffer.NewView(header.TCPMinimumSize + header.IPv4MinimumSize + len(h.TCPOpts) + len(payload)) copy(buf[len(buf)-len(payload):], payload) @@ -340,6 +339,20 @@ func (c *Context) SendPacket(payload []byte, h *Headers) { // Inject packet. var views [1]buffer.View vv := buf.ToVectorisedView(views) + + return vv +} + +// SendSegment sends a TCP segment that has already been built and written to a +// buffer.VectorisedView. +func (c *Context) SendSegment(s *buffer.VectorisedView) { + c.linkEP.Inject(ipv4.ProtocolNumber, s) +} + +// SendPacket builds and sends a TCP segment(with the provided payload & TCP +// headers) in an IPv4 packet via the link layer endpoint. +func (c *Context) SendPacket(payload []byte, h *Headers) { + vv := c.BuildSegment(payload, h) c.linkEP.Inject(ipv4.ProtocolNumber, &vv) } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index b2d7f9779..6a12c2f08 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -327,7 +327,10 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc if err != nil { return 0, err } - sendUDP(route, v, e.id.LocalPort, dstPort) + + if err := sendUDP(route, v, e.id.LocalPort, dstPort); err != nil { + return 0, err + } return uintptr(len(v)), nil } @@ -447,6 +450,9 @@ func sendUDP(r *stack.Route, data buffer.View, localPort, remotePort uint16) *tc udp.SetChecksum(^udp.CalculateChecksum(xsum, length)) } + // Track count of packets sent. + r.Stats().UDP.PacketsSent.Increment() + return r.WritePacket(&hdr, data, ProtocolNumber) } @@ -758,15 +764,18 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv hdr := header.UDP(vv.First()) if int(hdr.Length()) > vv.Size() { // Malformed packet. + e.stack.Stats().UDP.MalformedPacketsReceived.Increment() return } vv.TrimFront(header.UDPMinimumSize) e.rcvMu.Lock() + e.stack.Stats().UDP.PacketsReceived.Increment() // Drop the packet if our buffer is currently full. if !e.rcvReady || e.rcvClosed || e.rcvBufSize >= e.rcvBufSizeMax { + e.stack.Stats().UDP.ReceiveBufferErrors.Increment() e.rcvMu.Unlock() return } diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 7203d7705..c1c099900 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -661,3 +661,41 @@ func TestV4WriteOnConnected(t *testing.T) { c.t.Fatalf("Bad payload: got %x, want %x", udp.Payload(), payload) } } + +func TestReadIncrementsPacketsReceived(t *testing.T) { + c := newDualTestContext(t, defaultMTU) + defer c.cleanup() + + // Create IPv4 UDP endpoint + var err *tcpip.Error + c.ep, err = c.s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &c.wq) + if err != nil { + c.t.Fatalf("NewEndpoint failed: %v", err) + } + + // Bind to wildcard. + if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}, nil); err != nil { + c.t.Fatalf("Bind failed: %v", err) + } + + testV4Read(c) + + var want uint64 = 1 + if got := c.s.Stats().UDP.PacketsReceived.Value(); got != want { + c.t.Fatalf("Read did not increment PacketsReceived: got %v, want %v", got, want) + } +} + +func TestWriteIncrementsPacketsSent(t *testing.T) { + c := newDualTestContext(t, defaultMTU) + defer c.cleanup() + + c.createV6Endpoint(false) + + testDualWrite(c) + + var want uint64 = 2 + if got := c.s.Stats().UDP.PacketsSent.Value(); got != want { + c.t.Fatalf("Write did not increment PacketsSent: got %v, want %v", got, want) + } +} -- cgit v1.2.3 From 625edb9f2864c1b3aebc6b4c9828197131c2e003 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 31 Aug 2018 10:22:06 -0700 Subject: ipv6: ICMP support This CL does NDP link-address discovery for IPv6. It includes several small changes necessary to get linux to talk to this implementation. In particular, a hop limit of 255 is necessary for ICMPv6. PiperOrigin-RevId: 211103930 Change-Id: If25370ab84c6b1decfb15de917f3b0020f2c4e0e --- pkg/tcpip/link/channel/channel.go | 6 + pkg/tcpip/link/sniffer/sniffer.go | 31 +++++ pkg/tcpip/network/ipv4/ipv4.go | 2 +- pkg/tcpip/network/ipv6/BUILD | 19 ++- pkg/tcpip/network/ipv6/icmp.go | 137 ++++++++++++++++++++ pkg/tcpip/network/ipv6/icmp_test.go | 236 +++++++++++++++++++++++++++++++++++ pkg/tcpip/network/ipv6/ipv6.go | 30 ++--- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/transport/ping/endpoint.go | 38 +++++- pkg/tcpip/transport/ping/protocol.go | 16 ++- 10 files changed, 490 insertions(+), 27 deletions(-) create mode 100644 pkg/tcpip/network/ipv6/icmp_test.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 9d69f1d45..dd3fe7c87 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -71,6 +71,12 @@ func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv *buffer.Vecto e.dispatcher.DeliverNetworkPacket(e, "", protocol, &uu) } +// InjectLinkAddr injects an inbound packet with a remote link address. +func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, vv *buffer.VectorisedView) { + uu := vv.Clone(nil) + e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, &uu) +} + // Attach saves the stack network-layer dispatcher for use later when packets // are injected. func (e *Endpoint) Attach(dispatcher stack.NetworkDispatcher) { diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 414a7edb4..1e302f557 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -303,6 +303,37 @@ func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byt log.Infof("%s %s %v -> %v %s len:%d id:%04x code:%d", prefix, transName, src, dst, icmpType, size, id, icmp.Code()) return + case header.ICMPv6ProtocolNumber: + transName = "icmp" + icmp := header.ICMPv6(b) + icmpType := "unknown" + switch icmp.Type() { + case header.ICMPv6DstUnreachable: + icmpType = "destination unreachable" + case header.ICMPv6PacketTooBig: + icmpType = "packet too big" + case header.ICMPv6TimeExceeded: + icmpType = "time exceeded" + case header.ICMPv6ParamProblem: + icmpType = "param problem" + case header.ICMPv6EchoRequest: + icmpType = "echo request" + case header.ICMPv6EchoReply: + icmpType = "echo reply" + case header.ICMPv6RouterSolicit: + icmpType = "router solicit" + case header.ICMPv6RouterAdvert: + icmpType = "router advert" + case header.ICMPv6NeighborSolicit: + icmpType = "neighbor solicit" + case header.ICMPv6NeighborAdvert: + icmpType = "neighbor advert" + case header.ICMPv6RedirectMsg: + icmpType = "redirect message" + } + log.Infof("%s %s %v -> %v %s len:%d id:%04x code:%d", prefix, transName, src, dst, icmpType, size, id, icmp.Code()) + return + case header.UDPProtocolNumber: transName = "udp" udp := header.UDP(b) diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index e6b1f5128..512ef0d60 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -67,7 +67,7 @@ func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.Transpo fragmentation: fragmentation.NewFragmentation(fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout), } copy(e.address[:], addr) - e.id = stack.NetworkEndpointID{tcpip.Address(e.address[:])} + e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])} go e.echoReplier() diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index 1c3eccae0..2f19a659e 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ipv6", @@ -19,3 +19,20 @@ go_library( "//pkg/tcpip/stack", ], ) + +go_test( + name = "ipv6_test", + size = "small", + srcs = ["icmp_test.go"], + embed = [":ipv6"], + deps = [ + "//pkg/tcpip", + "//pkg/tcpip/buffer", + "//pkg/tcpip/header", + "//pkg/tcpip/link/channel", + "//pkg/tcpip/link/sniffer", + "//pkg/tcpip/stack", + "//pkg/tcpip/transport/ping", + "//pkg/waiter", + ], +) diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 8b8539def..6db004baa 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -17,6 +17,7 @@ package ipv6 import ( "encoding/binary" + "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" @@ -86,5 +87,141 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { case header.ICMPv6PortUnreachable: e.handleControl(stack.ControlPortUnreachable, 0, vv) } + + case header.ICMPv6NeighborSolicit: + if len(v) < header.ICMPv6NeighborSolicitMinimumSize { + return + } + targetAddr := tcpip.Address(v[8 : 8+16]) + if e.linkAddrCache.CheckLocalAddress(e.nicid, ProtocolNumber, targetAddr) == 0 { + // We don't have a useful answer; the best we can do is ignore the request. + return + } + hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize) + pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize)) + pkt.SetType(header.ICMPv6NeighborAdvert) + pkt[icmpV6FlagOffset] = ndpSolicitedFlag | ndpOverrideFlag + copy(pkt[icmpV6OptOffset-len(targetAddr):], targetAddr) + pkt[icmpV6OptOffset] = ndpOptDstLinkAddr + pkt[icmpV6LengthOffset] = 1 + copy(pkt[icmpV6LengthOffset+1:], r.LocalLinkAddress[:]) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) + r.WritePacket(&hdr, nil, header.ICMPv6ProtocolNumber) + + e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) + + case header.ICMPv6NeighborAdvert: + if len(v) < header.ICMPv6NeighborAdvertSize { + return + } + targetAddr := tcpip.Address(v[8 : 8+16]) + e.linkAddrCache.AddLinkAddress(e.nicid, targetAddr, r.RemoteLinkAddress) + if targetAddr != r.RemoteAddress { + e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) + } + + case header.ICMPv6EchoRequest: + if len(v) < header.ICMPv6EchoMinimumSize { + return + } + vv.TrimFront(header.ICMPv6EchoMinimumSize) + data := vv.ToView() + hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize) + pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) + copy(pkt, h) + pkt.SetType(header.ICMPv6EchoReply) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, data)) + r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber) + + case header.ICMPv6EchoReply: + if len(v) < header.ICMPv6EchoMinimumSize { + return + } + e.dispatcher.DeliverTransportPacket(r, header.ICMPv6ProtocolNumber, vv) + } } + +const ( + ndpSolicitedFlag = 1 << 6 + ndpOverrideFlag = 1 << 5 + + ndpOptSrcLinkAddr = 1 + ndpOptDstLinkAddr = 2 + + icmpV6FlagOffset = 4 + icmpV6OptOffset = 24 + icmpV6LengthOffset = 25 + + icmpV6HopLimit = 255 +) + +// solicitedNodeAddr computes the solicited-node multicast address. +// This is used for NDP. Described in RFC 4291. +func solicitedNodeAddr(addr tcpip.Address) tcpip.Address { + const solicitedNodeMulticastPrefix = "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff" + return solicitedNodeMulticastPrefix + addr[len(addr)-3:] +} + +var broadcastMAC = tcpip.LinkAddress([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) + +var _ stack.LinkAddressResolver = (*protocol)(nil) + +// LinkAddressProtocol implements stack.LinkAddressResolver. +func (*protocol) LinkAddressProtocol() tcpip.NetworkProtocolNumber { + return header.IPv6ProtocolNumber +} + +// LinkAddressRequest implements stack.LinkAddressResolver. +func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.LinkEndpoint) *tcpip.Error { + snaddr := solicitedNodeAddr(addr) + r := &stack.Route{ + LocalAddress: localAddr, + RemoteAddress: snaddr, + RemoteLinkAddress: broadcastMAC, + } + hdr := buffer.NewPrependable(int(linkEP.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize) + pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize)) + pkt.SetType(header.ICMPv6NeighborSolicit) + copy(pkt[icmpV6OptOffset-len(addr):], addr) + pkt[icmpV6OptOffset] = ndpOptSrcLinkAddr + pkt[icmpV6LengthOffset] = 1 + copy(pkt[icmpV6LengthOffset+1:], linkEP.LinkAddress()) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) + + length := uint16(hdr.UsedLength()) + ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) + ip.Encode(&header.IPv6Fields{ + PayloadLength: length, + NextHeader: uint8(header.ICMPv6ProtocolNumber), + HopLimit: icmpV6HopLimit, + SrcAddr: r.LocalAddress, + DstAddr: r.RemoteAddress, + }) + + return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber) +} + +// ResolveStaticAddress implements stack.LinkAddressResolver. +func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) { + return "", false +} + +func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, data []byte) uint16 { + // Calculate the IPv6 pseudo-header upper-layer checksum. + xsum := header.Checksum([]byte(src), 0) + xsum = header.Checksum([]byte(dst), xsum) + var upperLayerLength [4]byte + binary.BigEndian.PutUint32(upperLayerLength[:], uint32(len(h)+len(data))) + xsum = header.Checksum(upperLayerLength[:], xsum) + xsum = header.Checksum([]byte{0, 0, 0, uint8(header.ICMPv6ProtocolNumber)}, xsum) + xsum = header.Checksum(data, xsum) + + // h[2:4] is the checksum itself, set it aside to avoid checksumming the checksum. + h2, h3 := h[2], h[3] + h[2], h[3] = 0, 0 + xsum = ^header.Checksum(h, xsum) + h[2], h[3] = h2, h3 + + return xsum +} diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go new file mode 100644 index 000000000..582bbb40e --- /dev/null +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -0,0 +1,236 @@ +// Copyright 2018 Google Inc. +// +// 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 ipv6 + +import ( + "context" + "runtime" + "strings" + "testing" + "time" + + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/sniffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/ping" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +const ( + linkAddr0 = tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06") + linkAddr1 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0f") +) + +// linkLocalAddr computes the default IPv6 link-local address from +// a link-layer (MAC) address. +func linkLocalAddr(linkAddr tcpip.LinkAddress) tcpip.Address { + // Convert a 48-bit MAC to an EUI-64 and then prepend the + // link-local header, FE80::. + // + // The conversion is very nearly: + // aa:bb:cc:dd:ee:ff => FE80::Aabb:ccFF:FEdd:eeff + // Note the capital A. The conversion aa->Aa involves a bit flip. + lladdrb := [16]byte{ + 0: 0xFE, + 1: 0x80, + 8: linkAddr[0] ^ 2, + 9: linkAddr[1], + 10: linkAddr[2], + 11: 0xFF, + 12: 0xFE, + 13: linkAddr[3], + 14: linkAddr[4], + 15: linkAddr[5], + } + return tcpip.Address(lladdrb[:]) +} + +var ( + lladdr0 = linkLocalAddr(linkAddr0) + lladdr1 = linkLocalAddr(linkAddr1) +) + +type testContext struct { + t *testing.T + s0 *stack.Stack + s1 *stack.Stack + + linkEP0 *channel.Endpoint + linkEP1 *channel.Endpoint + + icmpCh chan header.ICMPv6Type +} + +type endpointWithResolutionCapability struct { + stack.LinkEndpoint +} + +func (e endpointWithResolutionCapability) Capabilities() stack.LinkEndpointCapabilities { + return e.LinkEndpoint.Capabilities() | stack.CapabilityResolutionRequired +} + +func newTestContext(t *testing.T) *testContext { + c := &testContext{ + t: t, + s0: stack.New([]string{ProtocolName}, []string{ping.ProtocolName6}, stack.Options{}), + s1: stack.New([]string{ProtocolName}, []string{ping.ProtocolName6}, stack.Options{}), + icmpCh: make(chan header.ICMPv6Type, 10), + } + + const defaultMTU = 65536 + _, linkEP0 := channel.New(256, defaultMTU, linkAddr0) + c.linkEP0 = linkEP0 + wrappedEP0 := endpointWithResolutionCapability{LinkEndpoint: linkEP0} + id0 := stack.RegisterLinkEndpoint(wrappedEP0) + if testing.Verbose() { + id0 = sniffer.New(id0) + } + if err := c.s0.CreateNIC(1, id0); err != nil { + t.Fatalf("CreateNIC s0: %v", err) + } + if err := c.s0.AddAddress(1, ProtocolNumber, lladdr0); err != nil { + t.Fatalf("AddAddress lladdr0: %v", err) + } + if err := c.s0.AddAddress(1, ProtocolNumber, solicitedNodeAddr(lladdr0)); err != nil { + t.Fatalf("AddAddress sn lladdr0: %v", err) + } + + _, linkEP1 := channel.New(256, defaultMTU, linkAddr1) + c.linkEP1 = linkEP1 + wrappedEP1 := endpointWithResolutionCapability{LinkEndpoint: linkEP1} + id1 := stack.RegisterLinkEndpoint(wrappedEP1) + if err := c.s1.CreateNIC(1, id1); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + if err := c.s1.AddAddress(1, ProtocolNumber, lladdr1); err != nil { + t.Fatalf("AddAddress lladdr1: %v", err) + } + if err := c.s1.AddAddress(1, ProtocolNumber, solicitedNodeAddr(lladdr1)); err != nil { + t.Fatalf("AddAddress sn lladdr1: %v", err) + } + + c.s0.SetRouteTable( + []tcpip.Route{{ + Destination: lladdr1, + Mask: tcpip.Address(strings.Repeat("\xff", 16)), + NIC: 1, + }}, + ) + c.s1.SetRouteTable( + []tcpip.Route{{ + Destination: lladdr0, + Mask: tcpip.Address(strings.Repeat("\xff", 16)), + NIC: 1, + }}, + ) + + go c.routePackets(linkEP0.C, linkEP1) + go c.routePackets(linkEP1.C, linkEP0) + + return c +} + +func (c *testContext) countPacket(pkt channel.PacketInfo) { + if pkt.Proto != ProtocolNumber { + return + } + ipv6 := header.IPv6(pkt.Header) + transProto := tcpip.TransportProtocolNumber(ipv6.NextHeader()) + if transProto != header.ICMPv6ProtocolNumber { + return + } + b := pkt.Header[header.IPv6MinimumSize:] + icmp := header.ICMPv6(b) + c.icmpCh <- icmp.Type() +} + +func (c *testContext) routePackets(ch <-chan channel.PacketInfo, ep *channel.Endpoint) { + for pkt := range ch { + c.countPacket(pkt) + views := []buffer.View{pkt.Header, pkt.Payload} + size := len(pkt.Header) + len(pkt.Payload) + vv := buffer.NewVectorisedView(size, views) + ep.InjectLinkAddr(pkt.Proto, ep.LinkAddress(), &vv) + } +} + +func (c *testContext) cleanup() { + close(c.linkEP0.C) + close(c.linkEP1.C) +} + +func TestLinkResolution(t *testing.T) { + c := newTestContext(t) + defer c.cleanup() + r, err := c.s0.FindRoute(1, lladdr0, lladdr1, ProtocolNumber) + if err != nil { + t.Fatal(err) + } + defer r.Release() + + hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize) + pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) + pkt.SetType(header.ICMPv6EchoRequest) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) + payload := tcpip.SlicePayload(hdr.UsedBytes()) + + // We can't send our payload directly over the route because that + // doesn't provoke NDP discovery. + var wq waiter.Queue + ep, err := c.s0.NewEndpoint(header.ICMPv6ProtocolNumber, ProtocolNumber, &wq) + if err != nil { + t.Fatal(err) + } + + // This actually takes about 10 milliseconds, so no need to wait for + // a multi-minute go test timeout if something is broken. + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + for { + if ctx.Err() != nil { + break + } + if _, err := ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{NIC: 1, Addr: lladdr1}}); err == tcpip.ErrNoLinkAddress { + // There's something asynchronous going on; yield to let it do its thing. + runtime.Gosched() + } else if err == nil { + break + } else { + t.Fatal(err) + } + } + + stats := make(map[header.ICMPv6Type]int) + for { + select { + case <-ctx.Done(): + t.Errorf("timeout waiting for ICMP, got: %#+v", stats) + return + case typ := <-c.icmpCh: + stats[typ]++ + + if stats[header.ICMPv6NeighborSolicit] > 0 && + stats[header.ICMPv6NeighborAdvert] > 0 && + stats[header.ICMPv6EchoRequest] > 0 && + stats[header.ICMPv6EchoReply] > 0 { + return + } + } + } +} diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index f48d120c5..51d34b7ec 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -42,18 +42,12 @@ const ( type address [header.IPv6AddressSize]byte type endpoint struct { - nicid tcpip.NICID - id stack.NetworkEndpointID - address address - linkEP stack.LinkEndpoint - dispatcher stack.TransportDispatcher -} - -func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) *endpoint { - e := &endpoint{nicid: nicid, linkEP: linkEP, dispatcher: dispatcher} - copy(e.address[:], addr) - e.id = stack.NetworkEndpointID{tcpip.Address(e.address[:])} - return e + nicid tcpip.NICID + id stack.NetworkEndpointID + address address + linkEP stack.LinkEndpoint + linkAddrCache stack.LinkAddressCache + dispatcher stack.TransportDispatcher } // MTU implements stack.NetworkEndpoint.MTU. It returns the link-layer MTU minus @@ -93,7 +87,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload ip.Encode(&header.IPv6Fields{ PayloadLength: length, NextHeader: uint8(protocol), - HopLimit: 65, + HopLimit: icmpV6HopLimit, SrcAddr: tcpip.Address(e.address[:]), DstAddr: r.RemoteAddress, }) @@ -154,7 +148,15 @@ func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { // NewEndpoint creates a new ipv6 endpoint. func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { - return newEndpoint(nicid, addr, dispatcher, linkEP), nil + e := &endpoint{ + nicid: nicid, + linkEP: linkEP, + linkAddrCache: linkAddrCache, + dispatcher: dispatcher, + } + copy(e.address[:], addr) + e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])} + return e, nil } // SetOption implements NetworkProtocol.SetOption. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index c158e2005..77134c42a 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -165,7 +165,7 @@ func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip. // Set up cache if link address resolution exists for this protocol. if n.linkEP.Capabilities()&CapabilityResolutionRequired != 0 { - if linkRes := n.stack.linkAddrResolvers[protocol]; linkRes != nil { + if _, ok := n.stack.linkAddrResolvers[protocol]; ok { ref.linkCache = n.stack } } diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index f097ac057..7e10c0aae 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -56,6 +56,7 @@ type endpoint struct { // change throughout the lifetime of the endpoint. stack *stack.Stack `state:"manual"` netProto tcpip.NetworkProtocolNumber + transProto tcpip.TransportProtocolNumber waiterQueue *waiter.Queue // The following fields are used to manage the receive queue, and are @@ -81,10 +82,11 @@ type endpoint struct { route stack.Route `state:"manual"` } -func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) *endpoint { +func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) *endpoint { return &endpoint{ stack: stack, netProto: netProto, + transProto: transProto, waiterQueue: waiterQueue, rcvBufSizeMax: 32 * 1024, sndBufSize: 32 * 1024, @@ -98,7 +100,7 @@ func (e *endpoint) Close() { e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite switch e.state { case stateBound, stateConnected: - e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, ProtocolNumber4, e.id) + e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id) } // Close the receive list and drain it. @@ -297,7 +299,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc err = sendPing4(route, e.id.LocalPort, v) case header.IPv6ProtocolNumber: - // TODO: Support IPv6. + err = sendPing6(route, e.id.LocalPort, v) } return uintptr(len(v)), err @@ -385,6 +387,30 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { return r.WritePacket(&hdr, data, header.ICMPv4ProtocolNumber) } +func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { + if len(data) < header.ICMPv6EchoMinimumSize { + return tcpip.ErrInvalidEndpointState + } + + // Set the ident. Sequence number is provided by the user. + binary.BigEndian.PutUint16(data[header.ICMPv6MinimumSize:], ident) + + hdr := buffer.NewPrependable(header.ICMPv6EchoMinimumSize + int(r.MaxHeaderLength())) + + icmpv6 := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) + copy(icmpv6, data) + data = data[header.ICMPv6EchoMinimumSize:] + + if icmpv6.Type() != header.ICMPv6EchoRequest || icmpv6.Code() != 0 { + return tcpip.ErrInvalidEndpointState + } + + icmpv6.SetChecksum(0) + icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0))) + + return r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber) +} + func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { netProto := e.netProto if header.IsV4MappedAddress(addr.Addr) { @@ -508,14 +534,14 @@ func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.Networ if id.LocalPort != 0 { // The endpoint already has a local port, just attempt to // register it. - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber4, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e) return id, err } // We need to find a port for the endpoint. _, err := e.stack.PickEphemeralPort(func(p uint16) (bool, *tcpip.Error) { id.LocalPort = p - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber4, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e) switch err { case nil: return true, nil @@ -564,7 +590,7 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error if commit != nil { if err := commit(); err != nil { // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, ProtocolNumber4, id) + e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, e.transProto, id) return err } } diff --git a/pkg/tcpip/transport/ping/protocol.go b/pkg/tcpip/transport/ping/protocol.go index 8a8192064..b885f3627 100644 --- a/pkg/tcpip/transport/ping/protocol.go +++ b/pkg/tcpip/transport/ping/protocol.go @@ -71,7 +71,7 @@ func (p *protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtoco if netProto != p.netProto() { return nil, tcpip.ErrUnknownProtocol } - return newEndpoint(stack, netProto, waiterQueue), nil + return newEndpoint(stack, netProto, p.number, waiterQueue), nil } // MinimumPacketSize returns the minimum valid ping packet size. @@ -87,8 +87,14 @@ func (p *protocol) MinimumPacketSize() int { // ParsePorts returns the source and destination ports stored in the given ping // packet. -func (*protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) { - return 0, binary.BigEndian.Uint16(v[header.ICMPv4MinimumSize:]), nil +func (p *protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) { + switch p.number { + case ProtocolNumber4: + return 0, binary.BigEndian.Uint16(v[header.ICMPv4MinimumSize:]), nil + case ProtocolNumber6: + return 0, binary.BigEndian.Uint16(v[header.ICMPv6MinimumSize:]), nil + } + panic(fmt.Sprint("unknown protocol number: ", p.number)) } // HandleUnknownDestinationPacket handles packets targeted at this protocol but @@ -112,5 +118,7 @@ func init() { return &protocol{ProtocolNumber4} }) - // TODO: Support IPv6. + stack.RegisterTransportProtocolFactory(ProtocolName6, func() stack.TransportProtocol { + return &protocol{ProtocolNumber6} + }) } -- cgit v1.2.3 From f0d88176549f097fadd3d547827aed3b951ddc92 Mon Sep 17 00:00:00 2001 From: Googler Date: Fri, 31 Aug 2018 15:47:49 -0700 Subject: Automated rollback of changelist 211103930 PiperOrigin-RevId: 211156845 Change-Id: Ie28011d7eb5f45f3a0158dbee2a68c5edf22f6e0 --- pkg/tcpip/link/channel/channel.go | 6 - pkg/tcpip/link/sniffer/sniffer.go | 31 ----- pkg/tcpip/network/ipv4/ipv4.go | 2 +- pkg/tcpip/network/ipv6/BUILD | 19 +-- pkg/tcpip/network/ipv6/icmp.go | 137 -------------------- pkg/tcpip/network/ipv6/icmp_test.go | 236 ----------------------------------- pkg/tcpip/network/ipv6/ipv6.go | 30 +++-- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/transport/ping/endpoint.go | 38 +----- pkg/tcpip/transport/ping/protocol.go | 16 +-- 10 files changed, 27 insertions(+), 490 deletions(-) delete mode 100644 pkg/tcpip/network/ipv6/icmp_test.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index dd3fe7c87..9d69f1d45 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -71,12 +71,6 @@ func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv *buffer.Vecto e.dispatcher.DeliverNetworkPacket(e, "", protocol, &uu) } -// InjectLinkAddr injects an inbound packet with a remote link address. -func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, vv *buffer.VectorisedView) { - uu := vv.Clone(nil) - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, &uu) -} - // Attach saves the stack network-layer dispatcher for use later when packets // are injected. func (e *Endpoint) Attach(dispatcher stack.NetworkDispatcher) { diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 1e302f557..414a7edb4 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -303,37 +303,6 @@ func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byt log.Infof("%s %s %v -> %v %s len:%d id:%04x code:%d", prefix, transName, src, dst, icmpType, size, id, icmp.Code()) return - case header.ICMPv6ProtocolNumber: - transName = "icmp" - icmp := header.ICMPv6(b) - icmpType := "unknown" - switch icmp.Type() { - case header.ICMPv6DstUnreachable: - icmpType = "destination unreachable" - case header.ICMPv6PacketTooBig: - icmpType = "packet too big" - case header.ICMPv6TimeExceeded: - icmpType = "time exceeded" - case header.ICMPv6ParamProblem: - icmpType = "param problem" - case header.ICMPv6EchoRequest: - icmpType = "echo request" - case header.ICMPv6EchoReply: - icmpType = "echo reply" - case header.ICMPv6RouterSolicit: - icmpType = "router solicit" - case header.ICMPv6RouterAdvert: - icmpType = "router advert" - case header.ICMPv6NeighborSolicit: - icmpType = "neighbor solicit" - case header.ICMPv6NeighborAdvert: - icmpType = "neighbor advert" - case header.ICMPv6RedirectMsg: - icmpType = "redirect message" - } - log.Infof("%s %s %v -> %v %s len:%d id:%04x code:%d", prefix, transName, src, dst, icmpType, size, id, icmp.Code()) - return - case header.UDPProtocolNumber: transName = "udp" udp := header.UDP(b) diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index 512ef0d60..e6b1f5128 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -67,7 +67,7 @@ func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.Transpo fragmentation: fragmentation.NewFragmentation(fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout), } copy(e.address[:], addr) - e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])} + e.id = stack.NetworkEndpointID{tcpip.Address(e.address[:])} go e.echoReplier() diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index 2f19a659e..1c3eccae0 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "ipv6", @@ -19,20 +19,3 @@ go_library( "//pkg/tcpip/stack", ], ) - -go_test( - name = "ipv6_test", - size = "small", - srcs = ["icmp_test.go"], - embed = [":ipv6"], - deps = [ - "//pkg/tcpip", - "//pkg/tcpip/buffer", - "//pkg/tcpip/header", - "//pkg/tcpip/link/channel", - "//pkg/tcpip/link/sniffer", - "//pkg/tcpip/stack", - "//pkg/tcpip/transport/ping", - "//pkg/waiter", - ], -) diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 6db004baa..8b8539def 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -17,7 +17,6 @@ package ipv6 import ( "encoding/binary" - "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" @@ -87,141 +86,5 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { case header.ICMPv6PortUnreachable: e.handleControl(stack.ControlPortUnreachable, 0, vv) } - - case header.ICMPv6NeighborSolicit: - if len(v) < header.ICMPv6NeighborSolicitMinimumSize { - return - } - targetAddr := tcpip.Address(v[8 : 8+16]) - if e.linkAddrCache.CheckLocalAddress(e.nicid, ProtocolNumber, targetAddr) == 0 { - // We don't have a useful answer; the best we can do is ignore the request. - return - } - hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize) - pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize)) - pkt.SetType(header.ICMPv6NeighborAdvert) - pkt[icmpV6FlagOffset] = ndpSolicitedFlag | ndpOverrideFlag - copy(pkt[icmpV6OptOffset-len(targetAddr):], targetAddr) - pkt[icmpV6OptOffset] = ndpOptDstLinkAddr - pkt[icmpV6LengthOffset] = 1 - copy(pkt[icmpV6LengthOffset+1:], r.LocalLinkAddress[:]) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) - r.WritePacket(&hdr, nil, header.ICMPv6ProtocolNumber) - - e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) - - case header.ICMPv6NeighborAdvert: - if len(v) < header.ICMPv6NeighborAdvertSize { - return - } - targetAddr := tcpip.Address(v[8 : 8+16]) - e.linkAddrCache.AddLinkAddress(e.nicid, targetAddr, r.RemoteLinkAddress) - if targetAddr != r.RemoteAddress { - e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) - } - - case header.ICMPv6EchoRequest: - if len(v) < header.ICMPv6EchoMinimumSize { - return - } - vv.TrimFront(header.ICMPv6EchoMinimumSize) - data := vv.ToView() - hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize) - pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) - copy(pkt, h) - pkt.SetType(header.ICMPv6EchoReply) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, data)) - r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber) - - case header.ICMPv6EchoReply: - if len(v) < header.ICMPv6EchoMinimumSize { - return - } - e.dispatcher.DeliverTransportPacket(r, header.ICMPv6ProtocolNumber, vv) - } } - -const ( - ndpSolicitedFlag = 1 << 6 - ndpOverrideFlag = 1 << 5 - - ndpOptSrcLinkAddr = 1 - ndpOptDstLinkAddr = 2 - - icmpV6FlagOffset = 4 - icmpV6OptOffset = 24 - icmpV6LengthOffset = 25 - - icmpV6HopLimit = 255 -) - -// solicitedNodeAddr computes the solicited-node multicast address. -// This is used for NDP. Described in RFC 4291. -func solicitedNodeAddr(addr tcpip.Address) tcpip.Address { - const solicitedNodeMulticastPrefix = "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff" - return solicitedNodeMulticastPrefix + addr[len(addr)-3:] -} - -var broadcastMAC = tcpip.LinkAddress([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) - -var _ stack.LinkAddressResolver = (*protocol)(nil) - -// LinkAddressProtocol implements stack.LinkAddressResolver. -func (*protocol) LinkAddressProtocol() tcpip.NetworkProtocolNumber { - return header.IPv6ProtocolNumber -} - -// LinkAddressRequest implements stack.LinkAddressResolver. -func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.LinkEndpoint) *tcpip.Error { - snaddr := solicitedNodeAddr(addr) - r := &stack.Route{ - LocalAddress: localAddr, - RemoteAddress: snaddr, - RemoteLinkAddress: broadcastMAC, - } - hdr := buffer.NewPrependable(int(linkEP.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize) - pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize)) - pkt.SetType(header.ICMPv6NeighborSolicit) - copy(pkt[icmpV6OptOffset-len(addr):], addr) - pkt[icmpV6OptOffset] = ndpOptSrcLinkAddr - pkt[icmpV6LengthOffset] = 1 - copy(pkt[icmpV6LengthOffset+1:], linkEP.LinkAddress()) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) - - length := uint16(hdr.UsedLength()) - ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) - ip.Encode(&header.IPv6Fields{ - PayloadLength: length, - NextHeader: uint8(header.ICMPv6ProtocolNumber), - HopLimit: icmpV6HopLimit, - SrcAddr: r.LocalAddress, - DstAddr: r.RemoteAddress, - }) - - return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber) -} - -// ResolveStaticAddress implements stack.LinkAddressResolver. -func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) { - return "", false -} - -func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, data []byte) uint16 { - // Calculate the IPv6 pseudo-header upper-layer checksum. - xsum := header.Checksum([]byte(src), 0) - xsum = header.Checksum([]byte(dst), xsum) - var upperLayerLength [4]byte - binary.BigEndian.PutUint32(upperLayerLength[:], uint32(len(h)+len(data))) - xsum = header.Checksum(upperLayerLength[:], xsum) - xsum = header.Checksum([]byte{0, 0, 0, uint8(header.ICMPv6ProtocolNumber)}, xsum) - xsum = header.Checksum(data, xsum) - - // h[2:4] is the checksum itself, set it aside to avoid checksumming the checksum. - h2, h3 := h[2], h[3] - h[2], h[3] = 0, 0 - xsum = ^header.Checksum(h, xsum) - h[2], h[3] = h2, h3 - - return xsum -} diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go deleted file mode 100644 index 582bbb40e..000000000 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2018 Google Inc. -// -// 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 ipv6 - -import ( - "context" - "runtime" - "strings" - "testing" - "time" - - "gvisor.googlesource.com/gvisor/pkg/tcpip" - "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" - "gvisor.googlesource.com/gvisor/pkg/tcpip/header" - "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel" - "gvisor.googlesource.com/gvisor/pkg/tcpip/link/sniffer" - "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" - "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/ping" - "gvisor.googlesource.com/gvisor/pkg/waiter" -) - -const ( - linkAddr0 = tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06") - linkAddr1 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0f") -) - -// linkLocalAddr computes the default IPv6 link-local address from -// a link-layer (MAC) address. -func linkLocalAddr(linkAddr tcpip.LinkAddress) tcpip.Address { - // Convert a 48-bit MAC to an EUI-64 and then prepend the - // link-local header, FE80::. - // - // The conversion is very nearly: - // aa:bb:cc:dd:ee:ff => FE80::Aabb:ccFF:FEdd:eeff - // Note the capital A. The conversion aa->Aa involves a bit flip. - lladdrb := [16]byte{ - 0: 0xFE, - 1: 0x80, - 8: linkAddr[0] ^ 2, - 9: linkAddr[1], - 10: linkAddr[2], - 11: 0xFF, - 12: 0xFE, - 13: linkAddr[3], - 14: linkAddr[4], - 15: linkAddr[5], - } - return tcpip.Address(lladdrb[:]) -} - -var ( - lladdr0 = linkLocalAddr(linkAddr0) - lladdr1 = linkLocalAddr(linkAddr1) -) - -type testContext struct { - t *testing.T - s0 *stack.Stack - s1 *stack.Stack - - linkEP0 *channel.Endpoint - linkEP1 *channel.Endpoint - - icmpCh chan header.ICMPv6Type -} - -type endpointWithResolutionCapability struct { - stack.LinkEndpoint -} - -func (e endpointWithResolutionCapability) Capabilities() stack.LinkEndpointCapabilities { - return e.LinkEndpoint.Capabilities() | stack.CapabilityResolutionRequired -} - -func newTestContext(t *testing.T) *testContext { - c := &testContext{ - t: t, - s0: stack.New([]string{ProtocolName}, []string{ping.ProtocolName6}, stack.Options{}), - s1: stack.New([]string{ProtocolName}, []string{ping.ProtocolName6}, stack.Options{}), - icmpCh: make(chan header.ICMPv6Type, 10), - } - - const defaultMTU = 65536 - _, linkEP0 := channel.New(256, defaultMTU, linkAddr0) - c.linkEP0 = linkEP0 - wrappedEP0 := endpointWithResolutionCapability{LinkEndpoint: linkEP0} - id0 := stack.RegisterLinkEndpoint(wrappedEP0) - if testing.Verbose() { - id0 = sniffer.New(id0) - } - if err := c.s0.CreateNIC(1, id0); err != nil { - t.Fatalf("CreateNIC s0: %v", err) - } - if err := c.s0.AddAddress(1, ProtocolNumber, lladdr0); err != nil { - t.Fatalf("AddAddress lladdr0: %v", err) - } - if err := c.s0.AddAddress(1, ProtocolNumber, solicitedNodeAddr(lladdr0)); err != nil { - t.Fatalf("AddAddress sn lladdr0: %v", err) - } - - _, linkEP1 := channel.New(256, defaultMTU, linkAddr1) - c.linkEP1 = linkEP1 - wrappedEP1 := endpointWithResolutionCapability{LinkEndpoint: linkEP1} - id1 := stack.RegisterLinkEndpoint(wrappedEP1) - if err := c.s1.CreateNIC(1, id1); err != nil { - t.Fatalf("CreateNIC failed: %v", err) - } - if err := c.s1.AddAddress(1, ProtocolNumber, lladdr1); err != nil { - t.Fatalf("AddAddress lladdr1: %v", err) - } - if err := c.s1.AddAddress(1, ProtocolNumber, solicitedNodeAddr(lladdr1)); err != nil { - t.Fatalf("AddAddress sn lladdr1: %v", err) - } - - c.s0.SetRouteTable( - []tcpip.Route{{ - Destination: lladdr1, - Mask: tcpip.Address(strings.Repeat("\xff", 16)), - NIC: 1, - }}, - ) - c.s1.SetRouteTable( - []tcpip.Route{{ - Destination: lladdr0, - Mask: tcpip.Address(strings.Repeat("\xff", 16)), - NIC: 1, - }}, - ) - - go c.routePackets(linkEP0.C, linkEP1) - go c.routePackets(linkEP1.C, linkEP0) - - return c -} - -func (c *testContext) countPacket(pkt channel.PacketInfo) { - if pkt.Proto != ProtocolNumber { - return - } - ipv6 := header.IPv6(pkt.Header) - transProto := tcpip.TransportProtocolNumber(ipv6.NextHeader()) - if transProto != header.ICMPv6ProtocolNumber { - return - } - b := pkt.Header[header.IPv6MinimumSize:] - icmp := header.ICMPv6(b) - c.icmpCh <- icmp.Type() -} - -func (c *testContext) routePackets(ch <-chan channel.PacketInfo, ep *channel.Endpoint) { - for pkt := range ch { - c.countPacket(pkt) - views := []buffer.View{pkt.Header, pkt.Payload} - size := len(pkt.Header) + len(pkt.Payload) - vv := buffer.NewVectorisedView(size, views) - ep.InjectLinkAddr(pkt.Proto, ep.LinkAddress(), &vv) - } -} - -func (c *testContext) cleanup() { - close(c.linkEP0.C) - close(c.linkEP1.C) -} - -func TestLinkResolution(t *testing.T) { - c := newTestContext(t) - defer c.cleanup() - r, err := c.s0.FindRoute(1, lladdr0, lladdr1, ProtocolNumber) - if err != nil { - t.Fatal(err) - } - defer r.Release() - - hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize) - pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) - pkt.SetType(header.ICMPv6EchoRequest) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) - payload := tcpip.SlicePayload(hdr.UsedBytes()) - - // We can't send our payload directly over the route because that - // doesn't provoke NDP discovery. - var wq waiter.Queue - ep, err := c.s0.NewEndpoint(header.ICMPv6ProtocolNumber, ProtocolNumber, &wq) - if err != nil { - t.Fatal(err) - } - - // This actually takes about 10 milliseconds, so no need to wait for - // a multi-minute go test timeout if something is broken. - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - - for { - if ctx.Err() != nil { - break - } - if _, err := ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{NIC: 1, Addr: lladdr1}}); err == tcpip.ErrNoLinkAddress { - // There's something asynchronous going on; yield to let it do its thing. - runtime.Gosched() - } else if err == nil { - break - } else { - t.Fatal(err) - } - } - - stats := make(map[header.ICMPv6Type]int) - for { - select { - case <-ctx.Done(): - t.Errorf("timeout waiting for ICMP, got: %#+v", stats) - return - case typ := <-c.icmpCh: - stats[typ]++ - - if stats[header.ICMPv6NeighborSolicit] > 0 && - stats[header.ICMPv6NeighborAdvert] > 0 && - stats[header.ICMPv6EchoRequest] > 0 && - stats[header.ICMPv6EchoReply] > 0 { - return - } - } - } -} diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 51d34b7ec..f48d120c5 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -42,12 +42,18 @@ const ( type address [header.IPv6AddressSize]byte type endpoint struct { - nicid tcpip.NICID - id stack.NetworkEndpointID - address address - linkEP stack.LinkEndpoint - linkAddrCache stack.LinkAddressCache - dispatcher stack.TransportDispatcher + nicid tcpip.NICID + id stack.NetworkEndpointID + address address + linkEP stack.LinkEndpoint + dispatcher stack.TransportDispatcher +} + +func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) *endpoint { + e := &endpoint{nicid: nicid, linkEP: linkEP, dispatcher: dispatcher} + copy(e.address[:], addr) + e.id = stack.NetworkEndpointID{tcpip.Address(e.address[:])} + return e } // MTU implements stack.NetworkEndpoint.MTU. It returns the link-layer MTU minus @@ -87,7 +93,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload ip.Encode(&header.IPv6Fields{ PayloadLength: length, NextHeader: uint8(protocol), - HopLimit: icmpV6HopLimit, + HopLimit: 65, SrcAddr: tcpip.Address(e.address[:]), DstAddr: r.RemoteAddress, }) @@ -148,15 +154,7 @@ func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { // NewEndpoint creates a new ipv6 endpoint. func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { - e := &endpoint{ - nicid: nicid, - linkEP: linkEP, - linkAddrCache: linkAddrCache, - dispatcher: dispatcher, - } - copy(e.address[:], addr) - e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])} - return e, nil + return newEndpoint(nicid, addr, dispatcher, linkEP), nil } // SetOption implements NetworkProtocol.SetOption. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 77134c42a..c158e2005 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -165,7 +165,7 @@ func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip. // Set up cache if link address resolution exists for this protocol. if n.linkEP.Capabilities()&CapabilityResolutionRequired != 0 { - if _, ok := n.stack.linkAddrResolvers[protocol]; ok { + if linkRes := n.stack.linkAddrResolvers[protocol]; linkRes != nil { ref.linkCache = n.stack } } diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index 7e10c0aae..f097ac057 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -56,7 +56,6 @@ type endpoint struct { // change throughout the lifetime of the endpoint. stack *stack.Stack `state:"manual"` netProto tcpip.NetworkProtocolNumber - transProto tcpip.TransportProtocolNumber waiterQueue *waiter.Queue // The following fields are used to manage the receive queue, and are @@ -82,11 +81,10 @@ type endpoint struct { route stack.Route `state:"manual"` } -func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) *endpoint { +func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) *endpoint { return &endpoint{ stack: stack, netProto: netProto, - transProto: transProto, waiterQueue: waiterQueue, rcvBufSizeMax: 32 * 1024, sndBufSize: 32 * 1024, @@ -100,7 +98,7 @@ func (e *endpoint) Close() { e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite switch e.state { case stateBound, stateConnected: - e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id) + e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, ProtocolNumber4, e.id) } // Close the receive list and drain it. @@ -299,7 +297,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc err = sendPing4(route, e.id.LocalPort, v) case header.IPv6ProtocolNumber: - err = sendPing6(route, e.id.LocalPort, v) + // TODO: Support IPv6. } return uintptr(len(v)), err @@ -387,30 +385,6 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { return r.WritePacket(&hdr, data, header.ICMPv4ProtocolNumber) } -func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { - if len(data) < header.ICMPv6EchoMinimumSize { - return tcpip.ErrInvalidEndpointState - } - - // Set the ident. Sequence number is provided by the user. - binary.BigEndian.PutUint16(data[header.ICMPv6MinimumSize:], ident) - - hdr := buffer.NewPrependable(header.ICMPv6EchoMinimumSize + int(r.MaxHeaderLength())) - - icmpv6 := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) - copy(icmpv6, data) - data = data[header.ICMPv6EchoMinimumSize:] - - if icmpv6.Type() != header.ICMPv6EchoRequest || icmpv6.Code() != 0 { - return tcpip.ErrInvalidEndpointState - } - - icmpv6.SetChecksum(0) - icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0))) - - return r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber) -} - func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { netProto := e.netProto if header.IsV4MappedAddress(addr.Addr) { @@ -534,14 +508,14 @@ func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.Networ if id.LocalPort != 0 { // The endpoint already has a local port, just attempt to // register it. - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber4, id, e) return id, err } // We need to find a port for the endpoint. _, err := e.stack.PickEphemeralPort(func(p uint16) (bool, *tcpip.Error) { id.LocalPort = p - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber4, id, e) switch err { case nil: return true, nil @@ -590,7 +564,7 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error if commit != nil { if err := commit(); err != nil { // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, e.transProto, id) + e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, ProtocolNumber4, id) return err } } diff --git a/pkg/tcpip/transport/ping/protocol.go b/pkg/tcpip/transport/ping/protocol.go index b885f3627..8a8192064 100644 --- a/pkg/tcpip/transport/ping/protocol.go +++ b/pkg/tcpip/transport/ping/protocol.go @@ -71,7 +71,7 @@ func (p *protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtoco if netProto != p.netProto() { return nil, tcpip.ErrUnknownProtocol } - return newEndpoint(stack, netProto, p.number, waiterQueue), nil + return newEndpoint(stack, netProto, waiterQueue), nil } // MinimumPacketSize returns the minimum valid ping packet size. @@ -87,14 +87,8 @@ func (p *protocol) MinimumPacketSize() int { // ParsePorts returns the source and destination ports stored in the given ping // packet. -func (p *protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) { - switch p.number { - case ProtocolNumber4: - return 0, binary.BigEndian.Uint16(v[header.ICMPv4MinimumSize:]), nil - case ProtocolNumber6: - return 0, binary.BigEndian.Uint16(v[header.ICMPv6MinimumSize:]), nil - } - panic(fmt.Sprint("unknown protocol number: ", p.number)) +func (*protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) { + return 0, binary.BigEndian.Uint16(v[header.ICMPv4MinimumSize:]), nil } // HandleUnknownDestinationPacket handles packets targeted at this protocol but @@ -118,7 +112,5 @@ func init() { return &protocol{ProtocolNumber4} }) - stack.RegisterTransportProtocolFactory(ProtocolName6, func() stack.TransportProtocol { - return &protocol{ProtocolNumber6} - }) + // TODO: Support IPv6. } -- cgit v1.2.3 From 2cff07381a911ad52cf9df70d702f39217e9539e Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Tue, 4 Sep 2018 14:30:15 -0700 Subject: Automated rollback of changelist 211156845 PiperOrigin-RevId: 211525182 Change-Id: I462c20328955c77ecc7bfd8ee803ac91f15858e6 --- pkg/tcpip/link/channel/channel.go | 6 + pkg/tcpip/link/sniffer/sniffer.go | 31 +++++ pkg/tcpip/network/ipv4/ipv4.go | 8 +- pkg/tcpip/network/ipv6/BUILD | 19 ++- pkg/tcpip/network/ipv6/icmp.go | 135 ++++++++++++++++++++ pkg/tcpip/network/ipv6/icmp_test.go | 236 +++++++++++++++++++++++++++++++++++ pkg/tcpip/network/ipv6/ipv6.go | 34 ++--- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/transport/ping/endpoint.go | 38 +++++- pkg/tcpip/transport/ping/protocol.go | 16 ++- 10 files changed, 497 insertions(+), 28 deletions(-) create mode 100644 pkg/tcpip/network/ipv6/icmp_test.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 9d69f1d45..dd3fe7c87 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -71,6 +71,12 @@ func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv *buffer.Vecto e.dispatcher.DeliverNetworkPacket(e, "", protocol, &uu) } +// InjectLinkAddr injects an inbound packet with a remote link address. +func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, vv *buffer.VectorisedView) { + uu := vv.Clone(nil) + e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, &uu) +} + // Attach saves the stack network-layer dispatcher for use later when packets // are injected. func (e *Endpoint) Attach(dispatcher stack.NetworkDispatcher) { diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 414a7edb4..1e302f557 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -303,6 +303,37 @@ func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byt log.Infof("%s %s %v -> %v %s len:%d id:%04x code:%d", prefix, transName, src, dst, icmpType, size, id, icmp.Code()) return + case header.ICMPv6ProtocolNumber: + transName = "icmp" + icmp := header.ICMPv6(b) + icmpType := "unknown" + switch icmp.Type() { + case header.ICMPv6DstUnreachable: + icmpType = "destination unreachable" + case header.ICMPv6PacketTooBig: + icmpType = "packet too big" + case header.ICMPv6TimeExceeded: + icmpType = "time exceeded" + case header.ICMPv6ParamProblem: + icmpType = "param problem" + case header.ICMPv6EchoRequest: + icmpType = "echo request" + case header.ICMPv6EchoReply: + icmpType = "echo reply" + case header.ICMPv6RouterSolicit: + icmpType = "router solicit" + case header.ICMPv6RouterAdvert: + icmpType = "router advert" + case header.ICMPv6NeighborSolicit: + icmpType = "neighbor solicit" + case header.ICMPv6NeighborAdvert: + icmpType = "neighbor advert" + case header.ICMPv6RedirectMsg: + icmpType = "redirect message" + } + log.Infof("%s %s %v -> %v %s len:%d id:%04x code:%d", prefix, transName, src, dst, icmpType, size, id, icmp.Code()) + return + case header.UDPProtocolNumber: transName = "udp" udp := header.UDP(b) diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index e6b1f5128..143d8e73e 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -44,6 +44,10 @@ const ( // buckets is the number of identifier buckets. buckets = 2048 + + // defaultIPv4TTL is the defautl TTL for IPv4 Packets egressed by + // Netstack. + defaultIPv4TTL = 255 ) type address [header.IPv4AddressSize]byte @@ -67,7 +71,7 @@ func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.Transpo fragmentation: fragmentation.NewFragmentation(fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout), } copy(e.address[:], addr) - e.id = stack.NetworkEndpointID{tcpip.Address(e.address[:])} + e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])} go e.echoReplier() @@ -115,7 +119,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload IHL: header.IPv4MinimumSize, TotalLength: length, ID: uint16(id), - TTL: 65, + TTL: defaultIPv4TTL, Protocol: uint8(protocol), SrcAddr: tcpip.Address(e.address[:]), DstAddr: r.RemoteAddress, diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index 1c3eccae0..2f19a659e 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ipv6", @@ -19,3 +19,20 @@ go_library( "//pkg/tcpip/stack", ], ) + +go_test( + name = "ipv6_test", + size = "small", + srcs = ["icmp_test.go"], + embed = [":ipv6"], + deps = [ + "//pkg/tcpip", + "//pkg/tcpip/buffer", + "//pkg/tcpip/header", + "//pkg/tcpip/link/channel", + "//pkg/tcpip/link/sniffer", + "//pkg/tcpip/stack", + "//pkg/tcpip/transport/ping", + "//pkg/waiter", + ], +) diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 8b8539def..e3ef89d26 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -17,6 +17,7 @@ package ipv6 import ( "encoding/binary" + "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" @@ -86,5 +87,139 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { case header.ICMPv6PortUnreachable: e.handleControl(stack.ControlPortUnreachable, 0, vv) } + + case header.ICMPv6NeighborSolicit: + if len(v) < header.ICMPv6NeighborSolicitMinimumSize { + return + } + targetAddr := tcpip.Address(v[8 : 8+16]) + if e.linkAddrCache.CheckLocalAddress(e.nicid, ProtocolNumber, targetAddr) == 0 { + // We don't have a useful answer; the best we can do is ignore the request. + return + } + hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize) + pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize)) + pkt.SetType(header.ICMPv6NeighborAdvert) + pkt[icmpV6FlagOffset] = ndpSolicitedFlag | ndpOverrideFlag + copy(pkt[icmpV6OptOffset-len(targetAddr):], targetAddr) + pkt[icmpV6OptOffset] = ndpOptDstLinkAddr + pkt[icmpV6LengthOffset] = 1 + copy(pkt[icmpV6LengthOffset+1:], r.LocalLinkAddress[:]) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) + r.WritePacket(&hdr, nil, header.ICMPv6ProtocolNumber) + + e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) + + case header.ICMPv6NeighborAdvert: + if len(v) < header.ICMPv6NeighborAdvertSize { + return + } + targetAddr := tcpip.Address(v[8 : 8+16]) + e.linkAddrCache.AddLinkAddress(e.nicid, targetAddr, r.RemoteLinkAddress) + if targetAddr != r.RemoteAddress { + e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) + } + + case header.ICMPv6EchoRequest: + if len(v) < header.ICMPv6EchoMinimumSize { + return + } + vv.TrimFront(header.ICMPv6EchoMinimumSize) + data := vv.ToView() + hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize) + pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) + copy(pkt, h) + pkt.SetType(header.ICMPv6EchoReply) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, data)) + r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber) + + case header.ICMPv6EchoReply: + if len(v) < header.ICMPv6EchoMinimumSize { + return + } + e.dispatcher.DeliverTransportPacket(r, header.ICMPv6ProtocolNumber, vv) + + } +} + +const ( + ndpSolicitedFlag = 1 << 6 + ndpOverrideFlag = 1 << 5 + + ndpOptSrcLinkAddr = 1 + ndpOptDstLinkAddr = 2 + + icmpV6FlagOffset = 4 + icmpV6OptOffset = 24 + icmpV6LengthOffset = 25 +) + +// solicitedNodeAddr computes the solicited-node multicast address. +// This is used for NDP. Described in RFC 4291. +func solicitedNodeAddr(addr tcpip.Address) tcpip.Address { + const solicitedNodeMulticastPrefix = "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff" + return solicitedNodeMulticastPrefix + addr[len(addr)-3:] +} + +var broadcastMAC = tcpip.LinkAddress([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) + +var _ stack.LinkAddressResolver = (*protocol)(nil) + +// LinkAddressProtocol implements stack.LinkAddressResolver. +func (*protocol) LinkAddressProtocol() tcpip.NetworkProtocolNumber { + return header.IPv6ProtocolNumber +} + +// LinkAddressRequest implements stack.LinkAddressResolver. +func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.LinkEndpoint) *tcpip.Error { + snaddr := solicitedNodeAddr(addr) + r := &stack.Route{ + LocalAddress: localAddr, + RemoteAddress: snaddr, + RemoteLinkAddress: broadcastMAC, } + hdr := buffer.NewPrependable(int(linkEP.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6NeighborAdvertSize) + pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize)) + pkt.SetType(header.ICMPv6NeighborSolicit) + copy(pkt[icmpV6OptOffset-len(addr):], addr) + pkt[icmpV6OptOffset] = ndpOptSrcLinkAddr + pkt[icmpV6LengthOffset] = 1 + copy(pkt[icmpV6LengthOffset+1:], linkEP.LinkAddress()) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) + + length := uint16(hdr.UsedLength()) + ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) + ip.Encode(&header.IPv6Fields{ + PayloadLength: length, + NextHeader: uint8(header.ICMPv6ProtocolNumber), + HopLimit: defaultIPv6HopLimit, + SrcAddr: r.LocalAddress, + DstAddr: r.RemoteAddress, + }) + + return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber) +} + +// ResolveStaticAddress implements stack.LinkAddressResolver. +func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) { + return "", false +} + +func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, data []byte) uint16 { + // Calculate the IPv6 pseudo-header upper-layer checksum. + xsum := header.Checksum([]byte(src), 0) + xsum = header.Checksum([]byte(dst), xsum) + var upperLayerLength [4]byte + binary.BigEndian.PutUint32(upperLayerLength[:], uint32(len(h)+len(data))) + xsum = header.Checksum(upperLayerLength[:], xsum) + xsum = header.Checksum([]byte{0, 0, 0, uint8(header.ICMPv6ProtocolNumber)}, xsum) + xsum = header.Checksum(data, xsum) + + // h[2:4] is the checksum itself, set it aside to avoid checksumming the checksum. + h2, h3 := h[2], h[3] + h[2], h[3] = 0, 0 + xsum = ^header.Checksum(h, xsum) + h[2], h[3] = h2, h3 + + return xsum } diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go new file mode 100644 index 000000000..582bbb40e --- /dev/null +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -0,0 +1,236 @@ +// Copyright 2018 Google Inc. +// +// 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 ipv6 + +import ( + "context" + "runtime" + "strings" + "testing" + "time" + + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/sniffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/ping" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +const ( + linkAddr0 = tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06") + linkAddr1 = tcpip.LinkAddress("\x0a\x0b\x0c\x0d\x0e\x0f") +) + +// linkLocalAddr computes the default IPv6 link-local address from +// a link-layer (MAC) address. +func linkLocalAddr(linkAddr tcpip.LinkAddress) tcpip.Address { + // Convert a 48-bit MAC to an EUI-64 and then prepend the + // link-local header, FE80::. + // + // The conversion is very nearly: + // aa:bb:cc:dd:ee:ff => FE80::Aabb:ccFF:FEdd:eeff + // Note the capital A. The conversion aa->Aa involves a bit flip. + lladdrb := [16]byte{ + 0: 0xFE, + 1: 0x80, + 8: linkAddr[0] ^ 2, + 9: linkAddr[1], + 10: linkAddr[2], + 11: 0xFF, + 12: 0xFE, + 13: linkAddr[3], + 14: linkAddr[4], + 15: linkAddr[5], + } + return tcpip.Address(lladdrb[:]) +} + +var ( + lladdr0 = linkLocalAddr(linkAddr0) + lladdr1 = linkLocalAddr(linkAddr1) +) + +type testContext struct { + t *testing.T + s0 *stack.Stack + s1 *stack.Stack + + linkEP0 *channel.Endpoint + linkEP1 *channel.Endpoint + + icmpCh chan header.ICMPv6Type +} + +type endpointWithResolutionCapability struct { + stack.LinkEndpoint +} + +func (e endpointWithResolutionCapability) Capabilities() stack.LinkEndpointCapabilities { + return e.LinkEndpoint.Capabilities() | stack.CapabilityResolutionRequired +} + +func newTestContext(t *testing.T) *testContext { + c := &testContext{ + t: t, + s0: stack.New([]string{ProtocolName}, []string{ping.ProtocolName6}, stack.Options{}), + s1: stack.New([]string{ProtocolName}, []string{ping.ProtocolName6}, stack.Options{}), + icmpCh: make(chan header.ICMPv6Type, 10), + } + + const defaultMTU = 65536 + _, linkEP0 := channel.New(256, defaultMTU, linkAddr0) + c.linkEP0 = linkEP0 + wrappedEP0 := endpointWithResolutionCapability{LinkEndpoint: linkEP0} + id0 := stack.RegisterLinkEndpoint(wrappedEP0) + if testing.Verbose() { + id0 = sniffer.New(id0) + } + if err := c.s0.CreateNIC(1, id0); err != nil { + t.Fatalf("CreateNIC s0: %v", err) + } + if err := c.s0.AddAddress(1, ProtocolNumber, lladdr0); err != nil { + t.Fatalf("AddAddress lladdr0: %v", err) + } + if err := c.s0.AddAddress(1, ProtocolNumber, solicitedNodeAddr(lladdr0)); err != nil { + t.Fatalf("AddAddress sn lladdr0: %v", err) + } + + _, linkEP1 := channel.New(256, defaultMTU, linkAddr1) + c.linkEP1 = linkEP1 + wrappedEP1 := endpointWithResolutionCapability{LinkEndpoint: linkEP1} + id1 := stack.RegisterLinkEndpoint(wrappedEP1) + if err := c.s1.CreateNIC(1, id1); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + if err := c.s1.AddAddress(1, ProtocolNumber, lladdr1); err != nil { + t.Fatalf("AddAddress lladdr1: %v", err) + } + if err := c.s1.AddAddress(1, ProtocolNumber, solicitedNodeAddr(lladdr1)); err != nil { + t.Fatalf("AddAddress sn lladdr1: %v", err) + } + + c.s0.SetRouteTable( + []tcpip.Route{{ + Destination: lladdr1, + Mask: tcpip.Address(strings.Repeat("\xff", 16)), + NIC: 1, + }}, + ) + c.s1.SetRouteTable( + []tcpip.Route{{ + Destination: lladdr0, + Mask: tcpip.Address(strings.Repeat("\xff", 16)), + NIC: 1, + }}, + ) + + go c.routePackets(linkEP0.C, linkEP1) + go c.routePackets(linkEP1.C, linkEP0) + + return c +} + +func (c *testContext) countPacket(pkt channel.PacketInfo) { + if pkt.Proto != ProtocolNumber { + return + } + ipv6 := header.IPv6(pkt.Header) + transProto := tcpip.TransportProtocolNumber(ipv6.NextHeader()) + if transProto != header.ICMPv6ProtocolNumber { + return + } + b := pkt.Header[header.IPv6MinimumSize:] + icmp := header.ICMPv6(b) + c.icmpCh <- icmp.Type() +} + +func (c *testContext) routePackets(ch <-chan channel.PacketInfo, ep *channel.Endpoint) { + for pkt := range ch { + c.countPacket(pkt) + views := []buffer.View{pkt.Header, pkt.Payload} + size := len(pkt.Header) + len(pkt.Payload) + vv := buffer.NewVectorisedView(size, views) + ep.InjectLinkAddr(pkt.Proto, ep.LinkAddress(), &vv) + } +} + +func (c *testContext) cleanup() { + close(c.linkEP0.C) + close(c.linkEP1.C) +} + +func TestLinkResolution(t *testing.T) { + c := newTestContext(t) + defer c.cleanup() + r, err := c.s0.FindRoute(1, lladdr0, lladdr1, ProtocolNumber) + if err != nil { + t.Fatal(err) + } + defer r.Release() + + hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize) + pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) + pkt.SetType(header.ICMPv6EchoRequest) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) + payload := tcpip.SlicePayload(hdr.UsedBytes()) + + // We can't send our payload directly over the route because that + // doesn't provoke NDP discovery. + var wq waiter.Queue + ep, err := c.s0.NewEndpoint(header.ICMPv6ProtocolNumber, ProtocolNumber, &wq) + if err != nil { + t.Fatal(err) + } + + // This actually takes about 10 milliseconds, so no need to wait for + // a multi-minute go test timeout if something is broken. + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + for { + if ctx.Err() != nil { + break + } + if _, err := ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{NIC: 1, Addr: lladdr1}}); err == tcpip.ErrNoLinkAddress { + // There's something asynchronous going on; yield to let it do its thing. + runtime.Gosched() + } else if err == nil { + break + } else { + t.Fatal(err) + } + } + + stats := make(map[header.ICMPv6Type]int) + for { + select { + case <-ctx.Done(): + t.Errorf("timeout waiting for ICMP, got: %#+v", stats) + return + case typ := <-c.icmpCh: + stats[typ]++ + + if stats[header.ICMPv6NeighborSolicit] > 0 && + stats[header.ICMPv6NeighborAdvert] > 0 && + stats[header.ICMPv6EchoRequest] > 0 && + stats[header.ICMPv6EchoReply] > 0 { + return + } + } + } +} diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index f48d120c5..cdb8284a2 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -37,23 +37,21 @@ const ( // maxTotalSize is maximum size that can be encoded in the 16-bit // PayloadLength field of the ipv6 header. maxPayloadSize = 0xffff + + // defaultIPv6HopLimit is the default hop limit for IPv6 Packets + // egressed by Netstack. + defaultIPv6HopLimit = 255 ) type address [header.IPv6AddressSize]byte type endpoint struct { - nicid tcpip.NICID - id stack.NetworkEndpointID - address address - linkEP stack.LinkEndpoint - dispatcher stack.TransportDispatcher -} - -func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) *endpoint { - e := &endpoint{nicid: nicid, linkEP: linkEP, dispatcher: dispatcher} - copy(e.address[:], addr) - e.id = stack.NetworkEndpointID{tcpip.Address(e.address[:])} - return e + nicid tcpip.NICID + id stack.NetworkEndpointID + address address + linkEP stack.LinkEndpoint + linkAddrCache stack.LinkAddressCache + dispatcher stack.TransportDispatcher } // MTU implements stack.NetworkEndpoint.MTU. It returns the link-layer MTU minus @@ -93,7 +91,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload ip.Encode(&header.IPv6Fields{ PayloadLength: length, NextHeader: uint8(protocol), - HopLimit: 65, + HopLimit: defaultIPv6HopLimit, SrcAddr: tcpip.Address(e.address[:]), DstAddr: r.RemoteAddress, }) @@ -154,7 +152,15 @@ func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { // NewEndpoint creates a new ipv6 endpoint. func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { - return newEndpoint(nicid, addr, dispatcher, linkEP), nil + e := &endpoint{ + nicid: nicid, + linkEP: linkEP, + linkAddrCache: linkAddrCache, + dispatcher: dispatcher, + } + copy(e.address[:], addr) + e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])} + return e, nil } // SetOption implements NetworkProtocol.SetOption. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index c158e2005..77134c42a 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -165,7 +165,7 @@ func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip. // Set up cache if link address resolution exists for this protocol. if n.linkEP.Capabilities()&CapabilityResolutionRequired != 0 { - if linkRes := n.stack.linkAddrResolvers[protocol]; linkRes != nil { + if _, ok := n.stack.linkAddrResolvers[protocol]; ok { ref.linkCache = n.stack } } diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index f097ac057..7e10c0aae 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -56,6 +56,7 @@ type endpoint struct { // change throughout the lifetime of the endpoint. stack *stack.Stack `state:"manual"` netProto tcpip.NetworkProtocolNumber + transProto tcpip.TransportProtocolNumber waiterQueue *waiter.Queue // The following fields are used to manage the receive queue, and are @@ -81,10 +82,11 @@ type endpoint struct { route stack.Route `state:"manual"` } -func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) *endpoint { +func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) *endpoint { return &endpoint{ stack: stack, netProto: netProto, + transProto: transProto, waiterQueue: waiterQueue, rcvBufSizeMax: 32 * 1024, sndBufSize: 32 * 1024, @@ -98,7 +100,7 @@ func (e *endpoint) Close() { e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite switch e.state { case stateBound, stateConnected: - e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, ProtocolNumber4, e.id) + e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id) } // Close the receive list and drain it. @@ -297,7 +299,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc err = sendPing4(route, e.id.LocalPort, v) case header.IPv6ProtocolNumber: - // TODO: Support IPv6. + err = sendPing6(route, e.id.LocalPort, v) } return uintptr(len(v)), err @@ -385,6 +387,30 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { return r.WritePacket(&hdr, data, header.ICMPv4ProtocolNumber) } +func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { + if len(data) < header.ICMPv6EchoMinimumSize { + return tcpip.ErrInvalidEndpointState + } + + // Set the ident. Sequence number is provided by the user. + binary.BigEndian.PutUint16(data[header.ICMPv6MinimumSize:], ident) + + hdr := buffer.NewPrependable(header.ICMPv6EchoMinimumSize + int(r.MaxHeaderLength())) + + icmpv6 := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) + copy(icmpv6, data) + data = data[header.ICMPv6EchoMinimumSize:] + + if icmpv6.Type() != header.ICMPv6EchoRequest || icmpv6.Code() != 0 { + return tcpip.ErrInvalidEndpointState + } + + icmpv6.SetChecksum(0) + icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0))) + + return r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber) +} + func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { netProto := e.netProto if header.IsV4MappedAddress(addr.Addr) { @@ -508,14 +534,14 @@ func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.Networ if id.LocalPort != 0 { // The endpoint already has a local port, just attempt to // register it. - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber4, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e) return id, err } // We need to find a port for the endpoint. _, err := e.stack.PickEphemeralPort(func(p uint16) (bool, *tcpip.Error) { id.LocalPort = p - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber4, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e) switch err { case nil: return true, nil @@ -564,7 +590,7 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error if commit != nil { if err := commit(); err != nil { // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, ProtocolNumber4, id) + e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, e.transProto, id) return err } } diff --git a/pkg/tcpip/transport/ping/protocol.go b/pkg/tcpip/transport/ping/protocol.go index 8a8192064..b885f3627 100644 --- a/pkg/tcpip/transport/ping/protocol.go +++ b/pkg/tcpip/transport/ping/protocol.go @@ -71,7 +71,7 @@ func (p *protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtoco if netProto != p.netProto() { return nil, tcpip.ErrUnknownProtocol } - return newEndpoint(stack, netProto, waiterQueue), nil + return newEndpoint(stack, netProto, p.number, waiterQueue), nil } // MinimumPacketSize returns the minimum valid ping packet size. @@ -87,8 +87,14 @@ func (p *protocol) MinimumPacketSize() int { // ParsePorts returns the source and destination ports stored in the given ping // packet. -func (*protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) { - return 0, binary.BigEndian.Uint16(v[header.ICMPv4MinimumSize:]), nil +func (p *protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) { + switch p.number { + case ProtocolNumber4: + return 0, binary.BigEndian.Uint16(v[header.ICMPv4MinimumSize:]), nil + case ProtocolNumber6: + return 0, binary.BigEndian.Uint16(v[header.ICMPv6MinimumSize:]), nil + } + panic(fmt.Sprint("unknown protocol number: ", p.number)) } // HandleUnknownDestinationPacket handles packets targeted at this protocol but @@ -112,5 +118,7 @@ func init() { return &protocol{ProtocolNumber4} }) - // TODO: Support IPv6. + stack.RegisterTransportProtocolFactory(ProtocolName6, func() stack.TransportProtocol { + return &protocol{ProtocolNumber6} + }) } -- cgit v1.2.3 From fe8ca76c22ff03c9ae8bf524031553d65b30f53d Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 5 Sep 2018 17:05:09 -0700 Subject: Implement Subnet removal This was used to implement https://fuchsia-review.googlesource.com/c/garnet/+/177771. PiperOrigin-RevId: 211725098 Change-Id: Ib0acc7c13430b7341e8e0ec6eb5fc35f5cee5083 --- pkg/tcpip/stack/nic.go | 69 ++++++++++++++++++++++++++++++ pkg/tcpip/stack/stack.go | 57 +++++++++++++++++++++---- pkg/tcpip/stack/stack_test.go | 97 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+), 9 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 77134c42a..7aa960096 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -82,6 +82,52 @@ func (n *NIC) setSpoofing(enable bool) { n.mu.Unlock() } +func (n *NIC) getMainNICAddress(protocol tcpip.NetworkProtocolNumber) (tcpip.Address, tcpip.Subnet, *tcpip.Error) { + n.mu.RLock() + defer n.mu.RUnlock() + + var r *referencedNetworkEndpoint + + // Check for a primary endpoint. + if list, ok := n.primary[protocol]; ok { + for e := list.Front(); e != nil; e = e.Next() { + ref := e.(*referencedNetworkEndpoint) + if ref.holdsInsertRef && ref.tryIncRef() { + r = ref + break + } + } + + } + + // If no primary endpoints then check for other endpoints. + if r == nil { + for _, ref := range n.endpoints { + if ref.holdsInsertRef && ref.tryIncRef() { + r = ref + break + } + } + } + + if r == nil { + return "", tcpip.Subnet{}, tcpip.ErrNoLinkAddress + } + + address := r.ep.ID().LocalAddress + r.decRef() + + // Find the least-constrained matching subnet for the address, if one + // exists, and return it. + var subnet tcpip.Subnet + for _, s := range n.subnets { + if s.Contains(address) && !subnet.Contains(s.ID()) { + subnet = s + } + } + return address, subnet, nil +} + // primaryEndpoint returns the primary endpoint of n for the given network // protocol. func (n *NIC) primaryEndpoint(protocol tcpip.NetworkProtocolNumber) *referencedNetworkEndpoint { @@ -216,6 +262,29 @@ func (n *NIC) AddSubnet(protocol tcpip.NetworkProtocolNumber, subnet tcpip.Subne n.mu.Unlock() } +// RemoveSubnet removes the given subnet from n. +func (n *NIC) RemoveSubnet(subnet tcpip.Subnet) { + n.mu.Lock() + + for i, sub := range n.subnets { + if sub == subnet { + n.subnets = append(n.subnets[:i], n.subnets[i+1:]...) + } + } + + n.mu.Unlock() +} + +// ContainsSubnet reports whether this NIC contains the given subnet. +func (n *NIC) ContainsSubnet(subnet tcpip.Subnet) bool { + for _, s := range n.Subnets() { + if s == subnet { + return true + } + } + return false +} + // Subnets returns the Subnets associated with this NIC. func (n *NIC) Subnets() []tcpip.Subnet { n.mu.RLock() diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 2c8c4aa31..675ccc6fa 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -623,13 +623,38 @@ func (s *Stack) AddSubnet(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, s.mu.RLock() defer s.mu.RUnlock() - nic := s.nics[id] - if nic == nil { - return tcpip.ErrUnknownNICID + if nic, ok := s.nics[id]; ok { + nic.AddSubnet(protocol, subnet) + return nil } - nic.AddSubnet(protocol, subnet) - return nil + return tcpip.ErrUnknownNICID +} + +// RemoveSubnet removes the subnet range from the specified NIC. +func (s *Stack) RemoveSubnet(id tcpip.NICID, subnet tcpip.Subnet) *tcpip.Error { + s.mu.RLock() + defer s.mu.RUnlock() + + if nic, ok := s.nics[id]; ok { + nic.RemoveSubnet(subnet) + return nil + } + + return tcpip.ErrUnknownNICID +} + +// ContainsSubnet reports whether the specified NIC contains the specified +// subnet. +func (s *Stack) ContainsSubnet(id tcpip.NICID, subnet tcpip.Subnet) (bool, *tcpip.Error) { + s.mu.RLock() + defer s.mu.RUnlock() + + if nic, ok := s.nics[id]; ok { + return nic.ContainsSubnet(subnet), nil + } + + return false, tcpip.ErrUnknownNICID } // RemoveAddress removes an existing network-layer address from the specified @@ -638,12 +663,26 @@ func (s *Stack) RemoveAddress(id tcpip.NICID, addr tcpip.Address) *tcpip.Error { s.mu.RLock() defer s.mu.RUnlock() - nic := s.nics[id] - if nic == nil { - return tcpip.ErrUnknownNICID + if nic, ok := s.nics[id]; ok { + return nic.RemoveAddress(addr) + } + + return tcpip.ErrUnknownNICID +} + +// GetMainNICAddress returns the first primary address (and the subnet that +// contains it) for the given NIC and protocol. Returns an arbitrary endpoint's +// address if no primary addresses exist. Returns an error if the NIC doesn't +// exist or has no endpoints. +func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber) (tcpip.Address, tcpip.Subnet, *tcpip.Error) { + s.mu.RLock() + defer s.mu.RUnlock() + + if nic, ok := s.nics[id]; ok { + return nic.getMainNICAddress(protocol) } - return nic.RemoveAddress(addr) + return "", tcpip.Subnet{}, tcpip.ErrUnknownNICID } // FindRoute creates a route to the given destination address, leaving through diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 57de5b93a..c46e91241 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -19,6 +19,7 @@ package stack_test import ( "math" + "strings" "testing" "gvisor.googlesource.com/gvisor/pkg/tcpip" @@ -763,6 +764,102 @@ func TestNetworkOptions(t *testing.T) { } } +func TestSubnetAddRemove(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) + id, _ := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + addr := tcpip.Address("\x01\x01\x01\x01") + mask := tcpip.AddressMask(strings.Repeat("\xff", len(addr))) + subnet, err := tcpip.NewSubnet(addr, mask) + if err != nil { + t.Fatalf("NewSubnet failed: %v", err) + } + + if contained, err := s.ContainsSubnet(1, subnet); err != nil { + t.Fatalf("ContainsSubnet failed: %v", err) + } else if contained { + t.Fatal("got s.ContainsSubnet(...) = true, want = false") + } + + if err := s.AddSubnet(1, fakeNetNumber, subnet); err != nil { + t.Fatalf("AddSubnet failed: %v", err) + } + + if contained, err := s.ContainsSubnet(1, subnet); err != nil { + t.Fatalf("ContainsSubnet failed: %v", err) + } else if !contained { + t.Fatal("got s.ContainsSubnet(...) = false, want = true") + } + + if err := s.RemoveSubnet(1, subnet); err != nil { + t.Fatalf("RemoveSubnet failed: %v", err) + } + + if contained, err := s.ContainsSubnet(1, subnet); err != nil { + t.Fatalf("ContainsSubnet failed: %v", err) + } else if contained { + t.Fatal("got s.ContainsSubnet(...) = true, want = false") + } +} + +func TestGetMainNICAddress(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) + id, _ := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + for _, tc := range []struct { + name string + address tcpip.Address + }{ + {"IPv4", "\x01\x01\x01\x01"}, + {"IPv6", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"}, + } { + t.Run(tc.name, func(t *testing.T) { + address := tc.address + mask := tcpip.AddressMask(strings.Repeat("\xff", len(address))) + subnet, err := tcpip.NewSubnet(address, mask) + if err != nil { + t.Fatalf("NewSubnet failed: %v", err) + } + + if err := s.AddAddress(1, fakeNetNumber, address); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + if err := s.AddSubnet(1, fakeNetNumber, subnet); err != nil { + t.Fatalf("AddSubnet failed: %v", err) + } + + // Check that we get the right initial address and subnet. + if gotAddress, gotSubnet, err := s.GetMainNICAddress(1, fakeNetNumber); err != nil { + t.Fatalf("GetMainNICAddress failed: %v", err) + } else if gotAddress != address { + t.Fatalf("got GetMainNICAddress = (%v, ...), want = (%v, ...)", gotAddress, address) + } else if gotSubnet != subnet { + t.Fatalf("got GetMainNICAddress = (..., %v), want = (..., %v)", gotSubnet, subnet) + } + + if err := s.RemoveSubnet(1, subnet); err != nil { + t.Fatalf("RemoveSubnet failed: %v", err) + } + + if err := s.RemoveAddress(1, address); err != nil { + t.Fatalf("RemoveAddress failed: %v", err) + } + + // Check that we get an error after removal. + if _, _, err := s.GetMainNICAddress(1, fakeNetNumber); err != tcpip.ErrNoLinkAddress { + t.Fatalf("got s.GetMainNICAddress(...) = %v, want = %v", err, tcpip.ErrNoLinkAddress) + } + }) + } +} + func init() { stack.RegisterNetworkProtocolFactory("fakeNet", func() stack.NetworkProtocol { return &fakeNetworkProtocol{} -- cgit v1.2.3 From 5685d6b5add2acce9618aa908b846f5ce3658346 Mon Sep 17 00:00:00 2001 From: Bert Muthalaly Date: Wed, 5 Sep 2018 17:33:18 -0700 Subject: Update {LinkEndpoint,NetworkEndpoint}#WritePacket to take a VectorisedView Makes it possible to avoid copying or allocating in cases where DeliverNetworkPacket (rx) needs to turn around and call WritePacket (tx) with its VectorisedView. Also removes the restriction on having VectorisedViews with multiple views in the write path. PiperOrigin-RevId: 211728717 Change-Id: Ie03a65ecb4e28bd15ebdb9c69f05eced18fdfcff --- pkg/tcpip/buffer/view.go | 2 +- pkg/tcpip/link/channel/channel.go | 12 ++++------ pkg/tcpip/link/fdbased/endpoint.go | 12 +++++----- pkg/tcpip/link/fdbased/endpoint_test.go | 7 +++--- pkg/tcpip/link/loopback/loopback.go | 18 +++++---------- pkg/tcpip/link/sharedmem/sharedmem.go | 5 +++-- pkg/tcpip/link/sharedmem/sharedmem_test.go | 35 ++++++++++++++++-------------- pkg/tcpip/link/sniffer/sniffer.go | 30 +++++++++++++++---------- pkg/tcpip/link/waitable/waitable.go | 2 +- pkg/tcpip/link/waitable/waitable_test.go | 8 +++---- pkg/tcpip/network/arp/arp.go | 6 ++--- pkg/tcpip/network/ip_test.go | 18 +++++++-------- pkg/tcpip/network/ipv4/icmp.go | 3 ++- pkg/tcpip/network/ipv4/ipv4.go | 4 ++-- pkg/tcpip/network/ipv6/icmp.go | 22 ++++++++++--------- pkg/tcpip/network/ipv6/icmp_test.go | 2 +- pkg/tcpip/network/ipv6/ipv6.go | 7 ++---- pkg/tcpip/stack/registration.go | 4 ++-- pkg/tcpip/stack/route.go | 2 +- pkg/tcpip/stack/stack_test.go | 5 ++--- pkg/tcpip/stack/transport_test.go | 3 ++- pkg/tcpip/transport/ping/endpoint.go | 7 +++--- pkg/tcpip/transport/tcp/connect.go | 34 ++++++++++++++--------------- pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/tcp/snd.go | 18 +++++---------- pkg/tcpip/transport/udp/endpoint.go | 12 +++++----- 26 files changed, 137 insertions(+), 143 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index 85ae38ac8..d151b8cf0 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -152,7 +152,7 @@ func (vv *VectorisedView) Size() int { return vv.size } -// ToView returns the a single view containing the content of the vectorised view. +// ToView returns a single view containing the content of the vectorised view. func (vv *VectorisedView) ToView() View { v := make([]byte, vv.size) u := v diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index dd3fe7c87..6983fae3f 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -111,15 +111,11 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { } // WritePacket stores outbound packets into the channel. -func (e *Endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { p := PacketInfo{ - Header: hdr.View(), - Proto: protocol, - } - - if payload != nil { - p.Payload = make(buffer.View, len(payload)) - copy(p.Payload, payload) + Header: hdr.View(), + Proto: protocol, + Payload: payload.ToView(), } select { diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 449acdfdd..12c249c0d 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -161,10 +161,12 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if e.handleLocal && r.LocalAddress != "" && r.LocalAddress == r.RemoteAddress { - hdrView := hdr.View() - vv := buffer.NewVectorisedView(len(hdrView)+len(payload), []buffer.View{hdrView, payload}) + views := make([]buffer.View, 1, 1+len(payload.Views())) + views[0] = hdr.View() + views = append(views, payload.Views()...) + vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, &vv) return nil } @@ -178,11 +180,11 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload }) } - if len(payload) == 0 { + if payload.Size() == 0 { return rawfile.NonBlockingWrite(e.fd, hdr.UsedBytes()) } - return rawfile.NonBlockingWrite2(e.fd, hdr.UsedBytes(), payload) + return rawfile.NonBlockingWrite2(e.fd, hdr.UsedBytes(), payload.ToView()) } func (e *endpoint) capViews(n int, buffers []int) int { diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 89e791543..408169bbe 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -152,13 +152,14 @@ func TestWritePacket(t *testing.T) { b[i] = uint8(rand.Intn(256)) } - // Buiild payload and write. - payload := make([]byte, plen) + // Build payload and write. + payload := make(buffer.View, plen) for i := range payload { payload[i] = uint8(rand.Intn(256)) } want := append(hdr.UsedBytes(), payload...) - if err := c.ep.WritePacket(r, &hdr, payload, proto); err != nil { + vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) + if err := c.ep.WritePacket(r, &hdr, vv, proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 015275721..4a750fa12 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -72,18 +72,12 @@ func (*endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements stack.LinkEndpoint.WritePacket. It delivers outbound // packets to the network-layer dispatcher. -func (e *endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { - if len(payload) == 0 { - // We don't have a payload, so just use the buffer from the - // header as the full packet. - v := hdr.View() - vv := v.ToVectorisedView([1]buffer.View{}) - e.dispatcher.DeliverNetworkPacket(e, "", protocol, &vv) - } else { - views := []buffer.View{hdr.View(), payload} - vv := buffer.NewVectorisedView(len(views[0])+len(views[1]), views) - e.dispatcher.DeliverNetworkPacket(e, "", protocol, &vv) - } +func (e *endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { + views := make([]buffer.View, 1, 1+len(payload.Views())) + views[0] = hdr.View() + views = append(views, payload.Views()...) + vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) + e.dispatcher.DeliverNetworkPacket(e, "", protocol, &vv) return nil } diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 824cab093..6bd5441f6 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -184,7 +184,7 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { // Add the ethernet header here. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) eth.Encode(&header.EthernetFields{ @@ -193,9 +193,10 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload Type: protocol, }) + v := payload.ToView() // Transmit the packet. e.mu.Lock() - ok := e.tx.transmit(hdr.UsedBytes(), payload) + ok := e.tx.transmit(hdr.UsedBytes(), v) e.mu.Unlock() if !ok { diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 1e229279a..69d4ef29f 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -270,8 +270,8 @@ func TestSimpleSend(t *testing.T) { randomFill(buf) proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) - err := c.ep.WritePacket(&r, &hdr, buf, proto) - if err != nil { + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) + if err := c.ep.WritePacket(&r, &hdr, vv, proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } @@ -330,13 +330,15 @@ func TestFillTxQueue(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses no more than 40 bytes, so write that many packets // until the tx queue if full. ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -351,8 +353,7 @@ func TestFillTxQueue(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -373,11 +374,12 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Send two packets so that the id slice has at least two slots. for i := 2; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } @@ -397,7 +399,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -412,8 +414,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -430,13 +431,14 @@ func TestFillTxMemory(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses up one buffer, so write as many as possible until // we fill the memory. ids := make(map[uint64]struct{}) for i := queueDataSize / bufferSize; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -452,7 +454,7 @@ func TestFillTxMemory(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) + err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber) if want := tcpip.ErrWouldBlock; err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } @@ -472,12 +474,13 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses up one buffer, so write as many as possible // until there is only one buffer left. for i := queueDataSize/bufferSize - 1; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -488,14 +491,14 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { // Attempt to write a two-buffer packet. It must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buffer.NewView(bufferSize), header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + uu := buffer.NewVectorisedView(bufferSize, []buffer.View{buffer.NewView(bufferSize)}) + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, uu, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } - // Attempt to write a one-buffer packet. It must succeed. + // Attempt to write the one-buffer packet again. It must succeed. hdr = buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 1e302f557..3bdc85210 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -118,7 +118,7 @@ func NewWithFile(lower tcpip.LinkEndpointID, file *os.File, snapLen uint32) (tcp // logs the packet before forwarding to the actual dispatcher. func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { - logPacket("recv", protocol, vv.First(), nil) + logPacket("recv", protocol, vv.First()) } if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 { vs := vv.Views() @@ -188,19 +188,19 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements the stack.LinkEndpoint interface. It is called by // higher-level protocols to write packets; it just logs the packet and forwards // the request to the lower endpoint. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { - logPacket("send", protocol, hdr.UsedBytes(), payload) + logPacket("send", protocol, hdr.UsedBytes()) } if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 { hdrBuf := hdr.UsedBytes() - length := len(hdrBuf) + len(payload) + length := len(hdrBuf) + payload.Size() if length > int(e.maxPCAPLen) { length = int(e.maxPCAPLen) } buf := bytes.NewBuffer(make([]byte, 0, pcapPacketHeaderLen+length)) - if err := binary.Write(buf, binary.BigEndian, newPCAPPacketHeader(uint32(length), uint32(hdr.UsedLength()+len(payload)))); err != nil { + if err := binary.Write(buf, binary.BigEndian, newPCAPPacketHeader(uint32(length), uint32(len(hdrBuf)+payload.Size()))); err != nil { panic(err) } if len(hdrBuf) > length { @@ -211,12 +211,18 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload } length -= len(hdrBuf) if length > 0 { - p := payload - if len(p) > length { - p = p[:length] - } - if _, err := buf.Write(p); err != nil { - panic(err) + for _, v := range payload.Views() { + if len(v) > length { + v = v[:length] + } + n, err := buf.Write(v) + if err != nil { + panic(err) + } + length -= n + if length == 0 { + break + } } } if _, err := e.file.Write(buf.Bytes()); err != nil { @@ -226,7 +232,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload return e.lower.WritePacket(r, hdr, payload, protocol) } -func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byte) { +func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b buffer.View) { // Figure out the network layer info. var transProto uint8 src := tcpip.Address("unknown") diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 08b8d66e7..1c19a4509 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -100,7 +100,7 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements stack.LinkEndpoint.WritePacket. It is called by // higher-level protocols to write packets. It only forwards packets to the // lower endpoint if Wait or WaitWrite haven't been called. -func (e *Endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if !e.writeGate.Enter() { return nil } diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 37efa60d6..0719a95a9 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -65,7 +65,7 @@ func (e *countedEndpoint) LinkAddress() tcpip.LinkAddress { return e.linkAddr } -func (e *countedEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *countedEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { e.writeCount++ return nil } @@ -75,21 +75,21 @@ func TestWaitWrite(t *testing.T) { _, wep := New(stack.RegisterLinkEndpoint(ep)) // Write and check that it goes through. - wep.WritePacket(nil, nil, nil, 0) + wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) if want := 1; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } // Wait on dispatches, then try to write. It must go through. wep.WaitDispatch() - wep.WritePacket(nil, nil, nil, 0) + wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) if want := 2; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } // Wait on writes, then try to write. It must not go through. wep.WaitWrite() - wep.WritePacket(nil, nil, nil, 0) + wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) if want := 2; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index e7dfc6444..6bf4be868 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -74,7 +74,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { func (e *endpoint) Close() {} -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { return tcpip.ErrNotSupported } @@ -98,7 +98,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { copy(pkt.HardwareAddressSender(), r.LocalLinkAddress[:]) copy(pkt.ProtocolAddressSender(), h.ProtocolAddressTarget()) copy(pkt.ProtocolAddressTarget(), h.ProtocolAddressSender()) - e.linkEP.WritePacket(r, &hdr, nil, ProtocolNumber) + e.linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber) fallthrough // also fill the cache from requests case header.ARPReply: addr := tcpip.Address(h.ProtocolAddressSender()) @@ -150,7 +150,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. copy(h.ProtocolAddressSender(), localAddr) copy(h.ProtocolAddressTarget(), addr) - return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber) + return linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber) } // ResolveStaticAddress implements stack.LinkAddressResolver. diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 4475a75cf..1e92b7ae9 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -66,7 +66,7 @@ type testObject struct { // checkValues verifies that the transport protocol, data contents, src & dst // addresses of a packet match what's expected. If any field doesn't match, the // test fails. -func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView, srcAddr, dstAddr tcpip.Address) { +func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView, srcAddr, dstAddr tcpip.Address) { v := vv.ToView() if protocol != t.protocol { t.t.Errorf("protocol = %v, want %v", protocol, t.protocol) @@ -95,7 +95,7 @@ func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv *buf // packets. This is used by the test object to verify that the results of the // parsing are expected. func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) { - t.checkValues(protocol, vv, r.RemoteAddress, r.LocalAddress) + t.checkValues(protocol, *vv, r.RemoteAddress, r.LocalAddress) t.dataCalls++ } @@ -103,7 +103,7 @@ func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.Trans // incoming control (ICMP) packets. This is used by the test object to verify // that the results of the parsing are expected. func (t *testObject) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ stack.ControlType, extra uint32, vv *buffer.VectorisedView) { - t.checkValues(trans, vv, remote, local) + t.checkValues(trans, *vv, remote, local) if typ != t.typ { t.t.Errorf("typ = %v, want %v", typ, t.typ) } @@ -145,7 +145,7 @@ func (*testObject) LinkAddress() tcpip.LinkAddress { // WritePacket is called by network endpoints after producing a packet and // writing it to the link endpoint. This is used by the test object to verify // that the produced packet is as expected. -func (t *testObject) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (t *testObject) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { var prot tcpip.TransportProtocolNumber var srcAddr tcpip.Address var dstAddr tcpip.Address @@ -162,9 +162,7 @@ func (t *testObject) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payloa srcAddr = h.SourceAddress() dstAddr = h.DestinationAddress() } - var views [1]buffer.View - vv := payload.ToVectorisedView(views) - t.checkValues(prot, &vv, srcAddr, dstAddr) + t.checkValues(prot, payload, srcAddr, dstAddr) return nil } @@ -223,7 +221,8 @@ func TestIPv4Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - if err := ep.WritePacket(&r, &hdr, payload, 123); err != nil { + vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) + if err := ep.WritePacket(&r, &hdr, vv, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) } } @@ -461,7 +460,8 @@ func TestIPv6Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - if err := ep.WritePacket(&r, &hdr, payload, 123); err != nil { + vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) + if err := ep.WritePacket(&r, &hdr, vv, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) } } diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index d11938d6e..de21e623e 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -120,5 +120,6 @@ func sendPing4(r *stack.Route, code byte, data buffer.View) *tcpip.Error { data = data[header.ICMPv4EchoMinimumSize-header.ICMPv4MinimumSize:] icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) - return r.WritePacket(&hdr, data, header.ICMPv4ProtocolNumber) + vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) + return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber) } diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index 143d8e73e..478957827 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -106,9 +106,9 @@ func (e *endpoint) MaxHeaderLength() uint16 { } // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize)) - length := uint16(hdr.UsedLength() + len(payload)) + length := uint16(hdr.UsedLength() + payload.Size()) id := uint32(0) if length > header.IPv4MaximumHeaderSize+8 { // Packets of 68 bytes or less are required by RFC 791 to not be diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index e3ef89d26..b18b78830 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -62,6 +62,7 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv *buffer e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv) } +// TODO: take buffer.VectorisedView by value. func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { v := vv.First() if len(v) < header.ICMPv6MinimumSize { @@ -105,8 +106,8 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { pkt[icmpV6OptOffset] = ndpOptDstLinkAddr pkt[icmpV6LengthOffset] = 1 copy(pkt[icmpV6LengthOffset+1:], r.LocalLinkAddress[:]) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) - r.WritePacket(&hdr, nil, header.ICMPv6ProtocolNumber) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{})) + r.WritePacket(&hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber) e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) @@ -125,13 +126,12 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { return } vv.TrimFront(header.ICMPv6EchoMinimumSize) - data := vv.ToView() hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize) pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) copy(pkt, h) pkt.SetType(header.ICMPv6EchoReply) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, data)) - r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, *vv)) + r.WritePacket(&hdr, *vv, header.ICMPv6ProtocolNumber) case header.ICMPv6EchoReply: if len(v) < header.ICMPv6EchoMinimumSize { @@ -185,7 +185,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. pkt[icmpV6OptOffset] = ndpOptSrcLinkAddr pkt[icmpV6LengthOffset] = 1 copy(pkt[icmpV6LengthOffset+1:], linkEP.LinkAddress()) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{})) length := uint16(hdr.UsedLength()) ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) @@ -197,7 +197,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. DstAddr: r.RemoteAddress, }) - return linkEP.WritePacket(r, &hdr, nil, ProtocolNumber) + return linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber) } // ResolveStaticAddress implements stack.LinkAddressResolver. @@ -205,15 +205,17 @@ func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bo return "", false } -func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, data []byte) uint16 { +func icmpChecksum(h header.ICMPv6, src, dst tcpip.Address, vv buffer.VectorisedView) uint16 { // Calculate the IPv6 pseudo-header upper-layer checksum. xsum := header.Checksum([]byte(src), 0) xsum = header.Checksum([]byte(dst), xsum) var upperLayerLength [4]byte - binary.BigEndian.PutUint32(upperLayerLength[:], uint32(len(h)+len(data))) + binary.BigEndian.PutUint32(upperLayerLength[:], uint32(len(h)+vv.Size())) xsum = header.Checksum(upperLayerLength[:], xsum) xsum = header.Checksum([]byte{0, 0, 0, uint8(header.ICMPv6ProtocolNumber)}, xsum) - xsum = header.Checksum(data, xsum) + for _, v := range vv.Views() { + xsum = header.Checksum(v, xsum) + } // h[2:4] is the checksum itself, set it aside to avoid checksumming the checksum. h2, h3 := h[2], h[3] diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index 582bbb40e..e9f400fe4 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -186,7 +186,7 @@ func TestLinkResolution(t *testing.T) { hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize) pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) pkt.SetType(header.ICMPv6EchoRequest) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, nil)) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{})) payload := tcpip.SlicePayload(hdr.UsedBytes()) // We can't send our payload directly over the route because that diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index cdb8284a2..19dc1b49e 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -82,11 +82,8 @@ func (e *endpoint) MaxHeaderLength() uint16 { } // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error { - length := uint16(hdr.UsedLength()) - if payload != nil { - length += uint16(len(payload)) - } +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { + length := uint16(hdr.UsedLength() + payload.Size()) ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) ip.Encode(&header.IPv6Fields{ PayloadLength: length, diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index bbe887144..b9e2cc045 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -141,7 +141,7 @@ type NetworkEndpoint interface { // WritePacket writes a packet to the given destination address and // protocol. - WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error + WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error // ID returns the network protocol endpoint ID. ID() *NetworkEndpointID @@ -234,7 +234,7 @@ type LinkEndpoint interface { // WritePacket writes a packet with the given protocol through the given // route. - WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error + WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error // Attach attaches the data link layer endpoint to the network-layer // dispatcher of the stack. diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 63a20e031..533a0b560 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -129,7 +129,7 @@ func (r *Route) IsResolutionRequired() bool { } // WritePacket writes the packet through the given route. -func (r *Route) WritePacket(hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error { +func (r *Route) WritePacket(hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { err := r.ref.ep.WritePacket(r, hdr, payload, protocol) if err == tcpip.ErrNoRoute { r.Stats().IP.OutgoingPacketErrors.Increment() diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index c46e91241..02f02dfa2 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -105,7 +105,7 @@ func (f *fakeNetworkEndpoint) Capabilities() stack.LinkEndpointCapabilities { return f.linkEP.Capabilities() } -func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.TransportProtocolNumber) *tcpip.Error { +func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { // Increment the sent packet count in the protocol descriptor. f.proto.sendPacketCount[int(r.RemoteAddress[0])%len(f.proto.sendPacketCount)]++ @@ -269,8 +269,7 @@ func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address) { defer r.Release() hdr := buffer.NewPrependable(int(r.MaxHeaderLength())) - err = r.WritePacket(&hdr, nil, fakeTransNumber) - if err != nil { + if err := r.WritePacket(&hdr, buffer.VectorisedView{}, fakeTransNumber); err != nil { t.Errorf("WritePacket failed: %v", err) return } diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 98d2f9d99..5ab485c98 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -70,7 +70,8 @@ func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) if err != nil { return 0, err } - if err := f.route.WritePacket(&hdr, v, fakeTransNumber); err != nil { + vv := buffer.NewVectorisedView(len(v), []buffer.View{v}) + if err := f.route.WritePacket(&hdr, vv, fakeTransNumber); err != nil { return 0, err } diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index 7e10c0aae..fc98c41eb 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -384,7 +384,8 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv4.SetChecksum(0) icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) - return r.WritePacket(&hdr, data, header.ICMPv4ProtocolNumber) + vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) + return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber) } func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { @@ -407,8 +408,8 @@ func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv6.SetChecksum(0) icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0))) - - return r.WritePacket(&hdr, data, header.ICMPv6ProtocolNumber) + vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) + return r.WritePacket(&hdr, vv, header.ICMPv6ProtocolNumber) } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 558dbc50a..de5f963cf 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -166,7 +166,7 @@ func (h *handshake) checkAck(s *segment) bool { // incoming segment acknowledges something not yet sent. The // connection remains in the same state. ack := s.sequenceNumber.Add(s.logicalLen()) - h.ep.sendRaw(nil, flagRst|flagAck, s.ackNumber, ack, 0) + h.ep.sendRaw(buffer.VectorisedView{}, flagRst|flagAck, s.ackNumber, ack, 0) return false } @@ -214,7 +214,7 @@ func (h *handshake) synSentState(s *segment) *tcpip.Error { // and the handshake is completed. if s.flagIsSet(flagAck) { h.state = handshakeCompleted - h.ep.sendRaw(nil, flagAck, h.iss+1, h.ackNum, h.rcvWnd>>h.effectiveRcvWndScale()) + h.ep.sendRaw(buffer.VectorisedView{}, flagAck, h.iss+1, h.ackNum, h.rcvWnd>>h.effectiveRcvWndScale()) return nil } @@ -263,7 +263,7 @@ func (h *handshake) synRcvdState(s *segment) *tcpip.Error { if s.flagIsSet(flagAck) { seq = s.ackNumber } - h.ep.sendRaw(nil, flagRst|flagAck, seq, ack, 0) + h.ep.sendRaw(buffer.VectorisedView{}, flagRst|flagAck, seq, ack, 0) if !h.active { return tcpip.ErrInvalidEndpointState @@ -563,14 +563,14 @@ func sendSynTCP(r *stack.Route, id stack.TransportEndpointID, flags byte, seq, a } options := makeSynOptions(opts) - err := sendTCPWithOptions(r, id, nil, flags, seq, ack, rcvWnd, options) + err := sendTCPWithOptions(r, id, buffer.VectorisedView{}, flags, seq, ack, rcvWnd, options) putOptions(options) return err } // sendTCPWithOptions sends a TCP segment with the provided options via the // provided network endpoint and under the provided identity. -func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffer.View, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte) *tcpip.Error { +func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte) *tcpip.Error { optLen := len(opts) // Allocate a buffer for the TCP header. hdr := buffer.NewPrependable(header.TCPMinimumSize + int(r.MaxHeaderLength()) + optLen) @@ -594,11 +594,10 @@ func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffe // Only calculate the checksum if offloading isn't supported. if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { - length := uint16(hdr.UsedLength()) + length := uint16(hdr.UsedLength() + data.Size()) xsum := r.PseudoHeaderChecksum(ProtocolNumber) - if data != nil { - length += uint16(len(data)) - xsum = header.Checksum(data, xsum) + for _, v := range data.Views() { + xsum = header.Checksum(v, xsum) } tcp.SetChecksum(^tcp.CalculateChecksum(xsum, length)) @@ -614,7 +613,7 @@ func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffe // sendTCP sends a TCP segment via the provided network endpoint and under the // provided identity. -func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.View, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error { +func sendTCP(r *stack.Route, id stack.TransportEndpointID, payload buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error { // Allocate a buffer for the TCP header. hdr := buffer.NewPrependable(header.TCPMinimumSize + int(r.MaxHeaderLength())) @@ -636,11 +635,10 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.View, fla // Only calculate the checksum if offloading isn't supported. if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { - length := uint16(hdr.UsedLength()) + length := uint16(hdr.UsedLength() + payload.Size()) xsum := r.PseudoHeaderChecksum(ProtocolNumber) - if data != nil { - length += uint16(len(data)) - xsum = header.Checksum(data, xsum) + for _, v := range payload.Views() { + xsum = header.Checksum(v, xsum) } tcp.SetChecksum(^tcp.CalculateChecksum(xsum, length)) @@ -651,7 +649,7 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.View, fla r.Stats().TCP.ResetsSent.Increment() } - return r.WritePacket(&hdr, data, ProtocolNumber) + return r.WritePacket(&hdr, payload, ProtocolNumber) } // makeOptions makes an options slice. @@ -694,7 +692,7 @@ func (e *endpoint) makeOptions(sackBlocks []header.SACKBlock) []byte { } // sendRaw sends a TCP segment to the endpoint's peer. -func (e *endpoint) sendRaw(data buffer.View, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error { +func (e *endpoint) sendRaw(data buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error { var sackBlocks []header.SACKBlock if e.state == stateConnected && e.rcv.pendingBufSize > 0 && (flags&flagAck != 0) { sackBlocks = e.sack.Blocks[:e.sack.NumBlocks] @@ -751,7 +749,7 @@ func (e *endpoint) handleClose() *tcpip.Error { // state with the given error code. This method must only be called from the // protocol goroutine. func (e *endpoint) resetConnectionLocked(err *tcpip.Error) { - e.sendRaw(nil, flagAck|flagRst, e.snd.sndUna, e.rcv.rcvNxt, 0) + e.sendRaw(buffer.VectorisedView{}, flagAck|flagRst, e.snd.sndUna, e.rcv.rcvNxt, 0) e.state = stateError e.hardError = err @@ -851,7 +849,7 @@ func (e *endpoint) keepaliveTimerExpired() *tcpip.Error { // seg.seq = snd.nxt-1. e.keepalive.unacked++ e.keepalive.Unlock() - e.snd.sendSegment(nil, flagAck, e.snd.sndNxt-1) + e.snd.sendSegment(buffer.VectorisedView{}, flagAck, e.snd.sndNxt-1) e.resetKeepaliveTimer(false) return nil } diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index 194d3f41d..006b2f074 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -147,7 +147,7 @@ func replyWithReset(s *segment) { ack := s.sequenceNumber.Add(s.logicalLen()) - sendTCP(&s.route, s.id, nil, flagRst|flagAck, seq, ack, 0) + sendTCP(&s.route, s.id, buffer.VectorisedView{}, flagRst|flagAck, seq, ack, 0) } // SetOption implements TransportProtocol.SetOption. diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index e4fa89912..284e720c6 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -270,7 +270,7 @@ func (s *sender) updateMaxPayloadSize(mtu, count int) { // sendAck sends an ACK segment. func (s *sender) sendAck() { - s.sendSegment(nil, flagAck, s.sndNxt) + s.sendSegment(buffer.VectorisedView{}, flagAck, s.sndNxt) } // updateRTO updates the retransmit timeout when a new roud-trip time is @@ -305,7 +305,7 @@ func (s *sender) resendSegment() { // Resend the segment. if seg := s.writeList.Front(); seg != nil { - s.sendSegment(&seg.data, seg.flags, seg.sequenceNumber) + s.sendSegment(seg.data, seg.flags, seg.sequenceNumber) } } @@ -419,7 +419,7 @@ func (s *sender) sendData() { segEnd = seg.sequenceNumber.Add(seqnum.Size(seg.data.Size())) } - s.sendSegment(&seg.data, seg.flags, seg.sequenceNumber) + s.sendSegment(seg.data, seg.flags, seg.sequenceNumber) // Update sndNxt if we actually sent new data (as opposed to // retransmitting some previously sent data). @@ -642,7 +642,7 @@ func (s *sender) handleRcvdSegment(seg *segment) { // sendSegment sends a new segment containing the given payload, flags and // sequence number. -func (s *sender) sendSegment(data *buffer.VectorisedView, flags byte, seq seqnum.Value) *tcpip.Error { +func (s *sender) sendSegment(data buffer.VectorisedView, flags byte, seq seqnum.Value) *tcpip.Error { s.lastSendTime = time.Now() if seq == s.rttMeasureSeqNum { s.rttMeasureTime = s.lastSendTime @@ -653,13 +653,5 @@ func (s *sender) sendSegment(data *buffer.VectorisedView, flags byte, seq seqnum // Remember the max sent ack. s.maxSentAck = rcvNxt - if data == nil { - return s.ep.sendRaw(nil, flags, seq, rcvNxt, rcvWnd) - } - - if len(data.Views()) > 1 { - panic("send path does not support views with multiple buffers") - } - - return s.ep.sendRaw(data.First(), flags, seq, rcvNxt, rcvWnd) + return s.ep.sendRaw(data, flags, seq, rcvNxt, rcvWnd) } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 6a12c2f08..283379a28 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -328,7 +328,8 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc return 0, err } - if err := sendUDP(route, v, e.id.LocalPort, dstPort); err != nil { + vv := buffer.NewVectorisedView(len(v), []buffer.View{v}) + if err := sendUDP(route, vv, e.id.LocalPort, dstPort); err != nil { return 0, err } return uintptr(len(v)), nil @@ -426,14 +427,14 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { // sendUDP sends a UDP segment via the provided network endpoint and under the // provided identity. -func sendUDP(r *stack.Route, data buffer.View, localPort, remotePort uint16) *tcpip.Error { +func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16) *tcpip.Error { // Allocate a buffer for the UDP header. hdr := buffer.NewPrependable(header.UDPMinimumSize + int(r.MaxHeaderLength())) // Initialize the header. udp := header.UDP(hdr.Prepend(header.UDPMinimumSize)) - length := uint16(hdr.UsedLength()) + uint16(len(data)) + length := uint16(hdr.UsedLength() + data.Size()) udp.Encode(&header.UDPFields{ SrcPort: localPort, DstPort: remotePort, @@ -443,10 +444,9 @@ func sendUDP(r *stack.Route, data buffer.View, localPort, remotePort uint16) *tc // Only calculate the checksum if offloading isn't supported. if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { xsum := r.PseudoHeaderChecksum(ProtocolNumber) - if data != nil { - xsum = header.Checksum(data, xsum) + for _, v := range data.Views() { + xsum = header.Checksum(v, xsum) } - udp.SetChecksum(^udp.CalculateChecksum(xsum, length)) } -- cgit v1.2.3 From 156b49ca85be7602ec034167767f0d0bfedf2be5 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 5 Sep 2018 18:58:09 -0700 Subject: Fix race condition introduced in 211135505 Now that it's possible to remove subnets, we must iterate over them with locks held. Also do the removal more efficiently while I'm here. PiperOrigin-RevId: 211737416 Change-Id: I29025ec8b0c3ad11f22d4447e8ad473f1c785463 --- pkg/tcpip/stack/nic.go | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 7aa960096..845b40f11 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -266,11 +266,14 @@ func (n *NIC) AddSubnet(protocol tcpip.NetworkProtocolNumber, subnet tcpip.Subne func (n *NIC) RemoveSubnet(subnet tcpip.Subnet) { n.mu.Lock() - for i, sub := range n.subnets { - if sub == subnet { - n.subnets = append(n.subnets[:i], n.subnets[i+1:]...) + // Use the same underlying array. + tmp := n.subnets[:0] + for _, sub := range n.subnets { + if sub != subnet { + tmp = append(tmp, sub) } } + n.subnets = tmp n.mu.Unlock() } @@ -369,33 +372,34 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin id := NetworkEndpointID{dst} n.mu.RLock() - ref := n.endpoints[id] - if ref != nil && !ref.tryIncRef() { + ref, ok := n.endpoints[id] + if ok && !ref.tryIncRef() { ref = nil } - promiscuous := n.promiscuous - subnets := n.subnets - n.mu.RUnlock() - - if ref == nil { + if ref != nil { + n.mu.RUnlock() + } else { + promiscuous := n.promiscuous // Check if the packet is for a subnet this NIC cares about. if !promiscuous { - for _, sn := range subnets { + for _, sn := range n.subnets { if sn.Contains(dst) { promiscuous = true break } } } + n.mu.RUnlock() if promiscuous { // Try again with the lock in exclusive mode. If we still can't // get the endpoint, create a new "temporary" one. It will only // exist while there's a route through it. n.mu.Lock() - ref = n.endpoints[id] - if ref == nil || !ref.tryIncRef() { - ref, _ = n.addAddressLocked(protocol, dst, true) - if ref != nil { + ref, ok = n.endpoints[id] + if !ok || !ref.tryIncRef() { + var err *tcpip.Error + ref, err = n.addAddressLocked(protocol, dst, true) + if err == nil { ref.holdsInsertRef = false } } -- cgit v1.2.3 From 5adb3468d4de249df055d641e01ce6582b3a9388 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 12 Sep 2018 20:38:27 -0700 Subject: Add multicast support PiperOrigin-RevId: 212750821 Change-Id: I822fd63e48c684b45fd91f9ce057867b7eceb792 --- pkg/dhcp/client.go | 6 +- pkg/tcpip/checker/checker.go | 16 +++ pkg/tcpip/header/ipv4.go | 16 +++ pkg/tcpip/header/ipv6.go | 9 ++ pkg/tcpip/network/arp/arp.go | 7 +- pkg/tcpip/network/ip_test.go | 4 +- pkg/tcpip/network/ipv4/BUILD | 18 ++- pkg/tcpip/network/ipv4/icmp.go | 2 +- pkg/tcpip/network/ipv4/ipv4.go | 13 +- pkg/tcpip/network/ipv4/ipv4_test.go | 92 ++++++++++++++ pkg/tcpip/network/ipv6/icmp.go | 5 +- pkg/tcpip/network/ipv6/ipv6.go | 22 ++-- pkg/tcpip/stack/nic.go | 53 ++++++-- pkg/tcpip/stack/registration.go | 6 +- pkg/tcpip/stack/route.go | 9 +- pkg/tcpip/stack/stack.go | 25 +++- pkg/tcpip/stack/stack_test.go | 8 +- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/tcpip.go | 22 ++++ pkg/tcpip/transport/ping/endpoint.go | 5 +- pkg/tcpip/transport/tcp/connect.go | 58 +-------- pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 123 +++++++++++++++--- pkg/tcpip/transport/udp/udp_test.go | 235 +++++++++++++++++++++++++++++------ 24 files changed, 605 insertions(+), 153 deletions(-) create mode 100644 pkg/tcpip/network/ipv4/ipv4_test.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 909040e79..cf8472c5f 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -119,10 +119,10 @@ func (c *Client) Config() Config { // If the server sets a lease limit a timer is set to automatically // renew it. func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg Config, reterr error) { - if err := c.stack.AddAddress(c.nicid, ipv4.ProtocolNumber, "\xff\xff\xff\xff"); err != nil && err != tcpip.ErrDuplicateAddress { + if err := c.stack.AddAddressWithOptions(c.nicid, ipv4.ProtocolNumber, "\xff\xff\xff\xff", stack.NeverPrimaryEndpoint); err != nil && err != tcpip.ErrDuplicateAddress { return Config{}, fmt.Errorf("dhcp: %v", err) } - if err := c.stack.AddAddress(c.nicid, ipv4.ProtocolNumber, "\x00\x00\x00\x00"); err != nil && err != tcpip.ErrDuplicateAddress { + if err := c.stack.AddAddressWithOptions(c.nicid, ipv4.ProtocolNumber, "\x00\x00\x00\x00", stack.NeverPrimaryEndpoint); err != nil && err != tcpip.ErrDuplicateAddress { return Config{}, fmt.Errorf("dhcp: %v", err) } defer c.stack.RemoveAddress(c.nicid, "\xff\xff\xff\xff") @@ -237,7 +237,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg // DHCPREQUEST addr := tcpip.Address(h.yiaddr()) - if err := c.stack.AddAddress(c.nicid, ipv4.ProtocolNumber, addr); err != nil { + if err := c.stack.AddAddressWithOptions(c.nicid, ipv4.ProtocolNumber, addr, stack.FirstPrimaryEndpoint); err != nil { if err != tcpip.ErrDuplicateAddress { return Config{}, fmt.Errorf("adding address: %v", err) } diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go index 518719de4..8e0e49efa 100644 --- a/pkg/tcpip/checker/checker.go +++ b/pkg/tcpip/checker/checker.go @@ -86,6 +86,22 @@ func DstAddr(addr tcpip.Address) NetworkChecker { } } +// TTL creates a checker that checks the TTL (ipv4) or HopLimit (ipv6). +func TTL(ttl uint8) NetworkChecker { + return func(t *testing.T, h []header.Network) { + var v uint8 + switch ip := h[0].(type) { + case header.IPv4: + v = ip.TTL() + case header.IPv6: + v = ip.HopLimit() + } + if v != ttl { + t.Fatalf("Bad TTL, got %v, want %v", v, ttl) + } + } +} + // PayloadLen creates a checker that checks the payload length. func PayloadLen(plen int) NetworkChecker { return func(t *testing.T, h []header.Network) { diff --git a/pkg/tcpip/header/ipv4.go b/pkg/tcpip/header/ipv4.go index 950c54f74..29570cc34 100644 --- a/pkg/tcpip/header/ipv4.go +++ b/pkg/tcpip/header/ipv4.go @@ -93,6 +93,12 @@ const ( // IPv4Version is the version of the ipv4 protocol. IPv4Version = 4 + + // IPv4Broadcast is the broadcast address of the IPv4 procotol. + IPv4Broadcast tcpip.Address = "\xff\xff\xff\xff" + + // IPv4Any is the non-routable IPv4 "any" meta address. + IPv4Any tcpip.Address = "\x00\x00\x00\x00" ) // Flags that may be set in an IPv4 packet. @@ -259,3 +265,13 @@ func (b IPv4) IsValid(pktSize int) bool { return true } + +// IsV4MulticastAddress determines if the provided address is an IPv4 multicast +// address (range 224.0.0.0 to 239.255.255.255). The four most significant bits +// will be 1110 = 0xe0. +func IsV4MulticastAddress(addr tcpip.Address) bool { + if len(addr) != IPv4AddressSize { + return false + } + return (addr[0] & 0xf0) == 0xe0 +} diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go index 62bc23c27..066e48a9a 100644 --- a/pkg/tcpip/header/ipv6.go +++ b/pkg/tcpip/header/ipv6.go @@ -193,3 +193,12 @@ func IsV4MappedAddress(addr tcpip.Address) bool { return strings.HasPrefix(string(addr), "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff") } + +// IsV6MulticastAddress determines if the provided address is an IPv6 +// multicast address (anything starting with FF). +func IsV6MulticastAddress(addr tcpip.Address) bool { + if len(addr) != IPv6AddressSize { + return false + } + return addr[0] == 0xff +} diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 6bf4be868..8f64e3f42 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -51,6 +51,11 @@ type endpoint struct { linkAddrCache stack.LinkAddressCache } +// DefaultTTL is unused for ARP. It implements stack.NetworkEndpoint. +func (e *endpoint) DefaultTTL() uint8 { + return 0 +} + func (e *endpoint) MTU() uint32 { lmtu := e.linkEP.MTU() return lmtu - uint32(e.MaxHeaderLength()) @@ -74,7 +79,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { func (e *endpoint) Close() {} -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { return tcpip.ErrNotSupported } diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 1e92b7ae9..0cb53fb42 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -222,7 +222,7 @@ func TestIPv4Send(t *testing.T) { t.Fatalf("could not find route: %v", err) } vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) - if err := ep.WritePacket(&r, &hdr, vv, 123); err != nil { + if err := ep.WritePacket(&r, &hdr, vv, 123, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) } } @@ -461,7 +461,7 @@ func TestIPv6Send(t *testing.T) { t.Fatalf("could not find route: %v", err) } vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) - if err := ep.WritePacket(&r, &hdr, vv, 123); err != nil { + if err := ep.WritePacket(&r, &hdr, vv, 123, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) } } diff --git a/pkg/tcpip/network/ipv4/BUILD b/pkg/tcpip/network/ipv4/BUILD index 19314e9bd..90d65d531 100644 --- a/pkg/tcpip/network/ipv4/BUILD +++ b/pkg/tcpip/network/ipv4/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ipv4", @@ -21,3 +21,19 @@ go_library( "//pkg/tcpip/stack", ], ) + +go_test( + name = "ipv4_test", + size = "small", + srcs = ["ipv4_test.go"], + deps = [ + "//pkg/tcpip", + "//pkg/tcpip/header", + "//pkg/tcpip/link/channel", + "//pkg/tcpip/link/sniffer", + "//pkg/tcpip/network/ipv4", + "//pkg/tcpip/stack", + "//pkg/tcpip/transport/udp", + "//pkg/waiter", + ], +) diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index de21e623e..74454f605 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -121,5 +121,5 @@ func sendPing4(r *stack.Route, code byte, data buffer.View) *tcpip.Error { icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) - return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber) + return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber, r.DefaultTTL()) } diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index 478957827..0a2378a6a 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -44,10 +44,6 @@ const ( // buckets is the number of identifier buckets. buckets = 2048 - - // defaultIPv4TTL is the defautl TTL for IPv4 Packets egressed by - // Netstack. - defaultIPv4TTL = 255 ) type address [header.IPv4AddressSize]byte @@ -78,6 +74,11 @@ func newEndpoint(nicid tcpip.NICID, addr tcpip.Address, dispatcher stack.Transpo return e } +// DefaultTTL is the default time-to-live value for this endpoint. +func (e *endpoint) DefaultTTL() uint8 { + return 255 +} + // MTU implements stack.NetworkEndpoint.MTU. It returns the link-layer MTU minus // the network layer max header length. func (e *endpoint) MTU() uint32 { @@ -106,7 +107,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { } // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize)) length := uint16(hdr.UsedLength() + payload.Size()) id := uint32(0) @@ -119,7 +120,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload IHL: header.IPv4MinimumSize, TotalLength: length, ID: uint16(id), - TTL: defaultIPv4TTL, + TTL: ttl, Protocol: uint8(protocol), SrcAddr: tcpip.Address(e.address[:]), DstAddr: r.RemoteAddress, diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go new file mode 100644 index 000000000..2b7067a50 --- /dev/null +++ b/pkg/tcpip/network/ipv4/ipv4_test.go @@ -0,0 +1,92 @@ +// Copyright 2018 Google Inc. +// +// 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 ipv4_test + +import ( + "testing" + + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/sniffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv4" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/udp" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +func TestExcludeBroadcast(t *testing.T) { + s := stack.New([]string{ipv4.ProtocolName}, []string{udp.ProtocolName}, stack.Options{}) + + const defaultMTU = 65536 + id, _ := channel.New(256, defaultMTU, "") + if testing.Verbose() { + id = sniffer.New(id) + } + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + if err := s.AddAddress(1, ipv4.ProtocolNumber, header.IPv4Broadcast); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + if err := s.AddAddress(1, ipv4.ProtocolNumber, header.IPv4Any); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{{ + Destination: "\x00\x00\x00\x00", + Mask: "\x00\x00\x00\x00", + Gateway: "", + NIC: 1, + }}) + + randomAddr := tcpip.FullAddress{NIC: 1, Addr: "\x0a\x00\x00\x01", Port: 53} + + var wq waiter.Queue + t.Run("WithoutPrimaryAddress", func(t *testing.T) { + ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq) + if err != nil { + t.Fatal(err) + } + defer ep.Close() + + // Cannot connect using a broadcast address as the source. + if err := ep.Connect(randomAddr); err != tcpip.ErrNoRoute { + t.Errorf("got ep.Connect(...) = %v, want = %v", err, tcpip.ErrNoRoute) + } + + // However, we can bind to a broadcast address to listen. + if err := ep.Bind(tcpip.FullAddress{Addr: header.IPv4Broadcast, Port: 53, NIC: 1}, nil); err != nil { + t.Errorf("Bind failed: %v", err) + } + }) + + t.Run("WithPrimaryAddress", func(t *testing.T) { + ep, err := s.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq) + if err != nil { + t.Fatal(err) + } + defer ep.Close() + + // Add a valid primary endpoint address, now we can connect. + if err := s.AddAddress(1, ipv4.ProtocolNumber, "\x0a\x00\x00\x02"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + if err := ep.Connect(randomAddr); err != nil { + t.Errorf("Connect failed: %v", err) + } + }) +} diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index b18b78830..2158ba8f7 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -62,7 +62,6 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv *buffer e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv) } -// TODO: take buffer.VectorisedView by value. func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { v := vv.First() if len(v) < header.ICMPv6MinimumSize { @@ -107,7 +106,7 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { pkt[icmpV6LengthOffset] = 1 copy(pkt[icmpV6LengthOffset+1:], r.LocalLinkAddress[:]) pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{})) - r.WritePacket(&hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber) + r.WritePacket(&hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber, r.DefaultTTL()) e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) @@ -131,7 +130,7 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { copy(pkt, h) pkt.SetType(header.ICMPv6EchoReply) pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, *vv)) - r.WritePacket(&hdr, *vv, header.ICMPv6ProtocolNumber) + r.WritePacket(&hdr, *vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) case header.ICMPv6EchoReply: if len(v) < header.ICMPv6EchoMinimumSize { diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 19dc1b49e..eb89168c3 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -43,17 +43,19 @@ const ( defaultIPv6HopLimit = 255 ) -type address [header.IPv6AddressSize]byte - type endpoint struct { nicid tcpip.NICID id stack.NetworkEndpointID - address address linkEP stack.LinkEndpoint linkAddrCache stack.LinkAddressCache dispatcher stack.TransportDispatcher } +// DefaultTTL is the default hop limit for this endpoint. +func (e *endpoint) DefaultTTL() uint8 { + return 255 +} + // MTU implements stack.NetworkEndpoint.MTU. It returns the link-layer MTU minus // the network layer max header length. func (e *endpoint) MTU() uint32 { @@ -82,14 +84,14 @@ func (e *endpoint) MaxHeaderLength() uint16 { } // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { length := uint16(hdr.UsedLength() + payload.Size()) ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) ip.Encode(&header.IPv6Fields{ PayloadLength: length, NextHeader: uint8(protocol), - HopLimit: defaultIPv6HopLimit, - SrcAddr: tcpip.Address(e.address[:]), + HopLimit: ttl, + SrcAddr: e.id.LocalAddress, DstAddr: r.RemoteAddress, }) r.Stats().IP.PacketsSent.Increment() @@ -149,15 +151,13 @@ func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) { // NewEndpoint creates a new ipv6 endpoint. func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) { - e := &endpoint{ + return &endpoint{ nicid: nicid, + id: stack.NetworkEndpointID{LocalAddress: addr}, linkEP: linkEP, linkAddrCache: linkAddrCache, dispatcher: dispatcher, - } - copy(e.address[:], addr) - e.id = stack.NetworkEndpointID{LocalAddress: tcpip.Address(e.address[:])} - return e, nil + }, nil } // SetOption implements NetworkProtocol.SetOption. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 845b40f11..61afa673e 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -43,6 +43,25 @@ type NIC struct { subnets []tcpip.Subnet } +// PrimaryEndpointBehavior is an enumeration of an endpoint's primacy behavior. +type PrimaryEndpointBehavior int + +const ( + // CanBePrimaryEndpoint indicates the endpoint can be used as a primary + // endpoint for new connections with no local address. This is the + // default when calling NIC.AddAddress. + CanBePrimaryEndpoint PrimaryEndpointBehavior = iota + + // FirstPrimaryEndpoint indicates the endpoint should be the first + // primary endpoint considered. If there are multiple endpoints with + // this behavior, the most recently-added one will be first. + FirstPrimaryEndpoint + + // NeverPrimaryEndpoint indicates the endpoint should never be a + // primary endpoint. + NeverPrimaryEndpoint +) + func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint) *NIC { return &NIC{ stack: stack, @@ -141,6 +160,11 @@ func (n *NIC) primaryEndpoint(protocol tcpip.NetworkProtocolNumber) *referencedN for e := list.Front(); e != nil; e = e.Next() { r := e.(*referencedNetworkEndpoint) + // TODO: allow broadcast address when SO_BROADCAST is set. + switch r.ep.ID().LocalAddress { + case header.IPv4Broadcast, header.IPv4Any: + continue + } if r.tryIncRef() { return r } @@ -150,7 +174,7 @@ func (n *NIC) primaryEndpoint(protocol tcpip.NetworkProtocolNumber) *referencedN } // findEndpoint finds the endpoint, if any, with the given address. -func (n *NIC) findEndpoint(protocol tcpip.NetworkProtocolNumber, address tcpip.Address) *referencedNetworkEndpoint { +func (n *NIC) findEndpoint(protocol tcpip.NetworkProtocolNumber, address tcpip.Address, peb PrimaryEndpointBehavior) *referencedNetworkEndpoint { id := NetworkEndpointID{address} n.mu.RLock() @@ -171,7 +195,7 @@ func (n *NIC) findEndpoint(protocol tcpip.NetworkProtocolNumber, address tcpip.A n.mu.Lock() ref = n.endpoints[id] if ref == nil || !ref.tryIncRef() { - ref, _ = n.addAddressLocked(protocol, address, true) + ref, _ = n.addAddressLocked(protocol, address, peb, true) if ref != nil { ref.holdsInsertRef = false } @@ -180,7 +204,7 @@ func (n *NIC) findEndpoint(protocol tcpip.NetworkProtocolNumber, address tcpip.A return ref } -func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) { +func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) { netProto, ok := n.stack.networkProtocols[protocol] if !ok { return nil, tcpip.ErrUnknownProtocol @@ -224,7 +248,12 @@ func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip. n.primary[protocol] = l } - l.PushBack(ref) + switch peb { + case CanBePrimaryEndpoint: + l.PushBack(ref) + case FirstPrimaryEndpoint: + l.PushFront(ref) + } return ref, nil } @@ -232,9 +261,15 @@ func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip. // AddAddress adds a new address to n, so that it starts accepting packets // targeted at the given address (and network protocol). func (n *NIC) AddAddress(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error { + return n.AddAddressWithOptions(protocol, addr, CanBePrimaryEndpoint) +} + +// AddAddressWithOptions is the same as AddAddress, but allows you to specify +// whether the new endpoint can be primary or not. +func (n *NIC) AddAddressWithOptions(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error { // Add the endpoint. n.mu.Lock() - _, err := n.addAddressLocked(protocol, addr, false) + _, err := n.addAddressLocked(protocol, addr, peb, false) n.mu.Unlock() return err @@ -319,7 +354,11 @@ func (n *NIC) removeEndpointLocked(r *referencedNetworkEndpoint) { } delete(n.endpoints, id) - n.primary[r.protocol].Remove(r) + wasInList := r.Next() != nil || r.Prev() != nil || r == n.primary[r.protocol].Front() + if wasInList { + n.primary[r.protocol].Remove(r) + } + r.ep.Close() } @@ -398,7 +437,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin ref, ok = n.endpoints[id] if !ok || !ref.tryIncRef() { var err *tcpip.Error - ref, err = n.addAddressLocked(protocol, dst, true) + ref, err = n.addAddressLocked(protocol, dst, CanBePrimaryEndpoint, true) if err == nil { ref.holdsInsertRef = false } diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index b9e2cc045..7afde3598 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -124,6 +124,10 @@ type TransportDispatcher interface { // NetworkEndpoint is the interface that needs to be implemented by endpoints // of network layer protocols (e.g., ipv4, ipv6). type NetworkEndpoint interface { + // DefaultTTL is the default time-to-live value (or hop limit, in ipv6) + // for this endpoint. + DefaultTTL() uint8 + // MTU is the maximum transmission unit for this endpoint. This is // generally calculated as the MTU of the underlying data link endpoint // minus the network endpoint max header length. @@ -141,7 +145,7 @@ type NetworkEndpoint interface { // WritePacket writes a packet to the given destination address and // protocol. - WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error + WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error // ID returns the network protocol endpoint ID. ID() *NetworkEndpointID diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 533a0b560..9dfb95b4a 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -129,14 +129,19 @@ func (r *Route) IsResolutionRequired() bool { } // WritePacket writes the packet through the given route. -func (r *Route) WritePacket(hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { - err := r.ref.ep.WritePacket(r, hdr, payload, protocol) +func (r *Route) WritePacket(hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { + err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl) if err == tcpip.ErrNoRoute { r.Stats().IP.OutgoingPacketErrors.Increment() } return err } +// DefaultTTL returns the default TTL of the underlying network endpoint. +func (r *Route) DefaultTTL() uint8 { + return r.ref.ep.DefaultTTL() +} + // MTU returns the MTU of the underlying network endpoint. func (r *Route) MTU() uint32 { return r.ref.ep.MTU() diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 675ccc6fa..789c819dd 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -607,6 +607,12 @@ type NICStateFlags struct { // AddAddress adds a new network-layer address to the specified NIC. func (s *Stack) AddAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error { + return s.AddAddressWithOptions(id, protocol, addr, CanBePrimaryEndpoint) +} + +// AddAddressWithOptions is the same as AddAddress, but allows you to specify +// whether the new endpoint can be primary or not. +func (s *Stack) AddAddressWithOptions(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error { s.mu.RLock() defer s.mu.RUnlock() @@ -615,7 +621,7 @@ func (s *Stack) AddAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, return tcpip.ErrUnknownNICID } - return nic.AddAddress(protocol, addr) + return nic.AddAddressWithOptions(protocol, addr, peb) } // AddSubnet adds a subnet range to the specified NIC. @@ -703,7 +709,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n var ref *referencedNetworkEndpoint if len(localAddr) != 0 { - ref = nic.findEndpoint(netProto, localAddr) + ref = nic.findEndpoint(netProto, localAddr, CanBePrimaryEndpoint) } else { ref = nic.primaryEndpoint(netProto) } @@ -746,7 +752,7 @@ func (s *Stack) CheckLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProto return 0 } - ref := nic.findEndpoint(protocol, addr) + ref := nic.findEndpoint(protocol, addr, CanBePrimaryEndpoint) if ref == nil { return 0 } @@ -758,7 +764,7 @@ func (s *Stack) CheckLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProto // Go through all the NICs. for _, nic := range s.nics { - ref := nic.findEndpoint(protocol, addr) + ref := nic.findEndpoint(protocol, addr, CanBePrimaryEndpoint) if ref != nil { ref.decRef() return nic.id @@ -926,3 +932,14 @@ func (s *Stack) RemoveTCPProbe() { s.tcpProbeFunc = nil s.mu.Unlock() } + +// JoinGroup joins the given multicast group on the given NIC. +func (s *Stack) JoinGroup(protocol tcpip.NetworkProtocolNumber, nicID tcpip.NICID, multicastAddr tcpip.Address) *tcpip.Error { + // TODO: notify network of subscription via igmp protocol. + return s.AddAddressWithOptions(nicID, protocol, multicastAddr, NeverPrimaryEndpoint) +} + +// LeaveGroup leaves the given multicast group on the given NIC. +func (s *Stack) LeaveGroup(protocol tcpip.NetworkProtocolNumber, nicID tcpip.NICID, multicastAddr tcpip.Address) *tcpip.Error { + return s.RemoveAddress(nicID, multicastAddr) +} diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 02f02dfa2..816707d27 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -65,6 +65,10 @@ func (f *fakeNetworkEndpoint) NICID() tcpip.NICID { return f.nicid } +func (*fakeNetworkEndpoint) DefaultTTL() uint8 { + return 123 +} + func (f *fakeNetworkEndpoint) ID() *stack.NetworkEndpointID { return &f.id } @@ -105,7 +109,7 @@ func (f *fakeNetworkEndpoint) Capabilities() stack.LinkEndpointCapabilities { return f.linkEP.Capabilities() } -func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber) *tcpip.Error { +func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, _ uint8) *tcpip.Error { // Increment the sent packet count in the protocol descriptor. f.proto.sendPacketCount[int(r.RemoteAddress[0])%len(f.proto.sendPacketCount)]++ @@ -269,7 +273,7 @@ func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address) { defer r.Release() hdr := buffer.NewPrependable(int(r.MaxHeaderLength())) - if err := r.WritePacket(&hdr, buffer.VectorisedView{}, fakeTransNumber); err != nil { + if err := r.WritePacket(&hdr, buffer.VectorisedView{}, fakeTransNumber, 123); err != nil { t.Errorf("WritePacket failed: %v", err) return } diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 5ab485c98..e4607192f 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -71,7 +71,7 @@ func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) return 0, err } vv := buffer.NewVectorisedView(len(v), []buffer.View{v}) - if err := f.route.WritePacket(&hdr, vv, fakeTransNumber); err != nil { + if err := f.route.WritePacket(&hdr, vv, fakeTransNumber, 123); err != nil { return 0, err } diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 4065fc30f..51360b11f 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -453,6 +453,28 @@ type KeepaliveIntervalOption time.Duration // closed. type KeepaliveCountOption int +// MulticastTTLOption is used by SetSockOpt/GetSockOpt to control the default +// TTL value for multicast messages. The default is 1. +type MulticastTTLOption uint8 + +// MembershipOption is used by SetSockOpt/GetSockOpt as an argument to +// AddMembershipOption and RemoveMembershipOption. +type MembershipOption struct { + NIC NICID + InterfaceAddr Address + MulticastAddr Address +} + +// AddMembershipOption is used by SetSockOpt/GetSockOpt to join a multicast +// group identified by the given multicast address, on the interface matching +// the given interface address. +type AddMembershipOption MembershipOption + +// RemoveMembershipOption is used by SetSockOpt/GetSockOpt to leave a multicast +// group identified by the given multicast address, on the interface matching +// the given interface address. +type RemoveMembershipOption MembershipOption + // Route is a row in the routing table. It specifies through which NIC (and // gateway) sets of packets should be routed. A row is considered viable if the // masked target address matches the destination adddress in the row. diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index fc98c41eb..7aaf2d9c6 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -385,7 +385,7 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) - return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber) + return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber, r.DefaultTTL()) } func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { @@ -408,8 +408,9 @@ func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv6.SetChecksum(0) icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0))) + vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) - return r.WritePacket(&hdr, vv, header.ICMPv6ProtocolNumber) + return r.WritePacket(&hdr, vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index de5f963cf..ce87d5818 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -563,14 +563,14 @@ func sendSynTCP(r *stack.Route, id stack.TransportEndpointID, flags byte, seq, a } options := makeSynOptions(opts) - err := sendTCPWithOptions(r, id, buffer.VectorisedView{}, flags, seq, ack, rcvWnd, options) + err := sendTCP(r, id, buffer.VectorisedView{}, r.DefaultTTL(), flags, seq, ack, rcvWnd, options) putOptions(options) return err } -// sendTCPWithOptions sends a TCP segment with the provided options via the -// provided network endpoint and under the provided identity. -func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte) *tcpip.Error { +// sendTCP sends a TCP segment with the provided options via the provided +// network endpoint and under the provided identity. +func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, ttl uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte) *tcpip.Error { optLen := len(opts) // Allocate a buffer for the TCP header. hdr := buffer.NewPrependable(header.TCPMinimumSize + int(r.MaxHeaderLength()) + optLen) @@ -608,48 +608,7 @@ func sendTCPWithOptions(r *stack.Route, id stack.TransportEndpointID, data buffe r.Stats().TCP.ResetsSent.Increment() } - return r.WritePacket(&hdr, data, ProtocolNumber) -} - -// sendTCP sends a TCP segment via the provided network endpoint and under the -// provided identity. -func sendTCP(r *stack.Route, id stack.TransportEndpointID, payload buffer.VectorisedView, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size) *tcpip.Error { - // Allocate a buffer for the TCP header. - hdr := buffer.NewPrependable(header.TCPMinimumSize + int(r.MaxHeaderLength())) - - if rcvWnd > 0xffff { - rcvWnd = 0xffff - } - - // Initialize the header. - tcp := header.TCP(hdr.Prepend(header.TCPMinimumSize)) - tcp.Encode(&header.TCPFields{ - SrcPort: id.LocalPort, - DstPort: id.RemotePort, - SeqNum: uint32(seq), - AckNum: uint32(ack), - DataOffset: header.TCPMinimumSize, - Flags: flags, - WindowSize: uint16(rcvWnd), - }) - - // Only calculate the checksum if offloading isn't supported. - if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { - length := uint16(hdr.UsedLength() + payload.Size()) - xsum := r.PseudoHeaderChecksum(ProtocolNumber) - for _, v := range payload.Views() { - xsum = header.Checksum(v, xsum) - } - - tcp.SetChecksum(^tcp.CalculateChecksum(xsum, length)) - } - - r.Stats().TCP.SegmentsSent.Increment() - if (flags & flagRst) != 0 { - r.Stats().TCP.ResetsSent.Increment() - } - - return r.WritePacket(&hdr, payload, ProtocolNumber) + return r.WritePacket(&hdr, data, ProtocolNumber, ttl) } // makeOptions makes an options slice. @@ -698,12 +657,7 @@ func (e *endpoint) sendRaw(data buffer.VectorisedView, flags byte, seq, ack seqn sackBlocks = e.sack.Blocks[:e.sack.NumBlocks] } options := e.makeOptions(sackBlocks) - if len(options) > 0 { - err := sendTCPWithOptions(&e.route, e.id, data, flags, seq, ack, rcvWnd, options) - putOptions(options) - return err - } - err := sendTCP(&e.route, e.id, data, flags, seq, ack, rcvWnd) + err := sendTCP(&e.route, e.id, data, e.route.DefaultTTL(), flags, seq, ack, rcvWnd, options) putOptions(options) return err } diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index 006b2f074..fe21f2c78 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -147,7 +147,7 @@ func replyWithReset(s *segment) { ack := s.sequenceNumber.Add(s.logicalLen()) - sendTCP(&s.route, s.id, buffer.VectorisedView{}, flagRst|flagAck, seq, ack, 0) + sendTCP(&s.route, s.id, buffer.VectorisedView{}, s.route.DefaultTTL(), flagRst|flagAck, seq, ack, 0, nil) } // SetOption implements TransportProtocol.SetOption. diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index d091a6196..5de518a55 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -70,19 +70,24 @@ type endpoint struct { rcvTimestamp bool // The following fields are protected by the mu mutex. - mu sync.RWMutex `state:"nosave"` - sndBufSize int - id stack.TransportEndpointID - state endpointState - bindNICID tcpip.NICID - regNICID tcpip.NICID - route stack.Route `state:"manual"` - dstPort uint16 - v6only bool + mu sync.RWMutex `state:"nosave"` + sndBufSize int + id stack.TransportEndpointID + state endpointState + bindNICID tcpip.NICID + regNICID tcpip.NICID + route stack.Route `state:"manual"` + dstPort uint16 + v6only bool + multicastTTL uint8 // shutdownFlags represent the current shutdown state of the endpoint. shutdownFlags tcpip.ShutdownFlags + // multicastMemberships that need to be remvoed when the endpoint is + // closed. Protected by the mu mutex. + multicastMemberships []multicastMembership + // effectiveNetProtos contains the network protocols actually in use. In // most cases it will only contain "netProto", but in cases like IPv6 // endpoints with v6only set to false, this could include multiple @@ -92,11 +97,29 @@ type endpoint struct { effectiveNetProtos []tcpip.NetworkProtocolNumber } +type multicastMembership struct { + nicID tcpip.NICID + multicastAddr tcpip.Address +} + func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) *endpoint { return &endpoint{ - stack: stack, - netProto: netProto, - waiterQueue: waiterQueue, + stack: stack, + netProto: netProto, + waiterQueue: waiterQueue, + // RFC 1075 section 5.4 recommends a TTL of 1 for membership + // requests. + // + // RFC 5135 4.2.1 appears to assume that IGMP messages have a + // TTL of 1. + // + // RFC 5135 Appendix A defines TTL=1: A multicast source that + // wants its traffic to not traverse a router (e.g., leave a + // home network) may find it useful to send traffic with IP + // TTL=1. + // + // Linux defaults to TTL=1. + multicastTTL: 1, rcvBufSizeMax: 32 * 1024, sndBufSize: 32 * 1024, } @@ -135,6 +158,11 @@ func (e *endpoint) Close() { e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.id.LocalAddress, e.id.LocalPort) } + for _, mem := range e.multicastMemberships { + e.stack.LeaveGroup(e.netProto, mem.nicID, mem.multicastAddr) + } + e.multicastMemberships = nil + // Close the receive list and drain it. e.rcvMu.Lock() e.rcvClosed = true @@ -329,8 +357,13 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc return 0, err } + ttl := route.DefaultTTL() + if header.IsV4MulticastAddress(route.RemoteAddress) || header.IsV6MulticastAddress(route.RemoteAddress) { + ttl = e.multicastTTL + } + vv := buffer.NewVectorisedView(len(v), []buffer.View{v}) - if err := sendUDP(route, vv, e.id.LocalPort, dstPort); err != nil { + if err := sendUDP(route, vv, e.id.LocalPort, dstPort, ttl); err != nil { return 0, err } return uintptr(len(v)), nil @@ -365,6 +398,56 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { e.rcvMu.Lock() e.rcvTimestamp = v != 0 e.rcvMu.Unlock() + + case tcpip.MulticastTTLOption: + e.mu.Lock() + defer e.mu.Unlock() + e.multicastTTL = uint8(v) + + case tcpip.AddMembershipOption: + nicID := v.NIC + if v.InterfaceAddr != header.IPv4Any { + nicID = e.stack.CheckLocalAddress(nicID, e.netProto, v.InterfaceAddr) + } + if nicID == 0 { + return tcpip.ErrNoRoute + } + + // TODO: check that v.MulticastAddr is a multicast address. + if err := e.stack.JoinGroup(e.netProto, nicID, v.MulticastAddr); err != nil { + return err + } + + e.mu.Lock() + defer e.mu.Unlock() + + e.multicastMemberships = append(e.multicastMemberships, multicastMembership{nicID, v.MulticastAddr}) + + case tcpip.RemoveMembershipOption: + nicID := v.NIC + if v.InterfaceAddr != header.IPv4Any { + nicID = e.stack.CheckLocalAddress(nicID, e.netProto, v.InterfaceAddr) + } + if nicID == 0 { + return tcpip.ErrNoRoute + } + + // TODO: check that v.MulticastAddr is a multicast address. + if err := e.stack.LeaveGroup(e.netProto, nicID, v.MulticastAddr); err != nil { + return err + } + + e.mu.Lock() + defer e.mu.Unlock() + for i, mem := range e.multicastMemberships { + if mem.nicID == nicID && mem.multicastAddr == v.MulticastAddr { + // Only remove the first match, so that each added membership above is + // paired with exactly 1 removal. + e.multicastMemberships[i] = e.multicastMemberships[len(e.multicastMemberships)-1] + e.multicastMemberships = e.multicastMemberships[:len(e.multicastMemberships)-1] + break + } + } } return nil } @@ -421,6 +504,12 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { *o = 1 } e.rcvMu.Unlock() + + case *tcpip.MulticastTTLOption: + e.mu.Lock() + *o = tcpip.MulticastTTLOption(e.multicastTTL) + e.mu.Unlock() + return nil } return tcpip.ErrUnknownProtocolOption @@ -428,7 +517,7 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { // sendUDP sends a UDP segment via the provided network endpoint and under the // provided identity. -func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16) *tcpip.Error { +func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort uint16, ttl uint8) *tcpip.Error { // Allocate a buffer for the UDP header. hdr := buffer.NewPrependable(header.UDPMinimumSize + int(r.MaxHeaderLength())) @@ -454,7 +543,7 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u // Track count of packets sent. r.Stats().UDP.PacketsSent.Increment() - return r.WritePacket(&hdr, data, ProtocolNumber) + return r.WritePacket(&hdr, data, ProtocolNumber, ttl) } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { @@ -581,7 +670,9 @@ func (e *endpoint) Shutdown(flags tcpip.ShutdownFlags) *tcpip.Error { e.mu.Lock() defer e.mu.Unlock() - if e.state != stateConnected { + // A socket in the bound state can still receive multicast messages, + // so we need to notify waiters on shutdown. + if e.state != stateBound && e.state != stateConnected { return tcpip.ErrNotConnected } diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 4700193c2..6d7a737bd 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -34,16 +34,20 @@ import ( ) const ( - stackV6Addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" - testV6Addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" - stackV4MappedAddr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + stackAddr - testV4MappedAddr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + testAddr - V4MappedWildcardAddr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00" - - stackAddr = "\x0a\x00\x00\x01" - stackPort = 1234 - testAddr = "\x0a\x00\x00\x02" - testPort = 4096 + stackV6Addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + testV6Addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" + stackV4MappedAddr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + stackAddr + testV4MappedAddr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + testAddr + multicastV4MappedAddr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + multicastAddr + V4MappedWildcardAddr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00" + + stackAddr = "\x0a\x00\x00\x01" + stackPort = 1234 + testAddr = "\x0a\x00\x00\x02" + testPort = 4096 + multicastAddr = "\xe8\x2b\xd3\xea" + multicastV6Addr = "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + multicastPort = 1234 // defaultMTU is the MTU, in bytes, used throughout the tests, except // where another value is explicitly used. It is chosen to match the MTU @@ -128,37 +132,35 @@ func (c *testContext) createV6Endpoint(v6only bool) { } } -func (c *testContext) getV6Packet() []byte { +func (c *testContext) getPacket(protocolNumber tcpip.NetworkProtocolNumber, multicast bool) []byte { select { case p := <-c.linkEP.C: - if p.Proto != ipv6.ProtocolNumber { - c.t.Fatalf("Bad network protocol: got %v, wanted %v", p.Proto, ipv6.ProtocolNumber) + if p.Proto != protocolNumber { + c.t.Fatalf("Bad network protocol: got %v, wanted %v", p.Proto, protocolNumber) } b := make([]byte, len(p.Header)+len(p.Payload)) copy(b, p.Header) copy(b[len(p.Header):], p.Payload) - checker.IPv6(c.t, b, checker.SrcAddr(stackV6Addr), checker.DstAddr(testV6Addr)) - return b - - case <-time.After(2 * time.Second): - c.t.Fatalf("Packet wasn't written out") - } - - return nil -} - -func (c *testContext) getPacket() []byte { - select { - case p := <-c.linkEP.C: - if p.Proto != ipv4.ProtocolNumber { - c.t.Fatalf("Bad network protocol: got %v, wanted %v", p.Proto, ipv4.ProtocolNumber) + var checkerFn func(*testing.T, []byte, ...checker.NetworkChecker) + var srcAddr, dstAddr tcpip.Address + switch protocolNumber { + case ipv4.ProtocolNumber: + checkerFn = checker.IPv4 + srcAddr, dstAddr = stackAddr, testAddr + if multicast { + dstAddr = multicastAddr + } + case ipv6.ProtocolNumber: + checkerFn = checker.IPv6 + srcAddr, dstAddr = stackV6Addr, testV6Addr + if multicast { + dstAddr = multicastV6Addr + } + default: + c.t.Fatalf("unknown protocol %d", protocolNumber) } - b := make([]byte, len(p.Header)+len(p.Payload)) - copy(b, p.Header) - copy(b[len(p.Header):], p.Payload) - - checker.IPv4(c.t, b, checker.SrcAddr(stackAddr), checker.DstAddr(testAddr)) + checkerFn(c.t, b, checker.SrcAddr(srcAddr), checker.DstAddr(dstAddr)) return b case <-time.After(2 * time.Second): @@ -495,7 +497,7 @@ func testV4Write(c *testContext) uint16 { } // Check that we received the packet. - b := c.getPacket() + b := c.getPacket(ipv4.ProtocolNumber, false) udp := header.UDP(header.IPv4(b).Payload()) checker.IPv4(c.t, b, checker.UDP( @@ -525,7 +527,7 @@ func testV6Write(c *testContext) uint16 { } // Check that we received the packet. - b := c.getV6Packet() + b := c.getPacket(ipv6.ProtocolNumber, false) udp := header.UDP(header.IPv6(b).Payload()) checker.IPv6(c.t, b, checker.UDP( @@ -682,7 +684,7 @@ func TestV6WriteOnConnected(t *testing.T) { } // Check that we received the packet. - b := c.getV6Packet() + b := c.getPacket(ipv6.ProtocolNumber, false) udp := header.UDP(header.IPv6(b).Payload()) checker.IPv6(c.t, b, checker.UDP( @@ -718,7 +720,7 @@ func TestV4WriteOnConnected(t *testing.T) { } // Check that we received the packet. - b := c.getPacket() + b := c.getPacket(ipv4.ProtocolNumber, false) udp := header.UDP(header.IPv4(b).Payload()) checker.IPv4(c.t, b, checker.UDP( @@ -769,3 +771,162 @@ func TestWriteIncrementsPacketsSent(t *testing.T) { c.t.Fatalf("Write did not increment PacketsSent: got %v, want %v", got, want) } } + +func TestTTL(t *testing.T) { + payload := tcpip.SlicePayload(buffer.View(newPayload())) + + for _, name := range []string{"v4", "v6", "dual"} { + t.Run(name, func(t *testing.T) { + var networkProtocolNumber tcpip.NetworkProtocolNumber + switch name { + case "v4": + networkProtocolNumber = ipv4.ProtocolNumber + case "v6", "dual": + networkProtocolNumber = ipv6.ProtocolNumber + default: + t.Fatal("unknown test variant") + } + + var variants []string + switch name { + case "v4": + variants = []string{"v4"} + case "v6": + variants = []string{"v6"} + case "dual": + variants = []string{"v6", "mapped"} + } + + for _, variant := range variants { + t.Run(variant, func(t *testing.T) { + for _, typ := range []string{"unicast", "multicast"} { + t.Run(typ, func(t *testing.T) { + var addr tcpip.Address + var port uint16 + switch typ { + case "unicast": + port = testPort + switch variant { + case "v4": + addr = testAddr + case "mapped": + addr = testV4MappedAddr + case "v6": + addr = testV6Addr + default: + t.Fatal("unknown test variant") + } + case "multicast": + port = multicastPort + switch variant { + case "v4": + addr = multicastAddr + case "mapped": + addr = multicastV4MappedAddr + case "v6": + addr = multicastV6Addr + default: + t.Fatal("unknown test variant") + } + default: + t.Fatal("unknown test variant") + } + + c := newDualTestContext(t, defaultMTU) + defer c.cleanup() + + var err *tcpip.Error + c.ep, err = c.s.NewEndpoint(udp.ProtocolNumber, networkProtocolNumber, &c.wq) + if err != nil { + c.t.Fatalf("NewEndpoint failed: %v", err) + } + + switch name { + case "v4": + case "v6": + if err := c.ep.SetSockOpt(tcpip.V6OnlyOption(1)); err != nil { + c.t.Fatalf("SetSockOpt failed: %v", err) + } + case "dual": + if err := c.ep.SetSockOpt(tcpip.V6OnlyOption(0)); err != nil { + c.t.Fatalf("SetSockOpt failed: %v", err) + } + default: + t.Fatal("unknown test variant") + } + + const multicastTTL = 42 + if err := c.ep.SetSockOpt(tcpip.MulticastTTLOption(multicastTTL)); err != nil { + c.t.Fatalf("SetSockOpt failed: %v", err) + } + + n, err := c.ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{Addr: addr, Port: port}}) + if err != nil { + c.t.Fatalf("Write failed: %v", err) + } + if n != uintptr(len(payload)) { + c.t.Fatalf("got c.ep.Write(...) = %d, want = %d", n, len(payload)) + } + + checkerFn := checker.IPv4 + switch variant { + case "v4", "mapped": + case "v6": + checkerFn = checker.IPv6 + default: + t.Fatal("unknown test variant") + } + var wantTTL uint8 + var multicast bool + switch typ { + case "unicast": + multicast = false + switch variant { + case "v4", "mapped": + ep, err := ipv4.NewProtocol().NewEndpoint(0, "", nil, nil, nil) + if err != nil { + t.Fatal(err) + } + wantTTL = ep.DefaultTTL() + ep.Close() + case "v6": + ep, err := ipv6.NewProtocol().NewEndpoint(0, "", nil, nil, nil) + if err != nil { + t.Fatal(err) + } + wantTTL = ep.DefaultTTL() + ep.Close() + default: + t.Fatal("unknown test variant") + } + case "multicast": + wantTTL = multicastTTL + multicast = true + default: + t.Fatal("unknown test variant") + } + + var networkProtocolNumber tcpip.NetworkProtocolNumber + switch variant { + case "v4", "mapped": + networkProtocolNumber = ipv4.ProtocolNumber + case "v6": + networkProtocolNumber = ipv6.ProtocolNumber + default: + t.Fatal("unknown test variant") + } + + b := c.getPacket(networkProtocolNumber, multicast) + checkerFn(c.t, b, + checker.TTL(wantTTL), + checker.UDP( + checker.DstPort(port), + ), + ) + }) + } + }) + } + }) + } +} -- cgit v1.2.3 From d689f8422fd55f74f6fc677f33b2bbf3720de89e Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 12 Sep 2018 21:57:04 -0700 Subject: Always pass buffer.VectorisedView by value PiperOrigin-RevId: 212757571 Change-Id: I04200df9e45c21eb64951cd2802532fa84afcb1a --- pkg/dhcp/dhcp_test.go | 6 +- pkg/tcpip/adapters/gonet/gonet.go | 3 +- pkg/tcpip/buffer/view.go | 62 ++-------- pkg/tcpip/buffer/view_test.go | 41 ++++--- pkg/tcpip/checker/checker.go | 133 ++++++++++++++------- pkg/tcpip/link/channel/channel.go | 10 +- pkg/tcpip/link/fdbased/endpoint.go | 14 +-- pkg/tcpip/link/fdbased/endpoint_test.go | 5 +- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem.go | 6 +- pkg/tcpip/link/sharedmem/sharedmem_test.go | 47 ++++---- pkg/tcpip/link/sniffer/sniffer.go | 2 +- pkg/tcpip/link/waitable/waitable.go | 2 +- pkg/tcpip/link/waitable/waitable_test.go | 8 +- pkg/tcpip/network/arp/arp.go | 2 +- pkg/tcpip/network/arp/arp_test.go | 80 ++++++------- pkg/tcpip/network/fragmentation/frag_heap.go | 6 +- pkg/tcpip/network/fragmentation/frag_heap_test.go | 30 +++-- pkg/tcpip/network/fragmentation/fragmentation.go | 2 +- .../network/fragmentation/fragmentation_test.go | 67 ++++------- pkg/tcpip/network/fragmentation/reassembler.go | 9 +- pkg/tcpip/network/ip_test.go | 44 +++---- pkg/tcpip/network/ipv4/icmp.go | 7 +- pkg/tcpip/network/ipv4/ipv4.go | 6 +- pkg/tcpip/network/ipv6/icmp.go | 8 +- pkg/tcpip/network/ipv6/icmp_test.go | 2 +- pkg/tcpip/network/ipv6/ipv6.go | 2 +- pkg/tcpip/stack/nic.go | 6 +- pkg/tcpip/stack/registration.go | 14 +-- pkg/tcpip/stack/stack.go | 4 +- pkg/tcpip/stack/stack_test.go | 65 ++++------ pkg/tcpip/stack/transport_demuxer.go | 6 +- pkg/tcpip/stack/transport_test.go | 29 ++--- pkg/tcpip/transport/ping/endpoint.go | 10 +- pkg/tcpip/transport/ping/protocol.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 4 +- pkg/tcpip/transport/tcp/forwarder.go | 2 +- pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/tcp/segment.go | 2 +- pkg/tcpip/transport/tcp/tcp_test.go | 4 +- pkg/tcpip/transport/tcp/testing/context/context.go | 22 ++-- pkg/tcpip/transport/udp/endpoint.go | 7 +- pkg/tcpip/transport/udp/protocol.go | 2 +- pkg/tcpip/transport/udp/udp_test.go | 8 +- 44 files changed, 360 insertions(+), 435 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index 67814683a..a187c5c2a 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -42,11 +42,7 @@ func createStack(t *testing.T) *stack.Stack { go func() { for pkt := range linkEP.C { - v := make(buffer.View, len(pkt.Header)+len(pkt.Payload)) - copy(v, pkt.Header) - copy(v[len(pkt.Header):], pkt.Payload) - vv := v.ToVectorisedView([1]buffer.View{}) - linkEP.Inject(pkt.Proto, &vv) + linkEP.Inject(pkt.Proto, buffer.NewVectorisedView(len(pkt.Header)+len(pkt.Payload), []buffer.View{pkt.Header, pkt.Payload})) } }() diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index 19491fb2c..490b9c648 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -350,8 +350,7 @@ func (c *Conn) Write(b []byte) (int, error) { default: } - v := buffer.NewView(len(b)) - copy(v, b) + v := buffer.NewViewFromBytes(b) // We must handle two soft failure conditions simultaneously: // 1. Write may write nothing and return tcpip.ErrWouldBlock. diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index 4a921ddcb..cea4e3657 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -45,11 +45,9 @@ func (v *View) CapLength(length int) { *v = (*v)[:length:length] } -// ToVectorisedView transforms a View in a VectorisedView from an -// already-allocated slice of View. -func (v *View) ToVectorisedView(views [1]View) VectorisedView { - views[0] = *v - return NewVectorisedView(len(*v), views[:]) +// ToVectorisedView returns a VectorisedView containing the receiver. +func (v View) ToVectorisedView() VectorisedView { + return NewVectorisedView(len(v), []View{v}) } // VectorisedView is a vectorised version of View using non contigous memory. @@ -107,21 +105,12 @@ func (vv *VectorisedView) CapLength(length int) { // Clone returns a clone of this VectorisedView. // If the buffer argument is large enough to contain all the Views of this VectorisedView, // the method will avoid allocations and use the buffer to store the Views of the clone. -func (vv *VectorisedView) Clone(buffer []View) VectorisedView { - var views []View - if len(buffer) >= len(vv.views) { - views = buffer[:len(vv.views)] - } else { - views = make([]View, len(vv.views)) - } - for i, v := range vv.views { - views[i] = v - } - return VectorisedView{views: views, size: vv.size} +func (vv VectorisedView) Clone(buffer []View) VectorisedView { + return VectorisedView{views: append(buffer[:0], vv.views...), size: vv.size} } // First returns the first view of the vectorised view. -func (vv *VectorisedView) First() View { +func (vv VectorisedView) First() View { if len(vv.views) == 0 { return nil } @@ -137,23 +126,13 @@ func (vv *VectorisedView) RemoveFirst() { vv.views = vv.views[1:] } -// SetSize unsafely sets the size of the VectorisedView. -func (vv *VectorisedView) SetSize(size int) { - vv.size = size -} - -// SetViews unsafely sets the views of the VectorisedView. -func (vv *VectorisedView) SetViews(views []View) { - vv.views = views -} - // Size returns the size in bytes of the entire content stored in the vectorised view. -func (vv *VectorisedView) Size() int { +func (vv VectorisedView) Size() int { return vv.size } // ToView returns a single view containing the content of the vectorised view. -func (vv *VectorisedView) ToView() View { +func (vv VectorisedView) ToView() View { u := make([]byte, 0, vv.size) for _, v := range vv.views { u = append(u, v...) @@ -162,29 +141,6 @@ func (vv *VectorisedView) ToView() View { } // Views returns the slice containing the all views. -func (vv *VectorisedView) Views() []View { +func (vv VectorisedView) Views() []View { return vv.views } - -// ByteSlice returns a slice containing the all views as a []byte. -func (vv *VectorisedView) ByteSlice() [][]byte { - s := make([][]byte, len(vv.views)) - for i := range vv.views { - s[i] = []byte(vv.views[i]) - } - return s -} - -// copy returns a deep-copy of the vectorised view. -// It is an expensive method that should be used only in tests. -func (vv *VectorisedView) copy() *VectorisedView { - uu := &VectorisedView{ - views: make([]View, len(vv.views)), - size: vv.size, - } - for i, v := range vv.views { - uu.views[i] = make(View, len(v)) - copy(uu.views[i], v) - } - return uu -} diff --git a/pkg/tcpip/buffer/view_test.go b/pkg/tcpip/buffer/view_test.go index 57fe12360..02c264593 100644 --- a/pkg/tcpip/buffer/view_test.go +++ b/pkg/tcpip/buffer/view_test.go @@ -20,22 +20,33 @@ import ( "testing" ) +// copy returns a deep-copy of the vectorised view. +func (vv VectorisedView) copy() VectorisedView { + uu := VectorisedView{ + views: make([]View, 0, len(vv.views)), + size: vv.size, + } + for _, v := range vv.views { + uu.views = append(uu.views, append(View(nil), v...)) + } + return uu +} + // vv is an helper to build VectorisedView from different strings. -func vv(size int, pieces ...string) *VectorisedView { +func vv(size int, pieces ...string) VectorisedView { views := make([]View, len(pieces)) for i, p := range pieces { views[i] = []byte(p) } - vv := NewVectorisedView(size, views) - return &vv + return NewVectorisedView(size, views) } var capLengthTestCases = []struct { comment string - in *VectorisedView + in VectorisedView length int - want *VectorisedView + want VectorisedView }{ { comment: "Simple case", @@ -88,9 +99,9 @@ func TestCapLength(t *testing.T) { var trimFrontTestCases = []struct { comment string - in *VectorisedView + in VectorisedView count int - want *VectorisedView + want VectorisedView }{ { comment: "Simple case", @@ -149,7 +160,7 @@ func TestTrimFront(t *testing.T) { var toViewCases = []struct { comment string - in *VectorisedView + in VectorisedView want View }{ { @@ -181,7 +192,7 @@ func TestToView(t *testing.T) { var toCloneCases = []struct { comment string - inView *VectorisedView + inView VectorisedView inBuffer []View }{ { @@ -213,10 +224,12 @@ var toCloneCases = []struct { func TestToClone(t *testing.T) { for _, c := range toCloneCases { - got := c.inView.Clone(c.inBuffer) - if !reflect.DeepEqual(&got, c.inView) { - t.Errorf("Test \"%s\" failed when calling Clone(%v) on %v. Got %v. Want %v", - c.comment, c.inBuffer, c.inView, got, c.inView) - } + t.Run(c.comment, func(t *testing.T) { + got := c.inView.Clone(c.inBuffer) + if !reflect.DeepEqual(got, c.inView) { + t.Fatalf("got (%+v).Clone(%+v) = %+v, want = %+v", + c.inView, c.inBuffer, got, c.inView) + } + }) } } diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go index 8e0e49efa..206531f20 100644 --- a/pkg/tcpip/checker/checker.go +++ b/pkg/tcpip/checker/checker.go @@ -39,40 +39,52 @@ type TransportChecker func(*testing.T, header.Transport) // // checker.IPv4(t, b, checker.SrcAddr(x), checker.DstAddr(y)) func IPv4(t *testing.T, b []byte, checkers ...NetworkChecker) { + t.Helper() + ipv4 := header.IPv4(b) if !ipv4.IsValid(len(b)) { - t.Fatalf("Not a valid IPv4 packet") + t.Error("Not a valid IPv4 packet") } xsum := ipv4.CalculateChecksum() if xsum != 0 && xsum != 0xffff { - t.Fatalf("Bad checksum: 0x%x, checksum in packet: 0x%x", xsum, ipv4.Checksum()) + t.Errorf("Bad checksum: 0x%x, checksum in packet: 0x%x", xsum, ipv4.Checksum()) } for _, f := range checkers { f(t, []header.Network{ipv4}) } + if t.Failed() { + t.FailNow() + } } // IPv6 checks the validity and properties of the given IPv6 packet. The usage // is similar to IPv4. func IPv6(t *testing.T, b []byte, checkers ...NetworkChecker) { + t.Helper() + ipv6 := header.IPv6(b) if !ipv6.IsValid(len(b)) { - t.Fatalf("Not a valid IPv6 packet") + t.Error("Not a valid IPv6 packet") } for _, f := range checkers { f(t, []header.Network{ipv6}) } + if t.Failed() { + t.FailNow() + } } // SrcAddr creates a checker that checks the source address. func SrcAddr(addr tcpip.Address) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + if a := h[0].SourceAddress(); a != addr { - t.Fatalf("Bad source address, got %v, want %v", a, addr) + t.Errorf("Bad source address, got %v, want %v", a, addr) } } } @@ -80,8 +92,10 @@ func SrcAddr(addr tcpip.Address) NetworkChecker { // DstAddr creates a checker that checks the destination address. func DstAddr(addr tcpip.Address) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + if a := h[0].DestinationAddress(); a != addr { - t.Fatalf("Bad destination address, got %v, want %v", a, addr) + t.Errorf("Bad destination address, got %v, want %v", a, addr) } } } @@ -105,8 +119,10 @@ func TTL(ttl uint8) NetworkChecker { // PayloadLen creates a checker that checks the payload length. func PayloadLen(plen int) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + if l := len(h[0].Payload()); l != plen { - t.Fatalf("Bad payload length, got %v, want %v", l, plen) + t.Errorf("Bad payload length, got %v, want %v", l, plen) } } } @@ -114,11 +130,13 @@ func PayloadLen(plen int) NetworkChecker { // FragmentOffset creates a checker that checks the FragmentOffset field. func FragmentOffset(offset uint16) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + // We only do this of IPv4 for now. switch ip := h[0].(type) { case header.IPv4: if v := ip.FragmentOffset(); v != offset { - t.Fatalf("Bad fragment offset, got %v, want %v", v, offset) + t.Errorf("Bad fragment offset, got %v, want %v", v, offset) } } } @@ -127,11 +145,13 @@ func FragmentOffset(offset uint16) NetworkChecker { // FragmentFlags creates a checker that checks the fragment flags field. func FragmentFlags(flags uint8) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + // We only do this of IPv4 for now. switch ip := h[0].(type) { case header.IPv4: if v := ip.Flags(); v != flags { - t.Fatalf("Bad fragment offset, got %v, want %v", v, flags) + t.Errorf("Bad fragment offset, got %v, want %v", v, flags) } } } @@ -140,8 +160,10 @@ func FragmentFlags(flags uint8) NetworkChecker { // TOS creates a checker that checks the TOS field. func TOS(tos uint8, label uint32) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + if v, l := h[0].TOS(); v != tos || l != label { - t.Fatalf("Bad TOS, got (%v, %v), want (%v,%v)", v, l, tos, label) + t.Errorf("Bad TOS, got (%v, %v), want (%v,%v)", v, l, tos, label) } } } @@ -153,8 +175,10 @@ func TOS(tos uint8, label uint32) NetworkChecker { // the bytes added by the IPv6 fragmentation. func Raw(want []byte) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + if got := h[len(h)-1].Payload(); !reflect.DeepEqual(got, want) { - t.Fatalf("Wrong payload, got %v, want %v", got, want) + t.Errorf("Wrong payload, got %v, want %v", got, want) } } } @@ -162,18 +186,23 @@ func Raw(want []byte) NetworkChecker { // IPv6Fragment creates a checker that validates an IPv6 fragment. func IPv6Fragment(checkers ...NetworkChecker) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + if p := h[0].TransportProtocol(); p != header.IPv6FragmentHeader { - t.Fatalf("Bad protocol, got %v, want %v", p, header.UDPProtocolNumber) + t.Errorf("Bad protocol, got %v, want %v", p, header.UDPProtocolNumber) } ipv6Frag := header.IPv6Fragment(h[0].Payload()) if !ipv6Frag.IsValid() { - t.Fatalf("Not a valid IPv6 fragment") + t.Error("Not a valid IPv6 fragment") } for _, f := range checkers { f(t, []header.Network{h[0], ipv6Frag}) } + if t.Failed() { + t.FailNow() + } } } @@ -181,11 +210,13 @@ func IPv6Fragment(checkers ...NetworkChecker) NetworkChecker { // potentially additional transport header fields. func TCP(checkers ...TransportChecker) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + first := h[0] last := h[len(h)-1] if p := last.TransportProtocol(); p != header.TCPProtocolNumber { - t.Fatalf("Bad protocol, got %v, want %v", p, header.TCPProtocolNumber) + t.Errorf("Bad protocol, got %v, want %v", p, header.TCPProtocolNumber) } // Verify the checksum. @@ -199,13 +230,16 @@ func TCP(checkers ...TransportChecker) NetworkChecker { xsum = header.Checksum(tcp, xsum) if xsum != 0 && xsum != 0xffff { - t.Fatalf("Bad checksum: 0x%x, checksum in segment: 0x%x", xsum, tcp.Checksum()) + t.Errorf("Bad checksum: 0x%x, checksum in segment: 0x%x", xsum, tcp.Checksum()) } // Run the transport checkers. for _, f := range checkers { f(t, tcp) } + if t.Failed() { + t.FailNow() + } } } @@ -213,24 +247,31 @@ func TCP(checkers ...TransportChecker) NetworkChecker { // potentially additional transport header fields. func UDP(checkers ...TransportChecker) NetworkChecker { return func(t *testing.T, h []header.Network) { + t.Helper() + last := h[len(h)-1] if p := last.TransportProtocol(); p != header.UDPProtocolNumber { - t.Fatalf("Bad protocol, got %v, want %v", p, header.UDPProtocolNumber) + t.Errorf("Bad protocol, got %v, want %v", p, header.UDPProtocolNumber) } udp := header.UDP(last.Payload()) for _, f := range checkers { f(t, udp) } + if t.Failed() { + t.FailNow() + } } } // SrcPort creates a checker that checks the source port. func SrcPort(port uint16) TransportChecker { return func(t *testing.T, h header.Transport) { + t.Helper() + if p := h.SourcePort(); p != port { - t.Fatalf("Bad source port, got %v, want %v", p, port) + t.Errorf("Bad source port, got %v, want %v", p, port) } } } @@ -239,7 +280,7 @@ func SrcPort(port uint16) TransportChecker { func DstPort(port uint16) TransportChecker { return func(t *testing.T, h header.Transport) { if p := h.DestinationPort(); p != port { - t.Fatalf("Bad destination port, got %v, want %v", p, port) + t.Errorf("Bad destination port, got %v, want %v", p, port) } } } @@ -247,13 +288,15 @@ func DstPort(port uint16) TransportChecker { // SeqNum creates a checker that checks the sequence number. func SeqNum(seq uint32) TransportChecker { return func(t *testing.T, h header.Transport) { + t.Helper() + tcp, ok := h.(header.TCP) if !ok { return } if s := tcp.SequenceNumber(); s != seq { - t.Fatalf("Bad sequence number, got %v, want %v", s, seq) + t.Errorf("Bad sequence number, got %v, want %v", s, seq) } } } @@ -268,7 +311,7 @@ func AckNum(seq uint32) TransportChecker { } if s := tcp.AckNumber(); s != seq { - t.Fatalf("Bad ack number, got %v, want %v", s, seq) + t.Errorf("Bad ack number, got %v, want %v", s, seq) } } } @@ -282,7 +325,7 @@ func Window(window uint16) TransportChecker { } if w := tcp.WindowSize(); w != window { - t.Fatalf("Bad window, got 0x%x, want 0x%x", w, window) + t.Errorf("Bad window, got 0x%x, want 0x%x", w, window) } } } @@ -290,13 +333,15 @@ func Window(window uint16) TransportChecker { // TCPFlags creates a checker that checks the tcp flags. func TCPFlags(flags uint8) TransportChecker { return func(t *testing.T, h header.Transport) { + t.Helper() + tcp, ok := h.(header.TCP) if !ok { return } if f := tcp.Flags(); f != flags { - t.Fatalf("Bad flags, got 0x%x, want 0x%x", f, flags) + t.Errorf("Bad flags, got 0x%x, want 0x%x", f, flags) } } } @@ -311,7 +356,7 @@ func TCPFlagsMatch(flags, mask uint8) TransportChecker { } if f := tcp.Flags(); (f & mask) != (flags & mask) { - t.Fatalf("Bad masked flags, got 0x%x, want 0x%x, mask 0x%x", f, flags, mask) + t.Errorf("Bad masked flags, got 0x%x, want 0x%x, mask 0x%x", f, flags, mask) } } } @@ -343,26 +388,26 @@ func TCPSynOptions(wantOpts header.TCPSynOptions) TransportChecker { case header.TCPOptionMSS: v := uint16(opts[i+2])<<8 | uint16(opts[i+3]) if wantOpts.MSS != v { - t.Fatalf("Bad MSS: got %v, want %v", v, wantOpts.MSS) + t.Errorf("Bad MSS: got %v, want %v", v, wantOpts.MSS) } foundMSS = true i += 4 case header.TCPOptionWS: if wantOpts.WS < 0 { - t.Fatalf("WS present when it shouldn't be") + t.Error("WS present when it shouldn't be") } v := int(opts[i+2]) if v != wantOpts.WS { - t.Fatalf("Bad WS: got %v, want %v", v, wantOpts.WS) + t.Errorf("Bad WS: got %v, want %v", v, wantOpts.WS) } foundWS = true i += 3 case header.TCPOptionTS: if i+9 >= limit { - t.Fatalf("TS Option truncated , option is only: %d bytes, want 10", limit-i) + t.Errorf("TS Option truncated , option is only: %d bytes, want 10", limit-i) } if opts[i+1] != 10 { - t.Fatalf("Bad length %d for TS option, limit: %d", opts[i+1], limit) + t.Errorf("Bad length %d for TS option, limit: %d", opts[i+1], limit) } tsVal = binary.BigEndian.Uint32(opts[i+2:]) tsEcr = uint32(0) @@ -375,10 +420,10 @@ func TCPSynOptions(wantOpts header.TCPSynOptions) TransportChecker { i += 10 case header.TCPOptionSACKPermitted: if i+1 >= limit { - t.Fatalf("SACKPermitted option truncated, option is only : %d bytes, want 2", limit-i) + t.Errorf("SACKPermitted option truncated, option is only : %d bytes, want 2", limit-i) } if opts[i+1] != 2 { - t.Fatalf("Bad length %d for SACKPermitted option, limit: %d", opts[i+1], limit) + t.Errorf("Bad length %d for SACKPermitted option, limit: %d", opts[i+1], limit) } foundSACKPermitted = true i += 2 @@ -389,23 +434,23 @@ func TCPSynOptions(wantOpts header.TCPSynOptions) TransportChecker { } if !foundMSS { - t.Fatalf("MSS option not found. Options: %x", opts) + t.Errorf("MSS option not found. Options: %x", opts) } if !foundWS && wantOpts.WS >= 0 { - t.Fatalf("WS option not found. Options: %x", opts) + t.Errorf("WS option not found. Options: %x", opts) } if wantOpts.TS && !foundTS { - t.Fatalf("TS option not found. Options: %x", opts) + t.Errorf("TS option not found. Options: %x", opts) } if foundTS && tsVal == 0 { - t.Fatalf("TS option specified but the timestamp value is zero") + t.Error("TS option specified but the timestamp value is zero") } if foundTS && tsEcr == 0 && wantOpts.TSEcr != 0 { - t.Fatalf("TS option specified but TSEcr is incorrect: got %d, want: %d", tsEcr, wantOpts.TSEcr) + t.Errorf("TS option specified but TSEcr is incorrect: got %d, want: %d", tsEcr, wantOpts.TSEcr) } if wantOpts.SACKPermitted && !foundSACKPermitted { - t.Fatalf("SACKPermitted option not found. Options: %x", opts) + t.Errorf("SACKPermitted option not found. Options: %x", opts) } } } @@ -435,10 +480,10 @@ func TCPTimestampChecker(wantTS bool, wantTSVal uint32, wantTSEcr uint32) Transp i++ case header.TCPOptionTS: if i+9 >= limit { - t.Fatalf("TS option found, but option is truncated, option length: %d, want 10 bytes", limit-i) + t.Errorf("TS option found, but option is truncated, option length: %d, want 10 bytes", limit-i) } if opts[i+1] != 10 { - t.Fatalf("TS option found, but bad length specified: %d, want: 10", opts[i+1]) + t.Errorf("TS option found, but bad length specified: %d, want: 10", opts[i+1]) } tsVal = binary.BigEndian.Uint32(opts[i+2:]) tsEcr = binary.BigEndian.Uint32(opts[i+6:]) @@ -458,13 +503,13 @@ func TCPTimestampChecker(wantTS bool, wantTSVal uint32, wantTSEcr uint32) Transp } if wantTS != foundTS { - t.Fatalf("TS Option mismatch: got TS= %v, want TS= %v", foundTS, wantTS) + t.Errorf("TS Option mismatch: got TS= %v, want TS= %v", foundTS, wantTS) } if wantTS && wantTSVal != 0 && wantTSVal != tsVal { - t.Fatalf("Timestamp value is incorrect: got: %d, want: %d", tsVal, wantTSVal) + t.Errorf("Timestamp value is incorrect: got: %d, want: %d", tsVal, wantTSVal) } if wantTS && wantTSEcr != 0 && tsEcr != wantTSEcr { - t.Fatalf("Timestamp Echo Reply is incorrect: got: %d, want: %d", tsEcr, wantTSEcr) + t.Errorf("Timestamp Echo Reply is incorrect: got: %d, want: %d", tsEcr, wantTSEcr) } } } @@ -497,12 +542,12 @@ func TCPSACKBlockChecker(sackBlocks []header.SACKBlock) TransportChecker { case header.TCPOptionSACK: if i+2 > limit { // Malformed SACK block. - t.Fatalf("malformed SACK option in options: %v", opts) + t.Errorf("malformed SACK option in options: %v", opts) } sackOptionLen := int(opts[i+1]) if i+sackOptionLen > limit || (sackOptionLen-2)%8 != 0 { // Malformed SACK block. - t.Fatalf("malformed SACK option length in options: %v", opts) + t.Errorf("malformed SACK option length in options: %v", opts) } numBlocks := sackOptionLen / 8 for j := 0; j < numBlocks; j++ { @@ -528,7 +573,7 @@ func TCPSACKBlockChecker(sackBlocks []header.SACKBlock) TransportChecker { } if !reflect.DeepEqual(gotSACKBlocks, sackBlocks) { - t.Fatalf("SACKBlocks are not equal, got: %v, want: %v", gotSACKBlocks, sackBlocks) + t.Errorf("SACKBlocks are not equal, got: %v, want: %v", gotSACKBlocks, sackBlocks) } } } @@ -537,7 +582,7 @@ func TCPSACKBlockChecker(sackBlocks []header.SACKBlock) TransportChecker { func Payload(want []byte) TransportChecker { return func(t *testing.T, h header.Transport) { if got := h.Payload(); !reflect.DeepEqual(got, want) { - t.Fatalf("Wrong payload, got %v, want %v", got, want) + t.Errorf("Wrong payload, got %v, want %v", got, want) } } } diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 6983fae3f..a927a1b3f 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -66,15 +66,13 @@ func (e *Endpoint) Drain() int { } // Inject injects an inbound packet. -func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { - uu := vv.Clone(nil) - e.dispatcher.DeliverNetworkPacket(e, "", protocol, &uu) +func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { + e.InjectLinkAddr(protocol, "", vv) } // InjectLinkAddr injects an inbound packet with a remote link address. -func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, vv *buffer.VectorisedView) { - uu := vv.Clone(nil) - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, &uu) +func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, vv buffer.VectorisedView) { + e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, vv.Clone(nil)) } // Attach saves the stack network-layer dispatcher for use later when packets diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 12c249c0d..0b985928b 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -57,7 +57,6 @@ type endpoint struct { // its end of the communication pipe. closed func(*tcpip.Error) - vv *buffer.VectorisedView iovecs []syscall.Iovec views []buffer.View dispatcher stack.NetworkDispatcher @@ -118,8 +117,6 @@ func New(opts *Options) tcpip.LinkEndpointID { iovecs: make([]syscall.Iovec, len(BufConfig)), handleLocal: opts.HandleLocal, } - vv := buffer.NewVectorisedView(0, e.views) - e.vv = &vv return stack.RegisterLinkEndpoint(e) } @@ -167,7 +164,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload views[0] = hdr.View() views = append(views, payload.Views()...) vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) - e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, &vv) + e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, vv) return nil } if e.hdrSize > 0 { @@ -246,11 +243,10 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { } used := e.capViews(n, BufConfig) - e.vv.SetViews(e.views[:used]) - e.vv.SetSize(n) - e.vv.TrimFront(e.hdrSize) + vv := buffer.NewVectorisedView(n, e.views[:used]) + vv.TrimFront(e.hdrSize) - e.dispatcher.DeliverNetworkPacket(e, addr, p, e.vv) + e.dispatcher.DeliverNetworkPacket(e, addr, p, vv) // Prepare e.views for another packet: release used views. for i := 0; i < used; i++ { @@ -290,7 +286,7 @@ func (e *InjectableEndpoint) Attach(dispatcher stack.NetworkDispatcher) { } // Inject injects an inbound packet. -func (e *InjectableEndpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { +func (e *InjectableEndpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { e.dispatcher.DeliverNetworkPacket(e, "", protocol, vv) } diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 408169bbe..21d2f10b0 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -77,7 +77,7 @@ func (c *context) cleanup() { syscall.Close(c.fds[1]) } -func (c *context) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { +func (c *context) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { c.ch <- packetInfo{remoteLinkAddr, protocol, vv.ToView()} } @@ -158,8 +158,7 @@ func TestWritePacket(t *testing.T) { payload[i] = uint8(rand.Intn(256)) } want := append(hdr.UsedBytes(), payload...) - vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) - if err := c.ep.WritePacket(r, &hdr, vv, proto); err != nil { + if err := c.ep.WritePacket(r, &hdr, payload.ToVectorisedView(), proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 4a750fa12..884de83c9 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -77,7 +77,7 @@ func (e *endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload views[0] = hdr.View() views = append(views, payload.Views()...) vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) - e.dispatcher.DeliverNetworkPacket(e, "", protocol, &vv) + e.dispatcher.DeliverNetworkPacket(e, "", protocol, vv) return nil } diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 6bd5441f6..0dd23794b 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -227,8 +227,6 @@ func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) { // Read in a loop until a stop is requested. var rxb []queue.RxBuffer - views := []buffer.View{nil} - vv := buffer.NewVectorisedView(0, views) for atomic.LoadUint32(&e.stopRequested) == 0 { var n uint32 rxb, n = e.rx.postAndReceive(rxb, &e.stopRequested) @@ -250,9 +248,7 @@ func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) { // Send packet up the stack. eth := header.Ethernet(b) - views[0] = b[header.EthernetMinimumSize:] - vv.SetSize(int(n) - header.EthernetMinimumSize) - d.DeliverNetworkPacket(e, eth.SourceAddress(), eth.Type(), &vv) + d.DeliverNetworkPacket(e, eth.SourceAddress(), eth.Type(), buffer.View(b[header.EthernetMinimumSize:]).ToVectorisedView()) } // Clean state. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 69d4ef29f..682c38400 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -129,7 +129,7 @@ func newTestContext(t *testing.T, mtu, bufferSize uint32, addr tcpip.LinkAddress return c } -func (c *testContext) DeliverNetworkPacket(_ stack.LinkEndpoint, remoteAddr tcpip.LinkAddress, proto tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { +func (c *testContext) DeliverNetworkPacket(_ stack.LinkEndpoint, remoteAddr tcpip.LinkAddress, proto tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { c.mu.Lock() c.packets = append(c.packets, packetInfo{ addr: remoteAddr, @@ -270,8 +270,7 @@ func TestSimpleSend(t *testing.T) { randomFill(buf) proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) - vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) - if err := c.ep.WritePacket(&r, &hdr, vv, proto); err != nil { + if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } @@ -330,7 +329,6 @@ func TestFillTxQueue(t *testing.T) { } buf := buffer.NewView(100) - vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses no more than 40 bytes, so write that many packets // until the tx queue if full. @@ -338,7 +336,7 @@ func TestFillTxQueue(t *testing.T) { for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -353,7 +351,7 @@ func TestFillTxQueue(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -374,12 +372,11 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { } buf := buffer.NewView(100) - vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Send two packets so that the id slice has at least two slots. for i := 2; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } @@ -399,7 +396,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -414,7 +411,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -431,14 +428,13 @@ func TestFillTxMemory(t *testing.T) { } buf := buffer.NewView(100) - vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses up one buffer, so write as many as possible until // we fill the memory. ids := make(map[uint64]struct{}) for i := queueDataSize / bufferSize; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -454,7 +450,7 @@ func TestFillTxMemory(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber) + err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber) if want := tcpip.ErrWouldBlock; err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } @@ -474,13 +470,12 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { } buf := buffer.NewView(100) - vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses up one buffer, so write as many as possible // until there is only one buffer left. for i := queueDataSize/bufferSize - 1; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -490,20 +485,26 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { } // Attempt to write a two-buffer packet. It must fail. - hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - uu := buffer.NewVectorisedView(bufferSize, []buffer.View{buffer.NewView(bufferSize)}) - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, uu, header.IPv4ProtocolNumber); err != want { - t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) + { + hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) + uu := buffer.NewView(bufferSize).ToVectorisedView() + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, uu, header.IPv4ProtocolNumber); err != want { + t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) + } } // Attempt to write the one-buffer packet again. It must succeed. - hdr = buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { - t.Fatalf("WritePacket failed unexpectedly: %v", err) + { + hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) + if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + t.Fatalf("WritePacket failed unexpectedly: %v", err) + } } } func pollPull(t *testing.T, p *pipe.Rx, to <-chan time.Time, errStr string) []byte { + t.Helper() + for { b := p.Pull() if b != nil { @@ -513,7 +514,7 @@ func pollPull(t *testing.T, p *pipe.Rx, to <-chan time.Time, errStr string) []by select { case <-time.After(10 * time.Millisecond): case <-to: - t.Fatalf(errStr) + t.Fatal(errStr) } } } diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 3bdc85210..5a70e062f 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -116,7 +116,7 @@ func NewWithFile(lower tcpip.LinkEndpointID, file *os.File, snapLen uint32) (tcp // DeliverNetworkPacket implements the stack.NetworkDispatcher interface. It is // called by the link-layer endpoint being wrapped when a packet arrives, and // logs the packet before forwarding to the actual dispatcher. -func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { +func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { logPacket("recv", protocol, vv.First()) } diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 1c19a4509..cc1717ac7 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -51,7 +51,7 @@ func New(lower tcpip.LinkEndpointID) (tcpip.LinkEndpointID, *Endpoint) { // It is called by the link-layer endpoint being wrapped when a packet arrives, // and only forwards to the actual dispatcher if Wait or WaitDispatch haven't // been called. -func (e *Endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { +func (e *Endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { if !e.dispatchGate.Enter() { return } diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 0719a95a9..f20ee2fcb 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -35,7 +35,7 @@ type countedEndpoint struct { dispatcher stack.NetworkDispatcher } -func (e *countedEndpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { +func (e *countedEndpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { e.dispatchCount++ } @@ -106,21 +106,21 @@ func TestWaitDispatch(t *testing.T) { } // Dispatch and check that it goes through. - ep.dispatcher.DeliverNetworkPacket(ep, "", 0, nil) + ep.dispatcher.DeliverNetworkPacket(ep, "", 0, buffer.VectorisedView{}) if want := 1; ep.dispatchCount != want { t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) } // Wait on writes, then try to dispatch. It must go through. wep.WaitWrite() - ep.dispatcher.DeliverNetworkPacket(ep, "", 0, nil) + ep.dispatcher.DeliverNetworkPacket(ep, "", 0, buffer.VectorisedView{}) if want := 2; ep.dispatchCount != want { t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) } // Wait on dispatches, then try to dispatch. It must not go through. wep.WaitDispatch() - ep.dispatcher.DeliverNetworkPacket(ep, "", 0, nil) + ep.dispatcher.DeliverNetworkPacket(ep, "", 0, buffer.VectorisedView{}) if want := 2; ep.dispatchCount != want { t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) } diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 8f64e3f42..3f63daadd 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -83,7 +83,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload return tcpip.ErrNotSupported } -func (e *endpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { v := vv.First() h := header.ARP(v) if !h.IsValid() { diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index 8fc79dc94..50628e4a2 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -96,54 +96,54 @@ func TestDirectRequest(t *testing.T) { copy(h.HardwareAddressSender(), senderMAC) copy(h.ProtocolAddressSender(), senderIPv4) - // stackAddr1 - copy(h.ProtocolAddressTarget(), stackAddr1) - vv := v.ToVectorisedView([1]buffer.View{}) - c.linkEP.Inject(arp.ProtocolNumber, &vv) - pkt := <-c.linkEP.C - if pkt.Proto != arp.ProtocolNumber { - t.Fatalf("stackAddr1: expected ARP response, got network protocol number %v", pkt.Proto) - } - rep := header.ARP(pkt.Header) - if !rep.IsValid() { - t.Fatalf("stackAddr1: invalid ARP response len(pkt.Header)=%d", len(pkt.Header)) - } - if tcpip.Address(rep.ProtocolAddressSender()) != stackAddr1 { - t.Errorf("stackAddr1: expected sender to be set") - } - if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != stackLinkAddr { - t.Errorf("stackAddr1: expected sender to be stackLinkAddr, got %q", got) + inject := func(addr tcpip.Address) { + copy(h.ProtocolAddressTarget(), addr) + c.linkEP.Inject(arp.ProtocolNumber, v.ToVectorisedView()) } - // stackAddr2 - copy(h.ProtocolAddressTarget(), stackAddr2) - vv = v.ToVectorisedView([1]buffer.View{}) - c.linkEP.Inject(arp.ProtocolNumber, &vv) - pkt = <-c.linkEP.C - if pkt.Proto != arp.ProtocolNumber { - t.Fatalf("stackAddr2: expected ARP response, got network protocol number %v", pkt.Proto) + inject(stackAddr1) + { + pkt := <-c.linkEP.C + if pkt.Proto != arp.ProtocolNumber { + t.Fatalf("stackAddr1: expected ARP response, got network protocol number %v", pkt.Proto) + } + rep := header.ARP(pkt.Header) + if !rep.IsValid() { + t.Fatalf("stackAddr1: invalid ARP response len(pkt.Header)=%d", len(pkt.Header)) + } + if tcpip.Address(rep.ProtocolAddressSender()) != stackAddr1 { + t.Errorf("stackAddr1: expected sender to be set") + } + if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != stackLinkAddr { + t.Errorf("stackAddr1: expected sender to be stackLinkAddr, got %q", got) + } } - rep = header.ARP(pkt.Header) - if !rep.IsValid() { - t.Fatalf("stackAddr2: invalid ARP response len(pkt.Header)=%d", len(pkt.Header)) - } - if tcpip.Address(rep.ProtocolAddressSender()) != stackAddr2 { - t.Errorf("stackAddr2: expected sender to be set") - } - if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != stackLinkAddr { - t.Errorf("stackAddr2: expected sender to be stackLinkAddr, got %q", got) + + inject(stackAddr2) + { + pkt := <-c.linkEP.C + if pkt.Proto != arp.ProtocolNumber { + t.Fatalf("stackAddr2: expected ARP response, got network protocol number %v", pkt.Proto) + } + rep := header.ARP(pkt.Header) + if !rep.IsValid() { + t.Fatalf("stackAddr2: invalid ARP response len(pkt.Header)=%d", len(pkt.Header)) + } + if tcpip.Address(rep.ProtocolAddressSender()) != stackAddr2 { + t.Errorf("stackAddr2: expected sender to be set") + } + if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != stackLinkAddr { + t.Errorf("stackAddr2: expected sender to be stackLinkAddr, got %q", got) + } } - // stackAddrBad - copy(h.ProtocolAddressTarget(), stackAddrBad) - vv = v.ToVectorisedView([1]buffer.View{}) - c.linkEP.Inject(arp.ProtocolNumber, &vv) + inject(stackAddrBad) select { case pkt := <-c.linkEP.C: t.Errorf("stackAddrBad: unexpected packet sent, Proto=%v", pkt.Proto) case <-time.After(100 * time.Millisecond): - // Sleep tests are gross, but this will only - // potentially fail flakily if there's a bugj - // If there is no bug this will reliably succeed. + // Sleep tests are gross, but this will only potentially flake + // if there's a bug. If there is no bug this will reliably + // succeed. } } diff --git a/pkg/tcpip/network/fragmentation/frag_heap.go b/pkg/tcpip/network/fragmentation/frag_heap.go index 073882e99..6c7faafe4 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap.go +++ b/pkg/tcpip/network/fragmentation/frag_heap.go @@ -23,7 +23,7 @@ import ( type fragment struct { offset uint16 - vv *buffer.VectorisedView + vv buffer.VectorisedView } type fragHeap []fragment @@ -60,7 +60,7 @@ func (h *fragHeap) reassemble() (buffer.VectorisedView, error) { size := curr.vv.Size() if curr.offset != 0 { - return buffer.NewVectorisedView(0, nil), fmt.Errorf("offset of the first packet is != 0 (%d)", curr.offset) + return buffer.VectorisedView{}, fmt.Errorf("offset of the first packet is != 0 (%d)", curr.offset) } for h.Len() > 0 { @@ -68,7 +68,7 @@ func (h *fragHeap) reassemble() (buffer.VectorisedView, error) { if int(curr.offset) < size { curr.vv.TrimFront(size - int(curr.offset)) } else if int(curr.offset) > size { - return buffer.NewVectorisedView(0, nil), fmt.Errorf("packet has a hole, expected offset %d, got %d", size, curr.offset) + return buffer.VectorisedView{}, fmt.Errorf("packet has a hole, expected offset %d, got %d", size, curr.offset) } size += curr.vv.Size() views = append(views, curr.vv.Views()...) diff --git a/pkg/tcpip/network/fragmentation/frag_heap_test.go b/pkg/tcpip/network/fragmentation/frag_heap_test.go index a2fe80264..a15540634 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap_test.go +++ b/pkg/tcpip/network/fragmentation/frag_heap_test.go @@ -25,7 +25,7 @@ import ( var reassambleTestCases = []struct { comment string in []fragment - want *buffer.VectorisedView + want buffer.VectorisedView }{ { comment: "Non-overlapping in-order", @@ -87,21 +87,25 @@ var reassambleTestCases = []struct { func TestReassamble(t *testing.T) { for _, c := range reassambleTestCases { - h := (fragHeap)(make([]fragment, 0, 8)) - heap.Init(&h) - for _, f := range c.in { - heap.Push(&h, f) - } - got, _ := h.reassemble() - - if !reflect.DeepEqual(got, *c.want) { - t.Errorf("Test \"%s\" reassembling failed. Got %v. Want %v", c.comment, got, *c.want) - } + t.Run(c.comment, func(t *testing.T) { + h := make(fragHeap, 0, 8) + heap.Init(&h) + for _, f := range c.in { + heap.Push(&h, f) + } + got, err := h.reassemble() + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(got, c.want) { + t.Errorf("got reassemble(%+v) = %v, want = %v", c.in, got, c.want) + } + }) } } func TestReassambleFailsForNonZeroOffset(t *testing.T) { - h := (fragHeap)(make([]fragment, 0, 8)) + h := make(fragHeap, 0, 8) heap.Init(&h) heap.Push(&h, fragment{offset: 1, vv: vv(1, "0")}) _, err := h.reassemble() @@ -111,7 +115,7 @@ func TestReassambleFailsForNonZeroOffset(t *testing.T) { } func TestReassambleFailsForHoles(t *testing.T) { - h := (fragHeap)(make([]fragment, 0, 8)) + h := make(fragHeap, 0, 8) heap.Init(&h) heap.Push(&h, fragment{offset: 0, vv: vv(1, "0")}) heap.Push(&h, fragment{offset: 2, vv: vv(1, "1")}) diff --git a/pkg/tcpip/network/fragmentation/fragmentation.go b/pkg/tcpip/network/fragmentation/fragmentation.go index 21497f876..885e3cca2 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation.go +++ b/pkg/tcpip/network/fragmentation/fragmentation.go @@ -82,7 +82,7 @@ func NewFragmentation(highMemoryLimit, lowMemoryLimit int, reassemblingTimeout t // Process processes an incoming fragment beloning to an ID // and returns a complete packet when all the packets belonging to that ID have been received. -func (f *Fragmentation) Process(id uint32, first, last uint16, more bool, vv *buffer.VectorisedView) (buffer.VectorisedView, bool) { +func (f *Fragmentation) Process(id uint32, first, last uint16, more bool, vv buffer.VectorisedView) (buffer.VectorisedView, bool) { f.mu.Lock() r, ok := f.reassemblers[id] if ok && r.tooOld(f.timeout) { diff --git a/pkg/tcpip/network/fragmentation/fragmentation_test.go b/pkg/tcpip/network/fragmentation/fragmentation_test.go index 7320e594f..fc62a15dd 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation_test.go +++ b/pkg/tcpip/network/fragmentation/fragmentation_test.go @@ -23,19 +23,13 @@ import ( ) // vv is a helper to build VectorisedView from different strings. -func vv(size int, pieces ...string) *buffer.VectorisedView { +func vv(size int, pieces ...string) buffer.VectorisedView { views := make([]buffer.View, len(pieces)) for i, p := range pieces { views[i] = []byte(p) } - vv := buffer.NewVectorisedView(size, views) - return &vv -} - -func emptyVv() *buffer.VectorisedView { - vv := buffer.NewVectorisedView(0, nil) - return &vv + return buffer.NewVectorisedView(size, views) } type processInput struct { @@ -43,11 +37,11 @@ type processInput struct { first uint16 last uint16 more bool - vv *buffer.VectorisedView + vv buffer.VectorisedView } type processOutput struct { - vv *buffer.VectorisedView + vv buffer.VectorisedView done bool } @@ -63,7 +57,7 @@ var processTestCases = []struct { {id: 0, first: 2, last: 3, more: false, vv: vv(2, "23")}, }, out: []processOutput{ - {vv: emptyVv(), done: false}, + {vv: buffer.VectorisedView{}, done: false}, {vv: vv(4, "01", "23"), done: true}, }, }, @@ -76,8 +70,8 @@ var processTestCases = []struct { {id: 0, first: 2, last: 3, more: false, vv: vv(2, "23")}, }, out: []processOutput{ - {vv: emptyVv(), done: false}, - {vv: emptyVv(), done: false}, + {vv: buffer.VectorisedView{}, done: false}, + {vv: buffer.VectorisedView{}, done: false}, {vv: vv(4, "ab", "cd"), done: true}, {vv: vv(4, "01", "23"), done: true}, }, @@ -86,26 +80,28 @@ var processTestCases = []struct { func TestFragmentationProcess(t *testing.T) { for _, c := range processTestCases { - f := NewFragmentation(1024, 512, DefaultReassembleTimeout) - for i, in := range c.in { - vv, done := f.Process(in.id, in.first, in.last, in.more, in.vv) - if !reflect.DeepEqual(vv, *(c.out[i].vv)) { - t.Errorf("Test \"%s\" Process() returned a wrong vv. Got %v. Want %v", c.comment, vv, *(c.out[i].vv)) - } - if done != c.out[i].done { - t.Errorf("Test \"%s\" Process() returned a wrong done. Got %t. Want %t", c.comment, done, c.out[i].done) - } - if c.out[i].done { - if _, ok := f.reassemblers[in.id]; ok { - t.Errorf("Test \"%s\" Process() didn't remove buffer from reassemblers.", c.comment) + t.Run(c.comment, func(t *testing.T) { + f := NewFragmentation(1024, 512, DefaultReassembleTimeout) + for i, in := range c.in { + vv, done := f.Process(in.id, in.first, in.last, in.more, in.vv) + if !reflect.DeepEqual(vv, c.out[i].vv) { + t.Errorf("got Process(%d) = %+v, want = %+v", i, vv, c.out[i].vv) + } + if done != c.out[i].done { + t.Errorf("got Process(%d) = %+v, want = %+v", i, done, c.out[i].done) } - for n := f.rList.Front(); n != nil; n = n.Next() { - if n.id == in.id { - t.Errorf("Test \"%s\" Process() didn't remove buffer from rList.", c.comment) + if c.out[i].done { + if _, ok := f.reassemblers[in.id]; ok { + t.Errorf("Process(%d) did not remove buffer from reassemblers", i) + } + for n := f.rList.Front(); n != nil; n = n.Next() { + if n.id == in.id { + t.Errorf("Process(%d) did not remove buffer from rList", i) + } } } } - } + }) } } @@ -161,16 +157,3 @@ func TestMemoryLimitsIgnoresDuplicates(t *testing.T) { t.Errorf("Wrong size, duplicates are not handled correctly: got=%d, want=%d.", got, want) } } - -func TestFragmentationViewsDoNotEscape(t *testing.T) { - f := NewFragmentation(1024, 512, DefaultReassembleTimeout) - in := vv(2, "0", "1") - f.Process(0, 0, 1, true, in) - // Modify input view. - in.RemoveFirst() - got, _ := f.Process(0, 2, 2, false, vv(1, "2")) - want := vv(3, "0", "1", "2") - if !reflect.DeepEqual(got, *want) { - t.Errorf("Process() returned a wrong vv. Got %v. Want %v", got, *want) - } -} diff --git a/pkg/tcpip/network/fragmentation/reassembler.go b/pkg/tcpip/network/fragmentation/reassembler.go index 7c465c1ac..b57fe82ec 100644 --- a/pkg/tcpip/network/fragmentation/reassembler.go +++ b/pkg/tcpip/network/fragmentation/reassembler.go @@ -78,7 +78,7 @@ func (r *reassembler) updateHoles(first, last uint16, more bool) bool { return used } -func (r *reassembler) process(first, last uint16, more bool, vv *buffer.VectorisedView) (buffer.VectorisedView, bool, int) { +func (r *reassembler) process(first, last uint16, more bool, vv buffer.VectorisedView) (buffer.VectorisedView, bool, int) { r.mu.Lock() defer r.mu.Unlock() consumed := 0 @@ -86,18 +86,17 @@ func (r *reassembler) process(first, last uint16, more bool, vv *buffer.Vectoris // A concurrent goroutine might have already reassembled // the packet and emptied the heap while this goroutine // was waiting on the mutex. We don't have to do anything in this case. - return buffer.NewVectorisedView(0, nil), false, consumed + return buffer.VectorisedView{}, false, consumed } if r.updateHoles(first, last, more) { // We store the incoming packet only if it filled some holes. - uu := vv.Clone(nil) - heap.Push(&r.heap, fragment{offset: first, vv: &uu}) + heap.Push(&r.heap, fragment{offset: first, vv: vv.Clone(nil)}) consumed = vv.Size() r.size += consumed } // Check if all the holes have been deleted and we are ready to reassamble. if r.deleted < len(r.holes) { - return buffer.NewVectorisedView(0, nil), false, consumed + return buffer.VectorisedView{}, false, consumed } res, err := r.heap.reassemble() if err != nil { diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 0cb53fb42..fe6bf0441 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -94,16 +94,16 @@ func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv buff // DeliverTransportPacket is called by network endpoints after parsing incoming // packets. This is used by the test object to verify that the results of the // parsing are expected. -func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) { - t.checkValues(protocol, *vv, r.RemoteAddress, r.LocalAddress) +func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView) { + t.checkValues(protocol, vv, r.RemoteAddress, r.LocalAddress) t.dataCalls++ } // DeliverTransportControlPacket is called by network endpoints after parsing // incoming control (ICMP) packets. This is used by the test object to verify // that the results of the parsing are expected. -func (t *testObject) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ stack.ControlType, extra uint32, vv *buffer.VectorisedView) { - t.checkValues(trans, *vv, remote, local) +func (t *testObject) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ stack.ControlType, extra uint32, vv buffer.VectorisedView) { + t.checkValues(trans, vv, remote, local) if typ != t.typ { t.t.Errorf("typ = %v, want %v", typ, t.typ) } @@ -221,8 +221,7 @@ func TestIPv4Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) - if err := ep.WritePacket(&r, &hdr, vv, 123, 123); err != nil { + if err := ep.WritePacket(&r, &hdr, payload.ToVectorisedView(), 123, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) } } @@ -262,9 +261,7 @@ func TestIPv4Receive(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - var views [1]buffer.View - vv := view.ToVectorisedView(views) - ep.HandlePacket(&r, &vv) + ep.HandlePacket(&r, view.ToVectorisedView()) if o.dataCalls != 1 { t.Fatalf("Bad number of data calls: got %x, want 1", o.dataCalls) } @@ -296,7 +293,6 @@ func TestIPv4ReceiveControl(t *testing.T) { } for _, c := range cases { t.Run(c.name, func(t *testing.T) { - var views [1]buffer.View o := testObject{t: t} proto := ipv4.NewProtocol() ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, &o, nil) @@ -351,9 +347,8 @@ func TestIPv4ReceiveControl(t *testing.T) { o.typ = c.expectedTyp o.extra = c.expectedExtra - vv := view.ToVectorisedView(views) - vv.CapLength(len(view) - c.trunc) - ep.HandlePacket(&r, &vv) + vv := view[:len(view)-c.trunc].ToVectorisedView() + ep.HandlePacket(&r, vv) if want := c.expectedCount; o.controlCalls != want { t.Fatalf("Bad number of control calls for %q case: got %v, want %v", c.name, o.controlCalls, want) } @@ -416,18 +411,13 @@ func TestIPv4FragmentationReceive(t *testing.T) { } // Send first segment. - var views1 [1]buffer.View - vv1 := frag1.ToVectorisedView(views1) - ep.HandlePacket(&r, &vv1) + ep.HandlePacket(&r, frag1.ToVectorisedView()) if o.dataCalls != 0 { t.Fatalf("Bad number of data calls: got %x, want 0", o.dataCalls) } // Send second segment. - var views2 [1]buffer.View - vv2 := frag2.ToVectorisedView(views2) - ep.HandlePacket(&r, &vv2) - + ep.HandlePacket(&r, frag2.ToVectorisedView()) if o.dataCalls != 1 { t.Fatalf("Bad number of data calls: got %x, want 1", o.dataCalls) } @@ -460,8 +450,7 @@ func TestIPv6Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) - if err := ep.WritePacket(&r, &hdr, vv, 123, 123); err != nil { + if err := ep.WritePacket(&r, &hdr, payload.ToVectorisedView(), 123, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) } } @@ -501,10 +490,7 @@ func TestIPv6Receive(t *testing.T) { t.Fatalf("could not find route: %v", err) } - var views [1]buffer.View - vv := view.ToVectorisedView(views) - ep.HandlePacket(&r, &vv) - + ep.HandlePacket(&r, view.ToVectorisedView()) if o.dataCalls != 1 { t.Fatalf("Bad number of data calls: got %x, want 1", o.dataCalls) } @@ -541,7 +527,6 @@ func TestIPv6ReceiveControl(t *testing.T) { } for _, c := range cases { t.Run(c.name, func(t *testing.T) { - var views [1]buffer.View o := testObject{t: t} proto := ipv6.NewProtocol() ep, err := proto.NewEndpoint(1, localIpv6Addr, nil, &o, nil) @@ -609,9 +594,8 @@ func TestIPv6ReceiveControl(t *testing.T) { o.typ = c.expectedTyp o.extra = c.expectedExtra - vv := view.ToVectorisedView(views) - vv.CapLength(len(view) - c.trunc) - ep.HandlePacket(&r, &vv) + vv := view[:len(view)-c.trunc].ToVectorisedView() + ep.HandlePacket(&r, vv) if want := c.expectedCount; o.controlCalls != want { t.Fatalf("Bad number of control calls for %q case: got %v, want %v", c.name, o.controlCalls, want) } diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index 74454f605..ab2fe8440 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -27,7 +27,7 @@ import ( // the original packet that caused the ICMP one to be sent. This information is // used to find out which transport endpoint must be notified about the ICMP // packet. -func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv *buffer.VectorisedView) { +func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer.VectorisedView) { h := header.IPv4(vv.First()) // We don't use IsValid() here because ICMP only requires that the IP @@ -55,7 +55,7 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv *buffer e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv) } -func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { +func (e *endpoint) handleICMP(r *stack.Route, vv buffer.VectorisedView) { v := vv.First() if len(v) < header.ICMPv4MinimumSize { return @@ -120,6 +120,5 @@ func sendPing4(r *stack.Route, code byte, data buffer.View) *tcpip.Error { data = data[header.ICMPv4EchoMinimumSize-header.ICMPv4MinimumSize:] icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) - vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) - return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(&hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) } diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index 0a2378a6a..877f34be8 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -133,7 +133,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload // HandlePacket is called by the link layer when new ipv4 packets arrive for // this endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { h := header.IPv4(vv.First()) if !h.IsValid(vv.Size()) { return @@ -148,11 +148,11 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { if more || h.FragmentOffset() != 0 { // The packet is a fragment, let's try to reassemble it. last := h.FragmentOffset() + uint16(vv.Size()) - 1 - tt, ready := e.fragmentation.Process(hash.IPv4FragmentHash(h), h.FragmentOffset(), last, more, vv) + var ready bool + vv, ready = e.fragmentation.Process(hash.IPv4FragmentHash(h), h.FragmentOffset(), last, more, vv) if !ready { return } - vv = &tt } p := h.TransportProtocol() if p == header.ICMPv4ProtocolNumber { diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 2158ba8f7..c6fcf58d2 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -27,7 +27,7 @@ import ( // the original packet that caused the ICMP one to be sent. This information is // used to find out which transport endpoint must be notified about the ICMP // packet. -func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv *buffer.VectorisedView) { +func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer.VectorisedView) { h := header.IPv6(vv.First()) // We don't use IsValid() here because ICMP only requires that up to @@ -62,7 +62,7 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv *buffer e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv) } -func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { +func (e *endpoint) handleICMP(r *stack.Route, vv buffer.VectorisedView) { v := vv.First() if len(v) < header.ICMPv6MinimumSize { return @@ -129,8 +129,8 @@ func (e *endpoint) handleICMP(r *stack.Route, vv *buffer.VectorisedView) { pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize)) copy(pkt, h) pkt.SetType(header.ICMPv6EchoReply) - pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, *vv)) - r.WritePacket(&hdr, *vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) + pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, vv)) + r.WritePacket(&hdr, vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) case header.ICMPv6EchoReply: if len(v) < header.ICMPv6EchoMinimumSize { diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index e9f400fe4..c48859be3 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -165,7 +165,7 @@ func (c *testContext) routePackets(ch <-chan channel.PacketInfo, ep *channel.End views := []buffer.View{pkt.Header, pkt.Payload} size := len(pkt.Header) + len(pkt.Payload) vv := buffer.NewVectorisedView(size, views) - ep.InjectLinkAddr(pkt.Proto, ep.LinkAddress(), &vv) + ep.InjectLinkAddr(pkt.Proto, ep.LinkAddress(), vv) } } diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index eb89168c3..8d5ae8303 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -101,7 +101,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload // HandlePacket is called by the link layer when new ipv6 packets arrive for // this endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { h := header.IPv6(vv.First()) if !h.IsValid(vv.Size()) { return diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 61afa673e..4c027e91a 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -391,7 +391,7 @@ func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error { // Note that the ownership of the slice backing vv is retained by the caller. // This rule applies only to the slice itself, not to the items of the slice; // the ownership of the items is not retained by the caller. -func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { +func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { netProto, ok := n.stack.networkProtocols[protocol] if !ok { n.stack.stats.UnknownProtocolRcvdPackets.Increment() @@ -459,7 +459,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin // DeliverTransportPacket delivers the packets to the appropriate transport // protocol endpoint. -func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) { +func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView) { state, ok := n.stack.transportProtocols[protocol] if !ok { n.stack.stats.UnknownProtocolRcvdPackets.Increment() @@ -502,7 +502,7 @@ func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolN // DeliverTransportControlPacket delivers control packets to the appropriate // transport protocol endpoint. -func (n *NIC) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv *buffer.VectorisedView) { +func (n *NIC) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv buffer.VectorisedView) { state, ok := n.stack.transportProtocols[trans] if !ok { return diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 7afde3598..acd3fa01b 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -64,11 +64,11 @@ const ( type TransportEndpoint interface { // HandlePacket is called by the stack when new packets arrive to // this transport endpoint. - HandlePacket(r *Route, id TransportEndpointID, vv *buffer.VectorisedView) + HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) // HandleControlPacket is called by the stack when new control (e.g., // ICMP) packets arrive to this transport endpoint. - HandleControlPacket(id TransportEndpointID, typ ControlType, extra uint32, vv *buffer.VectorisedView) + HandleControlPacket(id TransportEndpointID, typ ControlType, extra uint32, vv buffer.VectorisedView) } // TransportProtocol is the interface that needs to be implemented by transport @@ -95,7 +95,7 @@ type TransportProtocol interface { // // The return value indicates whether the packet was well-formed (for // stats purposes only). - HandleUnknownDestinationPacket(r *Route, id TransportEndpointID, vv *buffer.VectorisedView) bool + HandleUnknownDestinationPacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) bool // SetOption allows enabling/disabling protocol specific features. // SetOption returns an error if the option is not supported or the @@ -114,11 +114,11 @@ type TransportProtocol interface { type TransportDispatcher interface { // DeliverTransportPacket delivers packets to the appropriate // transport protocol endpoint. - DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView) + DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView) // DeliverTransportControlPacket delivers control packets to the // appropriate transport protocol endpoint. - DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv *buffer.VectorisedView) + DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv buffer.VectorisedView) } // NetworkEndpoint is the interface that needs to be implemented by endpoints @@ -155,7 +155,7 @@ type NetworkEndpoint interface { // HandlePacket is called by the link layer when new packets arrive to // this network endpoint. - HandlePacket(r *Route, vv *buffer.VectorisedView) + HandlePacket(r *Route, vv buffer.VectorisedView) // Close is called when the endpoint is reomved from a stack. Close() @@ -196,7 +196,7 @@ type NetworkProtocol interface { type NetworkDispatcher interface { // DeliverNetworkPacket finds the appropriate network protocol // endpoint and hands the packet over for further processing. - DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) + DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) } // LinkEndpointCapabilities is the type associated with the capabilities diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 789c819dd..2d313cc27 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -48,7 +48,7 @@ const ( type transportProtocolState struct { proto TransportProtocol - defaultHandler func(*Route, TransportEndpointID, *buffer.VectorisedView) bool + defaultHandler func(*Route, TransportEndpointID, buffer.VectorisedView) bool } // TCPProbeFunc is the expected function type for a TCP probe function to be @@ -428,7 +428,7 @@ func (s *Stack) TransportProtocolOption(transport tcpip.TransportProtocolNumber, // // It must be called only during initialization of the stack. Changing it as the // stack is operating is not supported. -func (s *Stack) SetTransportProtocolHandler(p tcpip.TransportProtocolNumber, h func(*Route, TransportEndpointID, *buffer.VectorisedView) bool) { +func (s *Stack) SetTransportProtocolHandler(p tcpip.TransportProtocolNumber, h func(*Route, TransportEndpointID, buffer.VectorisedView) bool) { state := s.transportProtocols[p] if state != nil { state.defaultHandler = h diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 816707d27..279867315 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -73,7 +73,7 @@ func (f *fakeNetworkEndpoint) ID() *stack.NetworkEndpointID { return &f.id } -func (f *fakeNetworkEndpoint) HandlePacket(r *stack.Route, vv *buffer.VectorisedView) { +func (f *fakeNetworkEndpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { // Increment the received packet count in the protocol descriptor. f.proto.packetCount[int(f.id.LocalAddress[0])%len(f.proto.packetCount)]++ @@ -205,15 +205,12 @@ func TestNetworkReceive(t *testing.T) { } fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) - var views [1]buffer.View - // Allocate the buffer containing the packet that will be injected into - // the stack. + buf := buffer.NewView(30) // Make sure packet with wrong address is not delivered. buf[0] = 3 - vv := buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 0 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0) } @@ -223,8 +220,7 @@ func TestNetworkReceive(t *testing.T) { // Make sure packet is delivered to first endpoint. buf[0] = 1 - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -234,8 +230,7 @@ func TestNetworkReceive(t *testing.T) { // Make sure packet is delivered to second endpoint. buf[0] = 2 - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -244,8 +239,7 @@ func TestNetworkReceive(t *testing.T) { } // Make sure packet is not delivered if protocol number is wrong. - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber-1, &vv) + linkEP.Inject(fakeNetNumber-1, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -255,8 +249,7 @@ func TestNetworkReceive(t *testing.T) { // Make sure packet that is too small is dropped. buf.CapLength(2) - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -460,16 +453,14 @@ func TestAddressRemoval(t *testing.T) { t.Fatalf("AddAddress failed: %v", err) } - var views [1]buffer.View - buf := buffer.NewView(30) - fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) + buf := buffer.NewView(30) + // Write a packet, and check that it gets delivered. fakeNet.packetCount[1] = 0 buf[0] = 1 - vv := buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -480,8 +471,7 @@ func TestAddressRemoval(t *testing.T) { t.Fatalf("RemoveAddress failed: %v", err) } - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -510,14 +500,12 @@ func TestDelayedRemovalDueToRoute(t *testing.T) { fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) - var views [1]buffer.View buf := buffer.NewView(30) // Write a packet, and check that it gets delivered. fakeNet.packetCount[1] = 0 buf[0] = 1 - vv := buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -528,8 +516,7 @@ func TestDelayedRemovalDueToRoute(t *testing.T) { t.Fatalf("FindRoute failed: %v", err) } - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 2 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 2) } @@ -540,8 +527,7 @@ func TestDelayedRemovalDueToRoute(t *testing.T) { t.Fatalf("RemoveAddress failed: %v", err) } - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 3 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 3) } @@ -553,8 +539,7 @@ func TestDelayedRemovalDueToRoute(t *testing.T) { // Release the route, then check that packet is not deliverable anymore. r.Release() - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 3 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 3) } @@ -574,15 +559,13 @@ func TestPromiscuousMode(t *testing.T) { fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) - var views [1]buffer.View buf := buffer.NewView(30) // Write a packet, and check that it doesn't get delivered as we don't // have a matching endpoint. fakeNet.packetCount[1] = 0 buf[0] = 1 - vv := buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 0 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0) } @@ -592,8 +575,7 @@ func TestPromiscuousMode(t *testing.T) { t.Fatalf("SetPromiscuousMode failed: %v", err) } - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -610,8 +592,7 @@ func TestPromiscuousMode(t *testing.T) { t.Fatalf("SetPromiscuousMode failed: %v", err) } - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -675,8 +656,8 @@ func TestSubnetAcceptsMatchingPacket(t *testing.T) { fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) - var views [1]buffer.View buf := buffer.NewView(30) + buf[0] = 1 fakeNet.packetCount[1] = 0 subnet, err := tcpip.NewSubnet(tcpip.Address("\x00"), tcpip.AddressMask("\xF0")) @@ -687,8 +668,7 @@ func TestSubnetAcceptsMatchingPacket(t *testing.T) { t.Fatalf("AddSubnet failed: %v", err) } - vv := buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 1 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 1) } @@ -709,8 +689,8 @@ func TestSubnetRejectsNonmatchingPacket(t *testing.T) { fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol) - var views [1]buffer.View buf := buffer.NewView(30) + buf[0] = 1 fakeNet.packetCount[1] = 0 subnet, err := tcpip.NewSubnet(tcpip.Address("\x10"), tcpip.AddressMask("\xF0")) @@ -720,8 +700,7 @@ func TestSubnetRejectsNonmatchingPacket(t *testing.T) { if err := s.AddSubnet(1, fakeNetNumber, subnet); err != nil { t.Fatalf("AddSubnet failed: %v", err) } - vv := buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeNet.packetCount[1] != 0 { t.Errorf("packetCount[1] = %d, want %d", fakeNet.packetCount[1], 0) } diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index 862afa693..a7470d606 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -100,7 +100,7 @@ func (d *transportDemuxer) unregisterEndpoint(netProtos []tcpip.NetworkProtocolN // deliverPacket attempts to deliver the given packet. Returns true if it found // an endpoint, false otherwise. -func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv *buffer.VectorisedView, id TransportEndpointID) bool { +func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView, id TransportEndpointID) bool { eps, ok := d.protocol[protocolIDs{r.NetProto, protocol}] if !ok { return false @@ -127,7 +127,7 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto // deliverControlPacket attempts to deliver the given control packet. Returns // true if it found an endpoint, false otherwise. -func (d *transportDemuxer) deliverControlPacket(net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv *buffer.VectorisedView, id TransportEndpointID) bool { +func (d *transportDemuxer) deliverControlPacket(net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv buffer.VectorisedView, id TransportEndpointID) bool { eps, ok := d.protocol[protocolIDs{net, trans}] if !ok { return false @@ -149,7 +149,7 @@ func (d *transportDemuxer) deliverControlPacket(net tcpip.NetworkProtocolNumber, return true } -func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv *buffer.VectorisedView, id TransportEndpointID) TransportEndpoint { +func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv buffer.VectorisedView, id TransportEndpointID) TransportEndpoint { // Try to find a match with the id as provided. if ep := eps.endpoints[id]; ep != nil { return ep diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index e4607192f..226191525 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -70,8 +70,7 @@ func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) if err != nil { return 0, err } - vv := buffer.NewVectorisedView(len(v), []buffer.View{v}) - if err := f.route.WritePacket(&hdr, vv, fakeTransNumber, 123); err != nil { + if err := f.route.WritePacket(&hdr, buffer.View(v).ToVectorisedView(), fakeTransNumber, 123); err != nil { return 0, err } @@ -149,12 +148,12 @@ func (*fakeTransportEndpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Erro return tcpip.FullAddress{}, nil } -func (f *fakeTransportEndpoint) HandlePacket(*stack.Route, stack.TransportEndpointID, *buffer.VectorisedView) { +func (f *fakeTransportEndpoint) HandlePacket(*stack.Route, stack.TransportEndpointID, buffer.VectorisedView) { // Increment the number of received packets. f.proto.packetCount++ } -func (f *fakeTransportEndpoint) HandleControlPacket(stack.TransportEndpointID, stack.ControlType, uint32, *buffer.VectorisedView) { +func (f *fakeTransportEndpoint) HandleControlPacket(stack.TransportEndpointID, stack.ControlType, uint32, buffer.VectorisedView) { // Increment the number of received control packets. f.proto.controlCount++ } @@ -193,7 +192,7 @@ func (*fakeTransportProtocol) ParsePorts(buffer.View) (src, dst uint16, err *tcp return 0, 0, nil } -func (*fakeTransportProtocol) HandleUnknownDestinationPacket(*stack.Route, stack.TransportEndpointID, *buffer.VectorisedView) bool { +func (*fakeTransportProtocol) HandleUnknownDestinationPacket(*stack.Route, stack.TransportEndpointID, buffer.VectorisedView) bool { return true } @@ -245,15 +244,13 @@ func TestTransportReceive(t *testing.T) { fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol) - var views [1]buffer.View // Create buffer that will hold the packet. buf := buffer.NewView(30) // Make sure packet with wrong protocol is not delivered. buf[0] = 1 buf[2] = 0 - vv := buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeTrans.packetCount != 0 { t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0) } @@ -262,8 +259,7 @@ func TestTransportReceive(t *testing.T) { buf[0] = 1 buf[1] = 3 buf[2] = byte(fakeTransNumber) - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeTrans.packetCount != 0 { t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0) } @@ -272,8 +268,7 @@ func TestTransportReceive(t *testing.T) { buf[0] = 1 buf[1] = 2 buf[2] = byte(fakeTransNumber) - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeTrans.packetCount != 1 { t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 1) } @@ -305,7 +300,6 @@ func TestTransportControlReceive(t *testing.T) { fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol) - var views [1]buffer.View // Create buffer that will hold the control packet. buf := buffer.NewView(2*fakeNetHeaderLen + 30) @@ -318,8 +312,7 @@ func TestTransportControlReceive(t *testing.T) { buf[fakeNetHeaderLen+0] = 0 buf[fakeNetHeaderLen+1] = 1 buf[fakeNetHeaderLen+2] = 0 - vv := buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeTrans.controlCount != 0 { t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0) } @@ -328,8 +321,7 @@ func TestTransportControlReceive(t *testing.T) { buf[fakeNetHeaderLen+0] = 3 buf[fakeNetHeaderLen+1] = 1 buf[fakeNetHeaderLen+2] = byte(fakeTransNumber) - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeTrans.controlCount != 0 { t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0) } @@ -338,8 +330,7 @@ func TestTransportControlReceive(t *testing.T) { buf[fakeNetHeaderLen+0] = 2 buf[fakeNetHeaderLen+1] = 1 buf[fakeNetHeaderLen+2] = byte(fakeTransNumber) - vv = buf.ToVectorisedView(views) - linkEP.Inject(fakeNetNumber, &vv) + linkEP.Inject(fakeNetNumber, buf.ToVectorisedView()) if fakeTrans.controlCount != 1 { t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 1) } diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index 7aaf2d9c6..fea9d6957 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -384,8 +384,7 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv4.SetChecksum(0) icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) - vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) - return r.WritePacket(&hdr, vv, header.ICMPv4ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(&hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) } func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { @@ -409,8 +408,7 @@ func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv6.SetChecksum(0) icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0))) - vv := buffer.NewVectorisedView(len(data), []buffer.View{data}) - return r.WritePacket(&hdr, vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(&hdr, data.ToVectorisedView(), header.ICMPv6ProtocolNumber, r.DefaultTTL()) } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { @@ -675,7 +673,7 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { e.rcvMu.Lock() // Drop the packet if our buffer is currently full. @@ -711,5 +709,5 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv } // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. -func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv *buffer.VectorisedView) { +func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv buffer.VectorisedView) { } diff --git a/pkg/tcpip/transport/ping/protocol.go b/pkg/tcpip/transport/ping/protocol.go index b885f3627..549b1b2d3 100644 --- a/pkg/tcpip/transport/ping/protocol.go +++ b/pkg/tcpip/transport/ping/protocol.go @@ -99,7 +99,7 @@ func (p *protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) // HandleUnknownDestinationPacket handles packets targeted at this protocol but // that don't match any existing endpoint. -func (p *protocol) HandleUnknownDestinationPacket(*stack.Route, stack.TransportEndpointID, *buffer.VectorisedView) bool { +func (p *protocol) HandleUnknownDestinationPacket(*stack.Route, stack.TransportEndpointID, buffer.VectorisedView) bool { return true } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 60e9daf74..4085585b0 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1323,7 +1323,7 @@ func (e *endpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { s := newSegment(r, id, vv) if !s.parse() { e.stack.Stats().MalformedRcvdPackets.Increment() @@ -1348,7 +1348,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv } // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. -func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv *buffer.VectorisedView) { +func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv buffer.VectorisedView) { switch typ { case stack.ControlPacketTooBig: e.sndBufMu.Lock() diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index 8a873db73..c80f3c7d6 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -63,7 +63,7 @@ func NewForwarder(s *stack.Stack, rcvWnd, maxInFlight int, handler func(*Forward // // This function is expected to be passed as an argument to the // stack.SetTransportProtocolHandler function. -func (f *Forwarder) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) bool { +func (f *Forwarder) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) bool { s := newSegment(r, id, vv) defer s.decRef() diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index fe21f2c78..abdc825cd 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -120,7 +120,7 @@ func (*protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) { // a reset is sent in response to any incoming segment except another reset. In // particular, SYNs addressed to a non-existent connection are rejected by this // means." -func (*protocol) HandleUnknownDestinationPacket(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) bool { +func (*protocol) HandleUnknownDestinationPacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) bool { s := newSegment(r, id, vv) defer s.decRef() diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 8dccea2ba..51a3d6aba 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -60,7 +60,7 @@ type segment struct { options []byte `state:".([]byte)"` } -func newSegment(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) *segment { +func newSegment(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) *segment { s := &segment{ refCnt: 1, id: id, diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index bf26ea24e..871177842 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -2668,11 +2668,11 @@ func TestReceivedInvalidSegmentCountIncrement(t *testing.T) { AckNum: c.IRS.Add(1), RcvWnd: 30000, }) - tcpbuf := vv.ByteSlice()[0][header.IPv4MinimumSize:] + tcpbuf := vv.First()[header.IPv4MinimumSize:] // 12 is the TCP header data offset. tcpbuf[12] = ((header.TCPMinimumSize - 1) / 4) << 4 - c.SendSegment(&vv) + c.SendSegment(vv) if got := stats.TCP.InvalidSegmentsReceived.Value(); got != want { t.Errorf("got stats.TCP.InvalidSegmentsReceived.Value() = %v, want = %v", got, want) diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index c46af4b8b..5b25534f4 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -205,9 +205,11 @@ func (c *Context) Stack() *stack.Stack { // CheckNoPacketTimeout verifies that no packet is received during the time // specified by wait. func (c *Context) CheckNoPacketTimeout(errMsg string, wait time.Duration) { + c.t.Helper() + select { case <-c.linkEP.C: - c.t.Fatalf(errMsg) + c.t.Fatal(errMsg) case <-time.After(wait): } @@ -290,9 +292,7 @@ func (c *Context) SendICMPPacket(typ header.ICMPv4Type, code uint8, p1, p2 []byt copy(icmp[header.ICMPv4MinimumSize+len(p1):], p2) // Inject packet. - var views [1]buffer.View - vv := buf.ToVectorisedView(views) - c.linkEP.Inject(ipv4.ProtocolNumber, &vv) + c.linkEP.Inject(ipv4.ProtocolNumber, buf.ToVectorisedView()) } // BuildSegment builds a TCP segment based on the given Headers and payload. @@ -337,23 +337,19 @@ func (c *Context) BuildSegment(payload []byte, h *Headers) buffer.VectorisedView t.SetChecksum(^t.CalculateChecksum(xsum, length)) // Inject packet. - var views [1]buffer.View - vv := buf.ToVectorisedView(views) - - return vv + return buf.ToVectorisedView() } // SendSegment sends a TCP segment that has already been built and written to a // buffer.VectorisedView. -func (c *Context) SendSegment(s *buffer.VectorisedView) { +func (c *Context) SendSegment(s buffer.VectorisedView) { c.linkEP.Inject(ipv4.ProtocolNumber, s) } // SendPacket builds and sends a TCP segment(with the provided payload & TCP // headers) in an IPv4 packet via the link layer endpoint. func (c *Context) SendPacket(payload []byte, h *Headers) { - vv := c.BuildSegment(payload, h) - c.linkEP.Inject(ipv4.ProtocolNumber, &vv) + c.linkEP.Inject(ipv4.ProtocolNumber, c.BuildSegment(payload, h)) } // SendAck sends an ACK packet. @@ -496,9 +492,7 @@ func (c *Context) SendV6Packet(payload []byte, h *Headers) { t.SetChecksum(^t.CalculateChecksum(xsum, length)) // Inject packet. - var views [1]buffer.View - vv := buf.ToVectorisedView(views) - c.linkEP.Inject(ipv6.ProtocolNumber, &vv) + c.linkEP.Inject(ipv6.ProtocolNumber, buf.ToVectorisedView()) } // CreateConnected creates a connected TCP endpoint. diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 5de518a55..e9337a88e 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -362,8 +362,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc ttl = e.multicastTTL } - vv := buffer.NewVectorisedView(len(v), []buffer.View{v}) - if err := sendUDP(route, vv, e.id.LocalPort, dstPort, ttl); err != nil { + if err := sendUDP(route, buffer.View(v).ToVectorisedView(), e.id.LocalPort, dstPort, ttl); err != nil { return 0, err } return uintptr(len(v)), nil @@ -843,7 +842,7 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv *buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { // Get the header then trim it from the view. hdr := header.UDP(vv.First()) if int(hdr.Length()) > vv.Size() { @@ -892,5 +891,5 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv } // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. -func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv *buffer.VectorisedView) { +func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, vv buffer.VectorisedView) { } diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index dabc5bd13..1334fec8a 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -62,7 +62,7 @@ func (*protocol) ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error) { // HandleUnknownDestinationPacket handles packets targeted at this protocol but // that don't match any existing endpoint. -func (p *protocol) HandleUnknownDestinationPacket(*stack.Route, stack.TransportEndpointID, *buffer.VectorisedView) bool { +func (p *protocol) HandleUnknownDestinationPacket(*stack.Route, stack.TransportEndpointID, buffer.VectorisedView) bool { return true } diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 6d7a737bd..46110c8ff 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -204,9 +204,7 @@ func (c *testContext) sendV6Packet(payload []byte, h *headers) { u.SetChecksum(^u.CalculateChecksum(xsum, length)) // Inject packet. - var views [1]buffer.View - vv := buf.ToVectorisedView(views) - c.linkEP.Inject(ipv6.ProtocolNumber, &vv) + c.linkEP.Inject(ipv6.ProtocolNumber, buf.ToVectorisedView()) } func (c *testContext) sendPacket(payload []byte, h *headers) { @@ -245,9 +243,7 @@ func (c *testContext) sendPacket(payload []byte, h *headers) { u.SetChecksum(^u.CalculateChecksum(xsum, length)) // Inject packet. - var views [1]buffer.View - vv := buf.ToVectorisedView(views) - c.linkEP.Inject(ipv4.ProtocolNumber, &vv) + c.linkEP.Inject(ipv4.ProtocolNumber, buf.ToVectorisedView()) } func newPayload() []byte { -- cgit v1.2.3 From d7a05b4e63252006818e1aadf7a0d383d130fe54 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 14 Sep 2018 15:22:42 -0700 Subject: Pass buffer.Prependable by value PiperOrigin-RevId: 213053370 Change-Id: I60ea89572b4fca53fd126c870fcbde74fcf52562 --- pkg/tcpip/buffer/prependable.go | 6 +++--- pkg/tcpip/link/channel/channel.go | 2 +- pkg/tcpip/link/fdbased/endpoint.go | 2 +- pkg/tcpip/link/fdbased/endpoint_test.go | 2 +- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_test.go | 22 +++++++++++----------- pkg/tcpip/link/sniffer/sniffer.go | 2 +- pkg/tcpip/link/waitable/waitable.go | 2 +- pkg/tcpip/link/waitable/waitable_test.go | 8 ++++---- pkg/tcpip/network/arp/arp.go | 6 +++--- pkg/tcpip/network/ip_test.go | 6 +++--- pkg/tcpip/network/ipv4/icmp.go | 2 +- pkg/tcpip/network/ipv4/ipv4.go | 2 +- pkg/tcpip/network/ipv6/icmp.go | 6 +++--- pkg/tcpip/network/ipv6/ipv6.go | 2 +- pkg/tcpip/stack/registration.go | 4 ++-- pkg/tcpip/stack/route.go | 2 +- pkg/tcpip/stack/stack_test.go | 4 ++-- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/transport/ping/endpoint.go | 4 ++-- pkg/tcpip/transport/tcp/connect.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 2 +- 23 files changed, 47 insertions(+), 47 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/buffer/prependable.go b/pkg/tcpip/buffer/prependable.go index 5af3ff114..bca23ef68 100644 --- a/pkg/tcpip/buffer/prependable.go +++ b/pkg/tcpip/buffer/prependable.go @@ -54,7 +54,7 @@ func (p *Prependable) Prepend(size int) []byte { // View returns a View of the backing buffer that contains all prepended // data so far. -func (p *Prependable) View() View { +func (p Prependable) View() View { v := p.buf v.TrimFront(p.usedIdx) return v @@ -62,11 +62,11 @@ func (p *Prependable) View() View { // UsedBytes returns a slice of the backing buffer that contains all prepended // data so far. -func (p *Prependable) UsedBytes() []byte { +func (p Prependable) UsedBytes() []byte { return p.buf[p.usedIdx:] } // UsedLength returns the number of bytes used so far. -func (p *Prependable) UsedLength() int { +func (p Prependable) UsedLength() int { return len(p.buf) - p.usedIdx } diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index a927a1b3f..8b680de7c 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -109,7 +109,7 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { } // WritePacket stores outbound packets into the channel. -func (e *Endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(_ *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { p := PacketInfo{ Header: hdr.View(), Proto: protocol, diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 0b985928b..0b0d6c1e2 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -158,7 +158,7 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if e.handleLocal && r.LocalAddress != "" && r.LocalAddress == r.RemoteAddress { views := make([]buffer.View, 1, 1+len(payload.Views())) views[0] = hdr.View() diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 21d2f10b0..f7890e031 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -158,7 +158,7 @@ func TestWritePacket(t *testing.T) { payload[i] = uint8(rand.Intn(256)) } want := append(hdr.UsedBytes(), payload...) - if err := c.ep.WritePacket(r, &hdr, payload.ToVectorisedView(), proto); err != nil { + if err := c.ep.WritePacket(r, hdr, payload.ToVectorisedView(), proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 884de83c9..554ad64de 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -72,7 +72,7 @@ func (*endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements stack.LinkEndpoint.WritePacket. It delivers outbound // packets to the network-layer dispatcher. -func (e *endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(_ *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { views := make([]buffer.View, 1, 1+len(payload.Views())) views[0] = hdr.View() views = append(views, payload.Views()...) diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 0dd23794b..887612957 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -184,7 +184,7 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { // Add the ethernet header here. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) eth.Encode(&header.EthernetFields{ diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 682c38400..9a0348deb 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -270,7 +270,7 @@ func TestSimpleSend(t *testing.T) { randomFill(buf) proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) - if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), proto); err != nil { + if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } @@ -336,7 +336,7 @@ func TestFillTxQueue(t *testing.T) { for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -351,7 +351,7 @@ func TestFillTxQueue(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -376,7 +376,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Send two packets so that the id slice has at least two slots. for i := 2; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } @@ -396,7 +396,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -411,7 +411,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -434,7 +434,7 @@ func TestFillTxMemory(t *testing.T) { ids := make(map[uint64]struct{}) for i := queueDataSize / bufferSize; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -450,7 +450,7 @@ func TestFillTxMemory(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber) + err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber) if want := tcpip.ErrWouldBlock; err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } @@ -475,7 +475,7 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { // until there is only one buffer left. for i := queueDataSize/bufferSize - 1; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -488,7 +488,7 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) uu := buffer.NewView(bufferSize).ToVectorisedView() - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, uu, header.IPv4ProtocolNumber); err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, hdr, uu, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -496,7 +496,7 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { // Attempt to write the one-buffer packet again. It must succeed. { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 5a70e062f..e6ce3ee13 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -188,7 +188,7 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements the stack.LinkEndpoint interface. It is called by // higher-level protocols to write packets; it just logs the packet and forwards // the request to the lower endpoint. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { logPacket("send", protocol, hdr.UsedBytes()) } diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index cc1717ac7..9b69f844e 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -100,7 +100,7 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements stack.LinkEndpoint.WritePacket. It is called by // higher-level protocols to write packets. It only forwards packets to the // lower endpoint if Wait or WaitWrite haven't been called. -func (e *Endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if !e.writeGate.Enter() { return nil } diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index f20ee2fcb..1301cd4b2 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -65,7 +65,7 @@ func (e *countedEndpoint) LinkAddress() tcpip.LinkAddress { return e.linkAddr } -func (e *countedEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *countedEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { e.writeCount++ return nil } @@ -75,21 +75,21 @@ func TestWaitWrite(t *testing.T) { _, wep := New(stack.RegisterLinkEndpoint(ep)) // Write and check that it goes through. - wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) + wep.WritePacket(nil, buffer.Prependable{}, buffer.VectorisedView{}, 0) if want := 1; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } // Wait on dispatches, then try to write. It must go through. wep.WaitDispatch() - wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) + wep.WritePacket(nil, buffer.Prependable{}, buffer.VectorisedView{}, 0) if want := 2; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } // Wait on writes, then try to write. It must not go through. wep.WaitWrite() - wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) + wep.WritePacket(nil, buffer.Prependable{}, buffer.VectorisedView{}, 0) if want := 2; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 3f63daadd..9d0881e11 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -79,7 +79,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { func (e *endpoint) Close() {} -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { return tcpip.ErrNotSupported } @@ -103,7 +103,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { copy(pkt.HardwareAddressSender(), r.LocalLinkAddress[:]) copy(pkt.ProtocolAddressSender(), h.ProtocolAddressTarget()) copy(pkt.ProtocolAddressTarget(), h.ProtocolAddressSender()) - e.linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber) + e.linkEP.WritePacket(r, hdr, buffer.VectorisedView{}, ProtocolNumber) fallthrough // also fill the cache from requests case header.ARPReply: addr := tcpip.Address(h.ProtocolAddressSender()) @@ -155,7 +155,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. copy(h.ProtocolAddressSender(), localAddr) copy(h.ProtocolAddressTarget(), addr) - return linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber) + return linkEP.WritePacket(r, hdr, buffer.VectorisedView{}, ProtocolNumber) } // ResolveStaticAddress implements stack.LinkAddressResolver. diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index fe6bf0441..b381c7214 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -145,7 +145,7 @@ func (*testObject) LinkAddress() tcpip.LinkAddress { // WritePacket is called by network endpoints after producing a packet and // writing it to the link endpoint. This is used by the test object to verify // that the produced packet is as expected. -func (t *testObject) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (t *testObject) WritePacket(_ *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { var prot tcpip.TransportProtocolNumber var srcAddr tcpip.Address var dstAddr tcpip.Address @@ -221,7 +221,7 @@ func TestIPv4Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - if err := ep.WritePacket(&r, &hdr, payload.ToVectorisedView(), 123, 123); err != nil { + if err := ep.WritePacket(&r, hdr, payload.ToVectorisedView(), 123, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) } } @@ -450,7 +450,7 @@ func TestIPv6Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - if err := ep.WritePacket(&r, &hdr, payload.ToVectorisedView(), 123, 123); err != nil { + if err := ep.WritePacket(&r, hdr, payload.ToVectorisedView(), 123, 123); err != nil { t.Fatalf("WritePacket failed: %v", err) } } diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index ab2fe8440..ee8172ac8 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -120,5 +120,5 @@ func sendPing4(r *stack.Route, code byte, data buffer.View) *tcpip.Error { data = data[header.ICMPv4EchoMinimumSize-header.ICMPv4MinimumSize:] icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) - return r.WritePacket(&hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) } diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index 877f34be8..d4eeeb5d9 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -107,7 +107,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { } // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize)) length := uint16(hdr.UsedLength() + payload.Size()) id := uint32(0) diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index c6fcf58d2..468201d77 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -106,7 +106,7 @@ func (e *endpoint) handleICMP(r *stack.Route, vv buffer.VectorisedView) { pkt[icmpV6LengthOffset] = 1 copy(pkt[icmpV6LengthOffset+1:], r.LocalLinkAddress[:]) pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{})) - r.WritePacket(&hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber, r.DefaultTTL()) + r.WritePacket(hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber, r.DefaultTTL()) e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) @@ -130,7 +130,7 @@ func (e *endpoint) handleICMP(r *stack.Route, vv buffer.VectorisedView) { copy(pkt, h) pkt.SetType(header.ICMPv6EchoReply) pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, vv)) - r.WritePacket(&hdr, vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) + r.WritePacket(hdr, vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) case header.ICMPv6EchoReply: if len(v) < header.ICMPv6EchoMinimumSize { @@ -196,7 +196,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. DstAddr: r.RemoteAddress, }) - return linkEP.WritePacket(r, &hdr, buffer.VectorisedView{}, ProtocolNumber) + return linkEP.WritePacket(r, hdr, buffer.VectorisedView{}, ProtocolNumber) } // ResolveStaticAddress implements stack.LinkAddressResolver. diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 8d5ae8303..e1f4ea863 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -84,7 +84,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { } // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { length := uint16(hdr.UsedLength() + payload.Size()) ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) ip.Encode(&header.IPv6Fields{ diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index acd3fa01b..2f51ada73 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -145,7 +145,7 @@ type NetworkEndpoint interface { // WritePacket writes a packet to the given destination address and // protocol. - WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error + WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error // ID returns the network protocol endpoint ID. ID() *NetworkEndpointID @@ -238,7 +238,7 @@ type LinkEndpoint interface { // WritePacket writes a packet with the given protocol through the given // route. - WritePacket(r *Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error + WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error // Attach attaches the data link layer endpoint to the network-layer // dispatcher of the stack. diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 9dfb95b4a..cc9b24e23 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -129,7 +129,7 @@ func (r *Route) IsResolutionRequired() bool { } // WritePacket writes the packet through the given route. -func (r *Route) WritePacket(hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { +func (r *Route) WritePacket(hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl) if err == tcpip.ErrNoRoute { r.Stats().IP.OutgoingPacketErrors.Increment() diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 279867315..a0b3399a8 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -109,7 +109,7 @@ func (f *fakeNetworkEndpoint) Capabilities() stack.LinkEndpointCapabilities { return f.linkEP.Capabilities() } -func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, _ uint8) *tcpip.Error { +func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, _ uint8) *tcpip.Error { // Increment the sent packet count in the protocol descriptor. f.proto.sendPacketCount[int(r.RemoteAddress[0])%len(f.proto.sendPacketCount)]++ @@ -266,7 +266,7 @@ func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address) { defer r.Release() hdr := buffer.NewPrependable(int(r.MaxHeaderLength())) - if err := r.WritePacket(&hdr, buffer.VectorisedView{}, fakeTransNumber, 123); err != nil { + if err := r.WritePacket(hdr, buffer.VectorisedView{}, fakeTransNumber, 123); err != nil { t.Errorf("WritePacket failed: %v", err) return } diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 226191525..9ec37e7b6 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -70,7 +70,7 @@ func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) if err != nil { return 0, err } - if err := f.route.WritePacket(&hdr, buffer.View(v).ToVectorisedView(), fakeTransNumber, 123); err != nil { + if err := f.route.WritePacket(hdr, buffer.View(v).ToVectorisedView(), fakeTransNumber, 123); err != nil { return 0, err } diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index fea9d6957..fcfb96624 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -384,7 +384,7 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv4.SetChecksum(0) icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) - return r.WritePacket(&hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) } func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { @@ -408,7 +408,7 @@ func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv6.SetChecksum(0) icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0))) - return r.WritePacket(&hdr, data.ToVectorisedView(), header.ICMPv6ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(hdr, data.ToVectorisedView(), header.ICMPv6ProtocolNumber, r.DefaultTTL()) } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index ce87d5818..68c0d4472 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -608,7 +608,7 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.Vectorise r.Stats().TCP.ResetsSent.Increment() } - return r.WritePacket(&hdr, data, ProtocolNumber, ttl) + return r.WritePacket(hdr, data, ProtocolNumber, ttl) } // makeOptions makes an options slice. diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index e9337a88e..4de2aa3e3 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -542,7 +542,7 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u // Track count of packets sent. r.Stats().UDP.PacketsSent.Increment() - return r.WritePacket(&hdr, data, ProtocolNumber, ttl) + return r.WritePacket(hdr, data, ProtocolNumber, ttl) } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { -- cgit v1.2.3 From 23258ca284b3f086cc83b69d9a1f8f382036a69e Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 17 Sep 2018 13:04:38 -0700 Subject: Implement packet forwarding to enable NAT PiperOrigin-RevId: 213323501 Change-Id: I0996ddbdcf097588745efe35481085d42dbaf446 --- pkg/tcpip/stack/nic.go | 110 +++++++++++++++++++++++++++++++---------------- pkg/tcpip/stack/stack.go | 21 ++++++++- 2 files changed, 92 insertions(+), 39 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 4c027e91a..29c9ddec4 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -408,53 +408,89 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.Lin } src, dst := netProto.ParseAddresses(vv.First()) - id := NetworkEndpointID{dst} - n.mu.RLock() - ref, ok := n.endpoints[id] - if ok && !ref.tryIncRef() { - ref = nil + if ref := n.getRef(protocol, dst); ref != nil { + r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) + r.RemoteLinkAddress = remoteLinkAddr + ref.ep.HandlePacket(&r, vv) + ref.decRef() + return } - if ref != nil { + + // This NIC doesn't care about the packet. Find a NIC that cares about the + // packet and forward it to the NIC. + // + // TODO: Should we be forwarding the packet even if promiscuous? + if n.stack.Forwarding() { + r, err := n.stack.FindRoute(0, "", dst, protocol) + if err != nil { + n.stack.stats.IP.InvalidAddressesReceived.Increment() + return + } + defer r.Release() + + r.LocalLinkAddress = n.linkEP.LinkAddress() + r.RemoteLinkAddress = remoteLinkAddr + + // Found a NIC. + n := r.ref.nic + n.mu.RLock() + ref, ok := n.endpoints[NetworkEndpointID{dst}] n.mu.RUnlock() - } else { - promiscuous := n.promiscuous - // Check if the packet is for a subnet this NIC cares about. - if !promiscuous { - for _, sn := range n.subnets { - if sn.Contains(dst) { - promiscuous = true - break - } - } + if ok && ref.tryIncRef() { + ref.ep.HandlePacket(&r, vv) + ref.decRef() + } else { + // n doesn't have a destination endpoint. + // Send the packet out of n. + hdr := buffer.NewPrependableFromView(vv.First()) + vv.RemoveFirst() + n.linkEP.WritePacket(&r, hdr, vv, protocol) } + return + } + + n.stack.stats.IP.InvalidAddressesReceived.Increment() +} + +func (n *NIC) getRef(protocol tcpip.NetworkProtocolNumber, dst tcpip.Address) *referencedNetworkEndpoint { + id := NetworkEndpointID{dst} + + n.mu.RLock() + if ref, ok := n.endpoints[id]; ok && ref.tryIncRef() { n.mu.RUnlock() - if promiscuous { - // Try again with the lock in exclusive mode. If we still can't - // get the endpoint, create a new "temporary" one. It will only - // exist while there's a route through it. - n.mu.Lock() - ref, ok = n.endpoints[id] - if !ok || !ref.tryIncRef() { - var err *tcpip.Error - ref, err = n.addAddressLocked(protocol, dst, CanBePrimaryEndpoint, true) - if err == nil { - ref.holdsInsertRef = false - } + return ref + } + + promiscuous := n.promiscuous + // Check if the packet is for a subnet this NIC cares about. + if !promiscuous { + for _, sn := range n.subnets { + if sn.Contains(dst) { + promiscuous = true + break } - n.mu.Unlock() } } - - if ref == nil { - n.stack.stats.IP.InvalidAddressesReceived.Increment() - return + n.mu.RUnlock() + if promiscuous { + // Try again with the lock in exclusive mode. If we still can't + // get the endpoint, create a new "temporary" one. It will only + // exist while there's a route through it. + n.mu.Lock() + if ref, ok := n.endpoints[id]; ok && ref.tryIncRef() { + n.mu.Unlock() + return ref + } + ref, err := n.addAddressLocked(protocol, dst, CanBePrimaryEndpoint, true) + n.mu.Unlock() + if err == nil { + ref.holdsInsertRef = false + return ref + } } - r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) - r.RemoteLinkAddress = remoteLinkAddr - ref.ep.HandlePacket(&r, vv) - ref.decRef() + return nil } // DeliverTransportPacket delivers the packets to the appropriate transport diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 2d313cc27..699519be1 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -283,8 +283,9 @@ type Stack struct { linkAddrCache *linkAddrCache - mu sync.RWMutex - nics map[tcpip.NICID]*NIC + mu sync.RWMutex + nics map[tcpip.NICID]*NIC + forwarding bool // route is the route table passed in by the user via SetRouteTable(), // it is used by FindRoute() to build a route for a specific @@ -448,6 +449,22 @@ func (s *Stack) Stats() tcpip.Stats { return s.stats } +// SetForwarding enables or disables the packet forwarding between NICs. +func (s *Stack) SetForwarding(enable bool) { + // TODO: Expose via /proc/sys/net/ipv4/ip_forward. + s.mu.Lock() + s.forwarding = enable + s.mu.Unlock() +} + +// Forwarding returns if the packet forwarding between NICs is enabled. +func (s *Stack) Forwarding() bool { + // TODO: Expose via /proc/sys/net/ipv4/ip_forward. + s.mu.RLock() + defer s.mu.RUnlock() + return s.forwarding +} + // SetRouteTable assigns the route table to be used by this stack. It // specifies which NIC to use for given destination address ranges. func (s *Stack) SetRouteTable(table []tcpip.Route) { -- cgit v1.2.3 From 2e497de2d9f6c410a214faae9962e762757b0648 Mon Sep 17 00:00:00 2001 From: Bert Muthalaly Date: Wed, 19 Sep 2018 13:42:55 -0700 Subject: Pass local link address to DeliverNetworkPacket This allows a NetworkDispatcher to implement transparent bridging, assuming all implementations of LinkEndpoint.WritePacket call eth.Encode with header.EthernetFields.SrcAddr set to the passed Route.LocalLinkAddress, if it is provided. PiperOrigin-RevId: 213686651 Change-Id: I446a4ac070970202f0724ef796ff1056ae4dd72a --- pkg/tcpip/link/channel/channel.go | 2 +- pkg/tcpip/link/fdbased/endpoint.go | 28 +++-- pkg/tcpip/link/fdbased/endpoint_test.go | 59 +++++++---- pkg/tcpip/link/loopback/loopback.go | 6 +- pkg/tcpip/link/sharedmem/sharedmem.go | 13 ++- pkg/tcpip/link/sharedmem/sharedmem_test.go | 158 ++++++++++++++++++++--------- pkg/tcpip/link/sniffer/sniffer.go | 4 +- pkg/tcpip/link/waitable/waitable.go | 4 +- pkg/tcpip/link/waitable/waitable_test.go | 8 +- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/stack/registration.go | 6 +- 11 files changed, 198 insertions(+), 92 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 8b680de7c..113cbbf5e 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -72,7 +72,7 @@ func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.Vector // InjectLinkAddr injects an inbound packet with a remote link address. func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, vv buffer.VectorisedView) { - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, vv.Clone(nil)) + e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, "" /* localLinkAddr */, protocol, vv.Clone(nil)) } // Attach saves the stack network-layer dispatcher for use later when packets diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 40a10eb9b..ee99ada07 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -164,17 +164,24 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b views[0] = hdr.View() views = append(views, payload.Views()...) vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) - e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, r.LocalLinkAddress, protocol, vv) return nil } if e.hdrSize > 0 { // Add ethernet header if needed. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) - eth.Encode(&header.EthernetFields{ + ethHdr := &header.EthernetFields{ DstAddr: r.RemoteLinkAddress, - SrcAddr: e.addr, Type: protocol, - }) + } + + // Preserve the src address if it's set in the route. + if r.LocalLinkAddress != "" { + ethHdr.SrcAddr = r.LocalLinkAddress + } else { + ethHdr.SrcAddr = e.addr + } + eth.Encode(ethHdr) } if payload.Size() == 0 { @@ -223,12 +230,15 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { return false, nil } - var p tcpip.NetworkProtocolNumber - var addr tcpip.LinkAddress + var ( + p tcpip.NetworkProtocolNumber + remoteLinkAddr, localLinkAddr tcpip.LinkAddress + ) if e.hdrSize > 0 { eth := header.Ethernet(e.views[0]) p = eth.Type() - addr = eth.SourceAddress() + remoteLinkAddr = eth.SourceAddress() + localLinkAddr = eth.DestinationAddress() } else { // We don't get any indication of what the packet is, so try to guess // if it's an IPv4 or IPv6 packet. @@ -246,7 +256,7 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { vv := buffer.NewVectorisedView(n, e.views[:used]) vv.TrimFront(e.hdrSize) - e.dispatcher.DeliverNetworkPacket(e, addr, p, vv) + e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, localLinkAddr, p, vv) // Prepare e.views for another packet: release used views. for i := 0; i < used; i++ { @@ -287,7 +297,7 @@ func (e *InjectableEndpoint) Attach(dispatcher stack.NetworkDispatcher) { // Inject injects an inbound packet. func (e *InjectableEndpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { - e.dispatcher.DeliverNetworkPacket(e, "", protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, "" /* remoteLinkAddr */, "" /* localLinkAddr */, protocol, vv) } // NewInjectable creates a new fd-based InjectableEndpoint. diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 411ad7832..52e532ebb 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -31,6 +31,13 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" ) +const ( + mtu = 1500 + laddr = tcpip.LinkAddress("\x11\x22\x33\x44\x55\x66") + raddr = tcpip.LinkAddress("\x77\x88\x99\xaa\xbb\xcc") + proto = 10 +) + type packetInfo struct { raddr tcpip.LinkAddress proto tcpip.NetworkProtocolNumber @@ -78,12 +85,11 @@ func (c *context) cleanup() { syscall.Close(c.fds[1]) } -func (c *context) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (c *context) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, localLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { c.ch <- packetInfo{remoteLinkAddr, protocol, vv.ToView()} } func TestNoEthernetProperties(t *testing.T) { - const mtu = 1500 c := newContext(t, &Options{MTU: mtu}) defer c.cleanup() @@ -97,7 +103,6 @@ func TestNoEthernetProperties(t *testing.T) { } func TestEthernetProperties(t *testing.T) { - const mtu = 1500 c := newContext(t, &Options{EthernetHeader: true, MTU: mtu}) defer c.cleanup() @@ -111,7 +116,6 @@ func TestEthernetProperties(t *testing.T) { } func TestAddress(t *testing.T) { - const mtu = 1500 addrs := []tcpip.LinkAddress{"", "abc", "def"} for _, a := range addrs { t.Run(fmt.Sprintf("Address: %q", a), func(t *testing.T) { @@ -126,13 +130,6 @@ func TestAddress(t *testing.T) { } func TestWritePacket(t *testing.T) { - const ( - mtu = 1500 - laddr = tcpip.LinkAddress("\x11\x22\x33\x44\x55\x66") - raddr = tcpip.LinkAddress("\x77\x88\x99\xaa\xbb\xcc") - proto = 10 - ) - lengths := []int{0, 100, 1000} eths := []bool{true, false} @@ -197,14 +194,40 @@ func TestWritePacket(t *testing.T) { } } -func TestDeliverPacket(t *testing.T) { - const ( - mtu = 1500 - laddr = tcpip.LinkAddress("\x11\x22\x33\x44\x55\x66") - raddr = tcpip.LinkAddress("\x77\x88\x99\xaa\xbb\xcc") - proto = 10 - ) +func TestPreserveSrcAddress(t *testing.T) { + baddr := tcpip.LinkAddress("\xcc\xbb\xaa\x77\x88\x99") + c := newContext(t, &Options{Address: laddr, MTU: mtu, EthernetHeader: true}) + defer c.cleanup() + + // Set LocalLinkAddress in route to the value of the bridged address. + r := &stack.Route{ + RemoteLinkAddress: raddr, + LocalLinkAddress: baddr, + } + + // WritePacket panics given a prependable with anything less than + // the minimum size of the ethernet header. + hdr := buffer.NewPrependable(header.EthernetMinimumSize) + if err := c.ep.WritePacket(r, hdr, buffer.VectorisedView{}, proto); err != nil { + t.Fatalf("WritePacket failed: %v", err) + } + + // Read from the FD, then compare with what we wrote. + b := make([]byte, mtu) + n, err := syscall.Read(c.fds[0], b) + if err != nil { + t.Fatalf("Read failed: %v", err) + } + b = b[:n] + h := header.Ethernet(b) + + if a := h.SourceAddress(); a != baddr { + t.Fatalf("SourceAddress() = %v, want %v", a, baddr) + } +} + +func TestDeliverPacket(t *testing.T) { lengths := []int{100, 1000} eths := []bool{true, false} diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 554ad64de..fc3f80c01 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -77,7 +77,11 @@ func (e *endpoint) WritePacket(_ *stack.Route, hdr buffer.Prependable, payload b views[0] = hdr.View() views = append(views, payload.Views()...) vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) - e.dispatcher.DeliverNetworkPacket(e, "", protocol, vv) + + // Because we're immediately turning around and writing the packet back to the + // rx path, we intentionally don't preserve the remote and local link + // addresses from the stack.Route we're passed. + e.dispatcher.DeliverNetworkPacket(e, "" /* remoteLinkAddr */, "" /* localLinkAddr */, protocol, vv) return nil } diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 5157f71e8..ce6e86767 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -187,11 +187,16 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { // Add the ethernet header here. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) - eth.Encode(&header.EthernetFields{ + ethHdr := &header.EthernetFields{ DstAddr: r.RemoteLinkAddress, - SrcAddr: e.addr, Type: protocol, - }) + } + if r.LocalLinkAddress != "" { + ethHdr.SrcAddr = r.LocalLinkAddress + } else { + ethHdr.SrcAddr = e.addr + } + eth.Encode(ethHdr) v := payload.ToView() // Transmit the packet. @@ -248,7 +253,7 @@ func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) { // Send packet up the stack. eth := header.Ethernet(b) - d.DeliverNetworkPacket(e, eth.SourceAddress(), eth.Type(), buffer.View(b[header.EthernetMinimumSize:]).ToVectorisedView()) + d.DeliverNetworkPacket(e, eth.SourceAddress(), eth.DestinationAddress(), eth.Type(), buffer.View(b[header.EthernetMinimumSize:]).ToVectorisedView()) } // Clean state. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 9a0348deb..9a6b7d929 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -17,10 +17,12 @@ package sharedmem import ( + "bytes" "io/ioutil" "math/rand" "os" "reflect" + "strings" "sync" "syscall" "testing" @@ -129,10 +131,10 @@ func newTestContext(t *testing.T, mtu, bufferSize uint32, addr tcpip.LinkAddress return c } -func (c *testContext) DeliverNetworkPacket(_ stack.LinkEndpoint, remoteAddr tcpip.LinkAddress, proto tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (c *testContext) DeliverNetworkPacket(_ stack.LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, proto tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { c.mu.Lock() c.packets = append(c.packets, packetInfo{ - addr: remoteAddr, + addr: remoteLinkAddr, proto: proto, vv: vv.Clone(nil), }) @@ -259,62 +261,120 @@ func TestSimpleSend(t *testing.T) { } for iters := 1000; iters > 0; iters-- { - // Prepare and send packet. - n := rand.Intn(10000) - hdr := buffer.NewPrependable(n + int(c.ep.MaxHeaderLength())) - hdrBuf := hdr.Prepend(n) - randomFill(hdrBuf) - - n = rand.Intn(10000) - buf := buffer.NewView(n) - randomFill(buf) - - proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) - if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), proto); err != nil { - t.Fatalf("WritePacket failed: %v", err) - } + func() { + // Prepare and send packet. + n := rand.Intn(10000) + hdr := buffer.NewPrependable(n + int(c.ep.MaxHeaderLength())) + hdrBuf := hdr.Prepend(n) + randomFill(hdrBuf) + + n = rand.Intn(10000) + buf := buffer.NewView(n) + randomFill(buf) + + proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) + if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), proto); err != nil { + t.Fatalf("WritePacket failed: %v", err) + } - // Receive packet. - desc := c.txq.tx.Pull() - pi := queue.DecodeTxPacketHeader(desc) - contents := make([]byte, 0, pi.Size) - for i := 0; i < pi.BufferCount; i++ { - bi := queue.DecodeTxBufferHeader(desc, i) - contents = append(contents, c.txq.data[bi.Offset:][:bi.Size]...) - } - c.txq.tx.Flush() + // Receive packet. + desc := c.txq.tx.Pull() + pi := queue.DecodeTxPacketHeader(desc) + if pi.Reserved != 0 { + t.Fatalf("Reserved value is non-zero: 0x%x", pi.Reserved) + } + contents := make([]byte, 0, pi.Size) + for i := 0; i < pi.BufferCount; i++ { + bi := queue.DecodeTxBufferHeader(desc, i) + contents = append(contents, c.txq.data[bi.Offset:][:bi.Size]...) + } + c.txq.tx.Flush() + + defer func() { + // Tell the endpoint about the completion of the write. + b := c.txq.rx.Push(8) + queue.EncodeTxCompletion(b, pi.ID) + c.txq.rx.Flush() + }() + + // Check the ethernet header. + ethTemplate := make(header.Ethernet, header.EthernetMinimumSize) + ethTemplate.Encode(&header.EthernetFields{ + SrcAddr: localLinkAddr, + DstAddr: remoteLinkAddr, + Type: proto, + }) + if got := contents[:header.EthernetMinimumSize]; !bytes.Equal(got, []byte(ethTemplate)) { + t.Fatalf("Bad ethernet header in packet: got %x, want %x", got, ethTemplate) + } - if pi.Reserved != 0 { - t.Fatalf("Reserved value is non-zero: 0x%x", pi.Reserved) - } + // Compare contents skipping the ethernet header added by the + // endpoint. + merged := append(hdrBuf, buf...) + if uint32(len(contents)) < pi.Size { + t.Fatalf("Sum of buffers is less than packet size: %v < %v", len(contents), pi.Size) + } + contents = contents[:pi.Size][header.EthernetMinimumSize:] - // Check the thernet header. - ethTemplate := make(header.Ethernet, header.EthernetMinimumSize) - ethTemplate.Encode(&header.EthernetFields{ - SrcAddr: localLinkAddr, - DstAddr: remoteLinkAddr, - Type: proto, - }) - if got := contents[:header.EthernetMinimumSize]; !reflect.DeepEqual(got, []byte(ethTemplate)) { - t.Fatalf("Bad ethernet header in packet: got %x, want %x", got, ethTemplate) - } + if !bytes.Equal(contents, merged) { + t.Fatalf("Buffers are different: got %x (%v bytes), want %x (%v bytes)", contents, len(contents), merged, len(merged)) + } + }() + } +} - // Compare contents skipping the ethernet header added by the - // endpoint. - merged := append(hdrBuf, buf...) - if uint32(len(contents)) < pi.Size { - t.Fatalf("Sum of buffers is less than packet size: %v < %v", len(contents), pi.Size) - } - contents = contents[:pi.Size][header.EthernetMinimumSize:] +// TestPreserveSrcAddressInSend calls WritePacket once with LocalLinkAddress +// set in Route (using much of the same code as TestSimpleSend), then checks +// that the encoded ethernet header received includes the correct SrcAddr. +func TestPreserveSrcAddressInSend(t *testing.T) { + c := newTestContext(t, 20000, 1500, localLinkAddr) + defer c.cleanup() - if !reflect.DeepEqual(contents, merged) { - t.Fatalf("Buffers are different: got %x (%v bytes), want %x (%v bytes)", contents, len(contents), merged, len(merged)) - } + newLocalLinkAddress := tcpip.LinkAddress(strings.Repeat("0xFE", 6)) + // Set both remote and local link address in route. + r := stack.Route{ + RemoteLinkAddress: remoteLinkAddr, + LocalLinkAddress: newLocalLinkAddress, + } + + // WritePacket panics given a prependable with anything less than + // the minimum size of the ethernet header. + hdr := buffer.NewPrependable(header.EthernetMinimumSize) + + proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) + if err := c.ep.WritePacket(&r, hdr, buffer.VectorisedView{}, proto); err != nil { + t.Fatalf("WritePacket failed: %v", err) + } + // Receive packet. + desc := c.txq.tx.Pull() + pi := queue.DecodeTxPacketHeader(desc) + if pi.Reserved != 0 { + t.Fatalf("Reserved value is non-zero: 0x%x", pi.Reserved) + } + contents := make([]byte, 0, pi.Size) + for i := 0; i < pi.BufferCount; i++ { + bi := queue.DecodeTxBufferHeader(desc, i) + contents = append(contents, c.txq.data[bi.Offset:][:bi.Size]...) + } + c.txq.tx.Flush() + + defer func() { // Tell the endpoint about the completion of the write. b := c.txq.rx.Push(8) queue.EncodeTxCompletion(b, pi.ID) c.txq.rx.Flush() + }() + + // Check that the ethernet header contains the expected SrcAddr. + ethTemplate := make(header.Ethernet, header.EthernetMinimumSize) + ethTemplate.Encode(&header.EthernetFields{ + SrcAddr: newLocalLinkAddress, + DstAddr: remoteLinkAddr, + Type: proto, + }) + if got := contents[:header.EthernetMinimumSize]; !bytes.Equal(got, []byte(ethTemplate)) { + t.Fatalf("Bad ethernet header in packet: got %x, want %x", got, ethTemplate) } } @@ -583,7 +643,7 @@ func TestSimpleReceive(t *testing.T) { c.mu.Unlock() contents = contents[header.EthernetMinimumSize:] - if !reflect.DeepEqual(contents, rcvd) { + if !bytes.Equal(contents, rcvd) { t.Fatalf("Unexpected buffer contents: got %x, want %x", rcvd, contents) } diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index bfb79fd57..a30e57a32 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -116,7 +116,7 @@ func NewWithFile(lower tcpip.LinkEndpointID, file *os.File, snapLen uint32) (tcp // DeliverNetworkPacket implements the stack.NetworkDispatcher interface. It is // called by the link-layer endpoint being wrapped when a packet arrives, and // logs the packet before forwarding to the actual dispatcher. -func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { logPacket("recv", protocol, vv.First()) } @@ -147,7 +147,7 @@ func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAdd panic(err) } } - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, localLinkAddr, protocol, vv) } // Attach implements the stack.LinkEndpoint interface. It saves the dispatcher diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 9b69f844e..ef8c88561 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -51,12 +51,12 @@ func New(lower tcpip.LinkEndpointID) (tcpip.LinkEndpointID, *Endpoint) { // It is called by the link-layer endpoint being wrapped when a packet arrives, // and only forwards to the actual dispatcher if Wait or WaitDispatch haven't // been called. -func (e *Endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (e *Endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr, localLinkAddress tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { if !e.dispatchGate.Enter() { return } - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, localLinkAddress, protocol, vv) e.dispatchGate.Leave() } diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 1301cd4b2..0a15c40de 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -35,7 +35,7 @@ type countedEndpoint struct { dispatcher stack.NetworkDispatcher } -func (e *countedEndpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (e *countedEndpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { e.dispatchCount++ } @@ -106,21 +106,21 @@ func TestWaitDispatch(t *testing.T) { } // Dispatch and check that it goes through. - ep.dispatcher.DeliverNetworkPacket(ep, "", 0, buffer.VectorisedView{}) + ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, buffer.VectorisedView{}) if want := 1; ep.dispatchCount != want { t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) } // Wait on writes, then try to dispatch. It must go through. wep.WaitWrite() - ep.dispatcher.DeliverNetworkPacket(ep, "", 0, buffer.VectorisedView{}) + ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, buffer.VectorisedView{}) if want := 2; ep.dispatchCount != want { t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) } // Wait on dispatches, then try to dispatch. It must not go through. wep.WaitDispatch() - ep.dispatcher.DeliverNetworkPacket(ep, "", 0, buffer.VectorisedView{}) + ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, buffer.VectorisedView{}) if want := 2; ep.dispatchCount != want { t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) } diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 29c9ddec4..dba95369c 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -391,7 +391,7 @@ func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error { // Note that the ownership of the slice backing vv is retained by the caller. // This rule applies only to the slice itself, not to the items of the slice; // the ownership of the items is not retained by the caller. -func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { netProto, ok := n.stack.networkProtocols[protocol] if !ok { n.stack.stats.UnknownProtocolRcvdPackets.Increment() diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 2f51ada73..595c7e793 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -196,7 +196,7 @@ type NetworkProtocol interface { type NetworkDispatcher interface { // DeliverNetworkPacket finds the appropriate network protocol // endpoint and hands the packet over for further processing. - DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) + DeliverNetworkPacket(linkEP LinkEndpoint, dstLinkAddr, srcLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) } // LinkEndpointCapabilities is the type associated with the capabilities @@ -238,6 +238,10 @@ type LinkEndpoint interface { // WritePacket writes a packet with the given protocol through the given // route. + // + // To participate in transparent bridging, a LinkEndpoint implementation + // should call eth.Encode with header.EthernetFields.SrcAddr set to + // r.LocalLinkAddress if it is provided. WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error // Attach attaches the data link layer endpoint to the network-layer -- cgit v1.2.3 From c17ea8c6e20f58510b063f064d45608792a014e4 Mon Sep 17 00:00:00 2001 From: Sepehr Raissian Date: Fri, 28 Sep 2018 10:59:21 -0700 Subject: Block for link address resolution Previously, if address resolution for UDP or Ping sockets required sending packets using Write in Transport layer, Resolve would return ErrWouldBlock and Write would return ErrNoLinkAddress. Meanwhile startAddressResolution would run in background. Further calls to Write using same address would also return ErrNoLinkAddress until resolution has been completed successfully. Since Write is not allowed to block and System Calls need to be interruptible in System Call layer, the caller to Write is responsible for blocking upon return of ErrWouldBlock. Now, when startAddressResolution is called a notification channel for the completion of the address resolution is returned. The channel will traverse up to the calling function of Write as well as ErrNoLinkAddress. Once address resolution is complete (success or not) the channel is closed. The caller would call Write again to send packets and check if address resolution was compeleted successfully or not. Fixes google/gvisor#5 Change-Id: Idafaf31982bee1915ca084da39ae7bd468cebd93 PiperOrigin-RevId: 214962200 --- pkg/dhcp/client.go | 17 ++++++++-- pkg/dhcp/server.go | 15 ++++++++- pkg/sentry/socket/epsocket/epsocket.go | 23 +++++++++++-- pkg/tcpip/adapters/gonet/gonet.go | 35 +++++++++++++++---- pkg/tcpip/network/ipv6/icmp_test.go | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/stack/linkaddrcache.go | 40 ++++++++++++++++------ pkg/tcpip/stack/linkaddrcache_test.go | 22 ++++++------ pkg/tcpip/stack/registration.go | 6 +++- pkg/tcpip/stack/route.go | 16 +++++---- pkg/tcpip/stack/stack.go | 4 +-- pkg/tcpip/stack/transport_test.go | 12 +++---- pkg/tcpip/tcpip.go | 7 +++- pkg/tcpip/transport/ping/endpoint.go | 29 ++++++++-------- pkg/tcpip/transport/tcp/connect.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 16 ++++----- pkg/tcpip/transport/tcp/tcp_test.go | 48 +++++++++++++-------------- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 4 +-- pkg/tcpip/transport/udp/endpoint.go | 31 ++++++++--------- pkg/tcpip/transport/udp/udp_test.go | 18 +++++----- 20 files changed, 220 insertions(+), 129 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index cf8472c5f..92c634a14 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -195,10 +195,23 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg wopts := tcpip.WriteOptions{ To: serverAddr, } - if _, err := ep.Write(tcpip.SlicePayload(h), wopts); err != nil { + var resCh <-chan struct{} + if _, resCh, err = ep.Write(tcpip.SlicePayload(h), wopts); err != nil && resCh == nil { return Config{}, fmt.Errorf("dhcp discovery write: %v", err) } + if resCh != nil { + select { + case <-resCh: + case <-ctx.Done(): + return Config{}, fmt.Errorf("dhcp client address resolution: %v", tcpip.ErrAborted) + } + + if _, _, err := ep.Write(tcpip.SlicePayload(h), wopts); err != nil { + return Config{}, fmt.Errorf("dhcp discovery write: %v", err) + } + } + we, ch := waiter.NewChannelEntry(nil) wq.EventRegister(&we, waiter.EventIn) defer wq.EventUnregister(&we) @@ -289,7 +302,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg reqOpts = append(reqOpts, option{optClientID, clientID}) } h.setOptions(reqOpts) - if _, err := ep.Write(tcpip.SlicePayload(h), wopts); err != nil { + if _, _, err := ep.Write(tcpip.SlicePayload(h), wopts); err != nil { return Config{}, fmt.Errorf("dhcp discovery write: %v", err) } diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index 003e272b2..26700bdbc 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -95,9 +95,22 @@ func (c *epConn) Read() (buffer.View, tcpip.FullAddress, error) { } func (c *epConn) Write(b []byte, addr *tcpip.FullAddress) error { - if _, err := c.ep.Write(tcpip.SlicePayload(b), tcpip.WriteOptions{To: addr}); err != nil { + _, resCh, err := c.ep.Write(tcpip.SlicePayload(b), tcpip.WriteOptions{To: addr}) + if err != nil && resCh == nil { return fmt.Errorf("write: %v", err) } + + if resCh != nil { + select { + case <-resCh: + case <-c.ctx.Done(): + return fmt.Errorf("dhcp server address resolution: %v", tcpip.ErrAborted) + } + + if _, _, err := c.ep.Write(tcpip.SlicePayload(b), tcpip.WriteOptions{To: addr}); err != nil { + return fmt.Errorf("write: %v", err) + } + } return nil } diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 4d32f7a31..550569b4c 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -276,10 +276,21 @@ func (i *ioSequencePayload) Size() int { // Write implements fs.FileOperations.Write. func (s *SocketOperations) Write(ctx context.Context, _ *fs.File, src usermem.IOSequence, _ int64) (int64, error) { f := &ioSequencePayload{ctx: ctx, src: src} - n, err := s.Endpoint.Write(f, tcpip.WriteOptions{}) + n, resCh, err := s.Endpoint.Write(f, tcpip.WriteOptions{}) if err == tcpip.ErrWouldBlock { return int64(n), syserror.ErrWouldBlock } + + if resCh != nil { + t := ctx.(*kernel.Task) + if err := t.Block(resCh); err != nil { + return int64(n), syserr.FromError(err).ToError() + } + + n, _, err = s.Endpoint.Write(f, tcpip.WriteOptions{}) + return int64(n), syserr.TranslateNetstackError(err).ToError() + } + return int64(n), syserr.TranslateNetstackError(err).ToError() } @@ -1016,7 +1027,13 @@ func (s *SocketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to [] EndOfRecord: flags&linux.MSG_EOR != 0, } - n, err := s.Endpoint.Write(tcpip.SlicePayload(v), opts) + n, resCh, err := s.Endpoint.Write(tcpip.SlicePayload(v), opts) + if resCh != nil { + if err := t.Block(resCh); err != nil { + return int(n), syserr.FromError(err) + } + n, _, err = s.Endpoint.Write(tcpip.SlicePayload(v), opts) + } if err != tcpip.ErrWouldBlock || flags&linux.MSG_DONTWAIT != 0 { return int(n), syserr.TranslateNetstackError(err) } @@ -1030,7 +1047,7 @@ func (s *SocketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to [] v.TrimFront(int(n)) total := n for { - n, err = s.Endpoint.Write(tcpip.SlicePayload(v), opts) + n, _, err = s.Endpoint.Write(tcpip.SlicePayload(v), opts) v.TrimFront(int(n)) total += n if err != tcpip.ErrWouldBlock { diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index 490b9c648..b64dce720 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -393,9 +393,22 @@ func (c *Conn) Write(b []byte) (int, error) { } var n uintptr - n, err = c.ep.Write(tcpip.SlicePayload(v), tcpip.WriteOptions{}) + var resCh <-chan struct{} + n, resCh, err = c.ep.Write(tcpip.SlicePayload(v), tcpip.WriteOptions{}) nbytes += int(n) v.TrimFront(int(n)) + + if resCh != nil { + select { + case <-deadline: + return nbytes, c.newOpError("write", &timeoutError{}) + case <-resCh: + } + + n, _, err = c.ep.Write(tcpip.SlicePayload(v), tcpip.WriteOptions{}) + nbytes += int(n) + v.TrimFront(int(n)) + } } if err == nil { @@ -571,7 +584,16 @@ func (c *PacketConn) WriteTo(b []byte, addr net.Addr) (int, error) { copy(v, b) wopts := tcpip.WriteOptions{To: &fullAddr} - n, err := c.ep.Write(tcpip.SlicePayload(v), wopts) + n, resCh, err := c.ep.Write(tcpip.SlicePayload(v), wopts) + if resCh != nil { + select { + case <-deadline: + return int(n), c.newRemoteOpError("write", addr, &timeoutError{}) + case <-resCh: + } + + n, _, err = c.ep.Write(tcpip.SlicePayload(v), wopts) + } if err == tcpip.ErrWouldBlock { // Create wait queue entry that notifies a channel. @@ -579,15 +601,16 @@ func (c *PacketConn) WriteTo(b []byte, addr net.Addr) (int, error) { c.wq.EventRegister(&waitEntry, waiter.EventOut) defer c.wq.EventUnregister(&waitEntry) for { - n, err = c.ep.Write(tcpip.SlicePayload(v), wopts) - if err != tcpip.ErrWouldBlock { - break - } select { case <-deadline: return int(n), c.newRemoteOpError("write", addr, &timeoutError{}) case <-notifyCh: } + + n, _, err = c.ep.Write(tcpip.SlicePayload(v), wopts) + if err != tcpip.ErrWouldBlock { + break + } } } diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index a8eef4cf2..b8e53c13e 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -190,7 +190,7 @@ func TestLinkResolution(t *testing.T) { if ctx.Err() != nil { break } - if _, err := ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{NIC: 1, Addr: lladdr1}}); err == tcpip.ErrNoLinkAddress { + if _, _, err := ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{NIC: 1, Addr: lladdr1}}); err == tcpip.ErrNoLinkAddress { // There's something asynchronous going on; yield to let it do its thing. runtime.Gosched() } else if err == nil { diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index d029193fb..c4707736e 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -80,7 +80,7 @@ func writer(ch chan struct{}, ep tcpip.Endpoint) { v.CapLength(n) for len(v) > 0 { - n, err := ep.Write(tcpip.SlicePayload(v), tcpip.WriteOptions{}) + n, _, err := ep.Write(tcpip.SlicePayload(v), tcpip.WriteOptions{}) if err != nil { fmt.Println("Write failed:", err) return diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index 04b8f251a..3a147a75f 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -88,12 +88,14 @@ type linkAddrEntry struct { linkAddr tcpip.LinkAddress expiration time.Time s entryState + resDone bool // wakers is a set of waiters for address resolution result. Anytime // state transitions out of 'incomplete' these waiters are notified. wakers map[*sleep.Waker]struct{} cancel chan struct{} + resCh chan struct{} } func (e *linkAddrEntry) state() entryState { @@ -182,15 +184,20 @@ func (c *linkAddrCache) makeAndAddEntry(k tcpip.FullAddress, v tcpip.LinkAddress // someone waiting for address resolution on it. entry.changeState(expired) if entry.cancel != nil { - entry.cancel <- struct{}{} + if !entry.resDone { + close(entry.resCh) + } + close(entry.cancel) } *entry = linkAddrEntry{ addr: k, linkAddr: v, expiration: time.Now().Add(c.ageLimit), + resDone: false, wakers: make(map[*sleep.Waker]struct{}), cancel: make(chan struct{}, 1), + resCh: make(chan struct{}, 1), } c.cache[k] = entry @@ -202,10 +209,10 @@ func (c *linkAddrCache) makeAndAddEntry(k tcpip.FullAddress, v tcpip.LinkAddress } // get reports any known link address for k. -func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) (tcpip.LinkAddress, *tcpip.Error) { +func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error) { if linkRes != nil { if addr, ok := linkRes.ResolveStaticAddress(k.Addr); ok { - return addr, nil + return addr, nil, nil } } @@ -214,10 +221,11 @@ func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, lo if entry == nil || entry.state() == expired { c.mu.Unlock() if linkRes == nil { - return "", tcpip.ErrNoLinkAddress + return "", nil, tcpip.ErrNoLinkAddress } - c.startAddressResolution(k, linkRes, localAddr, linkEP, waker) - return "", tcpip.ErrWouldBlock + + ch := c.startAddressResolution(k, linkRes, localAddr, linkEP, waker) + return "", ch, tcpip.ErrWouldBlock } defer c.mu.Unlock() @@ -227,13 +235,13 @@ func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, lo // in that case it's safe to consider it ready. fallthrough case ready: - return entry.linkAddr, nil + return entry.linkAddr, nil, nil case failed: - return "", tcpip.ErrNoLinkAddress + return "", nil, tcpip.ErrNoLinkAddress case incomplete: // Address resolution is still in progress. entry.addWaker(waker) - return "", tcpip.ErrWouldBlock + return "", entry.resCh, tcpip.ErrWouldBlock default: panic(fmt.Sprintf("invalid cache entry state: %d", s)) } @@ -249,13 +257,13 @@ func (c *linkAddrCache) removeWaker(k tcpip.FullAddress, waker *sleep.Waker) { } } -func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) { +func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) <-chan struct{} { c.mu.Lock() defer c.mu.Unlock() // Look up again with lock held to ensure entry wasn't added by someone else. if e := c.cache[k]; e != nil && e.state() != expired { - return + return nil } // Add 'incomplete' entry in the cache to mark that resolution is in progress. @@ -274,6 +282,15 @@ func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes Link select { case <-time.After(c.resolutionTimeout): if stop := c.checkLinkRequest(k, i); stop { + // If entry is evicted then resCh is already closed. + c.mu.Lock() + if e, ok := c.cache[k]; ok { + if !e.resDone { + e.resDone = true + close(e.resCh) + } + } + c.mu.Unlock() return } case <-cancel: @@ -281,6 +298,7 @@ func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes Link } } }() + return e.resCh } // checkLinkRequest checks whether previous attempt to resolve address has succeeded diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go index f0988d6de..e46267f12 100644 --- a/pkg/tcpip/stack/linkaddrcache_test.go +++ b/pkg/tcpip/stack/linkaddrcache_test.go @@ -73,7 +73,7 @@ func getBlocking(c *linkAddrCache, addr tcpip.FullAddress, linkRes LinkAddressRe defer s.Done() for { - if got, err := c.get(addr, linkRes, "", nil, &w); err != tcpip.ErrWouldBlock { + if got, _, err := c.get(addr, linkRes, "", nil, &w); err != tcpip.ErrWouldBlock { return got, err } s.Fetch(true) @@ -95,7 +95,7 @@ func TestCacheOverflow(t *testing.T) { for i := len(testaddrs) - 1; i >= 0; i-- { e := testaddrs[i] c.add(e.addr, e.linkAddr) - got, err := c.get(e.addr, nil, "", nil, nil) + got, _, err := c.get(e.addr, nil, "", nil, nil) if err != nil { t.Errorf("insert %d, c.get(%q)=%q, got error: %v", i, string(e.addr.Addr), got, err) } @@ -106,7 +106,7 @@ func TestCacheOverflow(t *testing.T) { // Expect to find at least half of the most recent entries. for i := 0; i < linkAddrCacheSize/2; i++ { e := testaddrs[i] - got, err := c.get(e.addr, nil, "", nil, nil) + got, _, err := c.get(e.addr, nil, "", nil, nil) if err != nil { t.Errorf("check %d, c.get(%q)=%q, got error: %v", i, string(e.addr.Addr), got, err) } @@ -117,7 +117,7 @@ func TestCacheOverflow(t *testing.T) { // The earliest entries should no longer be in the cache. for i := len(testaddrs) - 1; i >= len(testaddrs)-linkAddrCacheSize; i-- { e := testaddrs[i] - if _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { + if _, _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { t.Errorf("check %d, c.get(%q), got error: %v, want: error ErrNoLinkAddress", i, string(e.addr.Addr), err) } } @@ -143,7 +143,7 @@ func TestCacheConcurrent(t *testing.T) { // can fit in the cache, so our eviction strategy requires that // the last entry be present and the first be missing. e := testaddrs[len(testaddrs)-1] - got, err := c.get(e.addr, nil, "", nil, nil) + got, _, err := c.get(e.addr, nil, "", nil, nil) if err != nil { t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) } @@ -152,7 +152,7 @@ func TestCacheConcurrent(t *testing.T) { } e = testaddrs[0] - if _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { + if _, _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err) } } @@ -162,7 +162,7 @@ func TestCacheAgeLimit(t *testing.T) { e := testaddrs[0] c.add(e.addr, e.linkAddr) time.Sleep(50 * time.Millisecond) - if _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { + if _, _, err := c.get(e.addr, nil, "", nil, nil); err != tcpip.ErrNoLinkAddress { t.Errorf("c.get(%q), got error: %v, want: error ErrNoLinkAddress", string(e.addr.Addr), err) } } @@ -172,7 +172,7 @@ func TestCacheReplace(t *testing.T) { e := testaddrs[0] l2 := e.linkAddr + "2" c.add(e.addr, e.linkAddr) - got, err := c.get(e.addr, nil, "", nil, nil) + got, _, err := c.get(e.addr, nil, "", nil, nil) if err != nil { t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) } @@ -181,7 +181,7 @@ func TestCacheReplace(t *testing.T) { } c.add(e.addr, l2) - got, err = c.get(e.addr, nil, "", nil, nil) + got, _, err = c.get(e.addr, nil, "", nil, nil) if err != nil { t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) } @@ -206,7 +206,7 @@ func TestCacheResolution(t *testing.T) { // Check that after resolved, address stays in the cache and never returns WouldBlock. for i := 0; i < 10; i++ { e := testaddrs[len(testaddrs)-1] - got, err := c.get(e.addr, linkRes, "", nil, nil) + got, _, err := c.get(e.addr, linkRes, "", nil, nil) if err != nil { t.Errorf("c.get(%q)=%q, got error: %v", string(e.addr.Addr), got, err) } @@ -256,7 +256,7 @@ func TestStaticResolution(t *testing.T) { addr := tcpip.Address("broadcast") want := tcpip.LinkAddress("mac_broadcast") - got, err := c.get(tcpip.FullAddress{Addr: addr}, linkRes, "", nil, nil) + got, _, err := c.get(tcpip.FullAddress{Addr: addr}, linkRes, "", nil, nil) if err != nil { t.Errorf("c.get(%q)=%q, got error: %v", string(addr), string(got), err) } diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 595c7e793..0acec2984 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -289,7 +289,11 @@ type LinkAddressCache interface { // registered with the network protocol, the cache attempts to resolve the address // and returns ErrWouldBlock. Waker is notified when address resolution is // complete (success or not). - GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, w *sleep.Waker) (tcpip.LinkAddress, *tcpip.Error) + // + // If address resolution is required, ErrNoLinkAddress and a notification channel is + // returned for the top level caller to block. Channel is closed once address resolution + // is complete (success or not). + GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, w *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error) // RemoveWaker removes a waker that has been added in GetLinkAddress(). RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep.Waker) diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index cc9b24e23..6c6400c33 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -89,11 +89,15 @@ func (r *Route) Capabilities() LinkEndpointCapabilities { // Resolve attempts to resolve the link address if necessary. Returns ErrWouldBlock in // case address resolution requires blocking, e.g. wait for ARP reply. Waker is // notified when address resolution is complete (success or not). -func (r *Route) Resolve(waker *sleep.Waker) *tcpip.Error { +// +// If address resolution is required, ErrNoLinkAddress and a notification channel is +// returned for the top level caller to block. Channel is closed once address resolution +// is complete (success or not). +func (r *Route) Resolve(waker *sleep.Waker) (<-chan struct{}, *tcpip.Error) { if !r.IsResolutionRequired() { // Nothing to do if there is no cache (which does the resolution on cache miss) or // link address is already known. - return nil + return nil, nil } nextAddr := r.NextHop @@ -101,16 +105,16 @@ func (r *Route) Resolve(waker *sleep.Waker) *tcpip.Error { // Local link address is already known. if r.RemoteAddress == r.LocalAddress { r.RemoteLinkAddress = r.LocalLinkAddress - return nil + return nil, nil } nextAddr = r.RemoteAddress } - linkAddr, err := r.ref.linkCache.GetLinkAddress(r.ref.nic.ID(), nextAddr, r.LocalAddress, r.NetProto, waker) + linkAddr, ch, err := r.ref.linkCache.GetLinkAddress(r.ref.nic.ID(), nextAddr, r.LocalAddress, r.NetProto, waker) if err != nil { - return err + return ch, err } r.RemoteLinkAddress = linkAddr - return nil + return nil, nil } // RemoveWaker removes a waker that has been added in Resolve(). diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 699519be1..d1ec6a660 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -831,12 +831,12 @@ func (s *Stack) AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr t } // GetLinkAddress implements LinkAddressCache.GetLinkAddress. -func (s *Stack) GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, waker *sleep.Waker) (tcpip.LinkAddress, *tcpip.Error) { +func (s *Stack) GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, waker *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error) { s.mu.RLock() nic := s.nics[nicid] if nic == nil { s.mu.RUnlock() - return "", tcpip.ErrUnknownNICID + return "", nil, tcpip.ErrUnknownNICID } s.mu.RUnlock() diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 9ec37e7b6..98cc3b120 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -60,21 +60,21 @@ func (*fakeTransportEndpoint) Read(*tcpip.FullAddress) (buffer.View, tcpip.Contr return buffer.View{}, tcpip.ControlMessages{}, nil } -func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tcpip.Error) { +func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-chan struct{}, *tcpip.Error) { if len(f.route.RemoteAddress) == 0 { - return 0, tcpip.ErrNoRoute + return 0, nil, tcpip.ErrNoRoute } hdr := buffer.NewPrependable(int(f.route.MaxHeaderLength())) v, err := p.Get(p.Size()) if err != nil { - return 0, err + return 0, nil, err } if err := f.route.WritePacket(hdr, buffer.View(v).ToVectorisedView(), fakeTransNumber, 123); err != nil { - return 0, err + return 0, nil, err } - return uintptr(len(v)), nil + return uintptr(len(v)), nil, nil } func (f *fakeTransportEndpoint) Peek([][]byte) (uintptr, tcpip.ControlMessages, *tcpip.Error) { @@ -362,7 +362,7 @@ func TestTransportSend(t *testing.T) { // Create buffer that will hold the payload. view := buffer.NewView(30) - _, err = ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}) + _, _, err = ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}) if err != nil { t.Fatalf("write failed: %v", err) } diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 61272cb05..5f210cdd0 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -306,7 +306,12 @@ type Endpoint interface { // // Note that unlike io.Writer.Write, it is not an error for Write to // perform a partial write. - Write(Payload, WriteOptions) (uintptr, *Error) + // + // For UDP and Ping sockets if address resolution is required, + // ErrNoLinkAddress and a notification channel is returned for the caller to + // block. Channel is closed once address resolution is complete (success or + // not). The channel is only non-nil in this case. + Write(Payload, WriteOptions) (uintptr, <-chan struct{}, *Error) // Peek reads data without consuming it from the endpoint. // diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index fcfb96624..055daa918 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -198,10 +198,10 @@ func (e *endpoint) prepareForWrite(to *tcpip.FullAddress) (retry bool, err *tcpi // Write writes data to the endpoint's peer. This method does not block // if the data cannot be written. -func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tcpip.Error) { +func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-chan struct{}, *tcpip.Error) { // MSG_MORE is unimplemented. (This also means that MSG_EOR is a no-op.) if opts.More { - return 0, tcpip.ErrInvalidOptionValue + return 0, nil, tcpip.ErrInvalidOptionValue } to := opts.To @@ -211,14 +211,14 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // If we've shutdown with SHUT_WR we are in an invalid state for sending. if e.shutdownFlags&tcpip.ShutdownWrite != 0 { - return 0, tcpip.ErrClosedForSend + return 0, nil, tcpip.ErrClosedForSend } // Prepare for write. for { retry, err := e.prepareForWrite(to) if err != nil { - return 0, err + return 0, nil, err } if !retry { @@ -241,7 +241,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // Recheck state after lock was re-acquired. if e.state != stateConnected { - return 0, tcpip.ErrInvalidEndpointState + return 0, nil, tcpip.ErrInvalidEndpointState } } } else { @@ -250,7 +250,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc nicid := to.NIC if e.bindNICID != 0 { if nicid != 0 && nicid != e.bindNICID { - return 0, tcpip.ErrNoRoute + return 0, nil, tcpip.ErrNoRoute } nicid = e.bindNICID @@ -260,13 +260,13 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc to = &toCopy netProto, err := e.checkV4Mapped(to, true) if err != nil { - return 0, err + return 0, nil, err } // Find the enpoint. r, err := e.stack.FindRoute(nicid, e.bindAddr, to.Addr, netProto) if err != nil { - return 0, err + return 0, nil, err } defer r.Release() @@ -275,23 +275,20 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc if route.IsResolutionRequired() { waker := &sleep.Waker{} - if err := route.Resolve(waker); err != nil { + if ch, err := route.Resolve(waker); err != nil { if err == tcpip.ErrWouldBlock { // Link address needs to be resolved. Resolution was triggered the // background. Better luck next time. - // - // TODO: queue up the request and send after link address - // is resolved. route.RemoveWaker(waker) - return 0, tcpip.ErrNoLinkAddress + return 0, ch, tcpip.ErrNoLinkAddress } - return 0, err + return 0, nil, err } } v, err := p.Get(p.Size()) if err != nil { - return 0, err + return 0, nil, err } switch e.netProto { @@ -302,7 +299,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc err = sendPing6(route, e.id.LocalPort, v) } - return uintptr(len(v)), err + return uintptr(len(v)), nil, err } // Peek only returns data from a single datagram, so do nothing here. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 68c0d4472..27dbcace2 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -365,7 +365,7 @@ func (h *handshake) resolveRoute() *tcpip.Error { for { switch index { case wakerForResolution: - if err := h.ep.route.Resolve(resolutionWaker); err != tcpip.ErrWouldBlock { + if _, err := h.ep.route.Resolve(resolutionWaker); err != tcpip.ErrWouldBlock { // Either success (err == nil) or failure. return err } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index e82e25233..707d6be96 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -492,7 +492,7 @@ func (e *endpoint) readLocked() (buffer.View, *tcpip.Error) { } // Write writes data to the endpoint's peer. -func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tcpip.Error) { +func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-chan struct{}, *tcpip.Error) { // Linux completely ignores any address passed to sendto(2) for TCP sockets // (without the MSG_FASTOPEN flag). Corking is unimplemented, so opts.More // and opts.EndOfRecord are also ignored. @@ -504,15 +504,15 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc if e.state != stateConnected { switch e.state { case stateError: - return 0, e.hardError + return 0, nil, e.hardError default: - return 0, tcpip.ErrClosedForSend + return 0, nil, tcpip.ErrClosedForSend } } // Nothing to do if the buffer is empty. if p.Size() == 0 { - return 0, nil + return 0, nil, nil } e.sndBufMu.Lock() @@ -520,20 +520,20 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // Check if the connection has already been closed for sends. if e.sndClosed { e.sndBufMu.Unlock() - return 0, tcpip.ErrClosedForSend + return 0, nil, tcpip.ErrClosedForSend } // Check against the limit. avail := e.sndBufSize - e.sndBufUsed if avail <= 0 { e.sndBufMu.Unlock() - return 0, tcpip.ErrWouldBlock + return 0, nil, tcpip.ErrWouldBlock } v, perr := p.Get(avail) if perr != nil { e.sndBufMu.Unlock() - return 0, perr + return 0, nil, perr } var err *tcpip.Error @@ -558,7 +558,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // Let the protocol goroutine do the work. e.sndWaker.Assert() } - return uintptr(l), err + return uintptr(l), nil, err } // Peek reads data without consuming it from the endpoint. diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index ac21e565b..48852ea47 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -869,7 +869,7 @@ func TestSimpleSend(t *testing.T) { view := buffer.NewView(len(data)) copy(view, data) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -910,7 +910,7 @@ func TestZeroWindowSend(t *testing.T) { view := buffer.NewView(len(data)) copy(view, data) - _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}) + _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}) if err != nil { t.Fatalf("Write failed: %v", err) } @@ -971,7 +971,7 @@ func TestScaledWindowConnect(t *testing.T) { view := buffer.NewView(len(data)) copy(view, data) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -1004,7 +1004,7 @@ func TestNonScaledWindowConnect(t *testing.T) { view := buffer.NewView(len(data)) copy(view, data) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -1077,7 +1077,7 @@ func TestScaledWindowAccept(t *testing.T) { view := buffer.NewView(len(data)) copy(view, data) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -1150,7 +1150,7 @@ func TestNonScaledWindowAccept(t *testing.T) { view := buffer.NewView(len(data)) copy(view, data) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -1265,7 +1265,7 @@ func testBrokenUpWrite(t *testing.T, c *context.Context, maxPayload int) { view := buffer.NewView(len(data)) copy(view, data) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -1653,7 +1653,7 @@ func TestSendOnResetConnection(t *testing.T) { // Try to write. view := buffer.NewView(10) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != tcpip.ErrConnectionReset { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != tcpip.ErrConnectionReset { t.Fatalf("got c.EP.Write(...) = %v, want = %v", err, tcpip.ErrConnectionReset) } } @@ -1763,7 +1763,7 @@ func TestFinWithNoPendingData(t *testing.T) { // Write something out, and have it acknowledged. view := buffer.NewView(10) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -1836,7 +1836,7 @@ func TestFinWithPendingDataCwndFull(t *testing.T) { // any of them. view := buffer.NewView(10) for i := tcp.InitialCwnd; i > 0; i-- { - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } } @@ -1922,7 +1922,7 @@ func TestFinWithPendingData(t *testing.T) { // Write something out, and acknowledge it to get cwnd to 2. view := buffer.NewView(10) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -1948,7 +1948,7 @@ func TestFinWithPendingData(t *testing.T) { }) // Write new data, but don't acknowledge it. - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2009,7 +2009,7 @@ func TestFinWithPartialAck(t *testing.T) { // Write something out, and acknowledge it to get cwnd to 2. Also send // FIN from the test side. view := buffer.NewView(10) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2046,7 +2046,7 @@ func TestFinWithPartialAck(t *testing.T) { ) // Write new data, but don't acknowledge it. - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2116,7 +2116,7 @@ func TestExponentialIncreaseDuringSlowStart(t *testing.T) { // Write all the data in one shot. Packets will only be written at the // MTU size though. - if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2158,7 +2158,7 @@ func TestCongestionAvoidance(t *testing.T) { // Write all the data in one shot. Packets will only be written at the // MTU size though. - if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2263,7 +2263,7 @@ func TestCubicCongestionAvoidance(t *testing.T) { // Write all the data in one shot. Packets will only be written at the // MTU size though. - if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2371,7 +2371,7 @@ func TestFastRecovery(t *testing.T) { // Write all the data in one shot. Packets will only be written at the // MTU size though. - if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2503,11 +2503,11 @@ func TestRetransmit(t *testing.T) { // Write all the data in two shots. Packets will only be written at the // MTU size though. half := data[:len(data)/2] - if _, err := c.EP.Write(tcpip.SlicePayload(half), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(half), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } half = data[len(data)/2:] - if _, err := c.EP.Write(tcpip.SlicePayload(half), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(half), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -2605,7 +2605,7 @@ func scaledSendWindow(t *testing.T, scale uint8) { // Send some data. Check that it's capped by the window size. view := buffer.NewView(65535) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -3099,7 +3099,7 @@ func TestSelfConnect(t *testing.T) { data := []byte{1, 2, 3} view := buffer.NewView(len(data)) copy(view, data) - if _, err := ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := ep.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -3290,7 +3290,7 @@ func TestPathMTUDiscovery(t *testing.T) { data[i] = byte(i) } - if _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } @@ -3495,7 +3495,7 @@ func TestKeepalive(t *testing.T) { // Send some data and wait before ACKing it. Keepalives should be disabled // during this period. view := buffer.NewView(3) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Write failed: %v", err) } diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index 894ead507..ca16fc8fa 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -147,7 +147,7 @@ func timeStampEnabledAccept(t *testing.T, cookieEnabled bool, wndScale int, wndS view := buffer.NewView(len(data)) copy(view, data) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Unexpected error from Write: %v", err) } @@ -210,7 +210,7 @@ func timeStampDisabledAccept(t *testing.T, cookieEnabled bool, wndScale int, wnd view := buffer.NewView(len(data)) copy(view, data) - if _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { + if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil { t.Fatalf("Unexpected error from Write: %v", err) } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index f2dd98f35..6ed805357 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -258,10 +258,10 @@ func (e *endpoint) prepareForWrite(to *tcpip.FullAddress) (retry bool, err *tcpi // Write writes data to the endpoint's peer. This method does not block // if the data cannot be written. -func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tcpip.Error) { +func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-chan struct{}, *tcpip.Error) { // MSG_MORE is unimplemented. (This also means that MSG_EOR is a no-op.) if opts.More { - return 0, tcpip.ErrInvalidOptionValue + return 0, nil, tcpip.ErrInvalidOptionValue } to := opts.To @@ -271,14 +271,14 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // If we've shutdown with SHUT_WR we are in an invalid state for sending. if e.shutdownFlags&tcpip.ShutdownWrite != 0 { - return 0, tcpip.ErrClosedForSend + return 0, nil, tcpip.ErrClosedForSend } // Prepare for write. for { retry, err := e.prepareForWrite(to) if err != nil { - return 0, err + return 0, nil, err } if !retry { @@ -303,7 +303,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // Recheck state after lock was re-acquired. if e.state != stateConnected { - return 0, tcpip.ErrInvalidEndpointState + return 0, nil, tcpip.ErrInvalidEndpointState } } } else { @@ -312,7 +312,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc nicid := to.NIC if e.bindNICID != 0 { if nicid != 0 && nicid != e.bindNICID { - return 0, tcpip.ErrNoRoute + return 0, nil, tcpip.ErrNoRoute } nicid = e.bindNICID @@ -322,13 +322,13 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc to = &toCopy netProto, err := e.checkV4Mapped(to, false) if err != nil { - return 0, err + return 0, nil, err } // Find the enpoint. r, err := e.stack.FindRoute(nicid, e.id.LocalAddress, to.Addr, netProto) if err != nil { - return 0, err + return 0, nil, err } defer r.Release() @@ -338,23 +338,20 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc if route.IsResolutionRequired() { waker := &sleep.Waker{} - if err := route.Resolve(waker); err != nil { + if ch, err := route.Resolve(waker); err != nil { if err == tcpip.ErrWouldBlock { // Link address needs to be resolved. Resolution was triggered the background. // Better luck next time. - // - // TODO: queue up the request and send after link address - // is resolved. route.RemoveWaker(waker) - return 0, tcpip.ErrNoLinkAddress + return 0, ch, tcpip.ErrNoLinkAddress } - return 0, err + return 0, nil, err } } v, err := p.Get(p.Size()) if err != nil { - return 0, err + return 0, nil, err } ttl := route.DefaultTTL() @@ -363,9 +360,9 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc } if err := sendUDP(route, buffer.View(v).ToVectorisedView(), e.id.LocalPort, dstPort, ttl); err != nil { - return 0, err + return 0, nil, err } - return uintptr(len(v)), nil + return uintptr(len(v)), nil, nil } // Peek only returns data from a single datagram, so do nothing here. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 46110c8ff..c3f592bd4 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -482,7 +482,7 @@ func TestV4ReadOnV4(t *testing.T) { func testV4Write(c *testContext) uint16 { // Write to V4 mapped address. payload := buffer.View(newPayload()) - n, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + n, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}, }) if err != nil { @@ -512,7 +512,7 @@ func testV4Write(c *testContext) uint16 { func testV6Write(c *testContext) uint16 { // Write to v6 address. payload := buffer.View(newPayload()) - n, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + n, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV6Addr, Port: testPort}, }) if err != nil { @@ -590,7 +590,7 @@ func TestDualWriteConnectedToV6(t *testing.T) { // Write to V4 mapped address. payload := buffer.View(newPayload()) - _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + _, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}, }) if err != tcpip.ErrNetworkUnreachable { @@ -613,7 +613,7 @@ func TestDualWriteConnectedToV4Mapped(t *testing.T) { // Write to v6 address. payload := buffer.View(newPayload()) - _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + _, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV6Addr, Port: testPort}, }) if err != tcpip.ErrInvalidEndpointState { @@ -629,7 +629,7 @@ func TestV4WriteOnV6Only(t *testing.T) { // Write to V4 mapped address. payload := buffer.View(newPayload()) - _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + _, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}, }) if err != tcpip.ErrNoRoute { @@ -650,7 +650,7 @@ func TestV6WriteOnBoundToV4Mapped(t *testing.T) { // Write to v6 address. payload := buffer.View(newPayload()) - _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + _, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV6Addr, Port: testPort}, }) if err != tcpip.ErrInvalidEndpointState { @@ -671,7 +671,7 @@ func TestV6WriteOnConnected(t *testing.T) { // Write without destination. payload := buffer.View(newPayload()) - n, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{}) + n, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{}) if err != nil { c.t.Fatalf("Write failed: %v", err) } @@ -707,7 +707,7 @@ func TestV4WriteOnConnected(t *testing.T) { // Write without destination. payload := buffer.View(newPayload()) - n, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{}) + n, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{}) if err != nil { c.t.Fatalf("Write failed: %v", err) } @@ -856,7 +856,7 @@ func TestTTL(t *testing.T) { c.t.Fatalf("SetSockOpt failed: %v", err) } - n, err := c.ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{Addr: addr, Port: port}}) + n, _, err := c.ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{Addr: addr, Port: port}}) if err != nil { c.t.Fatalf("Write failed: %v", err) } -- cgit v1.2.3 From 8fce67af24945f82378b4c2731cca1788936d074 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Fri, 19 Oct 2018 16:34:09 -0700 Subject: Use correct company name in copyright header PiperOrigin-RevId: 217951017 Change-Id: Ie08bf6987f98467d07457bcf35b5f1ff6e43c035 --- kokoro/run_build.sh | 2 +- kokoro/run_tests.sh | 2 +- pkg/abi/abi.go | 2 +- pkg/abi/abi_linux.go | 2 +- pkg/abi/flag.go | 2 +- pkg/abi/linux/aio.go | 2 +- pkg/abi/linux/ashmem.go | 2 +- pkg/abi/linux/binder.go | 2 +- pkg/abi/linux/bpf.go | 2 +- pkg/abi/linux/capability.go | 2 +- pkg/abi/linux/dev.go | 2 +- pkg/abi/linux/elf.go | 2 +- pkg/abi/linux/errors.go | 2 +- pkg/abi/linux/eventfd.go | 2 +- pkg/abi/linux/exec.go | 2 +- pkg/abi/linux/fcntl.go | 2 +- pkg/abi/linux/file.go | 2 +- pkg/abi/linux/fs.go | 2 +- pkg/abi/linux/futex.go | 2 +- pkg/abi/linux/inotify.go | 2 +- pkg/abi/linux/ioctl.go | 2 +- pkg/abi/linux/ip.go | 2 +- pkg/abi/linux/ipc.go | 2 +- pkg/abi/linux/limits.go | 2 +- pkg/abi/linux/linux.go | 2 +- pkg/abi/linux/mm.go | 2 +- pkg/abi/linux/netdevice.go | 2 +- pkg/abi/linux/netlink.go | 2 +- pkg/abi/linux/netlink_route.go | 2 +- pkg/abi/linux/poll.go | 2 +- pkg/abi/linux/prctl.go | 2 +- pkg/abi/linux/ptrace.go | 2 +- pkg/abi/linux/rusage.go | 2 +- pkg/abi/linux/sched.go | 2 +- pkg/abi/linux/seccomp.go | 2 +- pkg/abi/linux/sem.go | 2 +- pkg/abi/linux/shm.go | 2 +- pkg/abi/linux/signal.go | 2 +- pkg/abi/linux/socket.go | 2 +- pkg/abi/linux/time.go | 2 +- pkg/abi/linux/timer.go | 2 +- pkg/abi/linux/tty.go | 2 +- pkg/abi/linux/uio.go | 2 +- pkg/abi/linux/utsname.go | 2 +- pkg/amutex/amutex.go | 2 +- pkg/amutex/amutex_test.go | 2 +- pkg/atomicbitops/atomic_bitops.go | 2 +- pkg/atomicbitops/atomic_bitops_amd64.s | 2 +- pkg/atomicbitops/atomic_bitops_common.go | 2 +- pkg/atomicbitops/atomic_bitops_test.go | 2 +- pkg/binary/binary.go | 2 +- pkg/binary/binary_test.go | 2 +- pkg/bits/bits.go | 2 +- pkg/bits/bits_template.go | 2 +- pkg/bits/uint64_arch_amd64.go | 2 +- pkg/bits/uint64_arch_amd64_asm.s | 2 +- pkg/bits/uint64_arch_generic.go | 2 +- pkg/bits/uint64_test.go | 2 +- pkg/bpf/bpf.go | 2 +- pkg/bpf/decoder.go | 2 +- pkg/bpf/decoder_test.go | 2 +- pkg/bpf/input_bytes.go | 2 +- pkg/bpf/interpreter.go | 2 +- pkg/bpf/interpreter_test.go | 2 +- pkg/bpf/program_builder.go | 2 +- pkg/bpf/program_builder_test.go | 2 +- pkg/compressio/compressio.go | 2 +- pkg/compressio/compressio_test.go | 2 +- pkg/control/client/client.go | 2 +- pkg/control/server/server.go | 2 +- pkg/cpuid/cpu_amd64.s | 2 +- pkg/cpuid/cpuid.go | 2 +- pkg/cpuid/cpuid_parse_test.go | 2 +- pkg/cpuid/cpuid_test.go | 2 +- pkg/dhcp/client.go | 2 +- pkg/dhcp/dhcp.go | 2 +- pkg/dhcp/dhcp_string.go | 2 +- pkg/dhcp/dhcp_test.go | 2 +- pkg/dhcp/server.go | 2 +- pkg/eventchannel/event.go | 2 +- pkg/eventchannel/event.proto | 2 +- pkg/fd/fd.go | 2 +- pkg/fd/fd_test.go | 2 +- pkg/gate/gate.go | 2 +- pkg/gate/gate_test.go | 2 +- pkg/ilist/list.go | 2 +- pkg/ilist/list_test.go | 2 +- pkg/linewriter/linewriter.go | 2 +- pkg/linewriter/linewriter_test.go | 2 +- pkg/log/glog.go | 2 +- pkg/log/glog_unsafe.go | 2 +- pkg/log/json.go | 2 +- pkg/log/json_test.go | 2 +- pkg/log/log.go | 2 +- pkg/log/log_test.go | 2 +- pkg/metric/metric.go | 2 +- pkg/metric/metric.proto | 2 +- pkg/metric/metric_test.go | 2 +- pkg/p9/buffer.go | 2 +- pkg/p9/client.go | 2 +- pkg/p9/client_file.go | 2 +- pkg/p9/client_test.go | 2 +- pkg/p9/file.go | 2 +- pkg/p9/handlers.go | 2 +- pkg/p9/local_server/local_server.go | 2 +- pkg/p9/messages.go | 2 +- pkg/p9/messages_test.go | 2 +- pkg/p9/p9.go | 2 +- pkg/p9/p9_test.go | 2 +- pkg/p9/p9test/client_test.go | 2 +- pkg/p9/p9test/mocks.go | 2 +- pkg/p9/pool.go | 2 +- pkg/p9/pool_test.go | 2 +- pkg/p9/server.go | 2 +- pkg/p9/transport.go | 2 +- pkg/p9/transport_test.go | 2 +- pkg/p9/version.go | 2 +- pkg/p9/version_test.go | 2 +- pkg/rand/rand.go | 2 +- pkg/rand/rand_linux.go | 2 +- pkg/refs/refcounter.go | 2 +- pkg/refs/refcounter_state.go | 2 +- pkg/refs/refcounter_test.go | 2 +- pkg/seccomp/seccomp.go | 2 +- pkg/seccomp/seccomp_rules.go | 2 +- pkg/seccomp/seccomp_test.go | 2 +- pkg/seccomp/seccomp_test_victim.go | 2 +- pkg/seccomp/seccomp_unsafe.go | 2 +- pkg/secio/full_reader.go | 2 +- pkg/secio/secio.go | 2 +- pkg/secio/secio_test.go | 2 +- pkg/segment/range.go | 2 +- pkg/segment/set.go | 2 +- pkg/segment/set_state.go | 2 +- pkg/segment/test/segment_test.go | 2 +- pkg/segment/test/set_functions.go | 2 +- pkg/sentry/arch/aligned.go | 2 +- pkg/sentry/arch/arch.go | 2 +- pkg/sentry/arch/arch_amd64.go | 2 +- pkg/sentry/arch/arch_amd64.s | 2 +- pkg/sentry/arch/arch_state_x86.go | 2 +- pkg/sentry/arch/arch_x86.go | 2 +- pkg/sentry/arch/auxv.go | 2 +- pkg/sentry/arch/registers.proto | 2 +- pkg/sentry/arch/signal_act.go | 2 +- pkg/sentry/arch/signal_amd64.go | 2 +- pkg/sentry/arch/signal_info.go | 2 +- pkg/sentry/arch/signal_stack.go | 2 +- pkg/sentry/arch/stack.go | 2 +- pkg/sentry/arch/syscalls_amd64.go | 2 +- pkg/sentry/context/context.go | 2 +- pkg/sentry/context/contexttest/contexttest.go | 2 +- pkg/sentry/control/control.go | 2 +- pkg/sentry/control/proc.go | 2 +- pkg/sentry/control/proc_test.go | 2 +- pkg/sentry/control/state.go | 2 +- pkg/sentry/device/device.go | 2 +- pkg/sentry/device/device_test.go | 2 +- pkg/sentry/fs/anon/anon.go | 2 +- pkg/sentry/fs/anon/device.go | 2 +- pkg/sentry/fs/ashmem/area.go | 2 +- pkg/sentry/fs/ashmem/device.go | 2 +- pkg/sentry/fs/ashmem/pin_board.go | 2 +- pkg/sentry/fs/ashmem/pin_board_test.go | 2 +- pkg/sentry/fs/attr.go | 2 +- pkg/sentry/fs/binder/binder.go | 2 +- pkg/sentry/fs/context.go | 2 +- pkg/sentry/fs/copy_up.go | 2 +- pkg/sentry/fs/copy_up_test.go | 2 +- pkg/sentry/fs/dentry.go | 2 +- pkg/sentry/fs/dev/dev.go | 2 +- pkg/sentry/fs/dev/device.go | 2 +- pkg/sentry/fs/dev/fs.go | 2 +- pkg/sentry/fs/dev/full.go | 2 +- pkg/sentry/fs/dev/null.go | 2 +- pkg/sentry/fs/dev/random.go | 2 +- pkg/sentry/fs/dirent.go | 2 +- pkg/sentry/fs/dirent_cache.go | 2 +- pkg/sentry/fs/dirent_cache_test.go | 2 +- pkg/sentry/fs/dirent_refs_test.go | 2 +- pkg/sentry/fs/dirent_state.go | 2 +- pkg/sentry/fs/fdpipe/pipe.go | 2 +- pkg/sentry/fs/fdpipe/pipe_opener.go | 2 +- pkg/sentry/fs/fdpipe/pipe_opener_test.go | 2 +- pkg/sentry/fs/fdpipe/pipe_state.go | 2 +- pkg/sentry/fs/fdpipe/pipe_test.go | 2 +- pkg/sentry/fs/file.go | 2 +- pkg/sentry/fs/file_operations.go | 2 +- pkg/sentry/fs/file_overlay.go | 2 +- pkg/sentry/fs/file_overlay_test.go | 2 +- pkg/sentry/fs/file_state.go | 2 +- pkg/sentry/fs/file_test.go | 2 +- pkg/sentry/fs/filesystems.go | 2 +- pkg/sentry/fs/filetest/filetest.go | 2 +- pkg/sentry/fs/flags.go | 2 +- pkg/sentry/fs/fs.go | 2 +- pkg/sentry/fs/fsutil/dirty_set.go | 2 +- pkg/sentry/fs/fsutil/dirty_set_test.go | 2 +- pkg/sentry/fs/fsutil/file.go | 2 +- pkg/sentry/fs/fsutil/file_range_set.go | 2 +- pkg/sentry/fs/fsutil/frame_ref_set.go | 2 +- pkg/sentry/fs/fsutil/fsutil.go | 2 +- pkg/sentry/fs/fsutil/handle.go | 2 +- pkg/sentry/fs/fsutil/handle_test.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper_state.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go | 2 +- pkg/sentry/fs/fsutil/inode.go | 2 +- pkg/sentry/fs/fsutil/inode_cached.go | 2 +- pkg/sentry/fs/fsutil/inode_cached_test.go | 2 +- pkg/sentry/fs/gofer/attr.go | 2 +- pkg/sentry/fs/gofer/cache_policy.go | 2 +- pkg/sentry/fs/gofer/context_file.go | 2 +- pkg/sentry/fs/gofer/device.go | 2 +- pkg/sentry/fs/gofer/file.go | 2 +- pkg/sentry/fs/gofer/file_state.go | 2 +- pkg/sentry/fs/gofer/fs.go | 2 +- pkg/sentry/fs/gofer/gofer_test.go | 2 +- pkg/sentry/fs/gofer/handles.go | 2 +- pkg/sentry/fs/gofer/inode.go | 2 +- pkg/sentry/fs/gofer/inode_state.go | 2 +- pkg/sentry/fs/gofer/path.go | 2 +- pkg/sentry/fs/gofer/session.go | 2 +- pkg/sentry/fs/gofer/session_state.go | 2 +- pkg/sentry/fs/gofer/socket.go | 2 +- pkg/sentry/fs/gofer/util.go | 2 +- pkg/sentry/fs/host/control.go | 2 +- pkg/sentry/fs/host/descriptor.go | 2 +- pkg/sentry/fs/host/descriptor_state.go | 2 +- pkg/sentry/fs/host/descriptor_test.go | 2 +- pkg/sentry/fs/host/device.go | 2 +- pkg/sentry/fs/host/file.go | 2 +- pkg/sentry/fs/host/fs.go | 2 +- pkg/sentry/fs/host/fs_test.go | 2 +- pkg/sentry/fs/host/inode.go | 2 +- pkg/sentry/fs/host/inode_state.go | 2 +- pkg/sentry/fs/host/inode_test.go | 2 +- pkg/sentry/fs/host/ioctl_unsafe.go | 2 +- pkg/sentry/fs/host/socket.go | 2 +- pkg/sentry/fs/host/socket_iovec.go | 2 +- pkg/sentry/fs/host/socket_state.go | 2 +- pkg/sentry/fs/host/socket_test.go | 2 +- pkg/sentry/fs/host/socket_unsafe.go | 2 +- pkg/sentry/fs/host/tty.go | 2 +- pkg/sentry/fs/host/util.go | 2 +- pkg/sentry/fs/host/util_unsafe.go | 2 +- pkg/sentry/fs/host/wait_test.go | 2 +- pkg/sentry/fs/inode.go | 2 +- pkg/sentry/fs/inode_inotify.go | 2 +- pkg/sentry/fs/inode_operations.go | 2 +- pkg/sentry/fs/inode_overlay.go | 2 +- pkg/sentry/fs/inode_overlay_test.go | 2 +- pkg/sentry/fs/inotify.go | 2 +- pkg/sentry/fs/inotify_event.go | 2 +- pkg/sentry/fs/inotify_watch.go | 2 +- pkg/sentry/fs/lock/lock.go | 2 +- pkg/sentry/fs/lock/lock_range_test.go | 2 +- pkg/sentry/fs/lock/lock_set_functions.go | 2 +- pkg/sentry/fs/lock/lock_test.go | 2 +- pkg/sentry/fs/mock.go | 2 +- pkg/sentry/fs/mount.go | 2 +- pkg/sentry/fs/mount_overlay.go | 2 +- pkg/sentry/fs/mount_state.go | 2 +- pkg/sentry/fs/mount_test.go | 2 +- pkg/sentry/fs/mounts.go | 2 +- pkg/sentry/fs/mounts_test.go | 2 +- pkg/sentry/fs/offset.go | 2 +- pkg/sentry/fs/overlay.go | 2 +- pkg/sentry/fs/path.go | 2 +- pkg/sentry/fs/path_test.go | 2 +- pkg/sentry/fs/proc/cpuinfo.go | 2 +- pkg/sentry/fs/proc/device/device.go | 2 +- pkg/sentry/fs/proc/exec_args.go | 2 +- pkg/sentry/fs/proc/fds.go | 2 +- pkg/sentry/fs/proc/file.go | 2 +- pkg/sentry/fs/proc/filesystems.go | 2 +- pkg/sentry/fs/proc/fs.go | 2 +- pkg/sentry/fs/proc/loadavg.go | 2 +- pkg/sentry/fs/proc/meminfo.go | 2 +- pkg/sentry/fs/proc/mounts.go | 2 +- pkg/sentry/fs/proc/net.go | 2 +- pkg/sentry/fs/proc/net_test.go | 2 +- pkg/sentry/fs/proc/proc.go | 2 +- pkg/sentry/fs/proc/rpcinet_proc.go | 2 +- pkg/sentry/fs/proc/seqfile/seqfile.go | 2 +- pkg/sentry/fs/proc/seqfile/seqfile_test.go | 2 +- pkg/sentry/fs/proc/stat.go | 2 +- pkg/sentry/fs/proc/sys.go | 2 +- pkg/sentry/fs/proc/sys_net.go | 2 +- pkg/sentry/fs/proc/sys_net_test.go | 2 +- pkg/sentry/fs/proc/task.go | 2 +- pkg/sentry/fs/proc/uid_gid_map.go | 2 +- pkg/sentry/fs/proc/uptime.go | 2 +- pkg/sentry/fs/proc/version.go | 2 +- pkg/sentry/fs/ramfs/dir.go | 2 +- pkg/sentry/fs/ramfs/file.go | 2 +- pkg/sentry/fs/ramfs/ramfs.go | 2 +- pkg/sentry/fs/ramfs/socket.go | 2 +- pkg/sentry/fs/ramfs/symlink.go | 2 +- pkg/sentry/fs/ramfs/test/test.go | 2 +- pkg/sentry/fs/ramfs/tree.go | 2 +- pkg/sentry/fs/ramfs/tree_test.go | 2 +- pkg/sentry/fs/restore.go | 2 +- pkg/sentry/fs/save.go | 2 +- pkg/sentry/fs/seek.go | 2 +- pkg/sentry/fs/sync.go | 2 +- pkg/sentry/fs/sys/device.go | 2 +- pkg/sentry/fs/sys/devices.go | 2 +- pkg/sentry/fs/sys/fs.go | 2 +- pkg/sentry/fs/sys/sys.go | 2 +- pkg/sentry/fs/timerfd/timerfd.go | 2 +- pkg/sentry/fs/tmpfs/device.go | 2 +- pkg/sentry/fs/tmpfs/file_regular.go | 2 +- pkg/sentry/fs/tmpfs/file_test.go | 2 +- pkg/sentry/fs/tmpfs/fs.go | 2 +- pkg/sentry/fs/tmpfs/inode_file.go | 2 +- pkg/sentry/fs/tmpfs/tmpfs.go | 2 +- pkg/sentry/fs/tty/dir.go | 2 +- pkg/sentry/fs/tty/fs.go | 2 +- pkg/sentry/fs/tty/inode.go | 2 +- pkg/sentry/fs/tty/line_discipline.go | 2 +- pkg/sentry/fs/tty/master.go | 2 +- pkg/sentry/fs/tty/queue.go | 2 +- pkg/sentry/fs/tty/slave.go | 2 +- pkg/sentry/fs/tty/terminal.go | 2 +- pkg/sentry/fs/tty/tty_test.go | 2 +- pkg/sentry/hostcpu/getcpu_amd64.s | 2 +- pkg/sentry/hostcpu/hostcpu.go | 2 +- pkg/sentry/hostcpu/hostcpu_test.go | 2 +- pkg/sentry/inet/context.go | 2 +- pkg/sentry/inet/inet.go | 2 +- pkg/sentry/inet/test_stack.go | 2 +- pkg/sentry/kernel/abstract_socket_namespace.go | 2 +- pkg/sentry/kernel/auth/auth.go | 2 +- pkg/sentry/kernel/auth/capability_set.go | 2 +- pkg/sentry/kernel/auth/context.go | 2 +- pkg/sentry/kernel/auth/credentials.go | 2 +- pkg/sentry/kernel/auth/id.go | 2 +- pkg/sentry/kernel/auth/id_map.go | 2 +- pkg/sentry/kernel/auth/id_map_functions.go | 2 +- pkg/sentry/kernel/auth/user_namespace.go | 2 +- pkg/sentry/kernel/context.go | 2 +- pkg/sentry/kernel/epoll/epoll.go | 2 +- pkg/sentry/kernel/epoll/epoll_state.go | 2 +- pkg/sentry/kernel/epoll/epoll_test.go | 2 +- pkg/sentry/kernel/eventfd/eventfd.go | 2 +- pkg/sentry/kernel/eventfd/eventfd_test.go | 2 +- pkg/sentry/kernel/fasync/fasync.go | 2 +- pkg/sentry/kernel/fd_map.go | 2 +- pkg/sentry/kernel/fd_map_test.go | 2 +- pkg/sentry/kernel/fs_context.go | 2 +- pkg/sentry/kernel/futex/futex.go | 2 +- pkg/sentry/kernel/futex/futex_test.go | 2 +- pkg/sentry/kernel/ipc_namespace.go | 2 +- pkg/sentry/kernel/kdefs/kdefs.go | 2 +- pkg/sentry/kernel/kernel.go | 2 +- pkg/sentry/kernel/kernel_state.go | 2 +- pkg/sentry/kernel/memevent/memory_events.go | 2 +- pkg/sentry/kernel/memevent/memory_events.proto | 2 +- pkg/sentry/kernel/pending_signals.go | 2 +- pkg/sentry/kernel/pending_signals_state.go | 2 +- pkg/sentry/kernel/pipe/buffers.go | 2 +- pkg/sentry/kernel/pipe/device.go | 2 +- pkg/sentry/kernel/pipe/node.go | 2 +- pkg/sentry/kernel/pipe/node_test.go | 2 +- pkg/sentry/kernel/pipe/pipe.go | 2 +- pkg/sentry/kernel/pipe/pipe_test.go | 2 +- pkg/sentry/kernel/pipe/reader.go | 2 +- pkg/sentry/kernel/pipe/reader_writer.go | 2 +- pkg/sentry/kernel/pipe/writer.go | 2 +- pkg/sentry/kernel/posixtimer.go | 2 +- pkg/sentry/kernel/ptrace.go | 2 +- pkg/sentry/kernel/rseq.go | 2 +- pkg/sentry/kernel/sched/cpuset.go | 2 +- pkg/sentry/kernel/sched/cpuset_test.go | 2 +- pkg/sentry/kernel/sched/sched.go | 2 +- pkg/sentry/kernel/seccomp.go | 2 +- pkg/sentry/kernel/semaphore/semaphore.go | 2 +- pkg/sentry/kernel/semaphore/semaphore_test.go | 2 +- pkg/sentry/kernel/sessions.go | 2 +- pkg/sentry/kernel/shm/device.go | 2 +- pkg/sentry/kernel/shm/shm.go | 2 +- pkg/sentry/kernel/signal.go | 2 +- pkg/sentry/kernel/signal_handlers.go | 2 +- pkg/sentry/kernel/syscalls.go | 2 +- pkg/sentry/kernel/syscalls_state.go | 2 +- pkg/sentry/kernel/syslog.go | 2 +- pkg/sentry/kernel/table_test.go | 2 +- pkg/sentry/kernel/task.go | 2 +- pkg/sentry/kernel/task_acct.go | 2 +- pkg/sentry/kernel/task_block.go | 2 +- pkg/sentry/kernel/task_clone.go | 2 +- pkg/sentry/kernel/task_context.go | 2 +- pkg/sentry/kernel/task_exec.go | 2 +- pkg/sentry/kernel/task_exit.go | 2 +- pkg/sentry/kernel/task_futex.go | 2 +- pkg/sentry/kernel/task_identity.go | 2 +- pkg/sentry/kernel/task_log.go | 2 +- pkg/sentry/kernel/task_net.go | 2 +- pkg/sentry/kernel/task_run.go | 2 +- pkg/sentry/kernel/task_sched.go | 2 +- pkg/sentry/kernel/task_signals.go | 2 +- pkg/sentry/kernel/task_start.go | 2 +- pkg/sentry/kernel/task_stop.go | 2 +- pkg/sentry/kernel/task_syscall.go | 2 +- pkg/sentry/kernel/task_test.go | 2 +- pkg/sentry/kernel/task_usermem.go | 2 +- pkg/sentry/kernel/thread_group.go | 2 +- pkg/sentry/kernel/threads.go | 2 +- pkg/sentry/kernel/time/context.go | 2 +- pkg/sentry/kernel/time/time.go | 2 +- pkg/sentry/kernel/timekeeper.go | 2 +- pkg/sentry/kernel/timekeeper_state.go | 2 +- pkg/sentry/kernel/timekeeper_test.go | 2 +- pkg/sentry/kernel/uts_namespace.go | 2 +- pkg/sentry/kernel/vdso.go | 2 +- pkg/sentry/kernel/version.go | 2 +- pkg/sentry/limits/context.go | 2 +- pkg/sentry/limits/limits.go | 2 +- pkg/sentry/limits/limits_test.go | 2 +- pkg/sentry/limits/linux.go | 2 +- pkg/sentry/loader/elf.go | 2 +- pkg/sentry/loader/interpreter.go | 2 +- pkg/sentry/loader/loader.go | 2 +- pkg/sentry/loader/vdso.go | 2 +- pkg/sentry/loader/vdso_state.go | 2 +- pkg/sentry/memmap/mapping_set.go | 2 +- pkg/sentry/memmap/mapping_set_test.go | 2 +- pkg/sentry/memmap/memmap.go | 2 +- pkg/sentry/memutil/memutil.go | 2 +- pkg/sentry/memutil/memutil_unsafe.go | 2 +- pkg/sentry/mm/address_space.go | 2 +- pkg/sentry/mm/aio_context.go | 2 +- pkg/sentry/mm/aio_context_state.go | 2 +- pkg/sentry/mm/debug.go | 2 +- pkg/sentry/mm/io.go | 2 +- pkg/sentry/mm/lifecycle.go | 2 +- pkg/sentry/mm/metadata.go | 2 +- pkg/sentry/mm/mm.go | 2 +- pkg/sentry/mm/mm_test.go | 2 +- pkg/sentry/mm/pma.go | 2 +- pkg/sentry/mm/proc_pid_maps.go | 2 +- pkg/sentry/mm/save_restore.go | 2 +- pkg/sentry/mm/shm.go | 2 +- pkg/sentry/mm/special_mappable.go | 2 +- pkg/sentry/mm/syscalls.go | 2 +- pkg/sentry/mm/vma.go | 2 +- pkg/sentry/platform/context.go | 2 +- pkg/sentry/platform/filemem/filemem.go | 2 +- pkg/sentry/platform/filemem/filemem_state.go | 2 +- pkg/sentry/platform/filemem/filemem_test.go | 2 +- pkg/sentry/platform/filemem/filemem_unsafe.go | 2 +- pkg/sentry/platform/interrupt/interrupt.go | 2 +- pkg/sentry/platform/interrupt/interrupt_test.go | 2 +- pkg/sentry/platform/kvm/address_space.go | 2 +- pkg/sentry/platform/kvm/allocator.go | 2 +- pkg/sentry/platform/kvm/bluepill.go | 2 +- pkg/sentry/platform/kvm/bluepill_amd64.go | 2 +- pkg/sentry/platform/kvm/bluepill_amd64.s | 2 +- pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/bluepill_fault.go | 2 +- pkg/sentry/platform/kvm/bluepill_unsafe.go | 2 +- pkg/sentry/platform/kvm/context.go | 2 +- pkg/sentry/platform/kvm/host_map.go | 2 +- pkg/sentry/platform/kvm/kvm.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/kvm_const.go | 2 +- pkg/sentry/platform/kvm/kvm_test.go | 2 +- pkg/sentry/platform/kvm/machine.go | 2 +- pkg/sentry/platform/kvm/machine_amd64.go | 2 +- pkg/sentry/platform/kvm/machine_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/machine_unsafe.go | 2 +- pkg/sentry/platform/kvm/physical_map.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil_amd64.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil_amd64.s | 2 +- pkg/sentry/platform/kvm/virtual_map.go | 2 +- pkg/sentry/platform/kvm/virtual_map_test.go | 2 +- pkg/sentry/platform/mmap_min_addr.go | 2 +- pkg/sentry/platform/platform.go | 2 +- pkg/sentry/platform/procid/procid.go | 2 +- pkg/sentry/platform/procid/procid_amd64.s | 2 +- pkg/sentry/platform/procid/procid_net_test.go | 2 +- pkg/sentry/platform/procid/procid_test.go | 2 +- pkg/sentry/platform/ptrace/ptrace.go | 2 +- pkg/sentry/platform/ptrace/ptrace_unsafe.go | 2 +- pkg/sentry/platform/ptrace/stub_amd64.s | 2 +- pkg/sentry/platform/ptrace/stub_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess.go | 2 +- pkg/sentry/platform/ptrace/subprocess_amd64.go | 2 +- pkg/sentry/platform/ptrace/subprocess_linux.go | 2 +- pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess_unsafe.go | 2 +- pkg/sentry/platform/ring0/defs.go | 2 +- pkg/sentry/platform/ring0/defs_amd64.go | 2 +- pkg/sentry/platform/ring0/entry_amd64.go | 2 +- pkg/sentry/platform/ring0/entry_amd64.s | 2 +- pkg/sentry/platform/ring0/gen_offsets/main.go | 2 +- pkg/sentry/platform/ring0/kernel.go | 2 +- pkg/sentry/platform/ring0/kernel_amd64.go | 2 +- pkg/sentry/platform/ring0/kernel_unsafe.go | 2 +- pkg/sentry/platform/ring0/lib_amd64.go | 2 +- pkg/sentry/platform/ring0/lib_amd64.s | 2 +- pkg/sentry/platform/ring0/offsets_amd64.go | 2 +- pkg/sentry/platform/ring0/pagetables/allocator.go | 2 +- pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_test.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_x86.go | 2 +- pkg/sentry/platform/ring0/pagetables/pcids_x86.go | 2 +- pkg/sentry/platform/ring0/pagetables/walker_amd64.go | 2 +- pkg/sentry/platform/ring0/ring0.go | 2 +- pkg/sentry/platform/ring0/x86.go | 2 +- pkg/sentry/platform/safecopy/atomic_amd64.s | 2 +- pkg/sentry/platform/safecopy/memclr_amd64.s | 2 +- pkg/sentry/platform/safecopy/memcpy_amd64.s | 2 +- pkg/sentry/platform/safecopy/safecopy.go | 2 +- pkg/sentry/platform/safecopy/safecopy_test.go | 2 +- pkg/sentry/platform/safecopy/safecopy_unsafe.go | 2 +- pkg/sentry/platform/safecopy/sighandler_amd64.s | 2 +- pkg/sentry/safemem/block_unsafe.go | 2 +- pkg/sentry/safemem/io.go | 2 +- pkg/sentry/safemem/io_test.go | 2 +- pkg/sentry/safemem/safemem.go | 2 +- pkg/sentry/safemem/seq_test.go | 2 +- pkg/sentry/safemem/seq_unsafe.go | 2 +- pkg/sentry/sighandling/sighandling.go | 2 +- pkg/sentry/sighandling/sighandling_unsafe.go | 2 +- pkg/sentry/socket/control/control.go | 2 +- pkg/sentry/socket/epsocket/device.go | 2 +- pkg/sentry/socket/epsocket/epsocket.go | 2 +- pkg/sentry/socket/epsocket/provider.go | 2 +- pkg/sentry/socket/epsocket/save_restore.go | 2 +- pkg/sentry/socket/epsocket/stack.go | 2 +- pkg/sentry/socket/hostinet/device.go | 2 +- pkg/sentry/socket/hostinet/hostinet.go | 2 +- pkg/sentry/socket/hostinet/save_restore.go | 2 +- pkg/sentry/socket/hostinet/socket.go | 2 +- pkg/sentry/socket/hostinet/socket_unsafe.go | 2 +- pkg/sentry/socket/hostinet/stack.go | 2 +- pkg/sentry/socket/netlink/message.go | 2 +- pkg/sentry/socket/netlink/port/port.go | 2 +- pkg/sentry/socket/netlink/port/port_test.go | 2 +- pkg/sentry/socket/netlink/provider.go | 2 +- pkg/sentry/socket/netlink/route/protocol.go | 2 +- pkg/sentry/socket/netlink/socket.go | 2 +- pkg/sentry/socket/rpcinet/conn/conn.go | 2 +- pkg/sentry/socket/rpcinet/device.go | 2 +- pkg/sentry/socket/rpcinet/notifier/notifier.go | 2 +- pkg/sentry/socket/rpcinet/rpcinet.go | 2 +- pkg/sentry/socket/rpcinet/socket.go | 2 +- pkg/sentry/socket/rpcinet/stack.go | 2 +- pkg/sentry/socket/rpcinet/stack_unsafe.go | 2 +- pkg/sentry/socket/socket.go | 2 +- pkg/sentry/socket/unix/device.go | 2 +- pkg/sentry/socket/unix/io.go | 2 +- pkg/sentry/socket/unix/transport/connectioned.go | 2 +- pkg/sentry/socket/unix/transport/connectioned_state.go | 2 +- pkg/sentry/socket/unix/transport/connectionless.go | 2 +- pkg/sentry/socket/unix/transport/queue.go | 2 +- pkg/sentry/socket/unix/transport/unix.go | 2 +- pkg/sentry/socket/unix/unix.go | 2 +- pkg/sentry/state/state.go | 2 +- pkg/sentry/state/state_metadata.go | 2 +- pkg/sentry/state/state_unsafe.go | 2 +- pkg/sentry/strace/clone.go | 2 +- pkg/sentry/strace/futex.go | 2 +- pkg/sentry/strace/linux64.go | 2 +- pkg/sentry/strace/open.go | 2 +- pkg/sentry/strace/ptrace.go | 2 +- pkg/sentry/strace/socket.go | 2 +- pkg/sentry/strace/strace.go | 2 +- pkg/sentry/strace/strace.proto | 2 +- pkg/sentry/strace/syscalls.go | 2 +- pkg/sentry/syscalls/epoll.go | 2 +- pkg/sentry/syscalls/linux/error.go | 2 +- pkg/sentry/syscalls/linux/flags.go | 2 +- pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sigset.go | 2 +- pkg/sentry/syscalls/linux/sys_aio.go | 2 +- pkg/sentry/syscalls/linux/sys_capability.go | 2 +- pkg/sentry/syscalls/linux/sys_epoll.go | 2 +- pkg/sentry/syscalls/linux/sys_eventfd.go | 2 +- pkg/sentry/syscalls/linux/sys_file.go | 2 +- pkg/sentry/syscalls/linux/sys_futex.go | 2 +- pkg/sentry/syscalls/linux/sys_getdents.go | 2 +- pkg/sentry/syscalls/linux/sys_identity.go | 2 +- pkg/sentry/syscalls/linux/sys_inotify.go | 2 +- pkg/sentry/syscalls/linux/sys_lseek.go | 2 +- pkg/sentry/syscalls/linux/sys_mmap.go | 2 +- pkg/sentry/syscalls/linux/sys_mount.go | 2 +- pkg/sentry/syscalls/linux/sys_pipe.go | 2 +- pkg/sentry/syscalls/linux/sys_poll.go | 2 +- pkg/sentry/syscalls/linux/sys_prctl.go | 2 +- pkg/sentry/syscalls/linux/sys_random.go | 2 +- pkg/sentry/syscalls/linux/sys_read.go | 2 +- pkg/sentry/syscalls/linux/sys_rlimit.go | 2 +- pkg/sentry/syscalls/linux/sys_rusage.go | 2 +- pkg/sentry/syscalls/linux/sys_sched.go | 2 +- pkg/sentry/syscalls/linux/sys_seccomp.go | 2 +- pkg/sentry/syscalls/linux/sys_sem.go | 2 +- pkg/sentry/syscalls/linux/sys_shm.go | 2 +- pkg/sentry/syscalls/linux/sys_signal.go | 2 +- pkg/sentry/syscalls/linux/sys_socket.go | 2 +- pkg/sentry/syscalls/linux/sys_stat.go | 2 +- pkg/sentry/syscalls/linux/sys_sync.go | 2 +- pkg/sentry/syscalls/linux/sys_sysinfo.go | 2 +- pkg/sentry/syscalls/linux/sys_syslog.go | 2 +- pkg/sentry/syscalls/linux/sys_thread.go | 2 +- pkg/sentry/syscalls/linux/sys_time.go | 2 +- pkg/sentry/syscalls/linux/sys_timer.go | 2 +- pkg/sentry/syscalls/linux/sys_timerfd.go | 2 +- pkg/sentry/syscalls/linux/sys_tls.go | 2 +- pkg/sentry/syscalls/linux/sys_utsname.go | 2 +- pkg/sentry/syscalls/linux/sys_write.go | 2 +- pkg/sentry/syscalls/linux/timespec.go | 2 +- pkg/sentry/syscalls/polling.go | 2 +- pkg/sentry/syscalls/syscalls.go | 2 +- pkg/sentry/syscalls/unimplemented_syscall.proto | 2 +- pkg/sentry/time/calibrated_clock.go | 2 +- pkg/sentry/time/calibrated_clock_test.go | 2 +- pkg/sentry/time/clock_id.go | 2 +- pkg/sentry/time/clocks.go | 2 +- pkg/sentry/time/muldiv_amd64.s | 2 +- pkg/sentry/time/parameters.go | 2 +- pkg/sentry/time/parameters_test.go | 2 +- pkg/sentry/time/sampler.go | 2 +- pkg/sentry/time/sampler_test.go | 2 +- pkg/sentry/time/sampler_unsafe.go | 2 +- pkg/sentry/time/tsc_amd64.s | 2 +- pkg/sentry/uniqueid/context.go | 2 +- pkg/sentry/usage/cpu.go | 2 +- pkg/sentry/usage/io.go | 2 +- pkg/sentry/usage/memory.go | 2 +- pkg/sentry/usage/memory_unsafe.go | 2 +- pkg/sentry/usage/usage.go | 2 +- pkg/sentry/usermem/access_type.go | 2 +- pkg/sentry/usermem/addr.go | 2 +- pkg/sentry/usermem/addr_range_seq_test.go | 2 +- pkg/sentry/usermem/addr_range_seq_unsafe.go | 2 +- pkg/sentry/usermem/bytes_io.go | 2 +- pkg/sentry/usermem/bytes_io_unsafe.go | 2 +- pkg/sentry/usermem/usermem.go | 2 +- pkg/sentry/usermem/usermem_test.go | 2 +- pkg/sentry/usermem/usermem_x86.go | 2 +- pkg/sentry/watchdog/watchdog.go | 2 +- pkg/sleep/commit_amd64.s | 2 +- pkg/sleep/commit_asm.go | 2 +- pkg/sleep/commit_noasm.go | 2 +- pkg/sleep/empty.s | 2 +- pkg/sleep/sleep_test.go | 2 +- pkg/sleep/sleep_unsafe.go | 2 +- pkg/state/decode.go | 2 +- pkg/state/encode.go | 2 +- pkg/state/encode_unsafe.go | 2 +- pkg/state/map.go | 2 +- pkg/state/object.proto | 2 +- pkg/state/printer.go | 2 +- pkg/state/state.go | 2 +- pkg/state/state_test.go | 2 +- pkg/state/statefile/statefile.go | 2 +- pkg/state/statefile/statefile_test.go | 2 +- pkg/state/stats.go | 2 +- pkg/sync/atomicptr_unsafe.go | 2 +- pkg/sync/atomicptrtest/atomicptr_test.go | 2 +- pkg/sync/memmove_unsafe.go | 2 +- pkg/sync/norace_unsafe.go | 2 +- pkg/sync/race_unsafe.go | 2 +- pkg/sync/seqatomic_unsafe.go | 2 +- pkg/sync/seqatomictest/seqatomic_test.go | 2 +- pkg/sync/seqcount.go | 2 +- pkg/sync/seqcount_test.go | 2 +- pkg/sync/sync.go | 2 +- pkg/syserr/host_linux.go | 2 +- pkg/syserr/netstack.go | 2 +- pkg/syserr/syserr.go | 2 +- pkg/syserror/syserror.go | 2 +- pkg/syserror/syserror_test.go | 2 +- pkg/tcpip/adapters/gonet/gonet.go | 2 +- pkg/tcpip/adapters/gonet/gonet_test.go | 2 +- pkg/tcpip/buffer/prependable.go | 2 +- pkg/tcpip/buffer/view.go | 2 +- pkg/tcpip/buffer/view_test.go | 2 +- pkg/tcpip/checker/checker.go | 2 +- pkg/tcpip/header/arp.go | 2 +- pkg/tcpip/header/checksum.go | 2 +- pkg/tcpip/header/eth.go | 2 +- pkg/tcpip/header/gue.go | 2 +- pkg/tcpip/header/icmpv4.go | 2 +- pkg/tcpip/header/icmpv6.go | 2 +- pkg/tcpip/header/interfaces.go | 2 +- pkg/tcpip/header/ipv4.go | 2 +- pkg/tcpip/header/ipv6.go | 2 +- pkg/tcpip/header/ipv6_fragment.go | 2 +- pkg/tcpip/header/ipversion_test.go | 2 +- pkg/tcpip/header/tcp.go | 2 +- pkg/tcpip/header/tcp_test.go | 2 +- pkg/tcpip/header/udp.go | 2 +- pkg/tcpip/link/channel/channel.go | 2 +- pkg/tcpip/link/fdbased/endpoint.go | 2 +- pkg/tcpip/link/fdbased/endpoint_test.go | 2 +- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/rawfile/blockingpoll_amd64.s | 2 +- pkg/tcpip/link/rawfile/blockingpoll_unsafe.go | 2 +- pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go | 2 +- pkg/tcpip/link/rawfile/errors.go | 2 +- pkg/tcpip/link/rawfile/rawfile_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe_test.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/rx.go | 2 +- pkg/tcpip/link/sharedmem/pipe/tx.go | 2 +- pkg/tcpip/link/sharedmem/queue/queue_test.go | 2 +- pkg/tcpip/link/sharedmem/queue/rx.go | 2 +- pkg/tcpip/link/sharedmem/queue/tx.go | 2 +- pkg/tcpip/link/sharedmem/rx.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_test.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/tx.go | 2 +- pkg/tcpip/link/sniffer/pcap.go | 2 +- pkg/tcpip/link/sniffer/sniffer.go | 2 +- pkg/tcpip/link/tun/tun_unsafe.go | 2 +- pkg/tcpip/link/waitable/waitable.go | 2 +- pkg/tcpip/link/waitable/waitable_test.go | 2 +- pkg/tcpip/network/arp/arp.go | 2 +- pkg/tcpip/network/arp/arp_test.go | 2 +- pkg/tcpip/network/fragmentation/frag_heap.go | 2 +- pkg/tcpip/network/fragmentation/frag_heap_test.go | 2 +- pkg/tcpip/network/fragmentation/fragmentation.go | 2 +- pkg/tcpip/network/fragmentation/fragmentation_test.go | 2 +- pkg/tcpip/network/fragmentation/reassembler.go | 2 +- pkg/tcpip/network/fragmentation/reassembler_test.go | 2 +- pkg/tcpip/network/hash/hash.go | 2 +- pkg/tcpip/network/ip_test.go | 2 +- pkg/tcpip/network/ipv4/icmp.go | 2 +- pkg/tcpip/network/ipv4/ipv4.go | 2 +- pkg/tcpip/network/ipv4/ipv4_test.go | 2 +- pkg/tcpip/network/ipv6/icmp.go | 2 +- pkg/tcpip/network/ipv6/icmp_test.go | 2 +- pkg/tcpip/network/ipv6/ipv6.go | 2 +- pkg/tcpip/ports/ports.go | 2 +- pkg/tcpip/ports/ports_test.go | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 2 +- pkg/tcpip/seqnum/seqnum.go | 2 +- pkg/tcpip/stack/linkaddrcache.go | 2 +- pkg/tcpip/stack/linkaddrcache_test.go | 2 +- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/stack/registration.go | 2 +- pkg/tcpip/stack/route.go | 2 +- pkg/tcpip/stack/stack.go | 2 +- pkg/tcpip/stack/stack_global_state.go | 2 +- pkg/tcpip/stack/stack_test.go | 2 +- pkg/tcpip/stack/transport_demuxer.go | 2 +- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/tcpip.go | 2 +- pkg/tcpip/tcpip_test.go | 2 +- pkg/tcpip/time.s | 2 +- pkg/tcpip/time_unsafe.go | 2 +- pkg/tcpip/transport/ping/endpoint.go | 2 +- pkg/tcpip/transport/ping/endpoint_state.go | 2 +- pkg/tcpip/transport/ping/protocol.go | 2 +- pkg/tcpip/transport/tcp/accept.go | 2 +- pkg/tcpip/transport/tcp/connect.go | 2 +- pkg/tcpip/transport/tcp/cubic.go | 2 +- pkg/tcpip/transport/tcp/dual_stack_test.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 2 +- pkg/tcpip/transport/tcp/endpoint_state.go | 2 +- pkg/tcpip/transport/tcp/forwarder.go | 2 +- pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/tcp/rcv.go | 2 +- pkg/tcpip/transport/tcp/reno.go | 2 +- pkg/tcpip/transport/tcp/sack.go | 2 +- pkg/tcpip/transport/tcp/segment.go | 2 +- pkg/tcpip/transport/tcp/segment_heap.go | 2 +- pkg/tcpip/transport/tcp/segment_queue.go | 2 +- pkg/tcpip/transport/tcp/segment_state.go | 2 +- pkg/tcpip/transport/tcp/snd.go | 2 +- pkg/tcpip/transport/tcp/snd_state.go | 2 +- pkg/tcpip/transport/tcp/tcp_sack_test.go | 2 +- pkg/tcpip/transport/tcp/tcp_test.go | 2 +- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 2 +- pkg/tcpip/transport/tcp/testing/context/context.go | 2 +- pkg/tcpip/transport/tcp/timer.go | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 2 +- pkg/tcpip/transport/udp/endpoint_state.go | 2 +- pkg/tcpip/transport/udp/protocol.go | 2 +- pkg/tcpip/transport/udp/udp_test.go | 2 +- pkg/tmutex/tmutex.go | 2 +- pkg/tmutex/tmutex_test.go | 2 +- pkg/unet/unet.go | 2 +- pkg/unet/unet_test.go | 2 +- pkg/unet/unet_unsafe.go | 2 +- pkg/urpc/urpc.go | 2 +- pkg/urpc/urpc_test.go | 2 +- pkg/waiter/fdnotifier/fdnotifier.go | 2 +- pkg/waiter/fdnotifier/poll_unsafe.go | 2 +- pkg/waiter/waiter.go | 2 +- pkg/waiter/waiter_test.go | 2 +- runsc/boot/compat.go | 2 +- runsc/boot/config.go | 2 +- runsc/boot/controller.go | 2 +- runsc/boot/debug.go | 2 +- runsc/boot/events.go | 2 +- runsc/boot/fds.go | 2 +- runsc/boot/filter/config.go | 2 +- runsc/boot/filter/extra_filters.go | 2 +- runsc/boot/filter/extra_filters_msan.go | 2 +- runsc/boot/filter/extra_filters_race.go | 2 +- runsc/boot/filter/filter.go | 2 +- runsc/boot/fs.go | 2 +- runsc/boot/limits.go | 2 +- runsc/boot/loader.go | 2 +- runsc/boot/loader_test.go | 2 +- runsc/boot/network.go | 2 +- runsc/boot/strace.go | 2 +- runsc/cgroup/cgroup.go | 2 +- runsc/cgroup/cgroup_test.go | 2 +- runsc/cmd/boot.go | 2 +- runsc/cmd/capability.go | 2 +- runsc/cmd/capability_test.go | 2 +- runsc/cmd/checkpoint.go | 2 +- runsc/cmd/cmd.go | 2 +- runsc/cmd/create.go | 2 +- runsc/cmd/debug.go | 2 +- runsc/cmd/delete.go | 2 +- runsc/cmd/delete_test.go | 2 +- runsc/cmd/events.go | 2 +- runsc/cmd/exec.go | 2 +- runsc/cmd/exec_test.go | 2 +- runsc/cmd/gofer.go | 2 +- runsc/cmd/kill.go | 2 +- runsc/cmd/list.go | 2 +- runsc/cmd/path.go | 2 +- runsc/cmd/pause.go | 2 +- runsc/cmd/ps.go | 2 +- runsc/cmd/restore.go | 2 +- runsc/cmd/resume.go | 2 +- runsc/cmd/run.go | 2 +- runsc/cmd/spec.go | 2 +- runsc/cmd/start.go | 2 +- runsc/cmd/state.go | 2 +- runsc/cmd/wait.go | 2 +- runsc/console/console.go | 2 +- runsc/container/console_test.go | 2 +- runsc/container/container.go | 2 +- runsc/container/container_test.go | 2 +- runsc/container/fs.go | 2 +- runsc/container/fs_test.go | 2 +- runsc/container/hook.go | 2 +- runsc/container/multi_container_test.go | 2 +- runsc/container/status.go | 2 +- runsc/container/test_app.go | 2 +- runsc/fsgofer/filter/config.go | 2 +- runsc/fsgofer/filter/extra_filters.go | 2 +- runsc/fsgofer/filter/extra_filters_msan.go | 2 +- runsc/fsgofer/filter/extra_filters_race.go | 2 +- runsc/fsgofer/filter/filter.go | 2 +- runsc/fsgofer/fsgofer.go | 2 +- runsc/fsgofer/fsgofer_test.go | 2 +- runsc/fsgofer/fsgofer_unsafe.go | 2 +- runsc/main.go | 2 +- runsc/sandbox/chroot.go | 2 +- runsc/sandbox/network.go | 2 +- runsc/sandbox/sandbox.go | 2 +- runsc/specutils/namespace.go | 2 +- runsc/specutils/specutils.go | 2 +- runsc/specutils/specutils_test.go | 2 +- runsc/test/image/image.go | 2 +- runsc/test/image/image_test.go | 2 +- runsc/test/image/mysql.sql | 2 +- runsc/test/image/ruby.rb | 2 +- runsc/test/image/ruby.sh | 2 +- runsc/test/install.sh | 2 +- runsc/test/integration/exec_test.go | 2 +- runsc/test/integration/integration.go | 2 +- runsc/test/integration/integration_test.go | 2 +- runsc/test/root/cgroup_test.go | 2 +- runsc/test/root/chroot_test.go | 2 +- runsc/test/root/root.go | 2 +- runsc/test/testutil/docker.go | 2 +- runsc/test/testutil/testutil.go | 2 +- runsc/test/testutil/testutil_race.go | 2 +- runsc/tools/dockercfg/dockercfg.go | 2 +- tools/go_generics/generics.go | 2 +- tools/go_generics/generics_tests/all_stmts/input.go | 2 +- tools/go_generics/generics_tests/all_stmts/output/output.go | 2 +- tools/go_generics/generics_tests/all_types/input.go | 2 +- tools/go_generics/generics_tests/all_types/lib/lib.go | 2 +- tools/go_generics/generics_tests/all_types/output/output.go | 2 +- tools/go_generics/generics_tests/consts/input.go | 2 +- tools/go_generics/generics_tests/consts/output/output.go | 2 +- tools/go_generics/generics_tests/imports/input.go | 2 +- tools/go_generics/generics_tests/imports/output/output.go | 2 +- tools/go_generics/generics_tests/remove_typedef/input.go | 2 +- tools/go_generics/generics_tests/remove_typedef/output/output.go | 2 +- tools/go_generics/generics_tests/simple/input.go | 2 +- tools/go_generics/generics_tests/simple/output/output.go | 2 +- tools/go_generics/globals/globals_visitor.go | 2 +- tools/go_generics/globals/scope.go | 2 +- tools/go_generics/go_generics_unittest.sh | 2 +- tools/go_generics/imports.go | 2 +- tools/go_generics/merge.go | 2 +- tools/go_generics/remove.go | 2 +- tools/go_generics/rules_tests/template.go | 2 +- tools/go_generics/rules_tests/template_test.go | 2 +- tools/go_stateify/main.go | 2 +- tools/workspace_status.sh | 2 +- vdso/barrier.h | 2 +- vdso/check_vdso.py | 2 +- vdso/compiler.h | 2 +- vdso/cycle_clock.h | 2 +- vdso/seqlock.h | 2 +- vdso/syscalls.h | 2 +- vdso/vdso.cc | 2 +- vdso/vdso_time.cc | 2 +- vdso/vdso_time.h | 2 +- 923 files changed, 923 insertions(+), 923 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/kokoro/run_build.sh b/kokoro/run_build.sh index f2b719f52..89e24b037 100755 --- a/kokoro/run_build.sh +++ b/kokoro/run_build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/kokoro/run_tests.sh b/kokoro/run_tests.sh index 3f8841cee..0a0d73d29 100755 --- a/kokoro/run_tests.sh +++ b/kokoro/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/pkg/abi/abi.go b/pkg/abi/abi.go index a53c2747b..7770f0405 100644 --- a/pkg/abi/abi.go +++ b/pkg/abi/abi.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/abi_linux.go b/pkg/abi/abi_linux.go index dd5d67b51..9d9f361a4 100644 --- a/pkg/abi/abi_linux.go +++ b/pkg/abi/abi_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/flag.go b/pkg/abi/flag.go index 0391ccf37..0698e410f 100644 --- a/pkg/abi/flag.go +++ b/pkg/abi/flag.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/aio.go b/pkg/abi/linux/aio.go index 9c39ca2ef..1b7ca714a 100644 --- a/pkg/abi/linux/aio.go +++ b/pkg/abi/linux/aio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ashmem.go b/pkg/abi/linux/ashmem.go index 7fbfd2e68..ced1e44d4 100644 --- a/pkg/abi/linux/ashmem.go +++ b/pkg/abi/linux/ashmem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/binder.go b/pkg/abi/linux/binder.go index b228898f9..522dc6f53 100644 --- a/pkg/abi/linux/binder.go +++ b/pkg/abi/linux/binder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go index 80e5b1af1..d9cd09948 100644 --- a/pkg/abi/linux/bpf.go +++ b/pkg/abi/linux/bpf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/capability.go b/pkg/abi/linux/capability.go index b470ce0a5..7d96f013e 100644 --- a/pkg/abi/linux/capability.go +++ b/pkg/abi/linux/capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/dev.go b/pkg/abi/linux/dev.go index ea5b16b7b..5b1199aac 100644 --- a/pkg/abi/linux/dev.go +++ b/pkg/abi/linux/dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/elf.go b/pkg/abi/linux/elf.go index 76c13b677..928067c04 100644 --- a/pkg/abi/linux/elf.go +++ b/pkg/abi/linux/elf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errors.go index b5ddb2b2f..01e4095b8 100644 --- a/pkg/abi/linux/errors.go +++ b/pkg/abi/linux/errors.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/eventfd.go b/pkg/abi/linux/eventfd.go index bc0fb44d2..5614f5cf1 100644 --- a/pkg/abi/linux/eventfd.go +++ b/pkg/abi/linux/eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/exec.go b/pkg/abi/linux/exec.go index 4d81eca54..a07c29243 100644 --- a/pkg/abi/linux/exec.go +++ b/pkg/abi/linux/exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/fcntl.go b/pkg/abi/linux/fcntl.go index 2a5ad6ed7..c8558933a 100644 --- a/pkg/abi/linux/fcntl.go +++ b/pkg/abi/linux/fcntl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 9bf229a57..72e5c6f83 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go index 32a0812b4..7817bfb52 100644 --- a/pkg/abi/linux/fs.go +++ b/pkg/abi/linux/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/futex.go b/pkg/abi/linux/futex.go index f63f5200c..5dff01fba 100644 --- a/pkg/abi/linux/futex.go +++ b/pkg/abi/linux/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/inotify.go b/pkg/abi/linux/inotify.go index 072a2d146..79c5d3593 100644 --- a/pkg/abi/linux/inotify.go +++ b/pkg/abi/linux/inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index afd9ee82b..9afc3d1ef 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ip.go b/pkg/abi/linux/ip.go index 6b68999ab..fcec16965 100644 --- a/pkg/abi/linux/ip.go +++ b/pkg/abi/linux/ip.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ipc.go b/pkg/abi/linux/ipc.go index 81e9904dd..10681768b 100644 --- a/pkg/abi/linux/ipc.go +++ b/pkg/abi/linux/ipc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go index e1f0932ec..b2e51b9bd 100644 --- a/pkg/abi/linux/limits.go +++ b/pkg/abi/linux/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/linux.go b/pkg/abi/linux/linux.go index de2af80dc..d365f693d 100644 --- a/pkg/abi/linux/linux.go +++ b/pkg/abi/linux/linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go index b48e1d18a..3fcdf8235 100644 --- a/pkg/abi/linux/mm.go +++ b/pkg/abi/linux/mm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/netdevice.go b/pkg/abi/linux/netdevice.go index 88654a1b3..e3b6b1e40 100644 --- a/pkg/abi/linux/netdevice.go +++ b/pkg/abi/linux/netdevice.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/netlink.go b/pkg/abi/linux/netlink.go index e823ffa7e..10ceb5bf2 100644 --- a/pkg/abi/linux/netlink.go +++ b/pkg/abi/linux/netlink.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/netlink_route.go b/pkg/abi/linux/netlink_route.go index a5d778748..4200b6506 100644 --- a/pkg/abi/linux/netlink_route.go +++ b/pkg/abi/linux/netlink_route.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/poll.go b/pkg/abi/linux/poll.go index f373cfca1..9f0b15d1c 100644 --- a/pkg/abi/linux/poll.go +++ b/pkg/abi/linux/poll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go index 074ec03f0..e152c4c27 100644 --- a/pkg/abi/linux/prctl.go +++ b/pkg/abi/linux/prctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ptrace.go b/pkg/abi/linux/ptrace.go index ba48d4d6d..7db4f5464 100644 --- a/pkg/abi/linux/ptrace.go +++ b/pkg/abi/linux/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/rusage.go b/pkg/abi/linux/rusage.go index a4a89abda..7fea4b589 100644 --- a/pkg/abi/linux/rusage.go +++ b/pkg/abi/linux/rusage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/sched.go b/pkg/abi/linux/sched.go index 05fda1604..ef96a3801 100644 --- a/pkg/abi/linux/sched.go +++ b/pkg/abi/linux/sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go index a8de9d3d0..9963ceeba 100644 --- a/pkg/abi/linux/seccomp.go +++ b/pkg/abi/linux/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/sem.go b/pkg/abi/linux/sem.go index 3495f5cd0..d1a0bdb32 100644 --- a/pkg/abi/linux/sem.go +++ b/pkg/abi/linux/sem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/shm.go b/pkg/abi/linux/shm.go index f50b3c2e2..82a80e609 100644 --- a/pkg/abi/linux/shm.go +++ b/pkg/abi/linux/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go index b2c7230c4..bf9bce6ed 100644 --- a/pkg/abi/linux/signal.go +++ b/pkg/abi/linux/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index 19b5fa212..af0761a3b 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/time.go b/pkg/abi/linux/time.go index 4569f4208..bbd21e726 100644 --- a/pkg/abi/linux/time.go +++ b/pkg/abi/linux/time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/timer.go b/pkg/abi/linux/timer.go index 6c4675c35..a6f420bdb 100644 --- a/pkg/abi/linux/timer.go +++ b/pkg/abi/linux/timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index f63dc52aa..e6f7c5b2a 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/uio.go b/pkg/abi/linux/uio.go index 93c972774..7e00d9959 100644 --- a/pkg/abi/linux/uio.go +++ b/pkg/abi/linux/uio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/utsname.go b/pkg/abi/linux/utsname.go index 7d33d20de..f80ed7d4a 100644 --- a/pkg/abi/linux/utsname.go +++ b/pkg/abi/linux/utsname.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/amutex/amutex.go b/pkg/amutex/amutex.go index 1cb73359a..26b674435 100644 --- a/pkg/amutex/amutex.go +++ b/pkg/amutex/amutex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/amutex/amutex_test.go b/pkg/amutex/amutex_test.go index 876e47b19..104e0dab1 100644 --- a/pkg/amutex/amutex_test.go +++ b/pkg/amutex/amutex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/atomicbitops/atomic_bitops.go b/pkg/atomicbitops/atomic_bitops.go index 6635ea0d2..9a57f9599 100644 --- a/pkg/atomicbitops/atomic_bitops.go +++ b/pkg/atomicbitops/atomic_bitops.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/atomicbitops/atomic_bitops_amd64.s b/pkg/atomicbitops/atomic_bitops_amd64.s index 542452bec..b37e3aad3 100644 --- a/pkg/atomicbitops/atomic_bitops_amd64.s +++ b/pkg/atomicbitops/atomic_bitops_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/atomicbitops/atomic_bitops_common.go b/pkg/atomicbitops/atomic_bitops_common.go index 542ff4e83..b03242baa 100644 --- a/pkg/atomicbitops/atomic_bitops_common.go +++ b/pkg/atomicbitops/atomic_bitops_common.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/atomicbitops/atomic_bitops_test.go b/pkg/atomicbitops/atomic_bitops_test.go index ec0c07ee2..ee6207cb3 100644 --- a/pkg/atomicbitops/atomic_bitops_test.go +++ b/pkg/atomicbitops/atomic_bitops_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/binary/binary.go b/pkg/binary/binary.go index 3b18a86ee..02f7e9fb8 100644 --- a/pkg/binary/binary.go +++ b/pkg/binary/binary.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/binary/binary_test.go b/pkg/binary/binary_test.go index 921a0369a..d8d481f32 100644 --- a/pkg/binary/binary_test.go +++ b/pkg/binary/binary_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/bits.go b/pkg/bits/bits.go index 50ca4bff7..eb3c80f49 100644 --- a/pkg/bits/bits.go +++ b/pkg/bits/bits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/bits_template.go b/pkg/bits/bits_template.go index 0a01f29c2..8c578cca2 100644 --- a/pkg/bits/bits_template.go +++ b/pkg/bits/bits_template.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/uint64_arch_amd64.go b/pkg/bits/uint64_arch_amd64.go index 068597f68..1fef89394 100644 --- a/pkg/bits/uint64_arch_amd64.go +++ b/pkg/bits/uint64_arch_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/uint64_arch_amd64_asm.s b/pkg/bits/uint64_arch_amd64_asm.s index 33885641a..8c7322f0f 100644 --- a/pkg/bits/uint64_arch_amd64_asm.s +++ b/pkg/bits/uint64_arch_amd64_asm.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/uint64_arch_generic.go b/pkg/bits/uint64_arch_generic.go index 862033a4b..cfb47400b 100644 --- a/pkg/bits/uint64_arch_generic.go +++ b/pkg/bits/uint64_arch_generic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/uint64_test.go b/pkg/bits/uint64_test.go index 906017e1a..d6dbaf602 100644 --- a/pkg/bits/uint64_test.go +++ b/pkg/bits/uint64_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/bpf.go b/pkg/bpf/bpf.go index 757744090..98d44d911 100644 --- a/pkg/bpf/bpf.go +++ b/pkg/bpf/bpf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/decoder.go b/pkg/bpf/decoder.go index ef41e9edc..ae6b8839a 100644 --- a/pkg/bpf/decoder.go +++ b/pkg/bpf/decoder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/decoder_test.go b/pkg/bpf/decoder_test.go index 18709b944..f093e1e41 100644 --- a/pkg/bpf/decoder_test.go +++ b/pkg/bpf/decoder_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/input_bytes.go b/pkg/bpf/input_bytes.go index 74af038eb..745c0749b 100644 --- a/pkg/bpf/input_bytes.go +++ b/pkg/bpf/input_bytes.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/interpreter.go b/pkg/bpf/interpreter.go index 111ada9d1..86c7add4d 100644 --- a/pkg/bpf/interpreter.go +++ b/pkg/bpf/interpreter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/interpreter_test.go b/pkg/bpf/interpreter_test.go index 9e5e33228..c46a43991 100644 --- a/pkg/bpf/interpreter_test.go +++ b/pkg/bpf/interpreter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/program_builder.go b/pkg/bpf/program_builder.go index bad56d7ac..b4ce228e1 100644 --- a/pkg/bpf/program_builder.go +++ b/pkg/bpf/program_builder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/program_builder_test.go b/pkg/bpf/program_builder_test.go index 7e4f06584..0e0b79d88 100644 --- a/pkg/bpf/program_builder_test.go +++ b/pkg/bpf/program_builder_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/compressio/compressio.go b/pkg/compressio/compressio.go index 667f17c5c..205536812 100644 --- a/pkg/compressio/compressio.go +++ b/pkg/compressio/compressio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/compressio/compressio_test.go b/pkg/compressio/compressio_test.go index 7cb5f8dc4..1bbabee79 100644 --- a/pkg/compressio/compressio_test.go +++ b/pkg/compressio/compressio_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/control/client/client.go b/pkg/control/client/client.go index f7c2e8776..0d0c9f148 100644 --- a/pkg/control/client/client.go +++ b/pkg/control/client/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/control/server/server.go b/pkg/control/server/server.go index d00061ce3..c46b5d70b 100644 --- a/pkg/control/server/server.go +++ b/pkg/control/server/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/cpuid/cpu_amd64.s b/pkg/cpuid/cpu_amd64.s index 48a13c6fd..905c1d12e 100644 --- a/pkg/cpuid/cpu_amd64.s +++ b/pkg/cpuid/cpu_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go index e91e34dc7..5b083a5fb 100644 --- a/pkg/cpuid/cpuid.go +++ b/pkg/cpuid/cpuid.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/cpuid/cpuid_parse_test.go b/pkg/cpuid/cpuid_parse_test.go index c4f52818c..81b06f48c 100644 --- a/pkg/cpuid/cpuid_parse_test.go +++ b/pkg/cpuid/cpuid_parse_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/cpuid/cpuid_test.go b/pkg/cpuid/cpuid_test.go index 02f732f85..0decd8f08 100644 --- a/pkg/cpuid/cpuid_test.go +++ b/pkg/cpuid/cpuid_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 92c634a14..3330c4998 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/dhcp.go b/pkg/dhcp/dhcp.go index ceaba34c3..ad11e178a 100644 --- a/pkg/dhcp/dhcp.go +++ b/pkg/dhcp/dhcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/dhcp_string.go b/pkg/dhcp/dhcp_string.go index 7cabed29e..8533895bd 100644 --- a/pkg/dhcp/dhcp_string.go +++ b/pkg/dhcp/dhcp_string.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index d60e3752b..a21dce6bc 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index 26700bdbc..3e06ab4c7 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/eventchannel/event.go b/pkg/eventchannel/event.go index bfd28256e..41a7b5ed3 100644 --- a/pkg/eventchannel/event.go +++ b/pkg/eventchannel/event.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/eventchannel/event.proto b/pkg/eventchannel/event.proto index 455f03658..c1679c7e7 100644 --- a/pkg/eventchannel/event.proto +++ b/pkg/eventchannel/event.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/fd/fd.go b/pkg/fd/fd.go index 32d24c41b..f6656ffa1 100644 --- a/pkg/fd/fd.go +++ b/pkg/fd/fd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/fd/fd_test.go b/pkg/fd/fd_test.go index 94b3eb7cc..42bb3ef6c 100644 --- a/pkg/fd/fd_test.go +++ b/pkg/fd/fd_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/gate/gate.go b/pkg/gate/gate.go index 93808c9dd..48122bf5a 100644 --- a/pkg/gate/gate.go +++ b/pkg/gate/gate.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/gate/gate_test.go b/pkg/gate/gate_test.go index 06587339b..95620fa8e 100644 --- a/pkg/gate/gate_test.go +++ b/pkg/gate/gate_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/ilist/list.go b/pkg/ilist/list.go index 4ae02eee9..51c9b6df3 100644 --- a/pkg/ilist/list.go +++ b/pkg/ilist/list.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/ilist/list_test.go b/pkg/ilist/list_test.go index 2c56280f6..4bda570b6 100644 --- a/pkg/ilist/list_test.go +++ b/pkg/ilist/list_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/linewriter/linewriter.go b/pkg/linewriter/linewriter.go index 98f974410..5fbd4e779 100644 --- a/pkg/linewriter/linewriter.go +++ b/pkg/linewriter/linewriter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/linewriter/linewriter_test.go b/pkg/linewriter/linewriter_test.go index ce97cca05..9140ee6af 100644 --- a/pkg/linewriter/linewriter_test.go +++ b/pkg/linewriter/linewriter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/glog.go b/pkg/log/glog.go index 58b4052e6..fbb58501b 100644 --- a/pkg/log/glog.go +++ b/pkg/log/glog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/glog_unsafe.go b/pkg/log/glog_unsafe.go index c320190b8..bb06aa7d3 100644 --- a/pkg/log/glog_unsafe.go +++ b/pkg/log/glog_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/json.go b/pkg/log/json.go index 3887f1cd5..96bd13d87 100644 --- a/pkg/log/json.go +++ b/pkg/log/json.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/json_test.go b/pkg/log/json_test.go index 3b167dab0..b8c7a795e 100644 --- a/pkg/log/json_test.go +++ b/pkg/log/json_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/log.go b/pkg/log/log.go index c496e86e4..b8d456aae 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/log_test.go b/pkg/log/log_test.go index d93e989dc..a59d457dd 100644 --- a/pkg/log/log_test.go +++ b/pkg/log/log_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/metric/metric.go b/pkg/metric/metric.go index 763cd6bc2..02af75974 100644 --- a/pkg/metric/metric.go +++ b/pkg/metric/metric.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/metric/metric.proto b/pkg/metric/metric.proto index 6108cb7c0..917fda1ac 100644 --- a/pkg/metric/metric.proto +++ b/pkg/metric/metric.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/metric/metric_test.go b/pkg/metric/metric_test.go index 7d156e4a5..40034a589 100644 --- a/pkg/metric/metric_test.go +++ b/pkg/metric/metric_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/buffer.go b/pkg/p9/buffer.go index fc65d2c5f..9575ddf12 100644 --- a/pkg/p9/buffer.go +++ b/pkg/p9/buffer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/client.go b/pkg/p9/client.go index 5fa231bc5..3ebfab82a 100644 --- a/pkg/p9/client.go +++ b/pkg/p9/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/client_file.go b/pkg/p9/client_file.go index a46efd27f..066639fda 100644 --- a/pkg/p9/client_file.go +++ b/pkg/p9/client_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/client_test.go b/pkg/p9/client_test.go index 06302a76a..f7145452d 100644 --- a/pkg/p9/client_test.go +++ b/pkg/p9/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/file.go b/pkg/p9/file.go index 9723fa24d..d2e89e373 100644 --- a/pkg/p9/file.go +++ b/pkg/p9/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index ea41f97c7..959dff31d 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/local_server/local_server.go b/pkg/p9/local_server/local_server.go index cef3701a7..1e6aaa762 100644 --- a/pkg/p9/local_server/local_server.go +++ b/pkg/p9/local_server/local_server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/messages.go b/pkg/p9/messages.go index b3d76801b..972c37344 100644 --- a/pkg/p9/messages.go +++ b/pkg/p9/messages.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/messages_test.go b/pkg/p9/messages_test.go index f353755f1..dfb41bb76 100644 --- a/pkg/p9/messages_test.go +++ b/pkg/p9/messages_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/p9.go b/pkg/p9/p9.go index c6899c3ce..3b0993ecd 100644 --- a/pkg/p9/p9.go +++ b/pkg/p9/p9.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/p9_test.go b/pkg/p9/p9_test.go index a50ac80a4..02498346c 100644 --- a/pkg/p9/p9_test.go +++ b/pkg/p9/p9_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/p9test/client_test.go b/pkg/p9/p9test/client_test.go index 34ddccd8b..db562b9ba 100644 --- a/pkg/p9/p9test/client_test.go +++ b/pkg/p9/p9test/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/p9test/mocks.go b/pkg/p9/p9test/mocks.go index 9d039ac63..9a8c14975 100644 --- a/pkg/p9/p9test/mocks.go +++ b/pkg/p9/p9test/mocks.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/pool.go b/pkg/p9/pool.go index 9a508b898..34ed898e8 100644 --- a/pkg/p9/pool.go +++ b/pkg/p9/pool.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/pool_test.go b/pkg/p9/pool_test.go index 96be2c8bd..71052d8c4 100644 --- a/pkg/p9/pool_test.go +++ b/pkg/p9/pool_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/server.go b/pkg/p9/server.go index 28a273ac6..5c7cb18c8 100644 --- a/pkg/p9/server.go +++ b/pkg/p9/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/transport.go b/pkg/p9/transport.go index b5df29961..97396806c 100644 --- a/pkg/p9/transport.go +++ b/pkg/p9/transport.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/transport_test.go b/pkg/p9/transport_test.go index d6d4b6365..3352a5205 100644 --- a/pkg/p9/transport_test.go +++ b/pkg/p9/transport_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/version.go b/pkg/p9/version.go index 8783eaa7e..ceb6fabbf 100644 --- a/pkg/p9/version.go +++ b/pkg/p9/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/version_test.go b/pkg/p9/version_test.go index 634ac3ca5..c053614c9 100644 --- a/pkg/p9/version_test.go +++ b/pkg/p9/version_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/rand/rand.go b/pkg/rand/rand.go index e81f0f5db..593a14380 100644 --- a/pkg/rand/rand.go +++ b/pkg/rand/rand.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/rand/rand_linux.go b/pkg/rand/rand_linux.go index a2be66b3b..7ebe8f3b0 100644 --- a/pkg/rand/rand_linux.go +++ b/pkg/rand/rand_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/refs/refcounter.go b/pkg/refs/refcounter.go index 638a93bab..8f08c74c7 100644 --- a/pkg/refs/refcounter.go +++ b/pkg/refs/refcounter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/refs/refcounter_state.go b/pkg/refs/refcounter_state.go index 093eae785..136f06fbf 100644 --- a/pkg/refs/refcounter_state.go +++ b/pkg/refs/refcounter_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/refs/refcounter_test.go b/pkg/refs/refcounter_test.go index cc11bcd71..abaa87453 100644 --- a/pkg/refs/refcounter_test.go +++ b/pkg/refs/refcounter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index a746dc9b3..1dfbf749e 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp_rules.go b/pkg/seccomp/seccomp_rules.go index 6b707f195..a9278c64b 100644 --- a/pkg/seccomp/seccomp_rules.go +++ b/pkg/seccomp/seccomp_rules.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp_test.go b/pkg/seccomp/seccomp_test.go index 0188ad4f3..226f30b7b 100644 --- a/pkg/seccomp/seccomp_test.go +++ b/pkg/seccomp/seccomp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp_test_victim.go b/pkg/seccomp/seccomp_test_victim.go index 4f2ae4dac..007038273 100644 --- a/pkg/seccomp/seccomp_test_victim.go +++ b/pkg/seccomp/seccomp_test_victim.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp_unsafe.go b/pkg/seccomp/seccomp_unsafe.go index ae18534bf..dd009221a 100644 --- a/pkg/seccomp/seccomp_unsafe.go +++ b/pkg/seccomp/seccomp_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/secio/full_reader.go b/pkg/secio/full_reader.go index b2dbb8615..90b1772a7 100644 --- a/pkg/secio/full_reader.go +++ b/pkg/secio/full_reader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/secio/secio.go b/pkg/secio/secio.go index fc625efb8..e5f74a497 100644 --- a/pkg/secio/secio.go +++ b/pkg/secio/secio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/secio/secio_test.go b/pkg/secio/secio_test.go index 64b4cc17d..8304c4f74 100644 --- a/pkg/secio/secio_test.go +++ b/pkg/secio/secio_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/range.go b/pkg/segment/range.go index 34c067265..057bcd7ff 100644 --- a/pkg/segment/range.go +++ b/pkg/segment/range.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/set.go b/pkg/segment/set.go index cffec2a2c..a9a3b8875 100644 --- a/pkg/segment/set.go +++ b/pkg/segment/set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/set_state.go b/pkg/segment/set_state.go index a763d1915..b86e1b75f 100644 --- a/pkg/segment/set_state.go +++ b/pkg/segment/set_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/test/segment_test.go b/pkg/segment/test/segment_test.go index 7ea24b177..0825105db 100644 --- a/pkg/segment/test/segment_test.go +++ b/pkg/segment/test/segment_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/test/set_functions.go b/pkg/segment/test/set_functions.go index 37c196ea1..05ba5fbb9 100644 --- a/pkg/segment/test/set_functions.go +++ b/pkg/segment/test/set_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/aligned.go b/pkg/sentry/arch/aligned.go index 193232e27..c88c034f6 100644 --- a/pkg/sentry/arch/aligned.go +++ b/pkg/sentry/arch/aligned.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index 21cb84502..575b7ba66 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index 5ba6c19ea..bb80a7bed 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch_amd64.s b/pkg/sentry/arch/arch_amd64.s index 10d621b6d..fa9857df7 100644 --- a/pkg/sentry/arch/arch_amd64.s +++ b/pkg/sentry/arch/arch_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch_state_x86.go b/pkg/sentry/arch/arch_state_x86.go index e9c23a06b..604bd08a6 100644 --- a/pkg/sentry/arch/arch_state_x86.go +++ b/pkg/sentry/arch/arch_state_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index b35eec53c..59bf89d99 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/auxv.go b/pkg/sentry/arch/auxv.go index 81cfb4a01..5df65a691 100644 --- a/pkg/sentry/arch/auxv.go +++ b/pkg/sentry/arch/auxv.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/registers.proto b/pkg/sentry/arch/registers.proto index 437ff44ca..f4c2f7043 100644 --- a/pkg/sentry/arch/registers.proto +++ b/pkg/sentry/arch/registers.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/signal_act.go b/pkg/sentry/arch/signal_act.go index 36437b965..ad098c746 100644 --- a/pkg/sentry/arch/signal_act.go +++ b/pkg/sentry/arch/signal_act.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index 9ca4c8ed1..f7f054b0b 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/signal_info.go b/pkg/sentry/arch/signal_info.go index ec004ae75..fa0ecbec5 100644 --- a/pkg/sentry/arch/signal_info.go +++ b/pkg/sentry/arch/signal_info.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/signal_stack.go b/pkg/sentry/arch/signal_stack.go index ba43dd1d4..c02ae3b7c 100644 --- a/pkg/sentry/arch/signal_stack.go +++ b/pkg/sentry/arch/signal_stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/stack.go b/pkg/sentry/arch/stack.go index 6c1b9be82..716a3574d 100644 --- a/pkg/sentry/arch/stack.go +++ b/pkg/sentry/arch/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/syscalls_amd64.go b/pkg/sentry/arch/syscalls_amd64.go index 41d8ba0d1..47c31d4b9 100644 --- a/pkg/sentry/arch/syscalls_amd64.go +++ b/pkg/sentry/arch/syscalls_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/context/context.go b/pkg/sentry/context/context.go index 598c5b4ff..12bdcef85 100644 --- a/pkg/sentry/context/context.go +++ b/pkg/sentry/context/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/context/contexttest/contexttest.go b/pkg/sentry/context/contexttest/contexttest.go index b3c6a566b..d2f084ed7 100644 --- a/pkg/sentry/context/contexttest/contexttest.go +++ b/pkg/sentry/context/contexttest/contexttest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/control/control.go b/pkg/sentry/control/control.go index a6ee6e649..32d30b6ea 100644 --- a/pkg/sentry/control/control.go +++ b/pkg/sentry/control/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/control/proc.go b/pkg/sentry/control/proc.go index 0ba730c1e..b6ac2f312 100644 --- a/pkg/sentry/control/proc.go +++ b/pkg/sentry/control/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/control/proc_test.go b/pkg/sentry/control/proc_test.go index 22c826236..5d52cd829 100644 --- a/pkg/sentry/control/proc_test.go +++ b/pkg/sentry/control/proc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/control/state.go b/pkg/sentry/control/state.go index cee4db636..0a480c84a 100644 --- a/pkg/sentry/control/state.go +++ b/pkg/sentry/control/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/device/device.go b/pkg/sentry/device/device.go index 21fee8f8a..27e4eb258 100644 --- a/pkg/sentry/device/device.go +++ b/pkg/sentry/device/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/device/device_test.go b/pkg/sentry/device/device_test.go index dfec45046..5d8805c2f 100644 --- a/pkg/sentry/device/device_test.go +++ b/pkg/sentry/device/device_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/anon/anon.go b/pkg/sentry/fs/anon/anon.go index ddc2c0985..743cf511f 100644 --- a/pkg/sentry/fs/anon/anon.go +++ b/pkg/sentry/fs/anon/anon.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/anon/device.go b/pkg/sentry/fs/anon/device.go index 1c666729c..2d1249299 100644 --- a/pkg/sentry/fs/anon/device.go +++ b/pkg/sentry/fs/anon/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index bfd7f2762..5372875ac 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index d0986fa11..962da141b 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ashmem/pin_board.go b/pkg/sentry/fs/ashmem/pin_board.go index ecba395a0..7c997f533 100644 --- a/pkg/sentry/fs/ashmem/pin_board.go +++ b/pkg/sentry/fs/ashmem/pin_board.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ashmem/pin_board_test.go b/pkg/sentry/fs/ashmem/pin_board_test.go index f4ea5de6d..736e628dc 100644 --- a/pkg/sentry/fs/ashmem/pin_board_test.go +++ b/pkg/sentry/fs/ashmem/pin_board_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index 091f4ac63..59e060e3c 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index 502a262dd..42b9e8b26 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/context.go b/pkg/sentry/fs/context.go index da46ad77f..1775d3486 100644 --- a/pkg/sentry/fs/context.go +++ b/pkg/sentry/fs/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/copy_up.go b/pkg/sentry/fs/copy_up.go index 8c949b176..d65dc74bf 100644 --- a/pkg/sentry/fs/copy_up.go +++ b/pkg/sentry/fs/copy_up.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/copy_up_test.go b/pkg/sentry/fs/copy_up_test.go index c3c9d963d..64f030f72 100644 --- a/pkg/sentry/fs/copy_up_test.go +++ b/pkg/sentry/fs/copy_up_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dentry.go b/pkg/sentry/fs/dentry.go index b347468ff..ef6d1a870 100644 --- a/pkg/sentry/fs/dentry.go +++ b/pkg/sentry/fs/dentry.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index 3f4f2a40a..05a5005ad 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/device.go b/pkg/sentry/fs/dev/device.go index 9d935e008..3cecdf6e2 100644 --- a/pkg/sentry/fs/dev/device.go +++ b/pkg/sentry/fs/dev/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go index 2ae49be4e..d96f4f423 100644 --- a/pkg/sentry/fs/dev/fs.go +++ b/pkg/sentry/fs/dev/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index 492b8eb3a..eeda646ab 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 2977c8670..68090f353 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index 47b76218f..33e4913e4 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index 27fea0019..2c01485a8 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent_cache.go b/pkg/sentry/fs/dirent_cache.go index c680e4828..502b0a09b 100644 --- a/pkg/sentry/fs/dirent_cache.go +++ b/pkg/sentry/fs/dirent_cache.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent_cache_test.go b/pkg/sentry/fs/dirent_cache_test.go index 82b7f6bd5..5d0e9d91c 100644 --- a/pkg/sentry/fs/dirent_cache_test.go +++ b/pkg/sentry/fs/dirent_cache_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent_refs_test.go b/pkg/sentry/fs/dirent_refs_test.go index f9dcba316..325404e27 100644 --- a/pkg/sentry/fs/dirent_refs_test.go +++ b/pkg/sentry/fs/dirent_refs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent_state.go b/pkg/sentry/fs/dirent_state.go index 04ab197b9..5cf151dab 100644 --- a/pkg/sentry/fs/dirent_state.go +++ b/pkg/sentry/fs/dirent_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 2e34604e6..bfafff5ec 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener.go b/pkg/sentry/fs/fdpipe/pipe_opener.go index 945cfaf08..92ab6ff0e 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener_test.go b/pkg/sentry/fs/fdpipe/pipe_opener_test.go index 83f6c1986..69516e048 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe_state.go b/pkg/sentry/fs/fdpipe/pipe_state.go index 99c40d8ed..4395666ad 100644 --- a/pkg/sentry/fs/fdpipe/pipe_state.go +++ b/pkg/sentry/fs/fdpipe/pipe_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe_test.go b/pkg/sentry/fs/fdpipe/pipe_test.go index 6cd314f5b..d3f15be6b 100644 --- a/pkg/sentry/fs/fdpipe/pipe_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 36794d378..d6752ed1b 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_operations.go b/pkg/sentry/fs/file_operations.go index d223bb5c7..28e8e233d 100644 --- a/pkg/sentry/fs/file_operations.go +++ b/pkg/sentry/fs/file_operations.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index 41e646ee8..9b958b64b 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_overlay_test.go b/pkg/sentry/fs/file_overlay_test.go index 830458ff9..11e4f7203 100644 --- a/pkg/sentry/fs/file_overlay_test.go +++ b/pkg/sentry/fs/file_overlay_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_state.go b/pkg/sentry/fs/file_state.go index f848d1b79..1c3bae3e8 100644 --- a/pkg/sentry/fs/file_state.go +++ b/pkg/sentry/fs/file_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_test.go b/pkg/sentry/fs/file_test.go index 18aee7101..f3ed9a70b 100644 --- a/pkg/sentry/fs/file_test.go +++ b/pkg/sentry/fs/file_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/filesystems.go b/pkg/sentry/fs/filesystems.go index 5a1e7a270..ba8be85e4 100644 --- a/pkg/sentry/fs/filesystems.go +++ b/pkg/sentry/fs/filesystems.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/filetest/filetest.go b/pkg/sentry/fs/filetest/filetest.go index 1831aa82f..65ca196d9 100644 --- a/pkg/sentry/fs/filetest/filetest.go +++ b/pkg/sentry/fs/filetest/filetest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index 1aa271560..bf2a20b33 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fs.go b/pkg/sentry/fs/fs.go index 6ec9ff446..b5c72990e 100644 --- a/pkg/sentry/fs/fs.go +++ b/pkg/sentry/fs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/dirty_set.go b/pkg/sentry/fs/fsutil/dirty_set.go index 8e31e48fd..5add16ac4 100644 --- a/pkg/sentry/fs/fsutil/dirty_set.go +++ b/pkg/sentry/fs/fsutil/dirty_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/dirty_set_test.go b/pkg/sentry/fs/fsutil/dirty_set_test.go index f7693cb19..f5c9d9215 100644 --- a/pkg/sentry/fs/fsutil/dirty_set_test.go +++ b/pkg/sentry/fs/fsutil/dirty_set_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go index d5881613b..46db2e51c 100644 --- a/pkg/sentry/fs/fsutil/file.go +++ b/pkg/sentry/fs/fsutil/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/file_range_set.go b/pkg/sentry/fs/fsutil/file_range_set.go index da6949ccb..dd7ab4b4a 100644 --- a/pkg/sentry/fs/fsutil/file_range_set.go +++ b/pkg/sentry/fs/fsutil/file_range_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/frame_ref_set.go b/pkg/sentry/fs/fsutil/frame_ref_set.go index 14dece315..b6e783614 100644 --- a/pkg/sentry/fs/fsutil/frame_ref_set.go +++ b/pkg/sentry/fs/fsutil/frame_ref_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/fsutil.go b/pkg/sentry/fs/fsutil/fsutil.go index 6fe4ef13d..3d7f3732d 100644 --- a/pkg/sentry/fs/fsutil/fsutil.go +++ b/pkg/sentry/fs/fsutil/fsutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/handle.go b/pkg/sentry/fs/fsutil/handle.go index e7efd3c0f..8920b72ee 100644 --- a/pkg/sentry/fs/fsutil/handle.go +++ b/pkg/sentry/fs/fsutil/handle.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/handle_test.go b/pkg/sentry/fs/fsutil/handle_test.go index d94c3eb0d..43e1a3bdf 100644 --- a/pkg/sentry/fs/fsutil/handle_test.go +++ b/pkg/sentry/fs/fsutil/handle_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go index 9c1e2f76f..9599665f0 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_state.go b/pkg/sentry/fs/fsutil/host_file_mapper_state.go index 57705decd..bbd15b30b 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper_state.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go index 790f3a5a6..86df76822 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index 3acc32752..d4db1c2de 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index 6777c8bf7..b0af44ddd 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/inode_cached_test.go b/pkg/sentry/fs/fsutil/inode_cached_test.go index 996c91849..e388ec3d7 100644 --- a/pkg/sentry/fs/fsutil/inode_cached_test.go +++ b/pkg/sentry/fs/fsutil/inode_cached_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/attr.go b/pkg/sentry/fs/gofer/attr.go index 5e24767f9..98700d014 100644 --- a/pkg/sentry/fs/gofer/attr.go +++ b/pkg/sentry/fs/gofer/attr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/cache_policy.go b/pkg/sentry/fs/gofer/cache_policy.go index 98f43c578..3d380f0e8 100644 --- a/pkg/sentry/fs/gofer/cache_policy.go +++ b/pkg/sentry/fs/gofer/cache_policy.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/context_file.go b/pkg/sentry/fs/gofer/context_file.go index d4b6f6eb7..a0265c2aa 100644 --- a/pkg/sentry/fs/gofer/context_file.go +++ b/pkg/sentry/fs/gofer/context_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/device.go b/pkg/sentry/fs/gofer/device.go index fac7306d4..52c5acf48 100644 --- a/pkg/sentry/fs/gofer/device.go +++ b/pkg/sentry/fs/gofer/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index c4a210656..6d961813d 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/file_state.go b/pkg/sentry/fs/gofer/file_state.go index 715af8f16..dd4f817bf 100644 --- a/pkg/sentry/fs/gofer/file_state.go +++ b/pkg/sentry/fs/gofer/file_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go index 3ae93f059..ed30cb1f1 100644 --- a/pkg/sentry/fs/gofer/fs.go +++ b/pkg/sentry/fs/gofer/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/gofer_test.go b/pkg/sentry/fs/gofer/gofer_test.go index c8d7bd773..3190d1e18 100644 --- a/pkg/sentry/fs/gofer/gofer_test.go +++ b/pkg/sentry/fs/gofer/gofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/handles.go b/pkg/sentry/fs/gofer/handles.go index a3e52aad6..f32e99ce0 100644 --- a/pkg/sentry/fs/gofer/handles.go +++ b/pkg/sentry/fs/gofer/handles.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index 7fc8f77b0..5811b8b12 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/inode_state.go b/pkg/sentry/fs/gofer/inode_state.go index ad11034f9..ad4d3df58 100644 --- a/pkg/sentry/fs/gofer/inode_state.go +++ b/pkg/sentry/fs/gofer/inode_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/path.go b/pkg/sentry/fs/gofer/path.go index 0bf7881da..a324dc990 100644 --- a/pkg/sentry/fs/gofer/path.go +++ b/pkg/sentry/fs/gofer/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go index 4e2293398..7552216f3 100644 --- a/pkg/sentry/fs/gofer/session.go +++ b/pkg/sentry/fs/gofer/session.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/session_state.go b/pkg/sentry/fs/gofer/session_state.go index 8e6424492..f657135fc 100644 --- a/pkg/sentry/fs/gofer/session_state.go +++ b/pkg/sentry/fs/gofer/session_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/socket.go b/pkg/sentry/fs/gofer/socket.go index d072da624..76ce58810 100644 --- a/pkg/sentry/fs/gofer/socket.go +++ b/pkg/sentry/fs/gofer/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/util.go b/pkg/sentry/fs/gofer/util.go index d9ed8c81e..1a759370d 100644 --- a/pkg/sentry/fs/gofer/util.go +++ b/pkg/sentry/fs/gofer/util.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/control.go b/pkg/sentry/fs/host/control.go index d2e34a69d..0753640a2 100644 --- a/pkg/sentry/fs/host/control.go +++ b/pkg/sentry/fs/host/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/descriptor.go b/pkg/sentry/fs/host/descriptor.go index 148291ba6..7c9d2b299 100644 --- a/pkg/sentry/fs/host/descriptor.go +++ b/pkg/sentry/fs/host/descriptor.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/descriptor_state.go b/pkg/sentry/fs/host/descriptor_state.go index 7fb274451..530c0109f 100644 --- a/pkg/sentry/fs/host/descriptor_state.go +++ b/pkg/sentry/fs/host/descriptor_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/descriptor_test.go b/pkg/sentry/fs/host/descriptor_test.go index f393a8b54..6bc1bd2ae 100644 --- a/pkg/sentry/fs/host/descriptor_test.go +++ b/pkg/sentry/fs/host/descriptor_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/device.go b/pkg/sentry/fs/host/device.go index f2a0b6b15..b5adedf44 100644 --- a/pkg/sentry/fs/host/device.go +++ b/pkg/sentry/fs/host/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index 22a5d9f12..975084c86 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index e46ae433c..fec890964 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/fs_test.go b/pkg/sentry/fs/host/fs_test.go index b08125ca8..e69559aac 100644 --- a/pkg/sentry/fs/host/fs_test.go +++ b/pkg/sentry/fs/host/fs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index e32497203..08754bd6b 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/inode_state.go b/pkg/sentry/fs/host/inode_state.go index 8bc99d94b..b7c1a9581 100644 --- a/pkg/sentry/fs/host/inode_state.go +++ b/pkg/sentry/fs/host/inode_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/inode_test.go b/pkg/sentry/fs/host/inode_test.go index 0ff87c418..9f1561bd5 100644 --- a/pkg/sentry/fs/host/inode_test.go +++ b/pkg/sentry/fs/host/inode_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/ioctl_unsafe.go b/pkg/sentry/fs/host/ioctl_unsafe.go index bc965a1c2..175dca613 100644 --- a/pkg/sentry/fs/host/ioctl_unsafe.go +++ b/pkg/sentry/fs/host/ioctl_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket.go b/pkg/sentry/fs/host/socket.go index 0eb267c00..af53bf533 100644 --- a/pkg/sentry/fs/host/socket.go +++ b/pkg/sentry/fs/host/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket_iovec.go b/pkg/sentry/fs/host/socket_iovec.go index 1a9587b90..d4ce4a8c1 100644 --- a/pkg/sentry/fs/host/socket_iovec.go +++ b/pkg/sentry/fs/host/socket_iovec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket_state.go b/pkg/sentry/fs/host/socket_state.go index 7fa500bfb..2932c1f16 100644 --- a/pkg/sentry/fs/host/socket_state.go +++ b/pkg/sentry/fs/host/socket_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket_test.go b/pkg/sentry/fs/host/socket_test.go index 483e99dd6..e9a88b124 100644 --- a/pkg/sentry/fs/host/socket_test.go +++ b/pkg/sentry/fs/host/socket_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket_unsafe.go b/pkg/sentry/fs/host/socket_unsafe.go index 5e4c5feed..f35e2492d 100644 --- a/pkg/sentry/fs/host/socket_unsafe.go +++ b/pkg/sentry/fs/host/socket_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/tty.go b/pkg/sentry/fs/host/tty.go index ad1323610..cf3639c46 100644 --- a/pkg/sentry/fs/host/tty.go +++ b/pkg/sentry/fs/host/tty.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/util.go b/pkg/sentry/fs/host/util.go index 74c703eb7..40c450660 100644 --- a/pkg/sentry/fs/host/util.go +++ b/pkg/sentry/fs/host/util.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/util_unsafe.go b/pkg/sentry/fs/host/util_unsafe.go index 2ecb54319..d00da89d6 100644 --- a/pkg/sentry/fs/host/util_unsafe.go +++ b/pkg/sentry/fs/host/util_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/wait_test.go b/pkg/sentry/fs/host/wait_test.go index c5f5c9c0d..9ca8c399f 100644 --- a/pkg/sentry/fs/host/wait_test.go +++ b/pkg/sentry/fs/host/wait_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index 409c81a97..95769ccf8 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode_inotify.go b/pkg/sentry/fs/inode_inotify.go index 683140afe..e213df924 100644 --- a/pkg/sentry/fs/inode_inotify.go +++ b/pkg/sentry/fs/inode_inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode_operations.go b/pkg/sentry/fs/inode_operations.go index 3ee3de10e..77973ce79 100644 --- a/pkg/sentry/fs/inode_operations.go +++ b/pkg/sentry/fs/inode_operations.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go index cf698a4da..78923fb5b 100644 --- a/pkg/sentry/fs/inode_overlay.go +++ b/pkg/sentry/fs/inode_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode_overlay_test.go b/pkg/sentry/fs/inode_overlay_test.go index 23e5635a4..bba20da14 100644 --- a/pkg/sentry/fs/inode_overlay_test.go +++ b/pkg/sentry/fs/inode_overlay_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 2aabdded8..f251df0d1 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go index e9b5e0f56..9e3e9d816 100644 --- a/pkg/sentry/fs/inotify_event.go +++ b/pkg/sentry/fs/inotify_event.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inotify_watch.go b/pkg/sentry/fs/inotify_watch.go index 3e1959e83..b83544c9f 100644 --- a/pkg/sentry/fs/inotify_watch.go +++ b/pkg/sentry/fs/inotify_watch.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go index 439e645db..5ff800d2d 100644 --- a/pkg/sentry/fs/lock/lock.go +++ b/pkg/sentry/fs/lock/lock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/lock/lock_range_test.go b/pkg/sentry/fs/lock/lock_range_test.go index 06a37c701..b0ab882b9 100644 --- a/pkg/sentry/fs/lock/lock_range_test.go +++ b/pkg/sentry/fs/lock/lock_range_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/lock/lock_set_functions.go b/pkg/sentry/fs/lock/lock_set_functions.go index e16f485be..395592a4b 100644 --- a/pkg/sentry/fs/lock/lock_set_functions.go +++ b/pkg/sentry/fs/lock/lock_set_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/lock/lock_test.go b/pkg/sentry/fs/lock/lock_test.go index c60f5f7a2..67fa4b1dd 100644 --- a/pkg/sentry/fs/lock/lock_test.go +++ b/pkg/sentry/fs/lock/lock_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mock.go b/pkg/sentry/fs/mock.go index 846b6e8bb..6bfcda6bb 100644 --- a/pkg/sentry/fs/mock.go +++ b/pkg/sentry/fs/mock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index 8345876fc..24e28ddb2 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go index dbc608c7e..fb91635bc 100644 --- a/pkg/sentry/fs/mount_overlay.go +++ b/pkg/sentry/fs/mount_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mount_state.go b/pkg/sentry/fs/mount_state.go index f5ed1dd8d..6344d5160 100644 --- a/pkg/sentry/fs/mount_state.go +++ b/pkg/sentry/fs/mount_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mount_test.go b/pkg/sentry/fs/mount_test.go index 968b435ab..a1c9f4f79 100644 --- a/pkg/sentry/fs/mount_test.go +++ b/pkg/sentry/fs/mount_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go index c0a803b2d..7c5348cce 100644 --- a/pkg/sentry/fs/mounts.go +++ b/pkg/sentry/fs/mounts.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mounts_test.go b/pkg/sentry/fs/mounts_test.go index 8669f3a38..cc7c32c9b 100644 --- a/pkg/sentry/fs/mounts_test.go +++ b/pkg/sentry/fs/mounts_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/offset.go b/pkg/sentry/fs/offset.go index 7cc8398e6..38aee765a 100644 --- a/pkg/sentry/fs/offset.go +++ b/pkg/sentry/fs/offset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go index 5a30af419..036c0f733 100644 --- a/pkg/sentry/fs/overlay.go +++ b/pkg/sentry/fs/overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/path.go b/pkg/sentry/fs/path.go index b74f6ed8c..91a9a8ffd 100644 --- a/pkg/sentry/fs/path.go +++ b/pkg/sentry/fs/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/path_test.go b/pkg/sentry/fs/path_test.go index 7ab070855..391b010a7 100644 --- a/pkg/sentry/fs/path_test.go +++ b/pkg/sentry/fs/path_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go index 4dfec03a4..f8be06dc3 100644 --- a/pkg/sentry/fs/proc/cpuinfo.go +++ b/pkg/sentry/fs/proc/cpuinfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/device/device.go b/pkg/sentry/fs/proc/device/device.go index 6194afe88..04b687bcf 100644 --- a/pkg/sentry/fs/proc/device/device.go +++ b/pkg/sentry/fs/proc/device/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index a69cbaa0e..b4896053f 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index dada8f982..5ebb33703 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/file.go b/pkg/sentry/fs/proc/file.go index 4b3448245..f659e590a 100644 --- a/pkg/sentry/fs/proc/file.go +++ b/pkg/sentry/fs/proc/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/filesystems.go b/pkg/sentry/fs/proc/filesystems.go index 49b92fd8a..c050a00be 100644 --- a/pkg/sentry/fs/proc/filesystems.go +++ b/pkg/sentry/fs/proc/filesystems.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/fs.go b/pkg/sentry/fs/proc/fs.go index 061824b8c..63f737ff4 100644 --- a/pkg/sentry/fs/proc/fs.go +++ b/pkg/sentry/fs/proc/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go index 6fac251d2..78f3a1dc0 100644 --- a/pkg/sentry/fs/proc/loadavg.go +++ b/pkg/sentry/fs/proc/loadavg.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go index 53dfd59ef..b31258eed 100644 --- a/pkg/sentry/fs/proc/meminfo.go +++ b/pkg/sentry/fs/proc/meminfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index 81dcc153a..0b0e87528 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go index 8cd6fe9d3..45f2a1211 100644 --- a/pkg/sentry/fs/proc/net.go +++ b/pkg/sentry/fs/proc/net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/net_test.go b/pkg/sentry/fs/proc/net_test.go index a31a20494..94677cc1d 100644 --- a/pkg/sentry/fs/proc/net_test.go +++ b/pkg/sentry/fs/proc/net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index 07029a7bb..33030bebf 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/rpcinet_proc.go b/pkg/sentry/fs/proc/rpcinet_proc.go index 50d0271f9..d025069df 100644 --- a/pkg/sentry/fs/proc/rpcinet_proc.go +++ b/pkg/sentry/fs/proc/rpcinet_proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index 51cae5e37..0499ba65b 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/seqfile/seqfile_test.go b/pkg/sentry/fs/proc/seqfile/seqfile_test.go index d90e3e736..f9a2ca38e 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile_test.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go index bf7650211..f2bbef375 100644 --- a/pkg/sentry/fs/proc/stat.go +++ b/pkg/sentry/fs/proc/stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index 384b4ffe1..54562508d 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index beb25be20..801eb6a1e 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/sys_net_test.go b/pkg/sentry/fs/proc/sys_net_test.go index 7ba392346..0ce9d30f1 100644 --- a/pkg/sentry/fs/proc/sys_net_test.go +++ b/pkg/sentry/fs/proc/sys_net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 748ca4320..404faea0a 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index a7e4cf0a6..f70399686 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index f3a9b81df..80c7ce0b4 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go index 00f6a2afd..b6d49d5e9 100644 --- a/pkg/sentry/fs/proc/version.go +++ b/pkg/sentry/fs/proc/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index 075e13b01..0a911b155 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/file.go b/pkg/sentry/fs/ramfs/file.go index 0b94d92a1..b7fc98ffc 100644 --- a/pkg/sentry/fs/ramfs/file.go +++ b/pkg/sentry/fs/ramfs/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/ramfs.go b/pkg/sentry/fs/ramfs/ramfs.go index 83cbcab23..d77688a34 100644 --- a/pkg/sentry/fs/ramfs/ramfs.go +++ b/pkg/sentry/fs/ramfs/ramfs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index 9ac00eb18..8c81478c8 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index 1c54d9991..a21fac2c7 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/test/test.go b/pkg/sentry/fs/ramfs/test/test.go index fb669558f..11bff7729 100644 --- a/pkg/sentry/fs/ramfs/test/test.go +++ b/pkg/sentry/fs/ramfs/test/test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/tree.go b/pkg/sentry/fs/ramfs/tree.go index 1fb335f74..29a70f698 100644 --- a/pkg/sentry/fs/ramfs/tree.go +++ b/pkg/sentry/fs/ramfs/tree.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/tree_test.go b/pkg/sentry/fs/ramfs/tree_test.go index 68e2929d5..d5567d9e1 100644 --- a/pkg/sentry/fs/ramfs/tree_test.go +++ b/pkg/sentry/fs/ramfs/tree_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/restore.go b/pkg/sentry/fs/restore.go index b4ac85a27..da2df7e1d 100644 --- a/pkg/sentry/fs/restore.go +++ b/pkg/sentry/fs/restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/save.go b/pkg/sentry/fs/save.go index bf2a85143..90988d385 100644 --- a/pkg/sentry/fs/save.go +++ b/pkg/sentry/fs/save.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/seek.go b/pkg/sentry/fs/seek.go index 1268726c2..72f3fb632 100644 --- a/pkg/sentry/fs/seek.go +++ b/pkg/sentry/fs/seek.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sync.go b/pkg/sentry/fs/sync.go index 9738a8f22..6dcc2fe8d 100644 --- a/pkg/sentry/fs/sync.go +++ b/pkg/sentry/fs/sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sys/device.go b/pkg/sentry/fs/sys/device.go index 54e414d1b..38ecd0c18 100644 --- a/pkg/sentry/fs/sys/device.go +++ b/pkg/sentry/fs/sys/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sys/devices.go b/pkg/sentry/fs/sys/devices.go index 2cf3a6f98..e64aa0edc 100644 --- a/pkg/sentry/fs/sys/devices.go +++ b/pkg/sentry/fs/sys/devices.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go index 625525540..5ce33f87f 100644 --- a/pkg/sentry/fs/sys/fs.go +++ b/pkg/sentry/fs/sys/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go index 7b9697668..7cc1942c7 100644 --- a/pkg/sentry/fs/sys/sys.go +++ b/pkg/sentry/fs/sys/sys.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index 767db95a0..7423e816c 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/device.go b/pkg/sentry/fs/tmpfs/device.go index e588b3440..aade93c26 100644 --- a/pkg/sentry/fs/tmpfs/device.go +++ b/pkg/sentry/fs/tmpfs/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index 342688f81..1f9d69909 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/file_test.go b/pkg/sentry/fs/tmpfs/file_test.go index f064eb1ac..b5830d3df 100644 --- a/pkg/sentry/fs/tmpfs/file_test.go +++ b/pkg/sentry/fs/tmpfs/file_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index ca620e65e..7c91e248b 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 1e4fe47d2..42a7d7b9c 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 38be6db46..91b782540 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index 7c0c0b0c1..e32b05c1d 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go index d9f8f02f3..0c412eb21 100644 --- a/pkg/sentry/fs/tty/fs.go +++ b/pkg/sentry/fs/tty/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/inode.go b/pkg/sentry/fs/tty/inode.go index c0fa2b407..d5d1caafc 100644 --- a/pkg/sentry/fs/tty/inode.go +++ b/pkg/sentry/fs/tty/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index 31804571e..484366f85 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index ae7540eff..dad0cad79 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/queue.go b/pkg/sentry/fs/tty/queue.go index 01dc8d1ac..a09ca0119 100644 --- a/pkg/sentry/fs/tty/queue.go +++ b/pkg/sentry/fs/tty/queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index 4a0d4fdb9..9de3168bf 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/terminal.go b/pkg/sentry/fs/tty/terminal.go index 3cb135124..79f9d76d7 100644 --- a/pkg/sentry/fs/tty/terminal.go +++ b/pkg/sentry/fs/tty/terminal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/tty_test.go b/pkg/sentry/fs/tty/tty_test.go index 32e1b1556..ad535838f 100644 --- a/pkg/sentry/fs/tty/tty_test.go +++ b/pkg/sentry/fs/tty/tty_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/hostcpu/getcpu_amd64.s b/pkg/sentry/hostcpu/getcpu_amd64.s index 7f6247d81..409db1450 100644 --- a/pkg/sentry/hostcpu/getcpu_amd64.s +++ b/pkg/sentry/hostcpu/getcpu_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/hostcpu/hostcpu.go b/pkg/sentry/hostcpu/hostcpu.go index fa46499ad..3adc847bb 100644 --- a/pkg/sentry/hostcpu/hostcpu.go +++ b/pkg/sentry/hostcpu/hostcpu.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/hostcpu/hostcpu_test.go b/pkg/sentry/hostcpu/hostcpu_test.go index a82e1a271..38de0e1f6 100644 --- a/pkg/sentry/hostcpu/hostcpu_test.go +++ b/pkg/sentry/hostcpu/hostcpu_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/inet/context.go b/pkg/sentry/inet/context.go index 370381f41..d05e96f15 100644 --- a/pkg/sentry/inet/context.go +++ b/pkg/sentry/inet/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index 30ca4e0c0..8206377cc 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/inet/test_stack.go b/pkg/sentry/inet/test_stack.go index bc10926ee..05c1a1792 100644 --- a/pkg/sentry/inet/test_stack.go +++ b/pkg/sentry/inet/test_stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go index 45088c988..1ea2cee36 100644 --- a/pkg/sentry/kernel/abstract_socket_namespace.go +++ b/pkg/sentry/kernel/abstract_socket_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/auth.go b/pkg/sentry/kernel/auth/auth.go index c49a6b852..19f15fd36 100644 --- a/pkg/sentry/kernel/auth/auth.go +++ b/pkg/sentry/kernel/auth/auth.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/capability_set.go b/pkg/sentry/kernel/auth/capability_set.go index 5b8164c49..88d6243aa 100644 --- a/pkg/sentry/kernel/auth/capability_set.go +++ b/pkg/sentry/kernel/auth/capability_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/context.go b/pkg/sentry/kernel/auth/context.go index 914589b28..f7e945599 100644 --- a/pkg/sentry/kernel/auth/context.go +++ b/pkg/sentry/kernel/auth/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index f18f7dac9..de33f1953 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/id.go b/pkg/sentry/kernel/auth/id.go index 37522b018..e5bed44d7 100644 --- a/pkg/sentry/kernel/auth/id.go +++ b/pkg/sentry/kernel/auth/id.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index bd0090e0f..43f439825 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/id_map_functions.go b/pkg/sentry/kernel/auth/id_map_functions.go index 889291d96..8f1a189ec 100644 --- a/pkg/sentry/kernel/auth/id_map_functions.go +++ b/pkg/sentry/kernel/auth/id_map_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index d359f3f31..5bb9c44c0 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/context.go b/pkg/sentry/kernel/context.go index 261ca6f7a..b629521eb 100644 --- a/pkg/sentry/kernel/context.go +++ b/pkg/sentry/kernel/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index a8eb114c0..9c13ecfcc 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/epoll/epoll_state.go b/pkg/sentry/kernel/epoll/epoll_state.go index dabb32f49..7f3e2004a 100644 --- a/pkg/sentry/kernel/epoll/epoll_state.go +++ b/pkg/sentry/kernel/epoll/epoll_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/epoll/epoll_test.go b/pkg/sentry/kernel/epoll/epoll_test.go index bc869fc13..d89c1b745 100644 --- a/pkg/sentry/kernel/epoll/epoll_test.go +++ b/pkg/sentry/kernel/epoll/epoll_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index a4ada0e78..26dc59a85 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/eventfd/eventfd_test.go b/pkg/sentry/kernel/eventfd/eventfd_test.go index 71326b62f..14e8996d9 100644 --- a/pkg/sentry/kernel/eventfd/eventfd_test.go +++ b/pkg/sentry/kernel/eventfd/eventfd_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/fasync/fasync.go b/pkg/sentry/kernel/fasync/fasync.go index f77339cae..aa4aac109 100644 --- a/pkg/sentry/kernel/fasync/fasync.go +++ b/pkg/sentry/kernel/fasync/fasync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index cad0b0a20..715f4714d 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/fd_map_test.go b/pkg/sentry/kernel/fd_map_test.go index 95123aef3..b49996137 100644 --- a/pkg/sentry/kernel/fd_map_test.go +++ b/pkg/sentry/kernel/fd_map_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index f3f05e8f5..3cf0db280 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index 54b1982a0..ea69d433b 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/futex/futex_test.go b/pkg/sentry/kernel/futex/futex_test.go index 726c26990..ea506a29b 100644 --- a/pkg/sentry/kernel/futex/futex_test.go +++ b/pkg/sentry/kernel/futex/futex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index 5eef49f59..9ceb9bd92 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/kdefs/kdefs.go b/pkg/sentry/kernel/kdefs/kdefs.go index bbb476544..8eafe810b 100644 --- a/pkg/sentry/kernel/kdefs/kdefs.go +++ b/pkg/sentry/kernel/kdefs/kdefs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 5d6856f3c..bad558d48 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/kernel_state.go b/pkg/sentry/kernel/kernel_state.go index bb2d5102d..a0a69b498 100644 --- a/pkg/sentry/kernel/kernel_state.go +++ b/pkg/sentry/kernel/kernel_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/memevent/memory_events.go b/pkg/sentry/kernel/memevent/memory_events.go index f7a183a1d..f05ef1b64 100644 --- a/pkg/sentry/kernel/memevent/memory_events.go +++ b/pkg/sentry/kernel/memevent/memory_events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/memevent/memory_events.proto b/pkg/sentry/kernel/memevent/memory_events.proto index abc565054..43b8deb76 100644 --- a/pkg/sentry/kernel/memevent/memory_events.proto +++ b/pkg/sentry/kernel/memevent/memory_events.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index bb5db0309..373e11772 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pending_signals_state.go b/pkg/sentry/kernel/pending_signals_state.go index 6d90ed033..72be6702f 100644 --- a/pkg/sentry/kernel/pending_signals_state.go +++ b/pkg/sentry/kernel/pending_signals_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index a82e45c3f..fa8045910 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/device.go b/pkg/sentry/kernel/pipe/device.go index 8d383577a..eec5c5de8 100644 --- a/pkg/sentry/kernel/pipe/device.go +++ b/pkg/sentry/kernel/pipe/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index 23d692da1..4b0e00b85 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/node_test.go b/pkg/sentry/kernel/pipe/node_test.go index cc1ebf4f6..eda551594 100644 --- a/pkg/sentry/kernel/pipe/node_test.go +++ b/pkg/sentry/kernel/pipe/node_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index ced2559a7..126054826 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/pipe_test.go b/pkg/sentry/kernel/pipe/pipe_test.go index 49ef8c8ac..3b9895927 100644 --- a/pkg/sentry/kernel/pipe/pipe_test.go +++ b/pkg/sentry/kernel/pipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index 1fa5e9a32..f27379969 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index 82607367b..63efc5bbe 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index d93324b53..6fea9769c 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/posixtimer.go b/pkg/sentry/kernel/posixtimer.go index 0ab958529..40b5acca3 100644 --- a/pkg/sentry/kernel/posixtimer.go +++ b/pkg/sentry/kernel/posixtimer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index 9fe28f435..20bac2b70 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 1f3de58e3..46b03c700 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/sched/cpuset.go b/pkg/sentry/kernel/sched/cpuset.go index 0a97603f0..69aee9127 100644 --- a/pkg/sentry/kernel/sched/cpuset.go +++ b/pkg/sentry/kernel/sched/cpuset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/sched/cpuset_test.go b/pkg/sentry/kernel/sched/cpuset_test.go index 8a6e12958..a036ed513 100644 --- a/pkg/sentry/kernel/sched/cpuset_test.go +++ b/pkg/sentry/kernel/sched/cpuset_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/sched/sched.go b/pkg/sentry/kernel/sched/sched.go index f1de1da60..e59909baf 100644 --- a/pkg/sentry/kernel/sched/sched.go +++ b/pkg/sentry/kernel/sched/sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go index d77c05e2f..37dd3e4c9 100644 --- a/pkg/sentry/kernel/seccomp.go +++ b/pkg/sentry/kernel/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index aa07946cf..232a276dc 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/semaphore/semaphore_test.go b/pkg/sentry/kernel/semaphore/semaphore_test.go index f9eb382e9..5f886bf31 100644 --- a/pkg/sentry/kernel/semaphore/semaphore_test.go +++ b/pkg/sentry/kernel/semaphore/semaphore_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index a9b4e7647..78a5b4063 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/shm/device.go b/pkg/sentry/kernel/shm/device.go index b0dacdbe0..bbc653ed8 100644 --- a/pkg/sentry/kernel/shm/device.go +++ b/pkg/sentry/kernel/shm/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index 77973951e..8d0d14e45 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/signal.go b/pkg/sentry/kernel/signal.go index e3a2a777a..b066df132 100644 --- a/pkg/sentry/kernel/signal.go +++ b/pkg/sentry/kernel/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 3649f5e4d..3f1ac9898 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index 4c7811b6c..19b711e9c 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/syscalls_state.go b/pkg/sentry/kernel/syscalls_state.go index 826809a70..981455d46 100644 --- a/pkg/sentry/kernel/syscalls_state.go +++ b/pkg/sentry/kernel/syscalls_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go index 6531bd5d2..2aecf3eea 100644 --- a/pkg/sentry/kernel/syslog.go +++ b/pkg/sentry/kernel/syslog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/table_test.go b/pkg/sentry/kernel/table_test.go index 71ca75555..3b29d3c6a 100644 --- a/pkg/sentry/kernel/table_test.go +++ b/pkg/sentry/kernel/table_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index 4f0b7fe3f..e22ec768d 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_acct.go b/pkg/sentry/kernel/task_acct.go index d2052921e..24230af89 100644 --- a/pkg/sentry/kernel/task_acct.go +++ b/pkg/sentry/kernel/task_acct.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_block.go b/pkg/sentry/kernel/task_block.go index 6dc7b938e..e5027e551 100644 --- a/pkg/sentry/kernel/task_block.go +++ b/pkg/sentry/kernel/task_block.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index de3aef40d..755fe0370 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index d2df7e9d1..45b8d2b04 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index 1b760aba4..a9b74da8e 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index 65969ca9b..44fbb487c 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_futex.go b/pkg/sentry/kernel/task_futex.go index 62ebbcb0d..5a11ca3df 100644 --- a/pkg/sentry/kernel/task_futex.go +++ b/pkg/sentry/kernel/task_futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_identity.go b/pkg/sentry/kernel/task_identity.go index b0921b2eb..8f90ed786 100644 --- a/pkg/sentry/kernel/task_identity.go +++ b/pkg/sentry/kernel/task_identity.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_log.go b/pkg/sentry/kernel/task_log.go index 1769da210..f4c881c2d 100644 --- a/pkg/sentry/kernel/task_log.go +++ b/pkg/sentry/kernel/task_log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_net.go b/pkg/sentry/kernel/task_net.go index 4df2e53d3..fc7cefc1f 100644 --- a/pkg/sentry/kernel/task_net.go +++ b/pkg/sentry/kernel/task_net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 49ac933b7..596b9aa16 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index 19dcc963a..3b3cdc24a 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index e2925a708..fe24f7542 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_start.go b/pkg/sentry/kernel/task_start.go index 6c8d7d316..c82a32c78 100644 --- a/pkg/sentry/kernel/task_start.go +++ b/pkg/sentry/kernel/task_start.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_stop.go b/pkg/sentry/kernel/task_stop.go index feaf6cae4..36846484c 100644 --- a/pkg/sentry/kernel/task_stop.go +++ b/pkg/sentry/kernel/task_stop.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index f0373c375..0318adb35 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_test.go b/pkg/sentry/kernel/task_test.go index 82ef858a1..3f37f505d 100644 --- a/pkg/sentry/kernel/task_test.go +++ b/pkg/sentry/kernel/task_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_usermem.go b/pkg/sentry/kernel/task_usermem.go index 2b4954869..c8e973bd5 100644 --- a/pkg/sentry/kernel/task_usermem.go +++ b/pkg/sentry/kernel/task_usermem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index dfff7b52d..d7652f57c 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 4e3d19e97..bdb907905 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/time/context.go b/pkg/sentry/kernel/time/context.go index ac4dc01d8..3675ea20d 100644 --- a/pkg/sentry/kernel/time/context.go +++ b/pkg/sentry/kernel/time/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index 52e0dfba1..ca0f4ba2e 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index 2167f3efe..6bff80f13 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/timekeeper_state.go b/pkg/sentry/kernel/timekeeper_state.go index 2e7fed4d8..f3a3ed543 100644 --- a/pkg/sentry/kernel/timekeeper_state.go +++ b/pkg/sentry/kernel/timekeeper_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/timekeeper_test.go b/pkg/sentry/kernel/timekeeper_test.go index 34a5cec27..71674c21c 100644 --- a/pkg/sentry/kernel/timekeeper_test.go +++ b/pkg/sentry/kernel/timekeeper_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go index 7e0fe0d21..ed5f0c031 100644 --- a/pkg/sentry/kernel/uts_namespace.go +++ b/pkg/sentry/kernel/uts_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go index 971e8bc59..0ec858a4a 100644 --- a/pkg/sentry/kernel/vdso.go +++ b/pkg/sentry/kernel/vdso.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/version.go b/pkg/sentry/kernel/version.go index a9e84673f..72bb0f93c 100644 --- a/pkg/sentry/kernel/version.go +++ b/pkg/sentry/kernel/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/limits/context.go b/pkg/sentry/limits/context.go index 75e97bf92..bf413eb7d 100644 --- a/pkg/sentry/limits/context.go +++ b/pkg/sentry/limits/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index 02c8b60e3..ba0b7d4fd 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/limits/limits_test.go b/pkg/sentry/limits/limits_test.go index dd6f80750..d41f62554 100644 --- a/pkg/sentry/limits/limits_test.go +++ b/pkg/sentry/limits/limits_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/limits/linux.go b/pkg/sentry/limits/linux.go index 8e6a24341..511db6733 100644 --- a/pkg/sentry/limits/linux.go +++ b/pkg/sentry/limits/linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/elf.go b/pkg/sentry/loader/elf.go index 849be5a3d..9b1e81dc9 100644 --- a/pkg/sentry/loader/elf.go +++ b/pkg/sentry/loader/elf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/interpreter.go b/pkg/sentry/loader/interpreter.go index 54534952b..06a3c7156 100644 --- a/pkg/sentry/loader/interpreter.go +++ b/pkg/sentry/loader/interpreter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go index 62b39e52b..d1417c4f1 100644 --- a/pkg/sentry/loader/loader.go +++ b/pkg/sentry/loader/loader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index a06e27ac9..437cc5da1 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/vdso_state.go b/pkg/sentry/loader/vdso_state.go index dc71e1c2d..b327f0e1e 100644 --- a/pkg/sentry/loader/vdso_state.go +++ b/pkg/sentry/loader/vdso_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memmap/mapping_set.go b/pkg/sentry/memmap/mapping_set.go index c9483905d..33cf16f91 100644 --- a/pkg/sentry/memmap/mapping_set.go +++ b/pkg/sentry/memmap/mapping_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memmap/mapping_set_test.go b/pkg/sentry/memmap/mapping_set_test.go index 10668d404..49ee34548 100644 --- a/pkg/sentry/memmap/mapping_set_test.go +++ b/pkg/sentry/memmap/mapping_set_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index cdc5f2b27..05349a77f 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memutil/memutil.go b/pkg/sentry/memutil/memutil.go index 4f245cf3c..286d50ca4 100644 --- a/pkg/sentry/memutil/memutil.go +++ b/pkg/sentry/memutil/memutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memutil/memutil_unsafe.go b/pkg/sentry/memutil/memutil_unsafe.go index 32c27eb2f..8d9fc64fb 100644 --- a/pkg/sentry/memutil/memutil_unsafe.go +++ b/pkg/sentry/memutil/memutil_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/address_space.go b/pkg/sentry/mm/address_space.go index 27554f163..7488f7c4a 100644 --- a/pkg/sentry/mm/address_space.go +++ b/pkg/sentry/mm/address_space.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go index b42156d45..87942af0e 100644 --- a/pkg/sentry/mm/aio_context.go +++ b/pkg/sentry/mm/aio_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/aio_context_state.go b/pkg/sentry/mm/aio_context_state.go index 1a5e56f8e..192a6f744 100644 --- a/pkg/sentry/mm/aio_context_state.go +++ b/pkg/sentry/mm/aio_context_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/debug.go b/pkg/sentry/mm/debug.go index 56d0490f0..d341b9c07 100644 --- a/pkg/sentry/mm/debug.go +++ b/pkg/sentry/mm/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/io.go b/pkg/sentry/mm/io.go index 6741db594..6600ddd78 100644 --- a/pkg/sentry/mm/io.go +++ b/pkg/sentry/mm/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/lifecycle.go b/pkg/sentry/mm/lifecycle.go index a4b5cb443..b248b76e7 100644 --- a/pkg/sentry/mm/lifecycle.go +++ b/pkg/sentry/mm/lifecycle.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/metadata.go b/pkg/sentry/mm/metadata.go index 32d5e2ff6..5ef1ba0b1 100644 --- a/pkg/sentry/mm/metadata.go +++ b/pkg/sentry/mm/metadata.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index 3299ae164..aab697f9e 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/mm_test.go b/pkg/sentry/mm/mm_test.go index b47aa7263..f2db43196 100644 --- a/pkg/sentry/mm/mm_test.go +++ b/pkg/sentry/mm/mm_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/pma.go b/pkg/sentry/mm/pma.go index 9febb25ac..5690fe6b4 100644 --- a/pkg/sentry/mm/pma.go +++ b/pkg/sentry/mm/pma.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/proc_pid_maps.go b/pkg/sentry/mm/proc_pid_maps.go index 5840b257c..0bf1cdb51 100644 --- a/pkg/sentry/mm/proc_pid_maps.go +++ b/pkg/sentry/mm/proc_pid_maps.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/save_restore.go b/pkg/sentry/mm/save_restore.go index 36fed8f1c..6e7080a84 100644 --- a/pkg/sentry/mm/save_restore.go +++ b/pkg/sentry/mm/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/shm.go b/pkg/sentry/mm/shm.go index bab137a5a..3bc48c7e7 100644 --- a/pkg/sentry/mm/shm.go +++ b/pkg/sentry/mm/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go index 5d7bd33bd..e511472f4 100644 --- a/pkg/sentry/mm/special_mappable.go +++ b/pkg/sentry/mm/special_mappable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index b0622b0c3..a721cc456 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index b81e861f1..dafdbd0e4 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/context.go b/pkg/sentry/platform/context.go index 0d200a5e2..cca21a23e 100644 --- a/pkg/sentry/platform/context.go +++ b/pkg/sentry/platform/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/filemem/filemem.go b/pkg/sentry/platform/filemem/filemem.go index f278c8d63..97da31e70 100644 --- a/pkg/sentry/platform/filemem/filemem.go +++ b/pkg/sentry/platform/filemem/filemem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/filemem/filemem_state.go b/pkg/sentry/platform/filemem/filemem_state.go index e28e021c9..964e2aaaa 100644 --- a/pkg/sentry/platform/filemem/filemem_state.go +++ b/pkg/sentry/platform/filemem/filemem_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/filemem/filemem_test.go b/pkg/sentry/platform/filemem/filemem_test.go index 4b165dc48..9becec25f 100644 --- a/pkg/sentry/platform/filemem/filemem_test.go +++ b/pkg/sentry/platform/filemem/filemem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/filemem/filemem_unsafe.go b/pkg/sentry/platform/filemem/filemem_unsafe.go index a23b9825a..776aed74d 100644 --- a/pkg/sentry/platform/filemem/filemem_unsafe.go +++ b/pkg/sentry/platform/filemem/filemem_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/interrupt/interrupt.go b/pkg/sentry/platform/interrupt/interrupt.go index ca4f42087..9c83f41eb 100644 --- a/pkg/sentry/platform/interrupt/interrupt.go +++ b/pkg/sentry/platform/interrupt/interrupt.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/interrupt/interrupt_test.go b/pkg/sentry/platform/interrupt/interrupt_test.go index 7c49eeea6..fb3284395 100644 --- a/pkg/sentry/platform/interrupt/interrupt_test.go +++ b/pkg/sentry/platform/interrupt/interrupt_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/address_space.go b/pkg/sentry/platform/kvm/address_space.go index c4293c517..72e897a9a 100644 --- a/pkg/sentry/platform/kvm/address_space.go +++ b/pkg/sentry/platform/kvm/address_space.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/allocator.go b/pkg/sentry/platform/kvm/allocator.go index f5cebd5b3..b25cad155 100644 --- a/pkg/sentry/platform/kvm/allocator.go +++ b/pkg/sentry/platform/kvm/allocator.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill.go b/pkg/sentry/platform/kvm/bluepill.go index ecc33d7dd..9f1c9510b 100644 --- a/pkg/sentry/platform/kvm/bluepill.go +++ b/pkg/sentry/platform/kvm/bluepill.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.go b/pkg/sentry/platform/kvm/bluepill_amd64.go index b364e3ef7..f013d1dc9 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.s b/pkg/sentry/platform/kvm/bluepill_amd64.s index 0881bd5f5..ec017f6c2 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.s +++ b/pkg/sentry/platform/kvm/bluepill_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go index 61ca61dcb..cd00a47f2 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_fault.go b/pkg/sentry/platform/kvm/bluepill_fault.go index 8650cd78f..e79a30ef2 100644 --- a/pkg/sentry/platform/kvm/bluepill_fault.go +++ b/pkg/sentry/platform/kvm/bluepill_fault.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_unsafe.go b/pkg/sentry/platform/kvm/bluepill_unsafe.go index 216d4b4b6..747a95997 100644 --- a/pkg/sentry/platform/kvm/bluepill_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/context.go b/pkg/sentry/platform/kvm/context.go index aac84febf..be902be88 100644 --- a/pkg/sentry/platform/kvm/context.go +++ b/pkg/sentry/platform/kvm/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/host_map.go b/pkg/sentry/platform/kvm/host_map.go index fc16ad2de..ee6a1a42d 100644 --- a/pkg/sentry/platform/kvm/host_map.go +++ b/pkg/sentry/platform/kvm/host_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm.go b/pkg/sentry/platform/kvm/kvm.go index 0c4dff308..d4f50024d 100644 --- a/pkg/sentry/platform/kvm/kvm.go +++ b/pkg/sentry/platform/kvm/kvm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm_amd64.go b/pkg/sentry/platform/kvm/kvm_amd64.go index 3d56ed895..70d0ac63b 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64.go +++ b/pkg/sentry/platform/kvm/kvm_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go index 476e783a0..c0a0af92d 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm_const.go b/pkg/sentry/platform/kvm/kvm_const.go index ca44c31b3..8c53c6f06 100644 --- a/pkg/sentry/platform/kvm/kvm_const.go +++ b/pkg/sentry/platform/kvm/kvm_const.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm_test.go b/pkg/sentry/platform/kvm/kvm_test.go index 52448839f..45eeb96ff 100644 --- a/pkg/sentry/platform/kvm/kvm_test.go +++ b/pkg/sentry/platform/kvm/kvm_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index 9f60b6b31..fc7ad258f 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go index bcd29a947..e0aec42b8 100644 --- a/pkg/sentry/platform/kvm/machine_amd64.go +++ b/pkg/sentry/platform/kvm/machine_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go index 8b9041f13..50e513f3b 100644 --- a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/machine_unsafe.go b/pkg/sentry/platform/kvm/machine_unsafe.go index 86323c891..4f5b01321 100644 --- a/pkg/sentry/platform/kvm/machine_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/physical_map.go b/pkg/sentry/platform/kvm/physical_map.go index 81a98656d..b908cae6a 100644 --- a/pkg/sentry/platform/kvm/physical_map.go +++ b/pkg/sentry/platform/kvm/physical_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/testutil/testutil.go b/pkg/sentry/platform/kvm/testutil/testutil.go index 8a614e25d..0d496561d 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil.go +++ b/pkg/sentry/platform/kvm/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/testutil/testutil_amd64.go b/pkg/sentry/platform/kvm/testutil/testutil_amd64.go index 39286a0af..fcba33813 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_amd64.go +++ b/pkg/sentry/platform/kvm/testutil/testutil_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/testutil/testutil_amd64.s b/pkg/sentry/platform/kvm/testutil/testutil_amd64.s index 3b5ad8817..f1da41a44 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_amd64.s +++ b/pkg/sentry/platform/kvm/testutil/testutil_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/virtual_map.go b/pkg/sentry/platform/kvm/virtual_map.go index 0d3fbe043..0343e9267 100644 --- a/pkg/sentry/platform/kvm/virtual_map.go +++ b/pkg/sentry/platform/kvm/virtual_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/virtual_map_test.go b/pkg/sentry/platform/kvm/virtual_map_test.go index 7875bd3e9..935e0eb93 100644 --- a/pkg/sentry/platform/kvm/virtual_map_test.go +++ b/pkg/sentry/platform/kvm/virtual_map_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/mmap_min_addr.go b/pkg/sentry/platform/mmap_min_addr.go index 6398e5e01..1bcc1f8e9 100644 --- a/pkg/sentry/platform/mmap_min_addr.go +++ b/pkg/sentry/platform/mmap_min_addr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go index 8a1620d93..f16588e6e 100644 --- a/pkg/sentry/platform/platform.go +++ b/pkg/sentry/platform/platform.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/procid/procid.go b/pkg/sentry/platform/procid/procid.go index 5f861908f..3f49ab093 100644 --- a/pkg/sentry/platform/procid/procid.go +++ b/pkg/sentry/platform/procid/procid.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/procid/procid_amd64.s b/pkg/sentry/platform/procid/procid_amd64.s index 5b1ba1f24..fd88ce82e 100644 --- a/pkg/sentry/platform/procid/procid_amd64.s +++ b/pkg/sentry/platform/procid/procid_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/procid/procid_net_test.go b/pkg/sentry/platform/procid/procid_net_test.go index 2d1605a08..e8dcc479d 100644 --- a/pkg/sentry/platform/procid/procid_net_test.go +++ b/pkg/sentry/platform/procid/procid_net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/procid/procid_test.go b/pkg/sentry/platform/procid/procid_test.go index 5e44da36f..7a57c7cdc 100644 --- a/pkg/sentry/platform/procid/procid_test.go +++ b/pkg/sentry/platform/procid/procid_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/ptrace.go b/pkg/sentry/platform/ptrace/ptrace.go index 4f20716f7..00d92b092 100644 --- a/pkg/sentry/platform/ptrace/ptrace.go +++ b/pkg/sentry/platform/ptrace/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/ptrace_unsafe.go b/pkg/sentry/platform/ptrace/ptrace_unsafe.go index 46a8bda8e..7a3cb8f49 100644 --- a/pkg/sentry/platform/ptrace/ptrace_unsafe.go +++ b/pkg/sentry/platform/ptrace/ptrace_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/stub_amd64.s b/pkg/sentry/platform/ptrace/stub_amd64.s index 9bf87b6f6..63f98e40d 100644 --- a/pkg/sentry/platform/ptrace/stub_amd64.s +++ b/pkg/sentry/platform/ptrace/stub_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/stub_unsafe.go b/pkg/sentry/platform/ptrace/stub_unsafe.go index c868a2d68..48c16c4a1 100644 --- a/pkg/sentry/platform/ptrace/stub_unsafe.go +++ b/pkg/sentry/platform/ptrace/stub_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess.go b/pkg/sentry/platform/ptrace/subprocess.go index 6d5ad6b71..6a9da5db8 100644 --- a/pkg/sentry/platform/ptrace/subprocess.go +++ b/pkg/sentry/platform/ptrace/subprocess.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess_amd64.go b/pkg/sentry/platform/ptrace/subprocess_amd64.go index c38dc1ff8..d23a1133e 100644 --- a/pkg/sentry/platform/ptrace/subprocess_amd64.go +++ b/pkg/sentry/platform/ptrace/subprocess_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index 53adadadd..7523487e7 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go b/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go index 697431472..0c9263060 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess_unsafe.go b/pkg/sentry/platform/ptrace/subprocess_unsafe.go index fe41641d3..ca6c4ac97 100644 --- a/pkg/sentry/platform/ptrace/subprocess_unsafe.go +++ b/pkg/sentry/platform/ptrace/subprocess_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/defs.go b/pkg/sentry/platform/ring0/defs.go index f09d045eb..18137e55d 100644 --- a/pkg/sentry/platform/ring0/defs.go +++ b/pkg/sentry/platform/ring0/defs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/defs_amd64.go b/pkg/sentry/platform/ring0/defs_amd64.go index 84819f132..67242b92b 100644 --- a/pkg/sentry/platform/ring0/defs_amd64.go +++ b/pkg/sentry/platform/ring0/defs_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/entry_amd64.go b/pkg/sentry/platform/ring0/entry_amd64.go index a3e992e0d..4a9affe64 100644 --- a/pkg/sentry/platform/ring0/entry_amd64.go +++ b/pkg/sentry/platform/ring0/entry_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/entry_amd64.s b/pkg/sentry/platform/ring0/entry_amd64.s index 08c15ad65..d48fbd2d1 100644 --- a/pkg/sentry/platform/ring0/entry_amd64.s +++ b/pkg/sentry/platform/ring0/entry_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/gen_offsets/main.go b/pkg/sentry/platform/ring0/gen_offsets/main.go index ffa7eaf77..11c49855f 100644 --- a/pkg/sentry/platform/ring0/gen_offsets/main.go +++ b/pkg/sentry/platform/ring0/gen_offsets/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/kernel.go b/pkg/sentry/platform/ring0/kernel.go index 62e67005e..e70eafde2 100644 --- a/pkg/sentry/platform/ring0/kernel.go +++ b/pkg/sentry/platform/ring0/kernel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/kernel_amd64.go b/pkg/sentry/platform/ring0/kernel_amd64.go index 0d2b0f7dc..ab562bca7 100644 --- a/pkg/sentry/platform/ring0/kernel_amd64.go +++ b/pkg/sentry/platform/ring0/kernel_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/kernel_unsafe.go b/pkg/sentry/platform/ring0/kernel_unsafe.go index cfb3ad853..faf4240e5 100644 --- a/pkg/sentry/platform/ring0/kernel_unsafe.go +++ b/pkg/sentry/platform/ring0/kernel_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/lib_amd64.go b/pkg/sentry/platform/ring0/lib_amd64.go index 989e3e383..2b95a0141 100644 --- a/pkg/sentry/platform/ring0/lib_amd64.go +++ b/pkg/sentry/platform/ring0/lib_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/lib_amd64.s b/pkg/sentry/platform/ring0/lib_amd64.s index 6f143ea5a..98a130525 100644 --- a/pkg/sentry/platform/ring0/lib_amd64.s +++ b/pkg/sentry/platform/ring0/lib_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/offsets_amd64.go b/pkg/sentry/platform/ring0/offsets_amd64.go index ca5fd456b..753d31ef8 100644 --- a/pkg/sentry/platform/ring0/offsets_amd64.go +++ b/pkg/sentry/platform/ring0/offsets_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/allocator.go b/pkg/sentry/platform/ring0/pagetables/allocator.go index 049fd0247..ee6e90a11 100644 --- a/pkg/sentry/platform/ring0/pagetables/allocator.go +++ b/pkg/sentry/platform/ring0/pagetables/allocator.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go index aca778913..f48647b3a 100644 --- a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go +++ b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables.go b/pkg/sentry/platform/ring0/pagetables/pagetables.go index ff5787f89..c7207ec18 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go index 878463018..746f614e5 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go index a7f2ad9a4..2f82c4353 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go index dca3f69ef..3e5dc7dc7 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go index ca49d20f8..6bd8c3584 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pcids_x86.go b/pkg/sentry/platform/ring0/pagetables/pcids_x86.go index fa068e35e..0d9a51aa5 100644 --- a/pkg/sentry/platform/ring0/pagetables/pcids_x86.go +++ b/pkg/sentry/platform/ring0/pagetables/pcids_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/walker_amd64.go b/pkg/sentry/platform/ring0/pagetables/walker_amd64.go index afa4d473a..c4c71d23e 100644 --- a/pkg/sentry/platform/ring0/pagetables/walker_amd64.go +++ b/pkg/sentry/platform/ring0/pagetables/walker_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/ring0.go b/pkg/sentry/platform/ring0/ring0.go index 4991031c5..10c51e88d 100644 --- a/pkg/sentry/platform/ring0/ring0.go +++ b/pkg/sentry/platform/ring0/ring0.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/x86.go b/pkg/sentry/platform/ring0/x86.go index f489fcecb..7c88010d8 100644 --- a/pkg/sentry/platform/ring0/x86.go +++ b/pkg/sentry/platform/ring0/x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/atomic_amd64.s b/pkg/sentry/platform/safecopy/atomic_amd64.s index 69947dec3..873ffa046 100644 --- a/pkg/sentry/platform/safecopy/atomic_amd64.s +++ b/pkg/sentry/platform/safecopy/atomic_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/memclr_amd64.s b/pkg/sentry/platform/safecopy/memclr_amd64.s index 7d1019f60..488b6e666 100644 --- a/pkg/sentry/platform/safecopy/memclr_amd64.s +++ b/pkg/sentry/platform/safecopy/memclr_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/memcpy_amd64.s b/pkg/sentry/platform/safecopy/memcpy_amd64.s index 96ef2eefc..0bf26fd7b 100644 --- a/pkg/sentry/platform/safecopy/memcpy_amd64.s +++ b/pkg/sentry/platform/safecopy/memcpy_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/safecopy.go b/pkg/sentry/platform/safecopy/safecopy.go index 90a2aad7b..c60f73103 100644 --- a/pkg/sentry/platform/safecopy/safecopy.go +++ b/pkg/sentry/platform/safecopy/safecopy.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/safecopy_test.go b/pkg/sentry/platform/safecopy/safecopy_test.go index 67df36121..1a682d28a 100644 --- a/pkg/sentry/platform/safecopy/safecopy_test.go +++ b/pkg/sentry/platform/safecopy/safecopy_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/safecopy_unsafe.go b/pkg/sentry/platform/safecopy/safecopy_unsafe.go index 72f243f8d..df1c35b66 100644 --- a/pkg/sentry/platform/safecopy/safecopy_unsafe.go +++ b/pkg/sentry/platform/safecopy/safecopy_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/sighandler_amd64.s b/pkg/sentry/platform/safecopy/sighandler_amd64.s index a65cb0c26..06614f1b4 100644 --- a/pkg/sentry/platform/safecopy/sighandler_amd64.s +++ b/pkg/sentry/platform/safecopy/sighandler_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/block_unsafe.go b/pkg/sentry/safemem/block_unsafe.go index 0b58f6497..e91ff66ae 100644 --- a/pkg/sentry/safemem/block_unsafe.go +++ b/pkg/sentry/safemem/block_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/io.go b/pkg/sentry/safemem/io.go index fd917648b..6cb52439f 100644 --- a/pkg/sentry/safemem/io.go +++ b/pkg/sentry/safemem/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/io_test.go b/pkg/sentry/safemem/io_test.go index edac4c1d7..2eda8c3bb 100644 --- a/pkg/sentry/safemem/io_test.go +++ b/pkg/sentry/safemem/io_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/safemem.go b/pkg/sentry/safemem/safemem.go index 2f8002004..090932d3e 100644 --- a/pkg/sentry/safemem/safemem.go +++ b/pkg/sentry/safemem/safemem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/seq_test.go b/pkg/sentry/safemem/seq_test.go index 3e83b3851..fddcaf714 100644 --- a/pkg/sentry/safemem/seq_test.go +++ b/pkg/sentry/safemem/seq_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/seq_unsafe.go b/pkg/sentry/safemem/seq_unsafe.go index e0d29a0b3..83a6b7183 100644 --- a/pkg/sentry/safemem/seq_unsafe.go +++ b/pkg/sentry/safemem/seq_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/sighandling/sighandling.go b/pkg/sentry/sighandling/sighandling.go index 29bcf55ab..6b5d5f993 100644 --- a/pkg/sentry/sighandling/sighandling.go +++ b/pkg/sentry/sighandling/sighandling.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/sighandling/sighandling_unsafe.go b/pkg/sentry/sighandling/sighandling_unsafe.go index a455b919f..5913d47a8 100644 --- a/pkg/sentry/sighandling/sighandling_unsafe.go +++ b/pkg/sentry/sighandling/sighandling_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index db97e95f2..d44f5e88a 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/device.go b/pkg/sentry/socket/epsocket/device.go index 17f2c9559..3cc138eb0 100644 --- a/pkg/sentry/socket/epsocket/device.go +++ b/pkg/sentry/socket/epsocket/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 47c575e7b..e90ef4835 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/provider.go b/pkg/sentry/socket/epsocket/provider.go index dbc232d26..686554437 100644 --- a/pkg/sentry/socket/epsocket/provider.go +++ b/pkg/sentry/socket/epsocket/provider.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/save_restore.go b/pkg/sentry/socket/epsocket/save_restore.go index 2613f90de..34d9a7cf0 100644 --- a/pkg/sentry/socket/epsocket/save_restore.go +++ b/pkg/sentry/socket/epsocket/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index e4ed52fc8..c0081c819 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/device.go b/pkg/sentry/socket/hostinet/device.go index a9a673316..c5133f3bb 100644 --- a/pkg/sentry/socket/hostinet/device.go +++ b/pkg/sentry/socket/hostinet/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/hostinet.go b/pkg/sentry/socket/hostinet/hostinet.go index 67c6c8066..7858892ab 100644 --- a/pkg/sentry/socket/hostinet/hostinet.go +++ b/pkg/sentry/socket/hostinet/hostinet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/save_restore.go b/pkg/sentry/socket/hostinet/save_restore.go index 0821a794a..3827f082a 100644 --- a/pkg/sentry/socket/hostinet/save_restore.go +++ b/pkg/sentry/socket/hostinet/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index e82624b44..e4e950fbb 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/socket_unsafe.go b/pkg/sentry/socket/hostinet/socket_unsafe.go index f8bb75636..59c8910ca 100644 --- a/pkg/sentry/socket/hostinet/socket_unsafe.go +++ b/pkg/sentry/socket/hostinet/socket_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/stack.go b/pkg/sentry/socket/hostinet/stack.go index f64809d39..4ce73c1f1 100644 --- a/pkg/sentry/socket/hostinet/stack.go +++ b/pkg/sentry/socket/hostinet/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/message.go b/pkg/sentry/socket/netlink/message.go index b902d7ec9..a95172cba 100644 --- a/pkg/sentry/socket/netlink/message.go +++ b/pkg/sentry/socket/netlink/message.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/port/port.go b/pkg/sentry/socket/netlink/port/port.go index 1c5d4c3a5..20b9a6e37 100644 --- a/pkg/sentry/socket/netlink/port/port.go +++ b/pkg/sentry/socket/netlink/port/port.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/port/port_test.go b/pkg/sentry/socket/netlink/port/port_test.go index 34565e2f9..49b3b48ab 100644 --- a/pkg/sentry/socket/netlink/port/port_test.go +++ b/pkg/sentry/socket/netlink/port/port_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/provider.go b/pkg/sentry/socket/netlink/provider.go index 5d0a04a07..06786bd50 100644 --- a/pkg/sentry/socket/netlink/provider.go +++ b/pkg/sentry/socket/netlink/provider.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index 70322b9ed..7e70b09b2 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index 0c03997f2..4d4130a4c 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/conn/conn.go b/pkg/sentry/socket/rpcinet/conn/conn.go index f4c8489b1..9c749b888 100644 --- a/pkg/sentry/socket/rpcinet/conn/conn.go +++ b/pkg/sentry/socket/rpcinet/conn/conn.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/device.go b/pkg/sentry/socket/rpcinet/device.go index f7b63436e..d2b9f9222 100644 --- a/pkg/sentry/socket/rpcinet/device.go +++ b/pkg/sentry/socket/rpcinet/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/notifier/notifier.go b/pkg/sentry/socket/rpcinet/notifier/notifier.go index f88a908ed..73c255c33 100644 --- a/pkg/sentry/socket/rpcinet/notifier/notifier.go +++ b/pkg/sentry/socket/rpcinet/notifier/notifier.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/rpcinet.go b/pkg/sentry/socket/rpcinet/rpcinet.go index 10b0dedc2..6c98e6acb 100644 --- a/pkg/sentry/socket/rpcinet/rpcinet.go +++ b/pkg/sentry/socket/rpcinet/rpcinet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index c7e761d54..44fa5c620 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/stack.go b/pkg/sentry/socket/rpcinet/stack.go index bcb89fb34..cb8344ec6 100644 --- a/pkg/sentry/socket/rpcinet/stack.go +++ b/pkg/sentry/socket/rpcinet/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/stack_unsafe.go b/pkg/sentry/socket/rpcinet/stack_unsafe.go index 9a896c623..d04fb2069 100644 --- a/pkg/sentry/socket/rpcinet/stack_unsafe.go +++ b/pkg/sentry/socket/rpcinet/stack_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index 31f8d42d7..a235c5249 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/device.go b/pkg/sentry/socket/unix/device.go index e8bcc7a9f..41820dbb3 100644 --- a/pkg/sentry/socket/unix/device.go +++ b/pkg/sentry/socket/unix/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/io.go b/pkg/sentry/socket/unix/io.go index 06333e14b..7d6434696 100644 --- a/pkg/sentry/socket/unix/io.go +++ b/pkg/sentry/socket/unix/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/connectioned.go b/pkg/sentry/socket/unix/transport/connectioned.go index 566e3d57b..4c913effc 100644 --- a/pkg/sentry/socket/unix/transport/connectioned.go +++ b/pkg/sentry/socket/unix/transport/connectioned.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/connectioned_state.go b/pkg/sentry/socket/unix/transport/connectioned_state.go index 7e6c73dcc..608a6a97a 100644 --- a/pkg/sentry/socket/unix/transport/connectioned_state.go +++ b/pkg/sentry/socket/unix/transport/connectioned_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/connectionless.go b/pkg/sentry/socket/unix/transport/connectionless.go index 86cd05199..cd4633106 100644 --- a/pkg/sentry/socket/unix/transport/connectionless.go +++ b/pkg/sentry/socket/unix/transport/connectionless.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/queue.go b/pkg/sentry/socket/unix/transport/queue.go index c4d7d863c..5b4dfab68 100644 --- a/pkg/sentry/socket/unix/transport/queue.go +++ b/pkg/sentry/socket/unix/transport/queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/unix.go b/pkg/sentry/socket/unix/transport/unix.go index 2934101a2..157133b65 100644 --- a/pkg/sentry/socket/unix/transport/unix.go +++ b/pkg/sentry/socket/unix/transport/unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 668363864..3543dd81f 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/state/state.go b/pkg/sentry/state/state.go index 43e88a713..70b33f190 100644 --- a/pkg/sentry/state/state.go +++ b/pkg/sentry/state/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/state/state_metadata.go b/pkg/sentry/state/state_metadata.go index afa21672a..7f047b808 100644 --- a/pkg/sentry/state/state_metadata.go +++ b/pkg/sentry/state/state_metadata.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/state/state_unsafe.go b/pkg/sentry/state/state_unsafe.go index 3ff7d24c8..f02e12b2a 100644 --- a/pkg/sentry/state/state_unsafe.go +++ b/pkg/sentry/state/state_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/clone.go b/pkg/sentry/strace/clone.go index b82ca1ad1..e18ce84dc 100644 --- a/pkg/sentry/strace/clone.go +++ b/pkg/sentry/strace/clone.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/futex.go b/pkg/sentry/strace/futex.go index 3da108cb7..ceb3dc21d 100644 --- a/pkg/sentry/strace/futex.go +++ b/pkg/sentry/strace/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/linux64.go b/pkg/sentry/strace/linux64.go index 1df148e7d..99714f12c 100644 --- a/pkg/sentry/strace/linux64.go +++ b/pkg/sentry/strace/linux64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/open.go b/pkg/sentry/strace/open.go index 839d5eda7..5a72a940c 100644 --- a/pkg/sentry/strace/open.go +++ b/pkg/sentry/strace/open.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/ptrace.go b/pkg/sentry/strace/ptrace.go index fcdb7e9f4..c572aafb4 100644 --- a/pkg/sentry/strace/ptrace.go +++ b/pkg/sentry/strace/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/socket.go b/pkg/sentry/strace/socket.go index 26831edd6..375418dc1 100644 --- a/pkg/sentry/strace/socket.go +++ b/pkg/sentry/strace/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index f7bfa3a1f..4286f0df7 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/strace.proto b/pkg/sentry/strace/strace.proto index 914e8c7b0..f1fc539d6 100644 --- a/pkg/sentry/strace/strace.proto +++ b/pkg/sentry/strace/strace.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/syscalls.go b/pkg/sentry/strace/syscalls.go index 8be4fa318..9eeb18a03 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/epoll.go b/pkg/sentry/syscalls/epoll.go index 01dd6fa71..b90d191b7 100644 --- a/pkg/sentry/syscalls/epoll.go +++ b/pkg/sentry/syscalls/epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go index 013b385bc..9fd002955 100644 --- a/pkg/sentry/syscalls/linux/error.go +++ b/pkg/sentry/syscalls/linux/error.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go index f01483cd3..d1e0833fc 100644 --- a/pkg/sentry/syscalls/linux/flags.go +++ b/pkg/sentry/syscalls/linux/flags.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 4465549ad..75e87f5ec 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sigset.go b/pkg/sentry/syscalls/linux/sigset.go index bfb541634..a033b7c70 100644 --- a/pkg/sentry/syscalls/linux/sigset.go +++ b/pkg/sentry/syscalls/linux/sigset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go index 54e4afa9e..355071131 100644 --- a/pkg/sentry/syscalls/linux/sys_aio.go +++ b/pkg/sentry/syscalls/linux/sys_aio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_capability.go b/pkg/sentry/syscalls/linux/sys_capability.go index 89c81ac90..cf972dc28 100644 --- a/pkg/sentry/syscalls/linux/sys_capability.go +++ b/pkg/sentry/syscalls/linux/sys_capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_epoll.go b/pkg/sentry/syscalls/linux/sys_epoll.go index e69dfc77a..62272efcd 100644 --- a/pkg/sentry/syscalls/linux/sys_epoll.go +++ b/pkg/sentry/syscalls/linux/sys_epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_eventfd.go b/pkg/sentry/syscalls/linux/sys_eventfd.go index 60fe5a133..903172890 100644 --- a/pkg/sentry/syscalls/linux/sys_eventfd.go +++ b/pkg/sentry/syscalls/linux/sys_eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 64704bb88..a70f35be0 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go index d35dcecbe..cf04428bc 100644 --- a/pkg/sentry/syscalls/linux/sys_futex.go +++ b/pkg/sentry/syscalls/linux/sys_futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_getdents.go b/pkg/sentry/syscalls/linux/sys_getdents.go index 29c0d7a39..4b441b31b 100644 --- a/pkg/sentry/syscalls/linux/sys_getdents.go +++ b/pkg/sentry/syscalls/linux/sys_getdents.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_identity.go b/pkg/sentry/syscalls/linux/sys_identity.go index 4fd0ed794..8d594aa83 100644 --- a/pkg/sentry/syscalls/linux/sys_identity.go +++ b/pkg/sentry/syscalls/linux/sys_identity.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_inotify.go b/pkg/sentry/syscalls/linux/sys_inotify.go index 725204dff..26a505782 100644 --- a/pkg/sentry/syscalls/linux/sys_inotify.go +++ b/pkg/sentry/syscalls/linux/sys_inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_lseek.go b/pkg/sentry/syscalls/linux/sys_lseek.go index 97b51ba7c..ad3bfd761 100644 --- a/pkg/sentry/syscalls/linux/sys_lseek.go +++ b/pkg/sentry/syscalls/linux/sys_lseek.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 1a98328dc..f8d9c43fd 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_mount.go b/pkg/sentry/syscalls/linux/sys_mount.go index 57cedccc1..bf0df7302 100644 --- a/pkg/sentry/syscalls/linux/sys_mount.go +++ b/pkg/sentry/syscalls/linux/sys_mount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_pipe.go b/pkg/sentry/syscalls/linux/sys_pipe.go index 2b544f145..3652c429e 100644 --- a/pkg/sentry/syscalls/linux/sys_pipe.go +++ b/pkg/sentry/syscalls/linux/sys_pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_poll.go b/pkg/sentry/syscalls/linux/sys_poll.go index b9bdefadb..bf0958435 100644 --- a/pkg/sentry/syscalls/linux/sys_poll.go +++ b/pkg/sentry/syscalls/linux/sys_poll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_prctl.go b/pkg/sentry/syscalls/linux/sys_prctl.go index a1242acd3..c7b39ede8 100644 --- a/pkg/sentry/syscalls/linux/sys_prctl.go +++ b/pkg/sentry/syscalls/linux/sys_prctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_random.go b/pkg/sentry/syscalls/linux/sys_random.go index be31e6b17..452dff058 100644 --- a/pkg/sentry/syscalls/linux/sys_random.go +++ b/pkg/sentry/syscalls/linux/sys_random.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go index 0be2d195a..b2e5a5449 100644 --- a/pkg/sentry/syscalls/linux/sys_read.go +++ b/pkg/sentry/syscalls/linux/sys_read.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_rlimit.go b/pkg/sentry/syscalls/linux/sys_rlimit.go index d806b58ab..2f16e1791 100644 --- a/pkg/sentry/syscalls/linux/sys_rlimit.go +++ b/pkg/sentry/syscalls/linux/sys_rlimit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_rusage.go b/pkg/sentry/syscalls/linux/sys_rusage.go index 82e42b589..ab07c77f9 100644 --- a/pkg/sentry/syscalls/linux/sys_rusage.go +++ b/pkg/sentry/syscalls/linux/sys_rusage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_sched.go b/pkg/sentry/syscalls/linux/sys_sched.go index ff9e46077..e679a6694 100644 --- a/pkg/sentry/syscalls/linux/sys_sched.go +++ b/pkg/sentry/syscalls/linux/sys_sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_seccomp.go b/pkg/sentry/syscalls/linux/sys_seccomp.go index 4323a4df4..969acaa36 100644 --- a/pkg/sentry/syscalls/linux/sys_seccomp.go +++ b/pkg/sentry/syscalls/linux/sys_seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_sem.go b/pkg/sentry/syscalls/linux/sys_sem.go index a8983705b..4ed52c4a7 100644 --- a/pkg/sentry/syscalls/linux/sys_sem.go +++ b/pkg/sentry/syscalls/linux/sys_sem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_shm.go b/pkg/sentry/syscalls/linux/sys_shm.go index 48ff1d5f0..b13d48b98 100644 --- a/pkg/sentry/syscalls/linux/sys_shm.go +++ b/pkg/sentry/syscalls/linux/sys_shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_signal.go b/pkg/sentry/syscalls/linux/sys_signal.go index ecdec5d3a..a539354c5 100644 --- a/pkg/sentry/syscalls/linux/sys_signal.go +++ b/pkg/sentry/syscalls/linux/sys_signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go index 5fa5ddce6..0a7551742 100644 --- a/pkg/sentry/syscalls/linux/sys_socket.go +++ b/pkg/sentry/syscalls/linux/sys_socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_stat.go b/pkg/sentry/syscalls/linux/sys_stat.go index 619a14d7c..9c433c45d 100644 --- a/pkg/sentry/syscalls/linux/sys_stat.go +++ b/pkg/sentry/syscalls/linux/sys_stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_sync.go b/pkg/sentry/syscalls/linux/sys_sync.go index 902d210db..826c6869d 100644 --- a/pkg/sentry/syscalls/linux/sys_sync.go +++ b/pkg/sentry/syscalls/linux/sys_sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_sysinfo.go b/pkg/sentry/syscalls/linux/sys_sysinfo.go index 6560bac57..5eeb3ba58 100644 --- a/pkg/sentry/syscalls/linux/sys_sysinfo.go +++ b/pkg/sentry/syscalls/linux/sys_sysinfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_syslog.go b/pkg/sentry/syscalls/linux/sys_syslog.go index 792040c81..7193b7aed 100644 --- a/pkg/sentry/syscalls/linux/sys_syslog.go +++ b/pkg/sentry/syscalls/linux/sys_syslog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go index 550f63a43..820ca680e 100644 --- a/pkg/sentry/syscalls/linux/sys_thread.go +++ b/pkg/sentry/syscalls/linux/sys_thread.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_time.go b/pkg/sentry/syscalls/linux/sys_time.go index 8e6683444..063fbb106 100644 --- a/pkg/sentry/syscalls/linux/sys_time.go +++ b/pkg/sentry/syscalls/linux/sys_time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_timer.go b/pkg/sentry/syscalls/linux/sys_timer.go index c41074d54..6baf4599b 100644 --- a/pkg/sentry/syscalls/linux/sys_timer.go +++ b/pkg/sentry/syscalls/linux/sys_timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_timerfd.go b/pkg/sentry/syscalls/linux/sys_timerfd.go index 92c6a3d60..f70d13682 100644 --- a/pkg/sentry/syscalls/linux/sys_timerfd.go +++ b/pkg/sentry/syscalls/linux/sys_timerfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_tls.go b/pkg/sentry/syscalls/linux/sys_tls.go index b95d62320..27ddb3808 100644 --- a/pkg/sentry/syscalls/linux/sys_tls.go +++ b/pkg/sentry/syscalls/linux/sys_tls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_utsname.go b/pkg/sentry/syscalls/linux/sys_utsname.go index 899116374..689f2f838 100644 --- a/pkg/sentry/syscalls/linux/sys_utsname.go +++ b/pkg/sentry/syscalls/linux/sys_utsname.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_write.go b/pkg/sentry/syscalls/linux/sys_write.go index caa7b01ea..08e263112 100644 --- a/pkg/sentry/syscalls/linux/sys_write.go +++ b/pkg/sentry/syscalls/linux/sys_write.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/timespec.go b/pkg/sentry/syscalls/linux/timespec.go index e865c6fc0..752ec326d 100644 --- a/pkg/sentry/syscalls/linux/timespec.go +++ b/pkg/sentry/syscalls/linux/timespec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/polling.go b/pkg/sentry/syscalls/polling.go index fd90184ef..2b33d6c19 100644 --- a/pkg/sentry/syscalls/polling.go +++ b/pkg/sentry/syscalls/polling.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/syscalls.go b/pkg/sentry/syscalls/syscalls.go index 1176f858d..bae32d727 100644 --- a/pkg/sentry/syscalls/syscalls.go +++ b/pkg/sentry/syscalls/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/unimplemented_syscall.proto b/pkg/sentry/syscalls/unimplemented_syscall.proto index d6febf5b1..41579b016 100644 --- a/pkg/sentry/syscalls/unimplemented_syscall.proto +++ b/pkg/sentry/syscalls/unimplemented_syscall.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/calibrated_clock.go b/pkg/sentry/time/calibrated_clock.go index cbb95e2d7..c8cf4eca4 100644 --- a/pkg/sentry/time/calibrated_clock.go +++ b/pkg/sentry/time/calibrated_clock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/calibrated_clock_test.go b/pkg/sentry/time/calibrated_clock_test.go index 8b6dd5592..a9237630e 100644 --- a/pkg/sentry/time/calibrated_clock_test.go +++ b/pkg/sentry/time/calibrated_clock_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/clock_id.go b/pkg/sentry/time/clock_id.go index 500102e58..1317a5dad 100644 --- a/pkg/sentry/time/clock_id.go +++ b/pkg/sentry/time/clock_id.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/clocks.go b/pkg/sentry/time/clocks.go index 9925b407d..e26386520 100644 --- a/pkg/sentry/time/clocks.go +++ b/pkg/sentry/time/clocks.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/muldiv_amd64.s b/pkg/sentry/time/muldiv_amd64.s index 291940b1d..bfcb8c724 100644 --- a/pkg/sentry/time/muldiv_amd64.s +++ b/pkg/sentry/time/muldiv_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/parameters.go b/pkg/sentry/time/parameters.go index 594b4874b..f3ad58454 100644 --- a/pkg/sentry/time/parameters.go +++ b/pkg/sentry/time/parameters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/parameters_test.go b/pkg/sentry/time/parameters_test.go index 7394fc5ee..4a0c4e880 100644 --- a/pkg/sentry/time/parameters_test.go +++ b/pkg/sentry/time/parameters_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/sampler.go b/pkg/sentry/time/sampler.go index cf581b5fa..445690d49 100644 --- a/pkg/sentry/time/sampler.go +++ b/pkg/sentry/time/sampler.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/sampler_test.go b/pkg/sentry/time/sampler_test.go index caf7e5c53..ec0e442b6 100644 --- a/pkg/sentry/time/sampler_test.go +++ b/pkg/sentry/time/sampler_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/sampler_unsafe.go b/pkg/sentry/time/sampler_unsafe.go index 7ea19d387..0f8eb4fc8 100644 --- a/pkg/sentry/time/sampler_unsafe.go +++ b/pkg/sentry/time/sampler_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/tsc_amd64.s b/pkg/sentry/time/tsc_amd64.s index 4cc604392..e53d477f7 100644 --- a/pkg/sentry/time/tsc_amd64.s +++ b/pkg/sentry/time/tsc_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/uniqueid/context.go b/pkg/sentry/uniqueid/context.go index e48fabc2d..399d98c29 100644 --- a/pkg/sentry/uniqueid/context.go +++ b/pkg/sentry/uniqueid/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/cpu.go b/pkg/sentry/usage/cpu.go index ed7b04b9e..cbd7cfe19 100644 --- a/pkg/sentry/usage/cpu.go +++ b/pkg/sentry/usage/cpu.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/io.go b/pkg/sentry/usage/io.go index 49faa507d..8e27a0a88 100644 --- a/pkg/sentry/usage/io.go +++ b/pkg/sentry/usage/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/memory.go b/pkg/sentry/usage/memory.go index 92a478d85..7e065cb76 100644 --- a/pkg/sentry/usage/memory.go +++ b/pkg/sentry/usage/memory.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/memory_unsafe.go b/pkg/sentry/usage/memory_unsafe.go index f990a7750..a3ae668a5 100644 --- a/pkg/sentry/usage/memory_unsafe.go +++ b/pkg/sentry/usage/memory_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/usage.go b/pkg/sentry/usage/usage.go index 3b3118659..ab327f8e2 100644 --- a/pkg/sentry/usage/usage.go +++ b/pkg/sentry/usage/usage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/access_type.go b/pkg/sentry/usermem/access_type.go index 75346d854..c71d05afe 100644 --- a/pkg/sentry/usermem/access_type.go +++ b/pkg/sentry/usermem/access_type.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/addr.go b/pkg/sentry/usermem/addr.go index fc94bee80..2a75aa60c 100644 --- a/pkg/sentry/usermem/addr.go +++ b/pkg/sentry/usermem/addr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/addr_range_seq_test.go b/pkg/sentry/usermem/addr_range_seq_test.go index cf9d785ed..bd6a1ec8a 100644 --- a/pkg/sentry/usermem/addr_range_seq_test.go +++ b/pkg/sentry/usermem/addr_range_seq_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/addr_range_seq_unsafe.go b/pkg/sentry/usermem/addr_range_seq_unsafe.go index 13b2998b3..f5fd446fa 100644 --- a/pkg/sentry/usermem/addr_range_seq_unsafe.go +++ b/pkg/sentry/usermem/addr_range_seq_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/bytes_io.go b/pkg/sentry/usermem/bytes_io.go index 01a746404..274f568d0 100644 --- a/pkg/sentry/usermem/bytes_io.go +++ b/pkg/sentry/usermem/bytes_io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/bytes_io_unsafe.go b/pkg/sentry/usermem/bytes_io_unsafe.go index efd71fcbc..8bdf3a508 100644 --- a/pkg/sentry/usermem/bytes_io_unsafe.go +++ b/pkg/sentry/usermem/bytes_io_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/usermem.go b/pkg/sentry/usermem/usermem.go index 5d8a1c558..1d6c0b4d6 100644 --- a/pkg/sentry/usermem/usermem.go +++ b/pkg/sentry/usermem/usermem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/usermem_test.go b/pkg/sentry/usermem/usermem_test.go index 563560da8..1991a9641 100644 --- a/pkg/sentry/usermem/usermem_test.go +++ b/pkg/sentry/usermem/usermem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/usermem_x86.go b/pkg/sentry/usermem/usermem_x86.go index 2484b0d82..9ec90f9ff 100644 --- a/pkg/sentry/usermem/usermem_x86.go +++ b/pkg/sentry/usermem/usermem_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/watchdog/watchdog.go b/pkg/sentry/watchdog/watchdog.go index 5b620693d..75b11237f 100644 --- a/pkg/sentry/watchdog/watchdog.go +++ b/pkg/sentry/watchdog/watchdog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/commit_amd64.s b/pkg/sleep/commit_amd64.s index d525e5b79..d08df7f37 100644 --- a/pkg/sleep/commit_amd64.s +++ b/pkg/sleep/commit_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/commit_asm.go b/pkg/sleep/commit_asm.go index 39a55df7e..90eef4cbc 100644 --- a/pkg/sleep/commit_asm.go +++ b/pkg/sleep/commit_asm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/commit_noasm.go b/pkg/sleep/commit_noasm.go index 584866cd8..967d22e24 100644 --- a/pkg/sleep/commit_noasm.go +++ b/pkg/sleep/commit_noasm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/empty.s b/pkg/sleep/empty.s index 8aca31bee..85d52cd9c 100644 --- a/pkg/sleep/empty.s +++ b/pkg/sleep/empty.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/sleep_test.go b/pkg/sleep/sleep_test.go index bc1738371..8feb9ffc2 100644 --- a/pkg/sleep/sleep_test.go +++ b/pkg/sleep/sleep_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/sleep_unsafe.go b/pkg/sleep/sleep_unsafe.go index b12cce681..45fb6f0ea 100644 --- a/pkg/sleep/sleep_unsafe.go +++ b/pkg/sleep/sleep_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/decode.go b/pkg/state/decode.go index 3ef59610b..54b5ad8b8 100644 --- a/pkg/state/decode.go +++ b/pkg/state/decode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/encode.go b/pkg/state/encode.go index fd052db12..577aaf051 100644 --- a/pkg/state/encode.go +++ b/pkg/state/encode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/encode_unsafe.go b/pkg/state/encode_unsafe.go index d96ba56d4..be94742a8 100644 --- a/pkg/state/encode_unsafe.go +++ b/pkg/state/encode_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/map.go b/pkg/state/map.go index c3d165501..0035d7250 100644 --- a/pkg/state/map.go +++ b/pkg/state/map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/object.proto b/pkg/state/object.proto index c78efed2a..d3b46ea97 100644 --- a/pkg/state/object.proto +++ b/pkg/state/object.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/printer.go b/pkg/state/printer.go index 2c8ce60a5..aee4b69fb 100644 --- a/pkg/state/printer.go +++ b/pkg/state/printer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/state.go b/pkg/state/state.go index 23a0b5922..4b141777e 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index 38ad9da9c..22bcad9e1 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/statefile/statefile.go b/pkg/state/statefile/statefile.go index 9c86c1934..99158fd02 100644 --- a/pkg/state/statefile/statefile.go +++ b/pkg/state/statefile/statefile.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/statefile/statefile_test.go b/pkg/state/statefile/statefile_test.go index fa3fb9f2c..b4f400e01 100644 --- a/pkg/state/statefile/statefile_test.go +++ b/pkg/state/statefile/statefile_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/stats.go b/pkg/state/stats.go index ddcc49f78..17ca258fc 100644 --- a/pkg/state/stats.go +++ b/pkg/state/stats.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/atomicptr_unsafe.go b/pkg/sync/atomicptr_unsafe.go index f12e9cb67..d943b7ff4 100644 --- a/pkg/sync/atomicptr_unsafe.go +++ b/pkg/sync/atomicptr_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/atomicptrtest/atomicptr_test.go b/pkg/sync/atomicptrtest/atomicptr_test.go index b458382b1..3262785ce 100644 --- a/pkg/sync/atomicptrtest/atomicptr_test.go +++ b/pkg/sync/atomicptrtest/atomicptr_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/memmove_unsafe.go b/pkg/sync/memmove_unsafe.go index 0c992d5a4..cd7a02dca 100644 --- a/pkg/sync/memmove_unsafe.go +++ b/pkg/sync/memmove_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/norace_unsafe.go b/pkg/sync/norace_unsafe.go index 968665078..1593b9e5d 100644 --- a/pkg/sync/norace_unsafe.go +++ b/pkg/sync/norace_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/race_unsafe.go b/pkg/sync/race_unsafe.go index d143a21c7..473eaddc6 100644 --- a/pkg/sync/race_unsafe.go +++ b/pkg/sync/race_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/seqatomic_unsafe.go b/pkg/sync/seqatomic_unsafe.go index a18e1229a..bea31adc5 100644 --- a/pkg/sync/seqatomic_unsafe.go +++ b/pkg/sync/seqatomic_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/seqatomictest/seqatomic_test.go b/pkg/sync/seqatomictest/seqatomic_test.go index b785d2344..f5e1fbfff 100644 --- a/pkg/sync/seqatomictest/seqatomic_test.go +++ b/pkg/sync/seqatomictest/seqatomic_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/seqcount.go b/pkg/sync/seqcount.go index 8e3304d69..732e856a4 100644 --- a/pkg/sync/seqcount.go +++ b/pkg/sync/seqcount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/seqcount_test.go b/pkg/sync/seqcount_test.go index fa4abed1d..b14a8878e 100644 --- a/pkg/sync/seqcount_test.go +++ b/pkg/sync/seqcount_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/sync.go b/pkg/sync/sync.go index 36d4c4dee..22c5348d7 100644 --- a/pkg/sync/sync.go +++ b/pkg/sync/sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserr/host_linux.go b/pkg/syserr/host_linux.go index 22009a799..74bbe9f5b 100644 --- a/pkg/syserr/host_linux.go +++ b/pkg/syserr/host_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go index b9786b48f..20e756edb 100644 --- a/pkg/syserr/netstack.go +++ b/pkg/syserr/netstack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserr/syserr.go b/pkg/syserr/syserr.go index dba6cb7de..6a66e23a2 100644 --- a/pkg/syserr/syserr.go +++ b/pkg/syserr/syserr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserror/syserror.go b/pkg/syserror/syserror.go index 5bc74e65e..4228707f4 100644 --- a/pkg/syserror/syserror.go +++ b/pkg/syserror/syserror.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserror/syserror_test.go b/pkg/syserror/syserror_test.go index fb7d8d5ee..0f0da5781 100644 --- a/pkg/syserror/syserror_test.go +++ b/pkg/syserror/syserror_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index b64dce720..81428770b 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/adapters/gonet/gonet_test.go b/pkg/tcpip/adapters/gonet/gonet_test.go index 79b7c77ee..05a730a05 100644 --- a/pkg/tcpip/adapters/gonet/gonet_test.go +++ b/pkg/tcpip/adapters/gonet/gonet_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/buffer/prependable.go b/pkg/tcpip/buffer/prependable.go index c5dd2819f..d3a9a0f88 100644 --- a/pkg/tcpip/buffer/prependable.go +++ b/pkg/tcpip/buffer/prependable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index cea4e3657..24479ea40 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/buffer/view_test.go b/pkg/tcpip/buffer/view_test.go index 02c264593..74a0a96fc 100644 --- a/pkg/tcpip/buffer/view_test.go +++ b/pkg/tcpip/buffer/view_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go index 206531f20..5dfb3ca1d 100644 --- a/pkg/tcpip/checker/checker.go +++ b/pkg/tcpip/checker/checker.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/arp.go b/pkg/tcpip/header/arp.go index ae373f112..22b259ccb 100644 --- a/pkg/tcpip/header/arp.go +++ b/pkg/tcpip/header/arp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/checksum.go b/pkg/tcpip/header/checksum.go index e67c50f50..12f208fde 100644 --- a/pkg/tcpip/header/checksum.go +++ b/pkg/tcpip/header/checksum.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/eth.go b/pkg/tcpip/header/eth.go index 99c29b750..77365bc41 100644 --- a/pkg/tcpip/header/eth.go +++ b/pkg/tcpip/header/eth.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/gue.go b/pkg/tcpip/header/gue.go index aac4593c5..2ad13955a 100644 --- a/pkg/tcpip/header/gue.go +++ b/pkg/tcpip/header/gue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/icmpv4.go b/pkg/tcpip/header/icmpv4.go index af1e94b7f..3ac89cdae 100644 --- a/pkg/tcpip/header/icmpv4.go +++ b/pkg/tcpip/header/icmpv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/icmpv6.go b/pkg/tcpip/header/icmpv6.go index 7d35caff7..e317975e8 100644 --- a/pkg/tcpip/header/icmpv6.go +++ b/pkg/tcpip/header/icmpv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/interfaces.go b/pkg/tcpip/header/interfaces.go index 042006983..ac327d8a5 100644 --- a/pkg/tcpip/header/interfaces.go +++ b/pkg/tcpip/header/interfaces.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/ipv4.go b/pkg/tcpip/header/ipv4.go index 29570cc34..1b882d3d8 100644 --- a/pkg/tcpip/header/ipv4.go +++ b/pkg/tcpip/header/ipv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go index 66c778fe1..d985b745d 100644 --- a/pkg/tcpip/header/ipv6.go +++ b/pkg/tcpip/header/ipv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/ipv6_fragment.go b/pkg/tcpip/header/ipv6_fragment.go index 44b28b326..e36d5177b 100644 --- a/pkg/tcpip/header/ipv6_fragment.go +++ b/pkg/tcpip/header/ipv6_fragment.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/ipversion_test.go b/pkg/tcpip/header/ipversion_test.go index 3ae9b7e4a..8301ba5cf 100644 --- a/pkg/tcpip/header/ipversion_test.go +++ b/pkg/tcpip/header/ipversion_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index 6689a6dc5..567a21167 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/tcp_test.go b/pkg/tcpip/header/tcp_test.go index 7854d3523..7cd98df3b 100644 --- a/pkg/tcpip/header/tcp_test.go +++ b/pkg/tcpip/header/tcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/udp.go b/pkg/tcpip/header/udp.go index cf2602e50..31c8ef456 100644 --- a/pkg/tcpip/header/udp.go +++ b/pkg/tcpip/header/udp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 113cbbf5e..da34032cc 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index ee99ada07..24af428dd 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 52e532ebb..19b007a9e 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index fc3f80c01..e6585be66 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s index fc5231831..63b8c4451 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s +++ b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go index a0a9d4acd..6a3e956ad 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go b/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go index 1f143c0db..89a8a9954 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/errors.go b/pkg/tcpip/link/rawfile/errors.go index de7593d9c..f42ff98db 100644 --- a/pkg/tcpip/link/rawfile/errors.go +++ b/pkg/tcpip/link/rawfile/errors.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go index cea3cd6a1..be4a4fa9c 100644 --- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go +++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe.go b/pkg/tcpip/link/sharedmem/pipe/pipe.go index 1a0edbaba..e014324cc 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go index db0737c98..30742ccb1 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go index 480dc4a23..f491d74a2 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/rx.go b/pkg/tcpip/link/sharedmem/pipe/rx.go index ff778cecd..8d641c76f 100644 --- a/pkg/tcpip/link/sharedmem/pipe/rx.go +++ b/pkg/tcpip/link/sharedmem/pipe/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/tx.go b/pkg/tcpip/link/sharedmem/pipe/tx.go index 717f5a4b1..e75175d98 100644 --- a/pkg/tcpip/link/sharedmem/pipe/tx.go +++ b/pkg/tcpip/link/sharedmem/pipe/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/queue/queue_test.go b/pkg/tcpip/link/sharedmem/queue/queue_test.go index 3d5909cef..391165bc3 100644 --- a/pkg/tcpip/link/sharedmem/queue/queue_test.go +++ b/pkg/tcpip/link/sharedmem/queue/queue_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/queue/rx.go b/pkg/tcpip/link/sharedmem/queue/rx.go index c40d62c33..d3a5da08a 100644 --- a/pkg/tcpip/link/sharedmem/queue/rx.go +++ b/pkg/tcpip/link/sharedmem/queue/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/queue/tx.go b/pkg/tcpip/link/sharedmem/queue/tx.go index 39b595e56..845108db1 100644 --- a/pkg/tcpip/link/sharedmem/queue/tx.go +++ b/pkg/tcpip/link/sharedmem/queue/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/rx.go b/pkg/tcpip/link/sharedmem/rx.go index b8e39eca1..3eeab769e 100644 --- a/pkg/tcpip/link/sharedmem/rx.go +++ b/pkg/tcpip/link/sharedmem/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index ce6e86767..27d7eb3b9 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index ad987d382..4b8061b13 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go index f0be2dc73..b91adbaf7 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/tx.go b/pkg/tcpip/link/sharedmem/tx.go index 42a21cb43..37da34831 100644 --- a/pkg/tcpip/link/sharedmem/tx.go +++ b/pkg/tcpip/link/sharedmem/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sniffer/pcap.go b/pkg/tcpip/link/sniffer/pcap.go index 04f3d494e..3d0d8d852 100644 --- a/pkg/tcpip/link/sniffer/pcap.go +++ b/pkg/tcpip/link/sniffer/pcap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index a30e57a32..1bd174bc3 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/tun/tun_unsafe.go b/pkg/tcpip/link/tun/tun_unsafe.go index 1dec41982..e4c589dda 100644 --- a/pkg/tcpip/link/tun/tun_unsafe.go +++ b/pkg/tcpip/link/tun/tun_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index ef8c88561..9ffb7b7e9 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 0a15c40de..5ebe09664 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 9d0881e11..2e0024925 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index 50628e4a2..5894f9114 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/frag_heap.go b/pkg/tcpip/network/fragmentation/frag_heap.go index 6c7faafe4..55615c8e6 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap.go +++ b/pkg/tcpip/network/fragmentation/frag_heap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/frag_heap_test.go b/pkg/tcpip/network/fragmentation/frag_heap_test.go index a15540634..1b1b72e88 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap_test.go +++ b/pkg/tcpip/network/fragmentation/frag_heap_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/fragmentation.go b/pkg/tcpip/network/fragmentation/fragmentation.go index 885e3cca2..a5dda0398 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation.go +++ b/pkg/tcpip/network/fragmentation/fragmentation.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/fragmentation_test.go b/pkg/tcpip/network/fragmentation/fragmentation_test.go index fc62a15dd..5bf3463a9 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation_test.go +++ b/pkg/tcpip/network/fragmentation/fragmentation_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/reassembler.go b/pkg/tcpip/network/fragmentation/reassembler.go index b57fe82ec..c9ad2bef6 100644 --- a/pkg/tcpip/network/fragmentation/reassembler.go +++ b/pkg/tcpip/network/fragmentation/reassembler.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/reassembler_test.go b/pkg/tcpip/network/fragmentation/reassembler_test.go index 4c137828f..a2bc9707a 100644 --- a/pkg/tcpip/network/fragmentation/reassembler_test.go +++ b/pkg/tcpip/network/fragmentation/reassembler_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/hash/hash.go b/pkg/tcpip/network/hash/hash.go index eddf7ca4d..07960ddf0 100644 --- a/pkg/tcpip/network/hash/hash.go +++ b/pkg/tcpip/network/hash/hash.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index e3c7af1f9..5c1e88e56 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index ee8172ac8..f82dc098f 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index d4eeeb5d9..d7801ec19 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go index 2b7067a50..190d548eb 100644 --- a/pkg/tcpip/network/ipv4/ipv4_test.go +++ b/pkg/tcpip/network/ipv4/ipv4_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 81aba0923..14107443b 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index fabbdc8c7..12c818b48 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 25bd998e5..4d0b6ee9c 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/ports/ports.go b/pkg/tcpip/ports/ports.go index 4e24efddb..41ef32921 100644 --- a/pkg/tcpip/ports/ports.go +++ b/pkg/tcpip/ports/ports.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/ports/ports_test.go b/pkg/tcpip/ports/ports_test.go index 4ab6a1fa2..72577dfcb 100644 --- a/pkg/tcpip/ports/ports_test.go +++ b/pkg/tcpip/ports/ports_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index c4707736e..67e8f0b9e 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index 910d1257f..ab40e9e0b 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/seqnum/seqnum.go b/pkg/tcpip/seqnum/seqnum.go index e507d02f7..f2b988839 100644 --- a/pkg/tcpip/seqnum/seqnum.go +++ b/pkg/tcpip/seqnum/seqnum.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index 3a147a75f..cb7b7116b 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go index e46267f12..651fa17ac 100644 --- a/pkg/tcpip/stack/linkaddrcache_test.go +++ b/pkg/tcpip/stack/linkaddrcache_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index dba95369c..3da99ac67 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 0acec2984..b6266eb55 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 6c6400c33..2b4185014 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index d1ec6a660..d4da980a9 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index b6c095efb..f2c6c9a8d 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index a0b3399a8..74bf2c99e 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index a7470d606..c8522ad9e 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 98cc3b120..f09760180 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index bf11c2175..413aee6c6 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/tcpip_test.go b/pkg/tcpip/tcpip_test.go index d283f71c7..361e359d4 100644 --- a/pkg/tcpip/tcpip_test.go +++ b/pkg/tcpip/tcpip_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/time.s b/pkg/tcpip/time.s index 8aca31bee..85d52cd9c 100644 --- a/pkg/tcpip/time.s +++ b/pkg/tcpip/time.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/time_unsafe.go b/pkg/tcpip/time_unsafe.go index 2102e9633..231151bf3 100644 --- a/pkg/tcpip/time_unsafe.go +++ b/pkg/tcpip/time_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index 055daa918..b3f54cfe0 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/ping/endpoint_state.go b/pkg/tcpip/transport/ping/endpoint_state.go index a16087304..80721d227 100644 --- a/pkg/tcpip/transport/ping/endpoint_state.go +++ b/pkg/tcpip/transport/ping/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/ping/protocol.go b/pkg/tcpip/transport/ping/protocol.go index 549b1b2d3..1d504773b 100644 --- a/pkg/tcpip/transport/ping/protocol.go +++ b/pkg/tcpip/transport/ping/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index c22ed5ea7..5a88d25d0 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 27dbcace2..800d2409e 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/cubic.go b/pkg/tcpip/transport/tcp/cubic.go index 8cea416d2..003525d86 100644 --- a/pkg/tcpip/transport/tcp/cubic.go +++ b/pkg/tcpip/transport/tcp/cubic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/dual_stack_test.go b/pkg/tcpip/transport/tcp/dual_stack_test.go index c88e98977..d3120c1d8 100644 --- a/pkg/tcpip/transport/tcp/dual_stack_test.go +++ b/pkg/tcpip/transport/tcp/dual_stack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 707d6be96..673a65c31 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index bed7ec6a6..e32c73aae 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index c80f3c7d6..2f90839e9 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index abdc825cd..753e1419e 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index 92ef9c6f7..05ff9e0d7 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/reno.go b/pkg/tcpip/transport/tcp/reno.go index feb593234..e4f8b7d5a 100644 --- a/pkg/tcpip/transport/tcp/reno.go +++ b/pkg/tcpip/transport/tcp/reno.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/sack.go b/pkg/tcpip/transport/tcp/sack.go index 05bac08cb..24e48fe7b 100644 --- a/pkg/tcpip/transport/tcp/sack.go +++ b/pkg/tcpip/transport/tcp/sack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 51a3d6aba..fc87a05fd 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/segment_heap.go b/pkg/tcpip/transport/tcp/segment_heap.go index e3a3405ef..98422fadf 100644 --- a/pkg/tcpip/transport/tcp/segment_heap.go +++ b/pkg/tcpip/transport/tcp/segment_heap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 6a2d7bc0b..0c637d7ad 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/segment_state.go b/pkg/tcpip/transport/tcp/segment_state.go index 22f0bbf18..46b6d85a6 100644 --- a/pkg/tcpip/transport/tcp/segment_state.go +++ b/pkg/tcpip/transport/tcp/segment_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index 0bd421ff4..eefe93d48 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go index d536839af..86bbd643f 100644 --- a/pkg/tcpip/transport/tcp/snd_state.go +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/tcp_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go index a61d0ca64..06b0702c5 100644 --- a/pkg/tcpip/transport/tcp/tcp_sack_test.go +++ b/pkg/tcpip/transport/tcp/tcp_sack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index 48852ea47..04e046257 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index ca16fc8fa..b08df0fec 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 5b25534f4..0695e8150 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/timer.go b/pkg/tcpip/transport/tcp/timer.go index 938c0bcef..38240d2d5 100644 --- a/pkg/tcpip/transport/tcp/timer.go +++ b/pkg/tcpip/transport/tcp/timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go index 5f8f1a64d..f7b2900de 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go index 514722ab7..aaeae9b18 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 840e95302..d777a80d0 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index 70a37c7f2..db1e281ad 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index 1334fec8a..b3fbed6e4 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index c3f592bd4..58a346cd9 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tmutex/tmutex.go b/pkg/tmutex/tmutex.go index bd5c681dd..df61d89f5 100644 --- a/pkg/tmutex/tmutex.go +++ b/pkg/tmutex/tmutex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tmutex/tmutex_test.go b/pkg/tmutex/tmutex_test.go index a9dc9972f..a4537cb3b 100644 --- a/pkg/tmutex/tmutex_test.go +++ b/pkg/tmutex/tmutex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/unet/unet.go b/pkg/unet/unet.go index f4800e0d9..deeea078d 100644 --- a/pkg/unet/unet.go +++ b/pkg/unet/unet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/unet/unet_test.go b/pkg/unet/unet_test.go index 6c546825f..ecc670925 100644 --- a/pkg/unet/unet_test.go +++ b/pkg/unet/unet_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/unet/unet_unsafe.go b/pkg/unet/unet_unsafe.go index fa15cf744..1d69de542 100644 --- a/pkg/unet/unet_unsafe.go +++ b/pkg/unet/unet_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/urpc/urpc.go b/pkg/urpc/urpc.go index 1ec06dd4c..753366be2 100644 --- a/pkg/urpc/urpc.go +++ b/pkg/urpc/urpc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/urpc/urpc_test.go b/pkg/urpc/urpc_test.go index d9cfc512e..f1b9a85ca 100644 --- a/pkg/urpc/urpc_test.go +++ b/pkg/urpc/urpc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/waiter/fdnotifier/fdnotifier.go b/pkg/waiter/fdnotifier/fdnotifier.go index 8bb93e39b..624b1a0c5 100644 --- a/pkg/waiter/fdnotifier/fdnotifier.go +++ b/pkg/waiter/fdnotifier/fdnotifier.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/waiter/fdnotifier/poll_unsafe.go b/pkg/waiter/fdnotifier/poll_unsafe.go index 26bca2b53..8459d4c74 100644 --- a/pkg/waiter/fdnotifier/poll_unsafe.go +++ b/pkg/waiter/fdnotifier/poll_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index 832b6a5a9..93390b299 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/waiter/waiter_test.go b/pkg/waiter/waiter_test.go index c45f22889..60853f9c1 100644 --- a/pkg/waiter/waiter_test.go +++ b/pkg/waiter/waiter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index 3250cdcdc..6766953b3 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/config.go b/runsc/boot/config.go index 51d20d06d..9ebbde424 100644 --- a/runsc/boot/config.go +++ b/runsc/boot/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index bee82f344..6dd7fadd9 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/debug.go b/runsc/boot/debug.go index 971962c91..d224d08b7 100644 --- a/runsc/boot/debug.go +++ b/runsc/boot/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/events.go b/runsc/boot/events.go index 595846b10..f954b8c0b 100644 --- a/runsc/boot/events.go +++ b/runsc/boot/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/fds.go b/runsc/boot/fds.go index 9416e3a5c..a3d21d963 100644 --- a/runsc/boot/fds.go +++ b/runsc/boot/fds.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/config.go b/runsc/boot/filter/config.go index 92a73db9a..378396b9b 100644 --- a/runsc/boot/filter/config.go +++ b/runsc/boot/filter/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/extra_filters.go b/runsc/boot/filter/extra_filters.go index 82cf00dfb..67f3101fe 100644 --- a/runsc/boot/filter/extra_filters.go +++ b/runsc/boot/filter/extra_filters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/extra_filters_msan.go b/runsc/boot/filter/extra_filters_msan.go index 76f3f6865..fb95283ab 100644 --- a/runsc/boot/filter/extra_filters_msan.go +++ b/runsc/boot/filter/extra_filters_msan.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/extra_filters_race.go b/runsc/boot/filter/extra_filters_race.go index ebd56c553..02a122c95 100644 --- a/runsc/boot/filter/extra_filters_race.go +++ b/runsc/boot/filter/extra_filters_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/filter.go b/runsc/boot/filter/filter.go index b656883ad..dc7294b1d 100644 --- a/runsc/boot/filter/filter.go +++ b/runsc/boot/filter/filter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index ea825e571..e52c89fe4 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/limits.go b/runsc/boot/limits.go index 510497eba..8ecda6d0e 100644 --- a/runsc/boot/limits.go +++ b/runsc/boot/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index c79b95bde..fa3de0133 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/loader_test.go b/runsc/boot/loader_test.go index 41ff3681b..c342ee005 100644 --- a/runsc/boot/loader_test.go +++ b/runsc/boot/loader_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 6a2678ac9..89f186139 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/strace.go b/runsc/boot/strace.go index 1e898672b..028bcc1f4 100644 --- a/runsc/boot/strace.go +++ b/runsc/boot/strace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cgroup/cgroup.go b/runsc/cgroup/cgroup.go index 7a75a189a..d6058a8a2 100644 --- a/runsc/cgroup/cgroup.go +++ b/runsc/cgroup/cgroup.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cgroup/cgroup_test.go b/runsc/cgroup/cgroup_test.go index cde915329..4a4713d4f 100644 --- a/runsc/cgroup/cgroup_test.go +++ b/runsc/cgroup/cgroup_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go index 023b63dc0..7c14857ba 100644 --- a/runsc/cmd/boot.go +++ b/runsc/cmd/boot.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/capability.go b/runsc/cmd/capability.go index 0b18c5481..e5da021e5 100644 --- a/runsc/cmd/capability.go +++ b/runsc/cmd/capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/capability_test.go b/runsc/cmd/capability_test.go index 3329b308d..dd278b32d 100644 --- a/runsc/cmd/capability_test.go +++ b/runsc/cmd/capability_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/checkpoint.go b/runsc/cmd/checkpoint.go index 023ab2455..d49d0169b 100644 --- a/runsc/cmd/checkpoint.go +++ b/runsc/cmd/checkpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/cmd.go b/runsc/cmd/cmd.go index 2937ae1c4..a1c3491a3 100644 --- a/runsc/cmd/cmd.go +++ b/runsc/cmd/cmd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/create.go b/runsc/cmd/create.go index 275a96f57..b84185b43 100644 --- a/runsc/cmd/create.go +++ b/runsc/cmd/create.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/debug.go b/runsc/cmd/debug.go index cb7d81057..288cbe435 100644 --- a/runsc/cmd/debug.go +++ b/runsc/cmd/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/delete.go b/runsc/cmd/delete.go index 92b609c3c..ea1ca1278 100644 --- a/runsc/cmd/delete.go +++ b/runsc/cmd/delete.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/delete_test.go b/runsc/cmd/delete_test.go index f6d164394..4a5b4774a 100644 --- a/runsc/cmd/delete_test.go +++ b/runsc/cmd/delete_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go index df65ea31d..df03415ec 100644 --- a/runsc/cmd/events.go +++ b/runsc/cmd/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 336edf3f6..9a395e6f1 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/exec_test.go b/runsc/cmd/exec_test.go index 623461e78..686c5e150 100644 --- a/runsc/cmd/exec_test.go +++ b/runsc/cmd/exec_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index fd4eee546..3842fdf64 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/kill.go b/runsc/cmd/kill.go index 7a98d10a2..1f1086250 100644 --- a/runsc/cmd/kill.go +++ b/runsc/cmd/kill.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go index 4d4a5cb0b..fd59b73e6 100644 --- a/runsc/cmd/list.go +++ b/runsc/cmd/list.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/path.go b/runsc/cmd/path.go index c207b80da..baba937a8 100644 --- a/runsc/cmd/path.go +++ b/runsc/cmd/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/pause.go b/runsc/cmd/pause.go index ac393b48e..5ff6f059c 100644 --- a/runsc/cmd/pause.go +++ b/runsc/cmd/pause.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/ps.go b/runsc/cmd/ps.go index 5d219bfdc..fd76cf975 100644 --- a/runsc/cmd/ps.go +++ b/runsc/cmd/ps.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/restore.go b/runsc/cmd/restore.go index 6dc044672..cc99b3503 100644 --- a/runsc/cmd/restore.go +++ b/runsc/cmd/restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/resume.go b/runsc/cmd/resume.go index a12adf1a3..274b5d084 100644 --- a/runsc/cmd/resume.go +++ b/runsc/cmd/resume.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/run.go b/runsc/cmd/run.go index 9a87cf240..b6a12f5d6 100644 --- a/runsc/cmd/run.go +++ b/runsc/cmd/run.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/spec.go b/runsc/cmd/spec.go index 6281fc49d..57ee37c86 100644 --- a/runsc/cmd/spec.go +++ b/runsc/cmd/spec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go index 97ea91fff..48bd4c401 100644 --- a/runsc/cmd/start.go +++ b/runsc/cmd/start.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go index 265014e1b..f8ce8c3d8 100644 --- a/runsc/cmd/state.go +++ b/runsc/cmd/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/wait.go b/runsc/cmd/wait.go index 956349140..121c54554 100644 --- a/runsc/cmd/wait.go +++ b/runsc/cmd/wait.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/console/console.go b/runsc/console/console.go index 3df184742..9f4f9214d 100644 --- a/runsc/console/console.go +++ b/runsc/console/console.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/console_test.go b/runsc/container/console_test.go index 8f019b54a..0b0dfb4cb 100644 --- a/runsc/container/console_test.go +++ b/runsc/container/console_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/container.go b/runsc/container/container.go index f76bad1aa..cb4c9b5c1 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index 662591b3b..243528d35 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/fs.go b/runsc/container/fs.go index 2ed42fd93..41022686b 100644 --- a/runsc/container/fs.go +++ b/runsc/container/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/fs_test.go b/runsc/container/fs_test.go index 84bde18fb..87cdb078e 100644 --- a/runsc/container/fs_test.go +++ b/runsc/container/fs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/hook.go b/runsc/container/hook.go index 3d93ca0be..6b9e5550a 100644 --- a/runsc/container/hook.go +++ b/runsc/container/hook.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/multi_container_test.go b/runsc/container/multi_container_test.go index 1781a4602..4548eb106 100644 --- a/runsc/container/multi_container_test.go +++ b/runsc/container/multi_container_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/status.go b/runsc/container/status.go index bf177e78a..234ffb0dd 100644 --- a/runsc/container/status.go +++ b/runsc/container/status.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/test_app.go b/runsc/container/test_app.go index cc3b087e1..b5071ada6 100644 --- a/runsc/container/test_app.go +++ b/runsc/container/test_app.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go index 35698f21f..75a087848 100644 --- a/runsc/fsgofer/filter/config.go +++ b/runsc/fsgofer/filter/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/extra_filters.go b/runsc/fsgofer/filter/extra_filters.go index 82cf00dfb..67f3101fe 100644 --- a/runsc/fsgofer/filter/extra_filters.go +++ b/runsc/fsgofer/filter/extra_filters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/extra_filters_msan.go b/runsc/fsgofer/filter/extra_filters_msan.go index 169a79ed8..7e142b790 100644 --- a/runsc/fsgofer/filter/extra_filters_msan.go +++ b/runsc/fsgofer/filter/extra_filters_msan.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/extra_filters_race.go b/runsc/fsgofer/filter/extra_filters_race.go index 9e6512d8c..3cd29472a 100644 --- a/runsc/fsgofer/filter/extra_filters_race.go +++ b/runsc/fsgofer/filter/extra_filters_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/filter.go b/runsc/fsgofer/filter/filter.go index 6f341f688..f50b6bc87 100644 --- a/runsc/fsgofer/filter/filter.go +++ b/runsc/fsgofer/filter/filter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index 9c4864cf1..e03bb7752 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/fsgofer_test.go b/runsc/fsgofer/fsgofer_test.go index a500a2976..48860f952 100644 --- a/runsc/fsgofer/fsgofer_test.go +++ b/runsc/fsgofer/fsgofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/fsgofer_unsafe.go b/runsc/fsgofer/fsgofer_unsafe.go index e676809ac..99bc25ec1 100644 --- a/runsc/fsgofer/fsgofer_unsafe.go +++ b/runsc/fsgofer/fsgofer_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/main.go b/runsc/main.go index 62b1f01b3..4a92db7c0 100644 --- a/runsc/main.go +++ b/runsc/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/sandbox/chroot.go b/runsc/sandbox/chroot.go index 35b19a0b1..354049871 100644 --- a/runsc/sandbox/chroot.go +++ b/runsc/sandbox/chroot.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index 86a52c6ae..52fe8fc0f 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 923a52f7f..0fe85cfe1 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/specutils/namespace.go b/runsc/specutils/namespace.go index 00293d45b..73fab13e1 100644 --- a/runsc/specutils/namespace.go +++ b/runsc/specutils/namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index b29802fde..ab14ed1fc 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/specutils/specutils_test.go b/runsc/specutils/specutils_test.go index 64e2172c8..b61f1ca62 100644 --- a/runsc/specutils/specutils_test.go +++ b/runsc/specutils/specutils_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/image/image.go b/runsc/test/image/image.go index 069d08013..bcb6f876f 100644 --- a/runsc/test/image/image.go +++ b/runsc/test/image/image.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/image/image_test.go b/runsc/test/image/image_test.go index d89d80a86..763152b47 100644 --- a/runsc/test/image/image_test.go +++ b/runsc/test/image/image_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/image/mysql.sql b/runsc/test/image/mysql.sql index dd5bfaa4e..c1271e719 100644 --- a/runsc/test/image/mysql.sql +++ b/runsc/test/image/mysql.sql @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/runsc/test/image/ruby.rb b/runsc/test/image/ruby.rb index ae5de3419..25d1ac129 100644 --- a/runsc/test/image/ruby.rb +++ b/runsc/test/image/ruby.rb @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/runsc/test/image/ruby.sh b/runsc/test/image/ruby.sh index 54be2c931..d3a9b5656 100644 --- a/runsc/test/image/ruby.sh +++ b/runsc/test/image/ruby.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/runsc/test/install.sh b/runsc/test/install.sh index c239588d4..32e1e884e 100755 --- a/runsc/test/install.sh +++ b/runsc/test/install.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/runsc/test/integration/exec_test.go b/runsc/test/integration/exec_test.go index 3cac674d0..fac8337f4 100644 --- a/runsc/test/integration/exec_test.go +++ b/runsc/test/integration/exec_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/integration/integration.go b/runsc/test/integration/integration.go index 49c3c893a..e15321c87 100644 --- a/runsc/test/integration/integration.go +++ b/runsc/test/integration/integration.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/integration/integration_test.go b/runsc/test/integration/integration_test.go index 536bb17e0..526b3a7a1 100644 --- a/runsc/test/integration/integration_test.go +++ b/runsc/test/integration/integration_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/root/cgroup_test.go b/runsc/test/root/cgroup_test.go index 5cb4b794f..fdb94ff64 100644 --- a/runsc/test/root/cgroup_test.go +++ b/runsc/test/root/cgroup_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/root/chroot_test.go b/runsc/test/root/chroot_test.go index 8831e6a78..0ffaaf87b 100644 --- a/runsc/test/root/chroot_test.go +++ b/runsc/test/root/chroot_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/root/root.go b/runsc/test/root/root.go index 790f62c29..586ea0fe3 100644 --- a/runsc/test/root/root.go +++ b/runsc/test/root/root.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/testutil/docker.go b/runsc/test/testutil/docker.go index 7d6a72e5f..3f74e0770 100644 --- a/runsc/test/testutil/docker.go +++ b/runsc/test/testutil/docker.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/testutil/testutil.go b/runsc/test/testutil/testutil.go index 4d7ac3bc9..1b5a02c0f 100644 --- a/runsc/test/testutil/testutil.go +++ b/runsc/test/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/testutil/testutil_race.go b/runsc/test/testutil/testutil_race.go index 59cfdaa7b..9267af150 100644 --- a/runsc/test/testutil/testutil_race.go +++ b/runsc/test/testutil/testutil_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/tools/dockercfg/dockercfg.go b/runsc/tools/dockercfg/dockercfg.go index 0bd6cad93..110a581ff 100644 --- a/runsc/tools/dockercfg/dockercfg.go +++ b/runsc/tools/dockercfg/dockercfg.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics.go b/tools/go_generics/generics.go index cc61a7537..eaf5c4970 100644 --- a/tools/go_generics/generics.go +++ b/tools/go_generics/generics.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_stmts/input.go b/tools/go_generics/generics_tests/all_stmts/input.go index 870af3b6c..19184a3fe 100644 --- a/tools/go_generics/generics_tests/all_stmts/input.go +++ b/tools/go_generics/generics_tests/all_stmts/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_stmts/output/output.go b/tools/go_generics/generics_tests/all_stmts/output/output.go index e4e670bf1..51582346c 100644 --- a/tools/go_generics/generics_tests/all_stmts/output/output.go +++ b/tools/go_generics/generics_tests/all_stmts/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_types/input.go b/tools/go_generics/generics_tests/all_types/input.go index 3a8643e3d..ed6e97c29 100644 --- a/tools/go_generics/generics_tests/all_types/input.go +++ b/tools/go_generics/generics_tests/all_types/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_types/lib/lib.go b/tools/go_generics/generics_tests/all_types/lib/lib.go index d3911d12d..7e73e678e 100644 --- a/tools/go_generics/generics_tests/all_types/lib/lib.go +++ b/tools/go_generics/generics_tests/all_types/lib/lib.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_types/output/output.go b/tools/go_generics/generics_tests/all_types/output/output.go index b89840936..ec09a6be4 100644 --- a/tools/go_generics/generics_tests/all_types/output/output.go +++ b/tools/go_generics/generics_tests/all_types/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/consts/input.go b/tools/go_generics/generics_tests/consts/input.go index dabf76e1e..394bcc262 100644 --- a/tools/go_generics/generics_tests/consts/input.go +++ b/tools/go_generics/generics_tests/consts/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/consts/output/output.go b/tools/go_generics/generics_tests/consts/output/output.go index 72865607e..91a07fdc2 100644 --- a/tools/go_generics/generics_tests/consts/output/output.go +++ b/tools/go_generics/generics_tests/consts/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/imports/input.go b/tools/go_generics/generics_tests/imports/input.go index 66b43fee5..22e6641a6 100644 --- a/tools/go_generics/generics_tests/imports/input.go +++ b/tools/go_generics/generics_tests/imports/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/imports/output/output.go b/tools/go_generics/generics_tests/imports/output/output.go index 5f20d43ce..2555c0004 100644 --- a/tools/go_generics/generics_tests/imports/output/output.go +++ b/tools/go_generics/generics_tests/imports/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/remove_typedef/input.go b/tools/go_generics/generics_tests/remove_typedef/input.go index c02307d32..d9c9b8530 100644 --- a/tools/go_generics/generics_tests/remove_typedef/input.go +++ b/tools/go_generics/generics_tests/remove_typedef/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/remove_typedef/output/output.go b/tools/go_generics/generics_tests/remove_typedef/output/output.go index d20a89abd..f111a9426 100644 --- a/tools/go_generics/generics_tests/remove_typedef/output/output.go +++ b/tools/go_generics/generics_tests/remove_typedef/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/simple/input.go b/tools/go_generics/generics_tests/simple/input.go index 670161d6e..711687cf5 100644 --- a/tools/go_generics/generics_tests/simple/input.go +++ b/tools/go_generics/generics_tests/simple/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/simple/output/output.go b/tools/go_generics/generics_tests/simple/output/output.go index 75b5467cd..139c9bf9d 100644 --- a/tools/go_generics/generics_tests/simple/output/output.go +++ b/tools/go_generics/generics_tests/simple/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/globals/globals_visitor.go b/tools/go_generics/globals/globals_visitor.go index fc0de4381..daaa17b1d 100644 --- a/tools/go_generics/globals/globals_visitor.go +++ b/tools/go_generics/globals/globals_visitor.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/globals/scope.go b/tools/go_generics/globals/scope.go index 18743bdee..b75a91689 100644 --- a/tools/go_generics/globals/scope.go +++ b/tools/go_generics/globals/scope.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/go_generics_unittest.sh b/tools/go_generics/go_generics_unittest.sh index 699e1f631..e7553a071 100755 --- a/tools/go_generics/go_generics_unittest.sh +++ b/tools/go_generics/go_generics_unittest.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tools/go_generics/imports.go b/tools/go_generics/imports.go index 97267098b..57f7c3dce 100644 --- a/tools/go_generics/imports.go +++ b/tools/go_generics/imports.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/merge.go b/tools/go_generics/merge.go index ebe7cf4e4..2f83facf8 100644 --- a/tools/go_generics/merge.go +++ b/tools/go_generics/merge.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/remove.go b/tools/go_generics/remove.go index 2a66de762..139d03955 100644 --- a/tools/go_generics/remove.go +++ b/tools/go_generics/remove.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/rules_tests/template.go b/tools/go_generics/rules_tests/template.go index 73c024f0e..f3f31ae8e 100644 --- a/tools/go_generics/rules_tests/template.go +++ b/tools/go_generics/rules_tests/template.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/rules_tests/template_test.go b/tools/go_generics/rules_tests/template_test.go index 76c4cdb64..3a38c8629 100644 --- a/tools/go_generics/rules_tests/template_test.go +++ b/tools/go_generics/rules_tests/template_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_stateify/main.go b/tools/go_stateify/main.go index 5646b879a..9e2c8e106 100644 --- a/tools/go_stateify/main.go +++ b/tools/go_stateify/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/workspace_status.sh b/tools/workspace_status.sh index d89db1f99..7d44dad37 100755 --- a/tools/workspace_status.sh +++ b/tools/workspace_status.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vdso/barrier.h b/vdso/barrier.h index db8185b2e..7866af414 100644 --- a/vdso/barrier.h +++ b/vdso/barrier.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/check_vdso.py b/vdso/check_vdso.py index 9a3142ab8..6f7d7e7ec 100644 --- a/vdso/check_vdso.py +++ b/vdso/check_vdso.py @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vdso/compiler.h b/vdso/compiler.h index a661516c3..d65f148fb 100644 --- a/vdso/compiler.h +++ b/vdso/compiler.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/cycle_clock.h b/vdso/cycle_clock.h index 93c5f2c0d..dfb5b427d 100644 --- a/vdso/cycle_clock.h +++ b/vdso/cycle_clock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/seqlock.h b/vdso/seqlock.h index b527bdbca..ab2f3fda3 100644 --- a/vdso/seqlock.h +++ b/vdso/seqlock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/syscalls.h b/vdso/syscalls.h index fd79c4642..0be8a7f9b 100644 --- a/vdso/syscalls.h +++ b/vdso/syscalls.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/vdso.cc b/vdso/vdso.cc index db3bdef01..f30dc26a2 100644 --- a/vdso/vdso.cc +++ b/vdso/vdso.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/vdso_time.cc b/vdso/vdso_time.cc index 5d5c8de65..a59771bff 100644 --- a/vdso/vdso_time.cc +++ b/vdso/vdso_time.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/vdso_time.h b/vdso/vdso_time.h index 71d6e2f64..464dadff2 100644 --- a/vdso/vdso_time.h +++ b/vdso/vdso_time.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. -- cgit v1.2.3 From 692df85673e2398a1a9393029b2a9b72448619f4 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Tue, 23 Oct 2018 08:15:15 -0700 Subject: Simplify channel management The channels {cancel,resCh} have roughly the same lifetime and are used for roughly the same purpose as an entry's waiters; we can unify the state management of the two mechanisms, while also reducing unncessary mutex locking and unlocking. Made some cosmetic changes while I'm here. PiperOrigin-RevId: 218343915 Change-Id: Ic69546a2b7b390162b2231f07f335dd6199472d7 --- pkg/tcpip/stack/linkaddrcache.go | 131 ++++++++++++++------------------------- 1 file changed, 47 insertions(+), 84 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index cb7b7116b..40e4bdb4a 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -77,7 +77,7 @@ func (s entryState) String() string { case expired: return "expired" default: - return fmt.Sprintf("invalid entryState: %d", s) + return fmt.Sprintf("unknown(%d)", s) } } @@ -88,14 +88,12 @@ type linkAddrEntry struct { linkAddr tcpip.LinkAddress expiration time.Time s entryState - resDone bool // wakers is a set of waiters for address resolution result. Anytime // state transitions out of 'incomplete' these waiters are notified. wakers map[*sleep.Waker]struct{} - cancel chan struct{} - resCh chan struct{} + done chan struct{} } func (e *linkAddrEntry) state() entryState { @@ -117,13 +115,13 @@ func (e *linkAddrEntry) changeState(ns entryState) { // All transitions are valid. case ready, failed: if ns != expired { - panic(fmt.Sprintf("invalid state transition from %v to %v", e.s, ns)) + panic(fmt.Sprintf("invalid state transition from %s to %s", e.s, ns)) } case expired: // Terminal state. - panic(fmt.Sprintf("invalid state transition from %v to %v", e.s, ns)) + panic(fmt.Sprintf("invalid state transition from %s to %s", e.s, ns)) default: - panic(fmt.Sprintf("invalid state: %v", e.s)) + panic(fmt.Sprintf("invalid state: %s", e.s)) } // Notify whoever is waiting on address resolution when transitioning @@ -133,6 +131,9 @@ func (e *linkAddrEntry) changeState(ns entryState) { w.Assert() } e.wakers = nil + if e.done != nil { + close(e.done) + } } e.s = ns } @@ -150,8 +151,8 @@ func (c *linkAddrCache) add(k tcpip.FullAddress, v tcpip.LinkAddress) { c.mu.Lock() defer c.mu.Unlock() - entry := c.cache[k] - if entry != nil { + entry, ok := c.cache[k] + if ok { s := entry.state() if s != expired && entry.linkAddr == v { // Disregard repeated calls. @@ -183,28 +184,17 @@ func (c *linkAddrCache) makeAndAddEntry(k tcpip.FullAddress, v tcpip.LinkAddress // Mark the soon-to-be-replaced entry as expired, just in case there is // someone waiting for address resolution on it. entry.changeState(expired) - if entry.cancel != nil { - if !entry.resDone { - close(entry.resCh) - } - close(entry.cancel) - } *entry = linkAddrEntry{ addr: k, linkAddr: v, expiration: time.Now().Add(c.ageLimit), - resDone: false, wakers: make(map[*sleep.Waker]struct{}), - cancel: make(chan struct{}, 1), - resCh: make(chan struct{}, 1), + done: make(chan struct{}), } c.cache[k] = entry - c.next++ - if c.next == len(c.entries) { - c.next = 0 - } + c.next = (c.next + 1) % len(c.entries) return entry } @@ -217,34 +207,34 @@ func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, lo } c.mu.Lock() - entry := c.cache[k] - if entry == nil || entry.state() == expired { - c.mu.Unlock() - if linkRes == nil { + defer c.mu.Unlock() + if entry, ok := c.cache[k]; ok { + switch s := entry.state(); s { + case expired: + case ready: + return entry.linkAddr, nil, nil + case failed: return "", nil, tcpip.ErrNoLinkAddress + case incomplete: + // Address resolution is still in progress. + entry.addWaker(waker) + return "", entry.done, tcpip.ErrWouldBlock + default: + panic(fmt.Sprintf("invalid cache entry state: %s", s)) } - - ch := c.startAddressResolution(k, linkRes, localAddr, linkEP, waker) - return "", ch, tcpip.ErrWouldBlock } - defer c.mu.Unlock() - switch s := entry.state(); s { - case expired: - // It's possible that entry expired between state() call above and here - // in that case it's safe to consider it ready. - fallthrough - case ready: - return entry.linkAddr, nil, nil - case failed: + if linkRes == nil { return "", nil, tcpip.ErrNoLinkAddress - case incomplete: - // Address resolution is still in progress. - entry.addWaker(waker) - return "", entry.resCh, tcpip.ErrWouldBlock - default: - panic(fmt.Sprintf("invalid cache entry state: %d", s)) } + + // Add 'incomplete' entry in the cache to mark that resolution is in progress. + e := c.makeAndAddEntry(k, "") + e.addWaker(waker) + + go c.startAddressResolution(k, linkRes, localAddr, linkEP, e.done) // S/R-SAFE: link non-savable; wakers dropped synchronously. + + return "", e.done, tcpip.ErrWouldBlock } // removeWaker removes a waker previously added through get(). @@ -252,53 +242,26 @@ func (c *linkAddrCache) removeWaker(k tcpip.FullAddress, waker *sleep.Waker) { c.mu.Lock() defer c.mu.Unlock() - if entry := c.cache[k]; entry != nil { + if entry, ok := c.cache[k]; ok { entry.removeWaker(waker) } } -func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) <-chan struct{} { - c.mu.Lock() - defer c.mu.Unlock() +func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, done <-chan struct{}) { + for i := 0; ; i++ { + // Send link request, then wait for the timeout limit and check + // whether the request succeeded. + linkRes.LinkAddressRequest(k.Addr, localAddr, linkEP) - // Look up again with lock held to ensure entry wasn't added by someone else. - if e := c.cache[k]; e != nil && e.state() != expired { - return nil - } - - // Add 'incomplete' entry in the cache to mark that resolution is in progress. - e := c.makeAndAddEntry(k, "") - e.addWaker(waker) - - go func() { // S/R-SAFE: link non-savable; wakers dropped synchronously. - for i := 0; ; i++ { - // Send link request, then wait for the timeout limit and check - // whether the request succeeded. - linkRes.LinkAddressRequest(k.Addr, localAddr, linkEP) - c.mu.Lock() - cancel := e.cancel - c.mu.Unlock() - - select { - case <-time.After(c.resolutionTimeout): - if stop := c.checkLinkRequest(k, i); stop { - // If entry is evicted then resCh is already closed. - c.mu.Lock() - if e, ok := c.cache[k]; ok { - if !e.resDone { - e.resDone = true - close(e.resCh) - } - } - c.mu.Unlock() - return - } - case <-cancel: + select { + case <-time.After(c.resolutionTimeout): + if stop := c.checkLinkRequest(k, i); stop { return } + case <-done: + return } - }() - return e.resCh + } } // checkLinkRequest checks whether previous attempt to resolve address has succeeded @@ -327,7 +290,7 @@ func (c *linkAddrCache) checkLinkRequest(k tcpip.FullAddress, attempt int) bool // No response yet, need to send another ARP request. return false default: - panic(fmt.Sprintf("invalid cache entry state: %d", s)) + panic(fmt.Sprintf("invalid cache entry state: %s", s)) } } -- cgit v1.2.3 From dce61075c03907a70362878d362b2b95ff06addf Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Wed, 7 Nov 2018 12:00:51 -0800 Subject: Fix flaky TestCacheResolutionTimeout Increase timeout to prevent the entry from being found when there is delay on the address resolution goroutine that doesn't mark the request as failed. PiperOrigin-RevId: 220504789 Change-Id: I7e44fd95d8624bd69962f862fbf5517a81395f2a --- pkg/tcpip/stack/linkaddrcache_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go index 651fa17ac..77a09ca86 100644 --- a/pkg/tcpip/stack/linkaddrcache_test.go +++ b/pkg/tcpip/stack/linkaddrcache_test.go @@ -237,8 +237,8 @@ func TestCacheResolutionFailed(t *testing.T) { } func TestCacheResolutionTimeout(t *testing.T) { - resolverDelay := 50 * time.Millisecond - expiration := resolverDelay / 2 + resolverDelay := 500 * time.Millisecond + expiration := resolverDelay / 10 c := newLinkAddrCache(expiration, 1*time.Millisecond, 3) linkRes := &testLinkAddressResolver{cache: c, delay: resolverDelay} -- cgit v1.2.3 From 33089561b1d53dada959a312ab69574cd6635b4b Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Fri, 9 Nov 2018 14:37:42 -0800 Subject: Add an implementation of a SACK scoreboard as per RFC6675. PiperOrigin-RevId: 220866996 Change-Id: I89d48215df57c00d6a6ec512fc18712a2ea9080b --- WORKSPACE | 6 + pkg/tcpip/header/BUILD | 1 + pkg/tcpip/header/tcp.go | 11 ++ pkg/tcpip/stack/stack.go | 12 +- pkg/tcpip/transport/tcp/BUILD | 19 +- pkg/tcpip/transport/tcp/sack_scoreboard.go | 227 ++++++++++++++++++++++++ pkg/tcpip/transport/tcp/sack_scoreboard_test.go | 150 ++++++++++++++++ 7 files changed, 416 insertions(+), 10 deletions(-) create mode 100644 pkg/tcpip/transport/tcp/sack_scoreboard.go create mode 100644 pkg/tcpip/transport/tcp/sack_scoreboard_test.go (limited to 'pkg/tcpip/stack') diff --git a/WORKSPACE b/WORKSPACE index f442f58eb..a22dc7596 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -131,3 +131,9 @@ http_archive( "https://github.com/google/glog/archive/028d37889a1e80e8a07da1b8945ac706259e5fd8.tar.gz", ], ) + +go_repository( + name = "com_github_google_btree", + importpath = "github.com/google/btree", + commit = "4030bb1f1f0c35b30ca7009e9ebd06849dd45306", +) diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 66b37720c..8e455fe1e 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -24,6 +24,7 @@ go_library( "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/seqnum", + "@com_github_google_btree//:go_default_library", ], ) diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index 567a21167..207046b36 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -17,6 +17,7 @@ package header import ( "encoding/binary" + "github.com/google/btree" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum" ) @@ -131,6 +132,16 @@ type SACKBlock struct { End seqnum.Value } +// Less returns true if r.Start < b.Start. +func (r SACKBlock) Less(b btree.Item) bool { + return r.Start.LessThan(b.(SACKBlock).Start) +} + +// Contains returns true if b is completely contained in r. +func (r SACKBlock) Contains(b SACKBlock) bool { + return r.Start.LessThanEq(b.Start) && b.End.LessThanEq(r.End) +} + // TCPOptions are used to parse and cache the TCP segment options for a non // syn/syn-ack segment. // diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index d4da980a9..7af343fba 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -200,9 +200,17 @@ type TCPSenderState struct { // TCPSACKInfo holds TCP SACK related information for a given TCP endpoint. type TCPSACKInfo struct { - // Blocks is the list of SACK block currently received by the - // TCP endpoint. + // Blocks is the list of SACK Blocks that identify the out of order segments + // held by a given TCP endpoint. Blocks []header.SACKBlock + + // ReceivedBlocks are the SACK blocks received by this endpoint + // from the peer endpoint. + ReceivedBlocks []header.SACKBlock + + // MaxSACKED is the highest sequence number that has been SACKED + // by the peer. + MaxSACKED seqnum.Value } // TCPEndpointState is a copy of the internal state of a TCP endpoint. diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 5a77ee232..18e6a5dc6 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -28,6 +28,7 @@ go_library( "rcv.go", "reno.go", "sack.go", + "sack_scoreboard.go", "segment.go", "segment_heap.go", "segment_queue.go", @@ -50,14 +51,24 @@ go_library( "//pkg/tcpip/stack", "//pkg/tmutex", "//pkg/waiter", + "@com_github_google_btree//:go_default_library", ], ) +filegroup( + name = "autogen", + srcs = [ + "tcp_segment_list.go", + ], + visibility = ["//:sandbox"], +) + go_test( name = "tcp_test", size = "small", srcs = [ "dual_stack_test.go", + "sack_scoreboard_test.go", "tcp_sack_test.go", "tcp_test.go", "tcp_timestamp_test.go", @@ -79,11 +90,3 @@ go_test( "//pkg/waiter", ], ) - -filegroup( - name = "autogen", - srcs = [ - "tcp_segment_list.go", - ], - visibility = ["//:sandbox"], -) diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard.go b/pkg/tcpip/transport/tcp/sack_scoreboard.go new file mode 100644 index 000000000..d251d32db --- /dev/null +++ b/pkg/tcpip/transport/tcp/sack_scoreboard.go @@ -0,0 +1,227 @@ +// Copyright 2018 Google LLC +// +// 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 tcp + +import ( + "fmt" + "strings" + + "github.com/google/btree" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" + "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum" +) + +// maxSACKBlocks is the maximum number of distinct SACKBlocks the scoreboard +// will track. Once there are 100 distinct blocks, new insertions will fail. +const maxSACKBlocks = 100 + +// SACKScoreboard stores a set of disjoint SACK ranges. +type SACKScoreboard struct { + smss uint16 + maxSACKED seqnum.Value + sacked seqnum.Size + ranges *btree.BTree +} + +// NewSACKScoreboard returns a new SACK Scoreboard. +func NewSACKScoreboard(smss uint16, iss seqnum.Value) *SACKScoreboard { + return &SACKScoreboard{ + smss: smss, + ranges: btree.New(2), + maxSACKED: iss, + } +} + +// Insert inserts/merges the provided SACKBlock into the scoreboard. +func (s *SACKScoreboard) Insert(r header.SACKBlock) { + if s.ranges.Len() >= maxSACKBlocks { + return + } + + // Check if we can merge the new range with a range before or after it. + var toDelete []btree.Item + if s.maxSACKED.LessThan(r.End - 1) { + s.maxSACKED = r.End - 1 + } + s.ranges.AscendGreaterOrEqual(r, func(i btree.Item) bool { + if i == r { + return true + } + sacked := i.(header.SACKBlock) + // There is a hole between these two SACK blocks, so we can't + // merge anymore. + if r.End.LessThan(r.Start) { + return false + } + // There is some overlap at this point, merge the blocks and + // delete the other one. + // + // ----sS--------sE + // r.S---------------rE + // -------sE + if sacked.End.LessThan(r.End) { + // sacked is contained in the newly inserted range. + // Delete this block. + toDelete = append(toDelete, i) + return true + } + // sacked covers a range past end of the newly inserted + // block. + r.End = sacked.End + toDelete = append(toDelete, i) + return true + }) + + s.ranges.DescendLessOrEqual(r, func(i btree.Item) bool { + if i == r { + return true + } + sacked := i.(header.SACKBlock) + // sA------sE + // rA----rE + if sacked.End.LessThan(r.Start) { + return false + } + // The previous range extends into the current block. Merge it + // into the newly inserted range and delete the other one. + // + // <-rA---rE----<---rE---> + // sA--------------sE + r.Start = sacked.Start + // Extend r to cover sacked if sacked extends past r. + if r.End.LessThan(sacked.End) { + r.End = sacked.End + } + toDelete = append(toDelete, i) + return true + }) + for _, i := range toDelete { + if sb := s.ranges.Delete(i); sb != nil { + sb := i.(header.SACKBlock) + s.sacked -= sb.Start.Size(sb.End) + } + } + + replaced := s.ranges.ReplaceOrInsert(r) + if replaced == nil { + s.sacked += r.Start.Size(r.End) + } +} + +// IsSACKED returns true if the a given range of sequence numbers denoted by r +// are already covered by SACK information in the scoreboard. +func (s *SACKScoreboard) IsSACKED(r header.SACKBlock) bool { + found := false + s.ranges.DescendLessOrEqual(r, func(i btree.Item) bool { + sacked := i.(header.SACKBlock) + if sacked.End.LessThan(r.Start) { + return false + } + if sacked.Contains(r) { + found = true + return false + } + return true + }) + return found +} + +// Dump prints the state of the scoreboard structure. +func (s *SACKScoreboard) String() string { + var str strings.Builder + str.WriteString("SACKScoreboard: {") + s.ranges.Ascend(func(i btree.Item) bool { + str.WriteString(fmt.Sprintf("%v,", i)) + return true + }) + str.WriteString("}\n") + return str.String() +} + +// Delete removes all SACK information prior to seq. +func (s *SACKScoreboard) Delete(seq seqnum.Value) { + toDelete := []btree.Item{} + r := header.SACKBlock{seq, seq.Add(1)} + s.ranges.DescendLessOrEqual(r, func(i btree.Item) bool { + if i == r { + return true + } + sb := i.(header.SACKBlock) + toDelete = append(toDelete, i) + if sb.End.LessThanEq(seq) { + s.sacked -= sb.Start.Size(sb.End) + } else { + newSB := header.SACKBlock{seq, sb.End} + s.ranges.ReplaceOrInsert(newSB) + s.sacked -= sb.Start.Size(seq) + } + return true + }) + for _, i := range toDelete { + s.ranges.Delete(i) + } +} + +// Copy provides a copy of the SACK scoreboard. +func (s *SACKScoreboard) Copy() (sackBlocks []header.SACKBlock, maxSACKED seqnum.Value) { + s.ranges.Ascend(func(i btree.Item) bool { + sackBlocks = append(sackBlocks, i.(header.SACKBlock)) + return true + }) + return sackBlocks, s.maxSACKED +} + +// IsLost implements the IsLost(SeqNum) operation defined in RFC 3517 section 4. +// +// This routine returns whether the given sequence number is considered to be +// lost. The routine returns true when either nDupAckThreshold discontiguous +// SACKed sequences have arrived above 'SeqNum' or (nDupAckThreshold * SMSS) +// bytes with sequence numbers greater than 'SeqNum' have been SACKed. +// Otherwise, the routine returns false. +func (s *SACKScoreboard) IsLost(r header.SACKBlock) bool { + nDupSACK := 0 + nDupSACKBytes := seqnum.Size(0) + isLost := false + s.ranges.AscendGreaterOrEqual(r, func(i btree.Item) bool { + sacked := i.(header.SACKBlock) + if sacked.Contains(r) { + return false + } + nDupSACKBytes += sacked.Start.Size(sacked.End) + nDupSACK++ + if nDupSACK >= nDupAckThreshold || nDupSACKBytes >= seqnum.Size(nDupAckThreshold*s.smss) { + isLost = true + return false + } + return true + }) + return isLost +} + +// Empty returns true if the SACK scoreboard has no entries, false otherwise. +func (s *SACKScoreboard) Empty() bool { + return s.ranges.Len() == 0 +} + +// Sacked returns the current number of bytes held in the SACK scoreboard. +func (s *SACKScoreboard) Sacked() seqnum.Size { + return s.sacked +} + +// MaxSACKED returns the highest sequence number ever inserted in the SACK +// scoreboard. +func (s *SACKScoreboard) MaxSACKED() seqnum.Value { + return s.maxSACKED +} diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go new file mode 100644 index 000000000..db4b52aca --- /dev/null +++ b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go @@ -0,0 +1,150 @@ +// Copyright 2018 Google LLC +// +// 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 tcp_test + +import ( + "testing" + + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" + "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/tcp" +) + +const smss = 1500 + +func initScoreboard(blocks []header.SACKBlock, iss seqnum.Value) *tcp.SACKScoreboard { + s := tcp.NewSACKScoreboard(smss, iss) + for _, blk := range blocks { + s.Insert(blk) + } + return s +} + +func TestSACKScoreboardIsSACKED(t *testing.T) { + type blockTest struct { + block header.SACKBlock + sacked bool + } + testCases := []struct { + comment string + scoreboardBlocks []header.SACKBlock + blockTests []blockTest + iss seqnum.Value + }{ + { + "Test holes and unsacked SACK blocks in SACKed ranges and insertion of overlapping SACK blocks", + []header.SACKBlock{{10, 20}, {10, 30}, {30, 40}, {41, 50}, {5, 10}, {1, 50}, {111, 120}, {101, 110}, {52, 120}}, + []blockTest{ + {header.SACKBlock{15, 21}, true}, + {header.SACKBlock{200, 201}, false}, + {header.SACKBlock{50, 51}, false}, + {header.SACKBlock{53, 120}, true}, + }, + 0, + }, + { + "Test disjoint SACKBlocks", + []header.SACKBlock{{2288624809, 2288810057}, {2288811477, 2288838565}}, + []blockTest{ + {header.SACKBlock{2288624809, 2288810057}, true}, + {header.SACKBlock{2288811477, 2288838565}, true}, + {header.SACKBlock{2288810057, 2288811477}, false}, + }, + 2288624809, + }, + { + "Test sequence number wrap around", + []header.SACKBlock{{4294254144, 225652}, {5340409, 5350509}}, + []blockTest{ + {header.SACKBlock{4294254144, 4294254145}, true}, + {header.SACKBlock{4294254143, 4294254144}, false}, + {header.SACKBlock{4294254144, 1}, true}, + {header.SACKBlock{225652, 5350509}, false}, + {header.SACKBlock{5340409, 5350509}, true}, + {header.SACKBlock{5350509, 5350609}, false}, + }, + 4294254144, + }, + } + for _, tc := range testCases { + sb := initScoreboard(tc.scoreboardBlocks, tc.iss) + for _, blkTest := range tc.blockTests { + if want, got := blkTest.sacked, sb.IsSACKED(blkTest.block); got != want { + t.Errorf("%s: s.IsSACKED(%v) = %v, want %v", tc.comment, blkTest.block, got, want) + } + } + } +} + +func TestSACKScoreboardIsLost(t *testing.T) { + s := tcp.NewSACKScoreboard(10, 0) + s.Insert(header.SACKBlock{1, 50}) + s.Insert(header.SACKBlock{51, 100}) + s.Insert(header.SACKBlock{111, 120}) + s.Insert(header.SACKBlock{101, 110}) + s.Insert(header.SACKBlock{121, 151}) + testCases := []struct { + block header.SACKBlock + lost bool + }{ + {header.SACKBlock{0, 1}, true}, + {header.SACKBlock{1, 2}, false}, + {header.SACKBlock{1, 45}, false}, + {header.SACKBlock{50, 51}, true}, + // This one should return true because there are > 3* 10 (smss) + // bytes that have been sacked above this sequence number. + {header.SACKBlock{119, 120}, true}, + {header.SACKBlock{120, 121}, true}, + {header.SACKBlock{125, 126}, false}, + } + for _, tc := range testCases { + if want, got := tc.lost, s.IsLost(tc.block); got != want { + t.Errorf("s.IsLost(%v) = %v, want %v", tc.block, got, want) + } + } +} + +func TestSACKScoreboardDelete(t *testing.T) { + blocks := []header.SACKBlock{{4294254144, 225652}, {5340409, 5350509}} + s := initScoreboard(blocks, 4294254143) + s.Delete(5340408) + if s.Empty() { + t.Fatalf("s.Empty() = true, want false") + } + if got, want := s.Sacked(), blocks[1].Start.Size(blocks[1].End); got != want { + t.Fatalf("incorrect sacked bytes in scoreboard got: %v, want: %v", got, want) + } + s.Delete(5340410) + if s.Empty() { + t.Fatal("s.Empty() = true, want false") + } + newSB := header.SACKBlock{5340410, 5350509} + if !s.IsSACKED(newSB) { + t.Fatalf("s.IsSACKED(%v) = false, want true, scoreboard: %v", newSB, s) + } + s.Delete(5350509) + lastOctet := header.SACKBlock{5350508, 5350509} + if s.IsSACKED(lastOctet) { + t.Fatalf("s.IsSACKED(%v) = false, want true", lastOctet) + } + + s.Delete(5350510) + if !s.Empty() { + t.Fatal("s.Empty() = false, want true") + } + if got, want := s.Sacked(), seqnum.Size(0); got != want { + t.Fatalf("incorrect sacked bytes in scoreboard got: %v, want: %v", got, want) + } +} -- cgit v1.2.3 From bc41e4761b6adfb4ef31401c438bd6a34f76ce87 Mon Sep 17 00:00:00 2001 From: Bert Muthalaly Date: Wed, 14 Nov 2018 14:45:29 -0800 Subject: Rename incorrectly named (dst, src) arguments in DeliverNetworkPacket prototype ...to (remote, local), reflecting the (correct) names in the implementation of DeliverNetworkPacket (see tcpip/stack/nic.go). Also trim the names in DeliverNetworkPacket and elsewhere to avoid stuttering; since the type is tcpip.LinkAddress, there's no need to include "LinkAddr" in the parameter names. Note that every callsite passes arguments in the order (src, dst). PiperOrigin-RevId: 221514396 Change-Id: I3637454ad0d6e62a19e4dcbc2a16493798bd0f09 --- pkg/tcpip/link/channel/channel.go | 4 ++-- pkg/tcpip/link/fdbased/endpoint.go | 12 ++++++------ pkg/tcpip/link/fdbased/endpoint_test.go | 4 ++-- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/sniffer/sniffer.go | 4 ++-- pkg/tcpip/link/waitable/waitable.go | 4 ++-- pkg/tcpip/link/waitable/waitable_test.go | 2 +- pkg/tcpip/stack/nic.go | 6 +++--- pkg/tcpip/stack/registration.go | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index da34032cc..25cffa787 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -71,8 +71,8 @@ func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.Vector } // InjectLinkAddr injects an inbound packet with a remote link address. -func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remoteLinkAddr tcpip.LinkAddress, vv buffer.VectorisedView) { - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, "" /* localLinkAddr */, protocol, vv.Clone(nil)) +func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remote tcpip.LinkAddress, vv buffer.VectorisedView) { + e.dispatcher.DeliverNetworkPacket(e, remote, "" /* local */, protocol, vv.Clone(nil)) } // Attach saves the stack network-layer dispatcher for use later when packets diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 24af428dd..3a79d13d4 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -231,14 +231,14 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { } var ( - p tcpip.NetworkProtocolNumber - remoteLinkAddr, localLinkAddr tcpip.LinkAddress + p tcpip.NetworkProtocolNumber + remote, local tcpip.LinkAddress ) if e.hdrSize > 0 { eth := header.Ethernet(e.views[0]) p = eth.Type() - remoteLinkAddr = eth.SourceAddress() - localLinkAddr = eth.DestinationAddress() + remote = eth.SourceAddress() + local = eth.DestinationAddress() } else { // We don't get any indication of what the packet is, so try to guess // if it's an IPv4 or IPv6 packet. @@ -256,7 +256,7 @@ func (e *endpoint) dispatch(largeV buffer.View) (bool, *tcpip.Error) { vv := buffer.NewVectorisedView(n, e.views[:used]) vv.TrimFront(e.hdrSize) - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, localLinkAddr, p, vv) + e.dispatcher.DeliverNetworkPacket(e, remote, local, p, vv) // Prepare e.views for another packet: release used views. for i := 0; i < used; i++ { @@ -297,7 +297,7 @@ func (e *InjectableEndpoint) Attach(dispatcher stack.NetworkDispatcher) { // Inject injects an inbound packet. func (e *InjectableEndpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { - e.dispatcher.DeliverNetworkPacket(e, "" /* remoteLinkAddr */, "" /* localLinkAddr */, protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, protocol, vv) } // NewInjectable creates a new fd-based InjectableEndpoint. diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 19b007a9e..226639443 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -85,8 +85,8 @@ func (c *context) cleanup() { syscall.Close(c.fds[1]) } -func (c *context) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, localLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { - c.ch <- packetInfo{remoteLinkAddr, protocol, vv.ToView()} +func (c *context) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote tcpip.LinkAddress, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { + c.ch <- packetInfo{remote, protocol, vv.ToView()} } func TestNoEthernetProperties(t *testing.T) { diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index e6585be66..fa54872da 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -81,7 +81,7 @@ func (e *endpoint) WritePacket(_ *stack.Route, hdr buffer.Prependable, payload b // Because we're immediately turning around and writing the packet back to the // rx path, we intentionally don't preserve the remote and local link // addresses from the stack.Route we're passed. - e.dispatcher.DeliverNetworkPacket(e, "" /* remoteLinkAddr */, "" /* localLinkAddr */, protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, protocol, vv) return nil } diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 1bd174bc3..4768321d3 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -116,7 +116,7 @@ func NewWithFile(lower tcpip.LinkEndpointID, file *os.File, snapLen uint32) (tcp // DeliverNetworkPacket implements the stack.NetworkDispatcher interface. It is // called by the link-layer endpoint being wrapped when a packet arrives, and // logs the packet before forwarding to the actual dispatcher. -func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { logPacket("recv", protocol, vv.First()) } @@ -147,7 +147,7 @@ func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAdd panic(err) } } - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, localLinkAddr, protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, remote, local, protocol, vv) } // Attach implements the stack.LinkEndpoint interface. It saves the dispatcher diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 9ffb7b7e9..39217e49c 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -51,12 +51,12 @@ func New(lower tcpip.LinkEndpointID) (tcpip.LinkEndpointID, *Endpoint) { // It is called by the link-layer endpoint being wrapped when a packet arrives, // and only forwards to the actual dispatcher if Wait or WaitDispatch haven't // been called. -func (e *Endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr, localLinkAddress tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (e *Endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { if !e.dispatchGate.Enter() { return } - e.dispatcher.DeliverNetworkPacket(e, remoteLinkAddr, localLinkAddress, protocol, vv) + e.dispatcher.DeliverNetworkPacket(e, remote, local, protocol, vv) e.dispatchGate.Leave() } diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 5ebe09664..6c57e597a 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -35,7 +35,7 @@ type countedEndpoint struct { dispatcher stack.NetworkDispatcher } -func (e *countedEndpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (e *countedEndpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { e.dispatchCount++ } diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 3da99ac67..6f3c24122 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -391,7 +391,7 @@ func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error { // Note that the ownership of the slice backing vv is retained by the caller. // This rule applies only to the slice itself, not to the items of the slice; // the ownership of the items is not retained by the caller. -func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { +func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { netProto, ok := n.stack.networkProtocols[protocol] if !ok { n.stack.stats.UnknownProtocolRcvdPackets.Increment() @@ -411,7 +411,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr, localLin if ref := n.getRef(protocol, dst); ref != nil { r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) - r.RemoteLinkAddress = remoteLinkAddr + r.RemoteLinkAddress = remote ref.ep.HandlePacket(&r, vv) ref.decRef() return @@ -430,7 +430,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remoteLinkAddr, localLin defer r.Release() r.LocalLinkAddress = n.linkEP.LinkAddress() - r.RemoteLinkAddress = remoteLinkAddr + r.RemoteLinkAddress = remote // Found a NIC. n := r.ref.nic diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index b6266eb55..6becd9426 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -196,7 +196,7 @@ type NetworkProtocol interface { type NetworkDispatcher interface { // DeliverNetworkPacket finds the appropriate network protocol // endpoint and hands the packet over for further processing. - DeliverNetworkPacket(linkEP LinkEndpoint, dstLinkAddr, srcLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) + DeliverNetworkPacket(linkEP LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) } // LinkEndpointCapabilities is the type associated with the capabilities -- cgit v1.2.3 From fab029c50b445e06ba770c9ccd7d6d0a06e15057 Mon Sep 17 00:00:00 2001 From: Chris Kuiper Date: Tue, 4 Dec 2018 19:08:13 -0800 Subject: Remove incorrect code and improve testing of Stack.GetMainNICAddress This removes code that should have never made it in in the first place, but did so due to incomplete testing. With the new tests the original code fails, the new code passes. PiperOrigin-RevId: 224086966 Change-Id: I646fef76977f4528f3705f497b95fad6b3ec32bc --- pkg/tcpip/stack/nic.go | 10 ------ pkg/tcpip/stack/stack_test.go | 76 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 11 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 6f3c24122..770d288cf 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -119,16 +119,6 @@ func (n *NIC) getMainNICAddress(protocol tcpip.NetworkProtocolNumber) (tcpip.Add } - // If no primary endpoints then check for other endpoints. - if r == nil { - for _, ref := range n.endpoints { - if ref.holdsInsertRef && ref.tryIncRef() { - r = ref - break - } - } - } - if r == nil { return "", tcpip.Subnet{}, tcpip.ErrNoLinkAddress } diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 74bf2c99e..8a9c9d234 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -18,6 +18,8 @@ package stack_test import ( + "bytes" + "fmt" "math" "strings" "testing" @@ -787,7 +789,79 @@ func TestSubnetAddRemove(t *testing.T) { } } -func TestGetMainNICAddress(t *testing.T) { +func TestGetMainNICAddressAddPrimaryNonPrimary(t *testing.T) { + for _, addrLen := range []int{4, 16} { + t.Run(fmt.Sprintf("addrLen=%d", addrLen), func(t *testing.T) { + for canBe := 0; canBe < 3; canBe++ { + t.Run(fmt.Sprintf("canBe=%d", canBe), func(t *testing.T) { + for never := 0; never < 3; never++ { + t.Run(fmt.Sprintf("never=%d", never), func(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) + id, _ := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + // Insert primary and never-primary addresses. + // Each one will add a network endpoint to the NIC. + primaryAddrAdded := make(map[tcpip.Address]tcpip.Subnet) + for i := 0; i < canBe+never; i++ { + var behavior stack.PrimaryEndpointBehavior + if i < canBe { + behavior = stack.CanBePrimaryEndpoint + } else { + behavior = stack.NeverPrimaryEndpoint + } + // Add an address and in case of a primary one also add a + // subnet. + address := tcpip.Address(bytes.Repeat([]byte{byte(i)}, addrLen)) + if err := s.AddAddressWithOptions(1, fakeNetNumber, address, behavior); err != nil { + t.Fatalf("AddAddressWithOptions failed: %v", err) + } + if behavior == stack.CanBePrimaryEndpoint { + mask := tcpip.AddressMask(strings.Repeat("\xff", len(address))) + subnet, err := tcpip.NewSubnet(address, mask) + if err != nil { + t.Fatalf("NewSubnet failed: %v", err) + } + if err := s.AddSubnet(1, fakeNetNumber, subnet); err != nil { + t.Fatalf("AddSubnet failed: %v", err) + } + // Remember the address/subnet. + primaryAddrAdded[address] = subnet + } + } + // Check that GetMainNICAddress returns an address if at least + // one primary address was added. In that case make sure the + // address/subnet matches what we added. + if len(primaryAddrAdded) == 0 { + // No primary addresses present, expect an error. + if _, _, err := s.GetMainNICAddress(1, fakeNetNumber); err != tcpip.ErrNoLinkAddress { + t.Fatalf("got s.GetMainNICAddress(...) = %v, wanted = %v", err, tcpip.ErrNoLinkAddress) + } + } else { + // At least one primary address was added, expect a valid + // address and subnet. + gotAddress, gotSubnet, err := s.GetMainNICAddress(1, fakeNetNumber) + if err != nil { + t.Fatalf("GetMainNICAddress failed: %v", err) + } + expectedSubnet, ok := primaryAddrAdded[gotAddress] + if !ok { + t.Fatalf("GetMainNICAddress: got address = %v, wanted any in {%v}", gotAddress, primaryAddrAdded) + } + if expectedSubnet != gotSubnet { + t.Fatalf("GetMainNICAddress: got subnet = %v, wanted %v", gotSubnet, expectedSubnet) + } + } + }) + } + }) + } + }) + } +} + +func TestGetMainNICAddressAddRemove(t *testing.T) { s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) id, _ := channel.New(10, defaultMTU, "") if err := s.CreateNIC(1, id); err != nil { -- cgit v1.2.3 From 1b3442cae017c4870baf2ed878c63f171029a662 Mon Sep 17 00:00:00 2001 From: Chris Kuiper Date: Thu, 6 Dec 2018 11:47:17 -0800 Subject: Allow sending of broadcast packets w/o route. Currently sending a broadcast packet (for DHCP, e.g.) requires a "default route" of the format "0.0.0.0/0 via 0.0.0.0 ". There is no good reason for this and on devices with several ports this creates a rather akward route table with lots of such default routes (which defeats the purpose of a default route). PiperOrigin-RevId: 224378769 Change-Id: Icd7ec8a206eb08083cff9a837f6f9ab231c73a19 --- pkg/tcpip/stack/BUILD | 1 + pkg/tcpip/stack/stack.go | 24 ++++++++++++++++++------ pkg/tcpip/stack/stack_test.go | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 7 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD index 5e7355135..90cc05cda 100644 --- a/pkg/tcpip/stack/BUILD +++ b/pkg/tcpip/stack/BUILD @@ -40,6 +40,7 @@ go_test( ":stack", "//pkg/tcpip", "//pkg/tcpip/buffer", + "//pkg/tcpip/header", "//pkg/tcpip/link/channel", "//pkg/waiter", ], diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 7af343fba..d39878a88 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -716,12 +716,29 @@ func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocol return "", tcpip.Subnet{}, tcpip.ErrUnknownNICID } +func (s *Stack) getRefEP(nic *NIC, localAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber) (ref *referencedNetworkEndpoint) { + if len(localAddr) == 0 { + return nic.primaryEndpoint(netProto) + } + return nic.findEndpoint(netProto, localAddr, CanBePrimaryEndpoint) +} + // FindRoute creates a route to the given destination address, leaving through // the given nic and local address (if provided). func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber) (Route, *tcpip.Error) { s.mu.RLock() defer s.mu.RUnlock() + // We don't require a route in the table to send a broadcast out on a NIC. + if id != 0 && remoteAddr == header.IPv4Broadcast { + if nic, ok := s.nics[id]; ok { + if ref := s.getRefEP(nic, localAddr, netProto); ref != nil { + return makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref), nil + } + } + return Route{}, tcpip.ErrNoRoute + } + for i := range s.routeTable { if (id != 0 && id != s.routeTable[i].NIC) || (len(remoteAddr) != 0 && !s.routeTable[i].Match(remoteAddr)) { continue @@ -732,12 +749,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n continue } - var ref *referencedNetworkEndpoint - if len(localAddr) != 0 { - ref = nic.findEndpoint(netProto, localAddr, CanBePrimaryEndpoint) - } else { - ref = nic.primaryEndpoint(netProto) - } + ref := s.getRefEP(nic, localAddr, netProto) if ref == nil { continue } diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 8a9c9d234..dc05517ba 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -26,6 +26,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" ) @@ -643,6 +644,42 @@ func TestAddressSpoofing(t *testing.T) { } } +func TestBroadcastNeedsNoRoute(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) + + id, _ := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + s.SetRouteTable([]tcpip.Route{}) + + // If there is no endpoint, it won't work. + if _, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber); err != tcpip.ErrNoRoute { + t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, tcpip.ErrNoRoute) + } + + if err := s.AddAddress(1, fakeNetNumber, header.IPv4Any); err != nil { + t.Fatalf("AddAddress(%v, %v) failed: %v", fakeNetNumber, header.IPv4Any, err) + } + r, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber) + if err != nil { + t.Fatalf("FindRoute(1, %v, %v, %v) failed: %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err) + } + + if r.LocalAddress != header.IPv4Any { + t.Errorf("Bad local address: got %v, want = %v", r.LocalAddress, header.IPv4Any) + } + + if r.RemoteAddress != header.IPv4Broadcast { + t.Errorf("Bad remote address: got %v, want = %v", r.RemoteAddress, header.IPv4Broadcast) + } + + // If the NIC doesn't exist, it won't work. + if _, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber); err != tcpip.ErrNoRoute { + t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, tcpip.ErrNoRoute) + } +} + // Set the subnet, then check that packet is delivered. func TestSubnetAcceptsMatchingPacket(t *testing.T) { s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) @@ -849,7 +886,7 @@ func TestGetMainNICAddressAddPrimaryNonPrimary(t *testing.T) { if !ok { t.Fatalf("GetMainNICAddress: got address = %v, wanted any in {%v}", gotAddress, primaryAddrAdded) } - if expectedSubnet != gotSubnet { + if gotSubnet != expectedSubnet { t.Fatalf("GetMainNICAddress: got subnet = %v, wanted %v", gotSubnet, expectedSubnet) } } -- cgit v1.2.3 From e491ebbacf548a2a2f818f1093b09d6f1c13e7e0 Mon Sep 17 00:00:00 2001 From: Chris Kuiper Date: Sun, 16 Dec 2018 23:04:56 -0800 Subject: Allow sending of multicast and IPv6 link-local packets w/o route. Same as with broadcast packets, sending of a multicast packet shouldn't require accessing the route table. The same applies to IPv6 link-local addresses, which aren't routable at all (they don't belong to any subnet by definition). PiperOrigin-RevId: 225775870 Change-Id: Ic53e6560c125a83be2be9c3d112e66b36e8dfe7b --- pkg/tcpip/header/ipv6.go | 12 ++++++ pkg/tcpip/stack/stack.go | 7 +++- pkg/tcpip/stack/stack_test.go | 86 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go index d985b745d..3d24736c7 100644 --- a/pkg/tcpip/header/ipv6.go +++ b/pkg/tcpip/header/ipv6.go @@ -77,6 +77,9 @@ const ( // IPv6MinimumMTU is the minimum MTU required by IPv6, per RFC 2460, // section 5. IPv6MinimumMTU = 1280 + + // IPv6Any is the non-routable IPv6 "any" meta address. + IPv6Any tcpip.Address = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" ) // PayloadLength returns the value of the "payload length" field of the ipv6 @@ -234,3 +237,12 @@ func LinkLocalAddr(linkAddr tcpip.LinkAddress) tcpip.Address { } return tcpip.Address(lladdrb[:]) } + +// IsV6LinkLocalAddress determines if the provided address is an IPv6 +// link-local address (fe80::/10). +func IsV6LinkLocalAddress(addr tcpip.Address) bool { + if len(addr) != IPv6AddressSize { + return false + } + return addr[0] == 0xfe && (addr[1]&0xc0) == 0x80 +} diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index d39878a88..0ac116675 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -729,8 +729,11 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n s.mu.RLock() defer s.mu.RUnlock() - // We don't require a route in the table to send a broadcast out on a NIC. - if id != 0 && remoteAddr == header.IPv4Broadcast { + // We don't require a route in the table to send a broadcast, multicast or + // IPv6 link-local packet out on a NIC. + isBroadcast := remoteAddr == header.IPv4Broadcast + isMulticast := header.IsV4MulticastAddress(remoteAddr) || header.IsV6MulticastAddress(remoteAddr) + if id != 0 && (isBroadcast || isMulticast || header.IsV6LinkLocalAddress(remoteAddr)) { if nic, ok := s.nics[id]; ok { if ref := s.getRefEP(nic, localAddr, netProto); ref != nil { return makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref), nil diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index dc05517ba..391319f35 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -680,6 +680,92 @@ func TestBroadcastNeedsNoRoute(t *testing.T) { } } +func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) { + for _, tc := range []struct { + name string + routeNeeded bool + address tcpip.Address + }{ + // IPv4 multicast address range: 224.0.0.0 - 239.255.255.255 + // <=> 0xe0.0x00.0x00.0x00 - 0xef.0xff.0xff.0xff + {"IPv4 Multicast 1", false, "\xe0\x00\x00\x00"}, + {"IPv4 Multicast 2", false, "\xef\xff\xff\xff"}, + {"IPv4 Unicast 1", true, "\xdf\xff\xff\xff"}, + {"IPv4 Unicast 2", true, "\xf0\x00\x00\x00"}, + {"IPv4 Unicast 3", true, "\x00\x00\x00\x00"}, + + // IPv6 multicast address is 0xff[8] + flags[4] + scope[4] + groupId[112] + {"IPv6 Multicast 1", false, "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Multicast 2", false, "\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Multicast 3", false, "\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"}, + + // IPv6 link-local address starts with fe80::/10. + {"IPv6 Unicast Link-Local 1", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Unicast Link-Local 2", false, "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"}, + {"IPv6 Unicast Link-Local 3", false, "\xfe\x80\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff"}, + {"IPv6 Unicast Link-Local 4", false, "\xfe\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Unicast Link-Local 5", false, "\xfe\xbf\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"}, + + // IPv6 addresses that are neither multicast nor link-local. + {"IPv6 Unicast Not Link-Local 1", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Unicast Not Link-Local 2", true, "\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"}, + {"IPv6 Unicast Not Link-local 3", true, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Unicast Not Link-Local 4", true, "\xfe\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Unicast Not Link-Local 5", true, "\xfe\xdf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Unicast Not Link-Local 6", true, "\xfd\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + {"IPv6 Unicast Not Link-Local 7", true, "\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, + } { + t.Run(tc.name, func(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) + + id, _ := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + + s.SetRouteTable([]tcpip.Route{}) + + var anyAddr tcpip.Address + if len(tc.address) == header.IPv4AddressSize { + anyAddr = header.IPv4Any + } else { + anyAddr = header.IPv6Any + } + + // If there is no endpoint, it won't work. + if _, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber); err != tcpip.ErrNoRoute { + t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute) + } + + if err := s.AddAddress(1, fakeNetNumber, anyAddr); err != nil { + t.Fatalf("AddAddress(%v, %v) failed: %v", fakeNetNumber, anyAddr, err) + } + + r, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber) + if tc.routeNeeded { + // Route table is empty but we need a route, this should cause an error. + if err != tcpip.ErrNoRoute { + t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute) + } + } else { + if err != nil { + t.Fatalf("FindRoute(1, %v, %v, %v) failed: %v", anyAddr, tc.address, fakeNetNumber, err) + } + if r.LocalAddress != anyAddr { + t.Errorf("Bad local address: got %v, want = %v", r.LocalAddress, anyAddr) + } + if r.RemoteAddress != tc.address { + t.Errorf("Bad remote address: got %v, want = %v", r.RemoteAddress, tc.address) + } + } + // If the NIC doesn't exist, it won't work. + if _, err := s.FindRoute(2, anyAddr, tc.address, fakeNetNumber); err != tcpip.ErrNoRoute { + t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute) + } + }) + } +} + // Set the subnet, then check that packet is delivered. func TestSubnetAcceptsMatchingPacket(t *testing.T) { s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) -- cgit v1.2.3 From 652d068119052b0b3bc4a0808a4400a22380a30b Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Fri, 28 Dec 2018 11:26:01 -0800 Subject: Implement SO_REUSEPORT for TCP and UDP sockets This option allows multiple sockets to be bound to the same port. Incoming packets are distributed to sockets using a hash based on source and destination addresses. This means that all packets from one sender will be received by the same server socket. PiperOrigin-RevId: 227153413 Change-Id: I59b6edda9c2209d5b8968671e9129adb675920cf --- pkg/sentry/socket/epsocket/epsocket.go | 20 ++ pkg/sentry/socket/rpcinet/socket.go | 5 +- pkg/tcpip/hash/jenkins/BUILD | 21 ++ pkg/tcpip/hash/jenkins/jenkins.go | 80 ++++++++ pkg/tcpip/hash/jenkins/jenkins_test.go | 176 +++++++++++++++++ pkg/tcpip/ports/BUILD | 4 +- pkg/tcpip/ports/ports.go | 74 +++++-- pkg/tcpip/ports/ports_test.go | 134 ++++++++----- pkg/tcpip/stack/BUILD | 1 + pkg/tcpip/stack/stack.go | 12 +- pkg/tcpip/stack/transport_demuxer.go | 144 +++++++++++++- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/tcpip.go | 4 + pkg/tcpip/transport/ping/endpoint.go | 8 +- pkg/tcpip/transport/tcp/accept.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 34 +++- pkg/tcpip/transport/udp/endpoint.go | 30 ++- pkg/tcpip/transport/udp/udp_test.go | 85 ++++++++ test/syscalls/linux/BUILD | 4 + test/syscalls/linux/socket_inet_loopback.cc | 289 ++++++++++++++++++++++++++++ test/syscalls/syscall_test_runner.go | 1 + 21 files changed, 1025 insertions(+), 105 deletions(-) create mode 100644 pkg/tcpip/hash/jenkins/BUILD create mode 100644 pkg/tcpip/hash/jenkins/jenkins.go create mode 100644 pkg/tcpip/hash/jenkins/jenkins_test.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 1b9c75949..d65b5f49e 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -634,6 +634,18 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family return int32(v), nil + case linux.SO_REUSEPORT: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + + var v tcpip.ReusePortOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + return int32(v), nil + case linux.SO_KEEPALIVE: if outLen < sizeOfInt32 { return nil, syserr.ErrInvalidArgument @@ -900,6 +912,14 @@ func setSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name i v := usermem.ByteOrder.Uint32(optVal) return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.ReuseAddressOption(v))) + case linux.SO_REUSEPORT: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.ReusePortOption(v))) + case linux.SO_PASSCRED: if len(optVal) < sizeOfInt32 { return syserr.ErrInvalidArgument diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index 257bc2d71..8c8ebadb7 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -285,7 +285,10 @@ func (s *socketOperations) Accept(t *kernel.Task, peerRequested bool, flags int, if blocking && se == syserr.ErrTryAgain { // Register for notifications. e, ch := waiter.NewChannelEntry(nil) - s.EventRegister(&e, waiter.EventIn) + // FIXME: This waiter.EventHUp is a partial + // measure, need to figure out how to translate linux events to + // internal events. + s.EventRegister(&e, waiter.EventIn|waiter.EventHUp) defer s.EventUnregister(&e) // Try to accept the connection again; if it fails, then wait until we diff --git a/pkg/tcpip/hash/jenkins/BUILD b/pkg/tcpip/hash/jenkins/BUILD new file mode 100644 index 000000000..bbb764db8 --- /dev/null +++ b/pkg/tcpip/hash/jenkins/BUILD @@ -0,0 +1,21 @@ +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") + +package(licenses = ["notice"]) # Apache 2.0 + +go_library( + name = "jenkins", + srcs = ["jenkins.go"], + importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/hash/jenkins", + visibility = [ + "//visibility:public", + ], +) + +go_test( + name = "jenkins_test", + size = "small", + srcs = [ + "jenkins_test.go", + ], + embed = [":jenkins"], +) diff --git a/pkg/tcpip/hash/jenkins/jenkins.go b/pkg/tcpip/hash/jenkins/jenkins.go new file mode 100644 index 000000000..e66d5f12b --- /dev/null +++ b/pkg/tcpip/hash/jenkins/jenkins.go @@ -0,0 +1,80 @@ +// Copyright 2018 Google LLC +// +// 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 jenkins implements Jenkins's one_at_a_time, non-cryptographic hash +// functions created by by Bob Jenkins. +// +// See https://en.wikipedia.org/wiki/Jenkins_hash_function#cite_note-dobbsx-1 +// +package jenkins + +import ( + "hash" +) + +// Sum32 represents Jenkins's one_at_a_time hash. +// +// Use the Sum32 type directly (as opposed to New32 below) +// to avoid allocations. +type Sum32 uint32 + +// New32 returns a new 32-bit Jenkins's one_at_a_time hash.Hash. +// +// Its Sum method will lay the value out in big-endian byte order. +func New32() hash.Hash32 { + var s Sum32 + return &s +} + +// Reset resets the hash to its initial state. +func (s *Sum32) Reset() { *s = 0 } + +// Sum32 returns the hash value +func (s *Sum32) Sum32() uint32 { + hash := *s + + hash += (hash << 3) + hash ^= hash >> 11 + hash += hash << 15 + + return uint32(hash) +} + +// Write adds more data to the running hash. +// +// It never returns an error. +func (s *Sum32) Write(data []byte) (int, error) { + hash := *s + for _, b := range data { + hash += Sum32(b) + hash += hash << 10 + hash ^= hash >> 6 + } + *s = hash + return len(data), nil +} + +// Size returns the number of bytes Sum will return. +func (s *Sum32) Size() int { return 4 } + +// BlockSize returns the hash's underlying block size. +func (s *Sum32) BlockSize() int { return 1 } + +// Sum appends the current hash to in and returns the resulting slice. +// +// It does not change the underlying hash state. +func (s *Sum32) Sum(in []byte) []byte { + v := s.Sum32() + return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} diff --git a/pkg/tcpip/hash/jenkins/jenkins_test.go b/pkg/tcpip/hash/jenkins/jenkins_test.go new file mode 100644 index 000000000..9d86174aa --- /dev/null +++ b/pkg/tcpip/hash/jenkins/jenkins_test.go @@ -0,0 +1,176 @@ +// Copyright 2018 Google LLC +// +// 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 jenkins + +import ( + "bytes" + "encoding/binary" + "hash" + "hash/fnv" + "math" + "testing" +) + +func TestGolden32(t *testing.T) { + var golden32 = []struct { + out []byte + in string + }{ + {[]byte{0x00, 0x00, 0x00, 0x00}, ""}, + {[]byte{0xca, 0x2e, 0x94, 0x42}, "a"}, + {[]byte{0x45, 0xe6, 0x1e, 0x58}, "ab"}, + {[]byte{0xed, 0x13, 0x1f, 0x5b}, "abc"}, + } + + hash := New32() + + for _, g := range golden32 { + hash.Reset() + done, error := hash.Write([]byte(g.in)) + if error != nil { + t.Fatalf("write error: %s", error) + } + if done != len(g.in) { + t.Fatalf("wrote only %d out of %d bytes", done, len(g.in)) + } + if actual := hash.Sum(nil); !bytes.Equal(g.out, actual) { + t.Errorf("hash(%q) = 0x%x want 0x%x", g.in, actual, g.out) + } + } +} + +func TestIntegrity32(t *testing.T) { + data := []byte{'1', '2', 3, 4, 5} + + h := New32() + h.Write(data) + sum := h.Sum(nil) + + if size := h.Size(); size != len(sum) { + t.Fatalf("Size()=%d but len(Sum())=%d", size, len(sum)) + } + + if a := h.Sum(nil); !bytes.Equal(sum, a) { + t.Fatalf("first Sum()=0x%x, second Sum()=0x%x", sum, a) + } + + h.Reset() + h.Write(data) + if a := h.Sum(nil); !bytes.Equal(sum, a) { + t.Fatalf("Sum()=0x%x, but after Reset() Sum()=0x%x", sum, a) + } + + h.Reset() + h.Write(data[:2]) + h.Write(data[2:]) + if a := h.Sum(nil); !bytes.Equal(sum, a) { + t.Fatalf("Sum()=0x%x, but with partial writes, Sum()=0x%x", sum, a) + } + + sum32 := h.(hash.Hash32).Sum32() + if sum32 != binary.BigEndian.Uint32(sum) { + t.Fatalf("Sum()=0x%x, but Sum32()=0x%x", sum, sum32) + } +} + +func BenchmarkJenkins32KB(b *testing.B) { + h := New32() + + b.SetBytes(1024) + data := make([]byte, 1024) + for i := range data { + data[i] = byte(i) + } + in := make([]byte, 0, h.Size()) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + h.Reset() + h.Write(data) + h.Sum(in) + } +} + +func BenchmarkFnv32(b *testing.B) { + arr := make([]int64, 1000) + for i := 0; i < b.N; i++ { + var payload [8]byte + binary.BigEndian.PutUint32(payload[:4], uint32(i)) + binary.BigEndian.PutUint32(payload[4:], uint32(i)) + + h := fnv.New32() + h.Write(payload[:]) + idx := int(h.Sum32()) % len(arr) + arr[idx]++ + } + b.StopTimer() + c := 0 + if b.N > 1000000 { + for i := 0; i < len(arr)-1; i++ { + if math.Abs(float64(arr[i]-arr[i+1]))/float64(arr[i]) > float64(0.1) { + if c == 0 { + b.Logf("i %d val[i] %d val[i+1] %d b.N %b\n", i, arr[i], arr[i+1], b.N) + } + c++ + } + } + if c > 0 { + b.Logf("Unbalanced buckets: %d", c) + } + } +} + +func BenchmarkSum32(b *testing.B) { + arr := make([]int64, 1000) + for i := 0; i < b.N; i++ { + var payload [8]byte + binary.BigEndian.PutUint32(payload[:4], uint32(i)) + binary.BigEndian.PutUint32(payload[4:], uint32(i)) + h := Sum32(0) + h.Write(payload[:]) + idx := int(h.Sum32()) % len(arr) + arr[idx]++ + } + b.StopTimer() + if b.N > 1000000 { + for i := 0; i < len(arr)-1; i++ { + if math.Abs(float64(arr[i]-arr[i+1]))/float64(arr[i]) > float64(0.1) { + b.Logf("val[%3d]=%8d\tval[%3d]=%8d\tb.N=%b\n", i, arr[i], i+1, arr[i+1], b.N) + break + } + } + } +} + +func BenchmarkNew32(b *testing.B) { + arr := make([]int64, 1000) + for i := 0; i < b.N; i++ { + var payload [8]byte + binary.BigEndian.PutUint32(payload[:4], uint32(i)) + binary.BigEndian.PutUint32(payload[4:], uint32(i)) + h := New32() + h.Write(payload[:]) + idx := int(h.Sum32()) % len(arr) + arr[idx]++ + } + b.StopTimer() + if b.N > 1000000 { + for i := 0; i < len(arr)-1; i++ { + if math.Abs(float64(arr[i]-arr[i+1]))/float64(arr[i]) > float64(0.1) { + b.Logf("val[%3d]=%8d\tval[%3d]=%8d\tb.N=%b\n", i, arr[i], i+1, arr[i+1], b.N) + break + } + } + } +} diff --git a/pkg/tcpip/ports/BUILD b/pkg/tcpip/ports/BUILD index c69fc0744..a2fa9b84a 100644 --- a/pkg/tcpip/ports/BUILD +++ b/pkg/tcpip/ports/BUILD @@ -7,7 +7,9 @@ go_library( srcs = ["ports.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/ports", visibility = ["//:sandbox"], - deps = ["//pkg/tcpip"], + deps = [ + "//pkg/tcpip", + ], ) go_test( diff --git a/pkg/tcpip/ports/ports.go b/pkg/tcpip/ports/ports.go index 41ef32921..d212a5792 100644 --- a/pkg/tcpip/ports/ports.go +++ b/pkg/tcpip/ports/ports.go @@ -42,23 +42,47 @@ type PortManager struct { allocatedPorts map[portDescriptor]bindAddresses } +type portNode struct { + reuse bool + refs int +} + // bindAddresses is a set of IP addresses. -type bindAddresses map[tcpip.Address]struct{} +type bindAddresses map[tcpip.Address]portNode // isAvailable checks whether an IP address is available to bind to. -func (b bindAddresses) isAvailable(addr tcpip.Address) bool { +func (b bindAddresses) isAvailable(addr tcpip.Address, reuse bool) bool { if addr == anyIPAddress { - return len(b) == 0 + if len(b) == 0 { + return true + } + if !reuse { + return false + } + for _, n := range b { + if !n.reuse { + return false + } + } + return true } // If all addresses for this portDescriptor are already bound, no // address is available. - if _, ok := b[anyIPAddress]; ok { - return false + if n, ok := b[anyIPAddress]; ok { + if !reuse { + return false + } + if !n.reuse { + return false + } } - if _, ok := b[addr]; ok { - return false + if n, ok := b[addr]; ok { + if !reuse { + return false + } + return n.reuse } return true } @@ -92,17 +116,17 @@ func (s *PortManager) PickEphemeralPort(testPort func(p uint16) (bool, *tcpip.Er } // IsPortAvailable tests if the given port is available on all given protocols. -func (s *PortManager) IsPortAvailable(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16) bool { +func (s *PortManager) IsPortAvailable(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16, reuse bool) bool { s.mu.Lock() defer s.mu.Unlock() - return s.isPortAvailableLocked(networks, transport, addr, port) + return s.isPortAvailableLocked(networks, transport, addr, port, reuse) } -func (s *PortManager) isPortAvailableLocked(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16) bool { +func (s *PortManager) isPortAvailableLocked(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16, reuse bool) bool { for _, network := range networks { desc := portDescriptor{network, transport, port} if addrs, ok := s.allocatedPorts[desc]; ok { - if !addrs.isAvailable(addr) { + if !addrs.isAvailable(addr, reuse) { return false } } @@ -114,14 +138,14 @@ func (s *PortManager) isPortAvailableLocked(networks []tcpip.NetworkProtocolNumb // reserved by another endpoint. If port is zero, ReservePort will search for // an unreserved ephemeral port and reserve it, returning its value in the // "port" return value. -func (s *PortManager) ReservePort(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16) (reservedPort uint16, err *tcpip.Error) { +func (s *PortManager) ReservePort(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16, reuse bool) (reservedPort uint16, err *tcpip.Error) { s.mu.Lock() defer s.mu.Unlock() // If a port is specified, just try to reserve it for all network // protocols. if port != 0 { - if !s.reserveSpecificPort(networks, transport, addr, port) { + if !s.reserveSpecificPort(networks, transport, addr, port, reuse) { return 0, tcpip.ErrPortInUse } return port, nil @@ -129,13 +153,13 @@ func (s *PortManager) ReservePort(networks []tcpip.NetworkProtocolNumber, transp // A port wasn't specified, so try to find one. return s.PickEphemeralPort(func(p uint16) (bool, *tcpip.Error) { - return s.reserveSpecificPort(networks, transport, addr, p), nil + return s.reserveSpecificPort(networks, transport, addr, p, reuse), nil }) } // reserveSpecificPort tries to reserve the given port on all given protocols. -func (s *PortManager) reserveSpecificPort(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16) bool { - if !s.isPortAvailableLocked(networks, transport, addr, port) { +func (s *PortManager) reserveSpecificPort(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16, reuse bool) bool { + if !s.isPortAvailableLocked(networks, transport, addr, port, reuse) { return false } @@ -147,7 +171,12 @@ func (s *PortManager) reserveSpecificPort(networks []tcpip.NetworkProtocolNumber m = make(bindAddresses) s.allocatedPorts[desc] = m } - m[addr] = struct{}{} + if n, ok := m[addr]; ok { + n.refs++ + m[addr] = n + } else { + m[addr] = portNode{reuse: reuse, refs: 1} + } } return true @@ -162,7 +191,16 @@ func (s *PortManager) ReleasePort(networks []tcpip.NetworkProtocolNumber, transp for _, network := range networks { desc := portDescriptor{network, transport, port} if m, ok := s.allocatedPorts[desc]; ok { - delete(m, addr) + n, ok := m[addr] + if !ok { + continue + } + n.refs-- + if n.refs == 0 { + delete(m, addr) + } else { + m[addr] = n + } if len(m) == 0 { delete(s.allocatedPorts, desc) } diff --git a/pkg/tcpip/ports/ports_test.go b/pkg/tcpip/ports/ports_test.go index 72577dfcb..01e7320b4 100644 --- a/pkg/tcpip/ports/ports_test.go +++ b/pkg/tcpip/ports/ports_test.go @@ -28,67 +28,99 @@ const ( fakeIPAddress1 = tcpip.Address("\x08\x08\x08\x09") ) -func TestPortReservation(t *testing.T) { - pm := NewPortManager() - net := []tcpip.NetworkProtocolNumber{fakeNetworkNumber} +type portReserveTestAction struct { + port uint16 + ip tcpip.Address + want *tcpip.Error + reuse bool + release bool +} +func TestPortReservation(t *testing.T) { for _, test := range []struct { - port uint16 - ip tcpip.Address - want *tcpip.Error + tname string + actions []portReserveTestAction }{ { - port: 80, - ip: fakeIPAddress, - want: nil, - }, - { - port: 80, - ip: fakeIPAddress1, - want: nil, - }, - { - /* N.B. Order of tests matters! */ - port: 80, - ip: anyIPAddress, - want: tcpip.ErrPortInUse, - }, - { - port: 22, - ip: anyIPAddress, - want: nil, - }, - { - port: 22, - ip: fakeIPAddress, - want: tcpip.ErrPortInUse, - }, - { - port: 0, - ip: fakeIPAddress, - want: nil, + tname: "bind to ip", + actions: []portReserveTestAction{ + {port: 80, ip: fakeIPAddress, want: nil}, + {port: 80, ip: fakeIPAddress1, want: nil}, + /* N.B. Order of tests matters! */ + {port: 80, ip: anyIPAddress, want: tcpip.ErrPortInUse}, + {port: 80, ip: fakeIPAddress, want: tcpip.ErrPortInUse, reuse: true}, + }, }, { - port: 0, - ip: fakeIPAddress, - want: nil, + tname: "bind to inaddr any", + actions: []portReserveTestAction{ + {port: 22, ip: anyIPAddress, want: nil}, + {port: 22, ip: fakeIPAddress, want: tcpip.ErrPortInUse}, + /* release fakeIPAddress, but anyIPAddress is still inuse */ + {port: 22, ip: fakeIPAddress, release: true}, + {port: 22, ip: fakeIPAddress, want: tcpip.ErrPortInUse}, + {port: 22, ip: fakeIPAddress, want: tcpip.ErrPortInUse, reuse: true}, + /* Release port 22 from any IP address, then try to reserve fake IP address on 22 */ + {port: 22, ip: anyIPAddress, want: nil, release: true}, + {port: 22, ip: fakeIPAddress, want: nil}, + }, + }, { + tname: "bind to zero port", + actions: []portReserveTestAction{ + {port: 00, ip: fakeIPAddress, want: nil}, + {port: 00, ip: fakeIPAddress, want: nil}, + {port: 00, ip: fakeIPAddress, reuse: true, want: nil}, + }, + }, { + tname: "bind to ip with reuseport", + actions: []portReserveTestAction{ + {port: 25, ip: fakeIPAddress, reuse: true, want: nil}, + {port: 25, ip: fakeIPAddress, reuse: true, want: nil}, + + {port: 25, ip: fakeIPAddress, reuse: false, want: tcpip.ErrPortInUse}, + {port: 25, ip: anyIPAddress, reuse: false, want: tcpip.ErrPortInUse}, + + {port: 25, ip: anyIPAddress, reuse: true, want: nil}, + }, + }, { + tname: "bind to inaddr any with reuseport", + actions: []portReserveTestAction{ + {port: 24, ip: anyIPAddress, reuse: true, want: nil}, + {port: 24, ip: anyIPAddress, reuse: true, want: nil}, + + {port: 24, ip: anyIPAddress, reuse: false, want: tcpip.ErrPortInUse}, + {port: 24, ip: fakeIPAddress, reuse: false, want: tcpip.ErrPortInUse}, + + {port: 24, ip: fakeIPAddress, reuse: true, want: nil}, + {port: 24, ip: fakeIPAddress, release: true, want: nil}, + + {port: 24, ip: anyIPAddress, release: true}, + {port: 24, ip: anyIPAddress, reuse: false, want: tcpip.ErrPortInUse}, + + {port: 24, ip: anyIPAddress, release: true}, + {port: 24, ip: anyIPAddress, reuse: false, want: nil}, + }, }, } { - gotPort, err := pm.ReservePort(net, fakeTransNumber, test.ip, test.port) - if err != test.want { - t.Fatalf("ReservePort(.., .., %s, %d) = %v, want %v", test.ip, test.port, err, test.want) - } - if test.port == 0 && (gotPort == 0 || gotPort < FirstEphemeral) { - t.Fatalf("ReservePort(.., .., .., 0) = %d, want port number >= %d to be picked", gotPort, FirstEphemeral) - } - } + t.Run(test.tname, func(t *testing.T) { + pm := NewPortManager() + net := []tcpip.NetworkProtocolNumber{fakeNetworkNumber} - // Release port 22 from any IP address, then try to reserve fake IP - // address on 22. - pm.ReleasePort(net, fakeTransNumber, anyIPAddress, 22) + for _, test := range test.actions { + if test.release { + pm.ReleasePort(net, fakeTransNumber, test.ip, test.port) + continue + } + gotPort, err := pm.ReservePort(net, fakeTransNumber, test.ip, test.port, test.reuse) + if err != test.want { + t.Fatalf("ReservePort(.., .., %s, %d, %t) = %v, want %v", test.ip, test.port, test.release, err, test.want) + } + if test.port == 0 && (gotPort == 0 || gotPort < FirstEphemeral) { + t.Fatalf("ReservePort(.., .., .., 0) = %d, want port number >= %d to be picked", gotPort, FirstEphemeral) + } + } + }) - if port, err := pm.ReservePort(net, fakeTransNumber, fakeIPAddress, 22); port != 22 || err != nil { - t.Fatalf("ReservePort(.., .., .., %d) = (port %d, err %v), want (22, nil); failed to reserve port after it should have been released", 22, port, err) } } diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD index 90cc05cda..9ff1c8731 100644 --- a/pkg/tcpip/stack/BUILD +++ b/pkg/tcpip/stack/BUILD @@ -22,6 +22,7 @@ go_library( "//pkg/sleep", "//pkg/tcpip", "//pkg/tcpip/buffer", + "//pkg/tcpip/hash/jenkins", "//pkg/tcpip/header", "//pkg/tcpip/ports", "//pkg/tcpip/seqnum", diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 0ac116675..7aa9dbd46 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -883,9 +883,9 @@ func (s *Stack) RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep. // transport dispatcher. Received packets that match the provided id will be // delivered to the given endpoint; specifying a nic is optional, but // nic-specific IDs have precedence over global ones. -func (s *Stack) RegisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint) *tcpip.Error { +func (s *Stack) RegisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint, reusePort bool) *tcpip.Error { if nicID == 0 { - return s.demux.registerEndpoint(netProtos, protocol, id, ep) + return s.demux.registerEndpoint(netProtos, protocol, id, ep, reusePort) } s.mu.RLock() @@ -896,14 +896,14 @@ func (s *Stack) RegisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.N return tcpip.ErrUnknownNICID } - return nic.demux.registerEndpoint(netProtos, protocol, id, ep) + return nic.demux.registerEndpoint(netProtos, protocol, id, ep, reusePort) } // UnregisterTransportEndpoint removes the endpoint with the given id from the // stack transport dispatcher. -func (s *Stack) UnregisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID) { +func (s *Stack) UnregisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint) { if nicID == 0 { - s.demux.unregisterEndpoint(netProtos, protocol, id) + s.demux.unregisterEndpoint(netProtos, protocol, id, ep) return } @@ -912,7 +912,7 @@ func (s *Stack) UnregisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip nic := s.nics[nicID] if nic != nil { - nic.demux.unregisterEndpoint(netProtos, protocol, id) + nic.demux.unregisterEndpoint(netProtos, protocol, id, ep) } } diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index c8522ad9e..a5ff2159a 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -15,10 +15,12 @@ package stack import ( + "math/rand" "sync" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/hash/jenkins" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" ) @@ -34,6 +36,23 @@ type transportEndpoints struct { endpoints map[TransportEndpointID]TransportEndpoint } +// unregisterEndpoint unregisters the endpoint with the given id such that it +// won't receive any more packets. +func (eps *transportEndpoints) unregisterEndpoint(id TransportEndpointID, ep TransportEndpoint) { + eps.mu.Lock() + defer eps.mu.Unlock() + e, ok := eps.endpoints[id] + if !ok { + return + } + if multiPortEp, ok := e.(*multiPortEndpoint); ok { + if !multiPortEp.unregisterEndpoint(ep) { + return + } + } + delete(eps.endpoints, id) +} + // transportDemuxer demultiplexes packets targeted at a transport endpoint // (i.e., after they've been parsed by the network layer). It does two levels // of demultiplexing: first based on the network and transport protocols, then @@ -57,10 +76,10 @@ func newTransportDemuxer(stack *Stack) *transportDemuxer { // registerEndpoint registers the given endpoint with the dispatcher such that // packets that match the endpoint ID are delivered to it. -func (d *transportDemuxer) registerEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint) *tcpip.Error { +func (d *transportDemuxer) registerEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint, reusePort bool) *tcpip.Error { for i, n := range netProtos { - if err := d.singleRegisterEndpoint(n, protocol, id, ep); err != nil { - d.unregisterEndpoint(netProtos[:i], protocol, id) + if err := d.singleRegisterEndpoint(n, protocol, id, ep, reusePort); err != nil { + d.unregisterEndpoint(netProtos[:i], protocol, id, ep) return err } } @@ -68,7 +87,97 @@ func (d *transportDemuxer) registerEndpoint(netProtos []tcpip.NetworkProtocolNum return nil } -func (d *transportDemuxer) singleRegisterEndpoint(netProto tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint) *tcpip.Error { +// multiPortEndpoint is a container for TransportEndpoints which are bound to +// the same pair of address and port. +type multiPortEndpoint struct { + mu sync.RWMutex + endpointsArr []TransportEndpoint + endpointsMap map[TransportEndpoint]int + // seed is a random secret for a jenkins hash. + seed uint32 +} + +// reciprocalScale scales a value into range [0, n). +// +// This is similar to val % n, but faster. +// See http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ +func reciprocalScale(val, n uint32) uint32 { + return uint32((uint64(val) * uint64(n)) >> 32) +} + +// selectEndpoint calculates a hash of destination and source addresses and +// ports then uses it to select a socket. In this case, all packets from one +// address will be sent to same endpoint. +func (ep *multiPortEndpoint) selectEndpoint(id TransportEndpointID) TransportEndpoint { + ep.mu.RLock() + defer ep.mu.RUnlock() + + payload := []byte{ + byte(id.LocalPort), + byte(id.LocalPort >> 8), + byte(id.RemotePort), + byte(id.RemotePort >> 8), + } + + h := jenkins.Sum32(ep.seed) + h.Write(payload) + h.Write([]byte(id.LocalAddress)) + h.Write([]byte(id.RemoteAddress)) + hash := h.Sum32() + + idx := reciprocalScale(hash, uint32(len(ep.endpointsArr))) + return ep.endpointsArr[idx] +} + +// HandlePacket is called by the stack when new packets arrive to this transport +// endpoint. +func (ep *multiPortEndpoint) HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) { + ep.selectEndpoint(id).HandlePacket(r, id, vv) +} + +// HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. +func (ep *multiPortEndpoint) HandleControlPacket(id TransportEndpointID, typ ControlType, extra uint32, vv buffer.VectorisedView) { + ep.selectEndpoint(id).HandleControlPacket(id, typ, extra, vv) +} + +func (ep *multiPortEndpoint) singleRegisterEndpoint(t TransportEndpoint) { + ep.mu.Lock() + defer ep.mu.Unlock() + + // A new endpoint is added into endpointsArr and its index there is + // saved in endpointsMap. This will allows to remove endpoint from + // the array fast. + ep.endpointsMap[ep] = len(ep.endpointsArr) + ep.endpointsArr = append(ep.endpointsArr, t) +} + +// unregisterEndpoint returns true if multiPortEndpoint has to be unregistered. +func (ep *multiPortEndpoint) unregisterEndpoint(t TransportEndpoint) bool { + ep.mu.Lock() + defer ep.mu.Unlock() + + idx, ok := ep.endpointsMap[t] + if !ok { + return false + } + delete(ep.endpointsMap, t) + l := len(ep.endpointsArr) + if l > 1 { + // The last endpoint in endpointsArr is moved instead of the deleted one. + lastEp := ep.endpointsArr[l-1] + ep.endpointsArr[idx] = lastEp + ep.endpointsMap[lastEp] = idx + ep.endpointsArr = ep.endpointsArr[0 : l-1] + return false + } + return true +} + +func (d *transportDemuxer) singleRegisterEndpoint(netProto tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint, reusePort bool) *tcpip.Error { + if id.RemotePort != 0 { + reusePort = false + } + eps, ok := d.protocol[protocolIDs{netProto, protocol}] if !ok { return nil @@ -77,10 +186,29 @@ func (d *transportDemuxer) singleRegisterEndpoint(netProto tcpip.NetworkProtocol eps.mu.Lock() defer eps.mu.Unlock() + var multiPortEp *multiPortEndpoint if _, ok := eps.endpoints[id]; ok { - return tcpip.ErrPortInUse + if !reusePort { + return tcpip.ErrPortInUse + } + multiPortEp, ok = eps.endpoints[id].(*multiPortEndpoint) + if !ok { + return tcpip.ErrPortInUse + } } + if reusePort { + if multiPortEp == nil { + multiPortEp = &multiPortEndpoint{} + multiPortEp.endpointsMap = make(map[TransportEndpoint]int) + multiPortEp.seed = rand.Uint32() + eps.endpoints[id] = multiPortEp + } + + multiPortEp.singleRegisterEndpoint(ep) + + return nil + } eps.endpoints[id] = ep return nil @@ -88,12 +216,10 @@ func (d *transportDemuxer) singleRegisterEndpoint(netProto tcpip.NetworkProtocol // unregisterEndpoint unregisters the endpoint with the given id such that it // won't receive any more packets. -func (d *transportDemuxer) unregisterEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID) { +func (d *transportDemuxer) unregisterEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, id TransportEndpointID, ep TransportEndpoint) { for _, n := range netProtos { if eps, ok := d.protocol[protocolIDs{n, protocol}]; ok { - eps.mu.Lock() - delete(eps.endpoints, id) - eps.mu.Unlock() + eps.unregisterEndpoint(id, ep) } } } diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index f09760180..022207081 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -107,7 +107,7 @@ func (f *fakeTransportEndpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { // Try to register so that we can start receiving packets. f.id.RemoteAddress = addr.Addr - err = f.stack.RegisterTransportEndpoint(0, []tcpip.NetworkProtocolNumber{fakeNetNumber}, fakeTransNumber, f.id, f) + err = f.stack.RegisterTransportEndpoint(0, []tcpip.NetworkProtocolNumber{fakeNetNumber}, fakeTransNumber, f.id, f, false) if err != nil { return err } diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 627786808..7d4fbe075 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -436,6 +436,10 @@ type CorkOption int // should allow reuse of local address. type ReuseAddressOption int +// ReusePortOption is used by SetSockOpt/GetSockOpt to permit multiple sockets +// to be bound to an identical socket address. +type ReusePortOption int + // QuickAckOption is stubbed out in SetSockOpt/GetSockOpt. type QuickAckOption int diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index d1b9b136c..29f6c543d 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -100,7 +100,7 @@ func (e *endpoint) Close() { e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite switch e.state { case stateBound, stateConnected: - e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id) + e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id, e) } // Close the receive list and drain it. @@ -541,14 +541,14 @@ func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.Networ if id.LocalPort != 0 { // The endpoint already has a local port, just attempt to // register it. - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e, false) return id, err } // We need to find a port for the endpoint. _, err := e.stack.PickEphemeralPort(func(p uint16) (bool, *tcpip.Error) { id.LocalPort = p - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, e.transProto, id, e, false) switch err { case nil: return true, nil @@ -597,7 +597,7 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error if commit != nil { if err := commit(); err != nil { // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, e.transProto, id) + e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, e.transProto, id, e) return err } } diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index d0e1d6782..78d2c76e0 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -215,7 +215,7 @@ func (l *listenContext) createConnectedEndpoint(s *segment, iss seqnum.Value, ir n.maybeEnableSACKPermitted(rcvdSynOpts) // Register new endpoint so that packets are routed to it. - if err := n.stack.RegisterTransportEndpoint(n.boundNICID, n.effectiveNetProtos, ProtocolNumber, n.id, n); err != nil { + if err := n.stack.RegisterTransportEndpoint(n.boundNICID, n.effectiveNetProtos, ProtocolNumber, n.id, n, n.reusePort); err != nil { n.Close() return nil, err } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index d4eda50ec..5281f8be2 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -162,6 +162,9 @@ type endpoint struct { // sack holds TCP SACK related information for this endpoint. sack SACKInfo + // reusePort is set to true if SO_REUSEPORT is enabled. + reusePort bool + // delay enables Nagle's algorithm. // // delay is a boolean (0 is false) and must be accessed atomically. @@ -416,7 +419,7 @@ func (e *endpoint) Close() { e.isPortReserved = false if e.isRegistered { - e.stack.UnregisterTransportEndpoint(e.boundNICID, e.effectiveNetProtos, ProtocolNumber, e.id) + e.stack.UnregisterTransportEndpoint(e.boundNICID, e.effectiveNetProtos, ProtocolNumber, e.id, e) e.isRegistered = false } } @@ -453,7 +456,7 @@ func (e *endpoint) cleanupLocked() { e.workerCleanup = false if e.isRegistered { - e.stack.UnregisterTransportEndpoint(e.boundNICID, e.effectiveNetProtos, ProtocolNumber, e.id) + e.stack.UnregisterTransportEndpoint(e.boundNICID, e.effectiveNetProtos, ProtocolNumber, e.id, e) } e.route.Release() @@ -681,6 +684,12 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { e.mu.Unlock() return nil + case tcpip.ReusePortOption: + e.mu.Lock() + e.reusePort = v != 0 + e.mu.Unlock() + return nil + case tcpip.QuickAckOption: if v == 0 { atomic.StoreUint32(&e.slowAck, 1) @@ -875,6 +884,17 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { } return nil + case *tcpip.ReusePortOption: + e.mu.RLock() + v := e.reusePort + e.mu.RUnlock() + + *o = 0 + if v { + *o = 1 + } + return nil + case *tcpip.QuickAckOption: *o = 1 if v := atomic.LoadUint32(&e.slowAck); v != 0 { @@ -1057,7 +1077,7 @@ func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) (er if e.id.LocalPort != 0 { // The endpoint is bound to a port, attempt to register it. - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber, e.id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber, e.id, e, e.reusePort) if err != nil { return err } @@ -1071,13 +1091,13 @@ func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) (er if sameAddr && p == e.id.RemotePort { return false, nil } - if !e.stack.IsPortAvailable(netProtos, ProtocolNumber, e.id.LocalAddress, p) { + if !e.stack.IsPortAvailable(netProtos, ProtocolNumber, e.id.LocalAddress, p, false) { return false, nil } id := e.id id.LocalPort = p - switch e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber, id, e) { + switch e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber, id, e, e.reusePort) { case nil: e.id = id return true, nil @@ -1234,7 +1254,7 @@ func (e *endpoint) Listen(backlog int) (err *tcpip.Error) { } // Register the endpoint. - if err := e.stack.RegisterTransportEndpoint(e.boundNICID, e.effectiveNetProtos, ProtocolNumber, e.id, e); err != nil { + if err := e.stack.RegisterTransportEndpoint(e.boundNICID, e.effectiveNetProtos, ProtocolNumber, e.id, e, e.reusePort); err != nil { return err } @@ -1315,7 +1335,7 @@ func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) (err } } - port, err := e.stack.ReservePort(netProtos, ProtocolNumber, addr.Addr, addr.Port) + port, err := e.stack.ReservePort(netProtos, ProtocolNumber, addr.Addr, addr.Port, e.reusePort) if err != nil { return err } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 67e9ca0ac..b2a27a7cb 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -81,6 +81,7 @@ type endpoint struct { dstPort uint16 v6only bool multicastTTL uint8 + reusePort bool // shutdownFlags represent the current shutdown state of the endpoint. shutdownFlags tcpip.ShutdownFlags @@ -132,7 +133,7 @@ func NewConnectedEndpoint(stack *stack.Stack, r *stack.Route, id stack.Transport ep := newEndpoint(stack, r.NetProto, waiterQueue) // Register new endpoint so that packets are routed to it. - if err := stack.RegisterTransportEndpoint(r.NICID(), []tcpip.NetworkProtocolNumber{r.NetProto}, ProtocolNumber, id, ep); err != nil { + if err := stack.RegisterTransportEndpoint(r.NICID(), []tcpip.NetworkProtocolNumber{r.NetProto}, ProtocolNumber, id, ep, ep.reusePort); err != nil { ep.Close() return nil, err } @@ -155,7 +156,7 @@ func (e *endpoint) Close() { switch e.state { case stateBound, stateConnected: - e.stack.UnregisterTransportEndpoint(e.regNICID, e.effectiveNetProtos, ProtocolNumber, e.id) + e.stack.UnregisterTransportEndpoint(e.regNICID, e.effectiveNetProtos, ProtocolNumber, e.id, e) e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.id.LocalAddress, e.id.LocalPort) } @@ -449,6 +450,12 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { break } } + + case tcpip.ReusePortOption: + e.mu.Lock() + e.reusePort = v != 0 + e.mu.Unlock() + return nil } return nil } @@ -513,6 +520,17 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { e.mu.Unlock() return nil + case *tcpip.ReusePortOption: + e.mu.RLock() + v := e.reusePort + e.mu.RUnlock() + + *o = 0 + if v { + *o = 1 + } + return nil + case *tcpip.KeepaliveEnabledOption: *o = 0 return nil @@ -648,7 +666,7 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { // Remove the old registration. if e.id.LocalPort != 0 { - e.stack.UnregisterTransportEndpoint(e.regNICID, e.effectiveNetProtos, ProtocolNumber, e.id) + e.stack.UnregisterTransportEndpoint(e.regNICID, e.effectiveNetProtos, ProtocolNumber, e.id, e) } e.id = id @@ -711,14 +729,14 @@ func (*endpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) { func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, id stack.TransportEndpointID) (stack.TransportEndpointID, *tcpip.Error) { if e.id.LocalPort == 0 { - port, err := e.stack.ReservePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort) + port, err := e.stack.ReservePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort, e.reusePort) if err != nil { return id, err } id.LocalPort = port } - err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber, id, e) + err := e.stack.RegisterTransportEndpoint(nicid, netProtos, ProtocolNumber, id, e, e.reusePort) if err != nil { e.stack.ReleasePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort) } @@ -766,7 +784,7 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error if commit != nil { if err := commit(); err != nil { // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, ProtocolNumber, id) + e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, ProtocolNumber, id, e) e.stack.ReleasePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort) return err } diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 58a346cd9..2a9cf4b57 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -16,6 +16,7 @@ package udp_test import ( "bytes" + "math" "math/rand" "testing" "time" @@ -254,6 +255,90 @@ func newPayload() []byte { return b } +func TestBindPortReuse(t *testing.T) { + c := newDualTestContext(t, defaultMTU) + defer c.cleanup() + + c.createV6Endpoint(false) + + var eps [5]tcpip.Endpoint + reusePortOpt := tcpip.ReusePortOption(1) + + pollChannel := make(chan tcpip.Endpoint) + for i := 0; i < len(eps); i++ { + // Try to receive the data. + wq := waiter.Queue{} + we, ch := waiter.NewChannelEntry(nil) + wq.EventRegister(&we, waiter.EventIn) + defer wq.EventUnregister(&we) + defer close(ch) + + var err *tcpip.Error + eps[i], err = c.s.NewEndpoint(udp.ProtocolNumber, ipv6.ProtocolNumber, &wq) + if err != nil { + c.t.Fatalf("NewEndpoint failed: %v", err) + } + + go func(ep tcpip.Endpoint) { + for range ch { + pollChannel <- ep + } + }(eps[i]) + + defer eps[i].Close() + if err := eps[i].SetSockOpt(reusePortOpt); err != nil { + c.t.Fatalf("SetSockOpt failed failed: %v", err) + } + if err := eps[i].Bind(tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort}, nil); err != nil { + t.Fatalf("ep.Bind(...) failed: %v", err) + } + } + + npackets := 100000 + nports := 10000 + ports := make(map[uint16]tcpip.Endpoint) + stats := make(map[tcpip.Endpoint]int) + for i := 0; i < npackets; i++ { + // Send a packet. + port := uint16(i % nports) + payload := newPayload() + c.sendV6Packet(payload, &headers{ + srcPort: testPort + port, + dstPort: stackPort, + }) + + var addr tcpip.FullAddress + ep := <-pollChannel + _, _, err := ep.Read(&addr) + if err != nil { + c.t.Fatalf("Read failed: %v", err) + } + stats[ep]++ + if i < nports { + ports[uint16(i)] = ep + } else { + // Check that all packets from one client are handled + // by the same socket. + if ports[port] != ep { + t.Fatalf("Port mismatch") + } + } + } + + if len(stats) != len(eps) { + t.Fatalf("Only %d(expected %d) sockets received packets", len(stats), len(eps)) + } + + // Check that a packet distribution is fair between sockets. + for _, c := range stats { + n := float64(npackets) / float64(len(eps)) + // The deviation is less than 10%. + if math.Abs(float64(c)-n) > n/10 { + t.Fatal(c, n) + } + } +} + func testV4Read(c *testContext) { // Send a packet. payload := newPayload() diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index ae33d14da..f0e61e083 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -2163,9 +2163,13 @@ cc_binary( ":socket_test_util", "//test/util:file_descriptor", "//test/util:posix_error", + "//test/util:save_util", "//test/util:test_main", "//test/util:test_util", + "//test/util:thread_util", + "@com_google_absl//absl/memory", "@com_google_absl//absl/strings", + "@com_google_absl//absl/time", "@com_google_googletest//:gtest", ], ) diff --git a/test/syscalls/linux/socket_inet_loopback.cc b/test/syscalls/linux/socket_inet_loopback.cc index 17a46e149..0893be5a7 100644 --- a/test/syscalls/linux/socket_inet_loopback.cc +++ b/test/syscalls/linux/socket_inet_loopback.cc @@ -17,17 +17,24 @@ #include #include +#include +#include #include #include #include #include +#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/memory/memory.h" #include "absl/strings/str_cat.h" +#include "absl/time/time.h" #include "test/syscalls/linux/socket_test_util.h" #include "test/util/file_descriptor.h" #include "test/util/posix_error.h" +#include "test/util/save_util.h" #include "test/util/test_util.h" +#include "test/util/thread_util.h" namespace gvisor { namespace testing { @@ -227,6 +234,238 @@ INSTANTIATE_TEST_CASE_P( TestParam{V6Loopback(), V6Loopback()}), DescribeTestParam); +using SocketInetReusePortTest = ::testing::TestWithParam; + +TEST_P(SocketInetReusePortTest, TcpPortReuseMultiThread) { + auto const& param = GetParam(); + + TestAddress const& listener = param.listener; + TestAddress const& connector = param.connector; + sockaddr_storage listen_addr = listener.addr; + sockaddr_storage conn_addr = connector.addr; + constexpr int kThreadCount = 3; + + // Create the listening socket. + FileDescriptor listener_fds[kThreadCount]; + for (int i = 0; i < kThreadCount; i++) { + listener_fds[i] = ASSERT_NO_ERRNO_AND_VALUE( + Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP)); + int fd = listener_fds[i].get(); + + ASSERT_THAT(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceeds()); + ASSERT_THAT( + bind(fd, reinterpret_cast(&listen_addr), listener.addr_len), + SyscallSucceeds()); + ASSERT_THAT(listen(fd, 40), SyscallSucceeds()); + + // On the first bind we need to determine which port was bound. + if (i != 0) continue; + + // Get the port bound by the listening socket. + socklen_t addrlen = listener.addr_len; + ASSERT_THAT( + getsockname(listener_fds[0].get(), + reinterpret_cast(&listen_addr), &addrlen), + SyscallSucceeds()); + uint16_t const port = + ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); + ASSERT_NO_ERRNO(SetAddrPort(listener.family(), &listen_addr, port)); + ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); + } + + constexpr int kConnectAttempts = 10000; + std::atomic connects_received = ATOMIC_VAR_INIT(0); + std::unique_ptr listen_thread[kThreadCount]; + int accept_counts[kThreadCount] = {}; + // TODO: figure how to not disable S/R for the whole test. + // We need to take into account that this test executes a lot of system + // calls from many threads. + DisableSave ds; + + for (int i = 0; i < kThreadCount; i++) { + listen_thread[i] = absl::make_unique( + [&listener_fds, &accept_counts, i, &connects_received]() { + do { + auto fd = Accept(listener_fds[i].get(), nullptr, nullptr); + if (!fd.ok()) { + if (connects_received >= kConnectAttempts) { + // Another thread have shutdown our read side causing the + // accept to fail. + break; + } + ASSERT_NO_ERRNO(fd); + break; + } + // Receive some data from a socket to be sure that the connect() + // system call has been completed on another side. + int data; + EXPECT_THAT( + RetryEINTR(recv)(fd.ValueOrDie().get(), &data, sizeof(data), 0), + SyscallSucceedsWithValue(sizeof(data))); + accept_counts[i]++; + } while (++connects_received < kConnectAttempts); + + // Shutdown all sockets to wake up other threads. + for (int j = 0; j < kThreadCount; j++) { + shutdown(listener_fds[j].get(), SHUT_RDWR); + } + }); + } + + ScopedThread connecting_thread([&connector, &conn_addr]() { + for (int i = 0; i < kConnectAttempts; i++) { + const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE( + Socket(connector.family(), SOCK_STREAM, IPPROTO_TCP)); + ASSERT_THAT( + RetryEINTR(connect)(fd.get(), reinterpret_cast(&conn_addr), + connector.addr_len), + SyscallSucceeds()); + + EXPECT_THAT(RetryEINTR(send)(fd.get(), &i, sizeof(i), 0), + SyscallSucceedsWithValue(sizeof(i))); + } + }); + + // Join threads to be sure that all connections have been counted + connecting_thread.Join(); + for (int i = 0; i < kThreadCount; i++) { + listen_thread[i]->Join(); + } + // Check that connections are distributed fairly between listening sockets + for (int i = 0; i < kThreadCount; i++) + EXPECT_THAT(accept_counts[i], + EquivalentWithin((kConnectAttempts / kThreadCount), 0.10)); +} + +TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread) { + auto const& param = GetParam(); + + TestAddress const& listener = param.listener; + TestAddress const& connector = param.connector; + sockaddr_storage listen_addr = listener.addr; + sockaddr_storage conn_addr = connector.addr; + constexpr int kThreadCount = 3; + + // Create the listening socket. + FileDescriptor listener_fds[kThreadCount]; + for (int i = 0; i < kThreadCount; i++) { + listener_fds[i] = + ASSERT_NO_ERRNO_AND_VALUE(Socket(listener.family(), SOCK_DGRAM, 0)); + int fd = listener_fds[i].get(); + + ASSERT_THAT(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceeds()); + ASSERT_THAT( + bind(fd, reinterpret_cast(&listen_addr), listener.addr_len), + SyscallSucceeds()); + + // On the first bind we need to determine which port was bound. + if (i != 0) continue; + + // Get the port bound by the listening socket. + socklen_t addrlen = listener.addr_len; + ASSERT_THAT( + getsockname(listener_fds[0].get(), + reinterpret_cast(&listen_addr), &addrlen), + SyscallSucceeds()); + uint16_t const port = + ASSERT_NO_ERRNO_AND_VALUE(AddrPort(listener.family(), listen_addr)); + ASSERT_NO_ERRNO(SetAddrPort(listener.family(), &listen_addr, port)); + ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port)); + } + + constexpr int kConnectAttempts = 10000; + std::atomic packets_received = ATOMIC_VAR_INIT(0); + std::unique_ptr receiver_thread[kThreadCount]; + int packets_per_socket[kThreadCount] = {}; + // TODO: figure how to not disable S/R for the whole test. + DisableSave ds; // Too expensive. + + for (int i = 0; i < kThreadCount; i++) { + receiver_thread[i] = absl::make_unique( + [&listener_fds, &packets_per_socket, i, &packets_received]() { + do { + struct sockaddr_storage addr = {}; + socklen_t addrlen = sizeof(addr); + int data; + + auto ret = RetryEINTR(recvfrom)( + listener_fds[i].get(), &data, sizeof(data), 0, + reinterpret_cast(&addr), &addrlen); + + if (packets_received < kConnectAttempts) { + ASSERT_THAT(ret, SyscallSucceedsWithValue(sizeof(data))); + } + + if (ret != sizeof(data)) { + // Another thread may have shutdown our read side causing the + // recvfrom to fail. + break; + } + + packets_received++; + packets_per_socket[i]++; + + // A response is required to synchronize with the main thread, + // otherwise the main thread can send more than can fit into receive + // queues. + EXPECT_THAT(RetryEINTR(sendto)( + listener_fds[i].get(), &data, sizeof(data), 0, + reinterpret_cast(&addr), addrlen), + SyscallSucceedsWithValue(sizeof(data))); + } while (packets_received < kConnectAttempts); + + // Shutdown all sockets to wake up other threads. + for (int j = 0; j < kThreadCount; j++) + shutdown(listener_fds[j].get(), SHUT_RDWR); + }); + } + + ScopedThread main_thread([&connector, &conn_addr]() { + for (int i = 0; i < kConnectAttempts; i++) { + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Socket(connector.family(), SOCK_DGRAM, 0)); + EXPECT_THAT(RetryEINTR(sendto)(fd.get(), &i, sizeof(i), 0, + reinterpret_cast(&conn_addr), + connector.addr_len), + SyscallSucceedsWithValue(sizeof(i))); + int data; + EXPECT_THAT(RetryEINTR(recv)(fd.get(), &data, sizeof(data), 0), + SyscallSucceedsWithValue(sizeof(data))); + } + }); + + main_thread.Join(); + + // Join threads to be sure that all connections have been counted + for (int i = 0; i < kThreadCount; i++) { + receiver_thread[i]->Join(); + } + // Check that packets are distributed fairly between listening sockets. + for (int i = 0; i < kThreadCount; i++) + EXPECT_THAT(packets_per_socket[i], + EquivalentWithin((kConnectAttempts / kThreadCount), 0.10)); +} + +INSTANTIATE_TEST_CASE_P( + All, SocketInetReusePortTest, + ::testing::Values( + // Listeners bound to IPv4 addresses refuse connections using IPv6 + // addresses. + TestParam{V4Any(), V4Loopback()}, + TestParam{V4Loopback(), V4MappedLoopback()}, + + // Listeners bound to IN6ADDR_ANY accept all connections. + TestParam{V6Any(), V4Loopback()}, TestParam{V6Any(), V6Loopback()}, + + // Listeners bound to IN6ADDR_LOOPBACK refuse connections using IPv4 + // addresses. + TestParam{V6Loopback(), V6Loopback()}), + DescribeTestParam); + struct ProtocolTestParam { std::string description; int type; @@ -806,6 +1045,56 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { } } +TEST_P(SocketMultiProtocolInetLoopbackTest, PortReuseTwoSockets) { + auto const& param = GetParam(); + TestAddress const& test_addr = V4Loopback(); + sockaddr_storage addr = test_addr.addr; + + for (int i = 0; i < 2; i++) { + const int portreuse1 = i % 2; + auto s1 = + ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); + int fd1 = s1.get(); + socklen_t addrlen = test_addr.addr_len; + + EXPECT_THAT( + setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &portreuse1, sizeof(int)), + SyscallSucceeds()); + + ASSERT_THAT(bind(fd1, reinterpret_cast(&addr), addrlen), + SyscallSucceeds()); + + ASSERT_THAT(getsockname(fd1, reinterpret_cast(&addr), &addrlen), + SyscallSucceeds()); + if (param.type == SOCK_STREAM) { + ASSERT_THAT(listen(fd1, 1), SyscallSucceeds()); + } + + // j is less than 4 to check that the port reuse logic works correctly after + // closing bound sockets. + for (int j = 0; j < 4; j++) { + const int portreuse2 = j % 2; + auto s2 = + ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); + int fd2 = s2.get(); + + EXPECT_THAT( + setsockopt(fd2, SOL_SOCKET, SO_REUSEPORT, &portreuse2, sizeof(int)), + SyscallSucceeds()); + + LOG(INFO) << portreuse1 << " " << portreuse2; + int ret = bind(fd2, reinterpret_cast(&addr), addrlen); + + // Verify that two sockets can be bound to the same port only if + // SO_REUSEPORT is set for both of them. + if (!portreuse1 || !portreuse2) + ASSERT_THAT(ret, SyscallFailsWithErrno(EADDRINUSE)); + else + ASSERT_THAT(ret, SyscallSucceeds()); + } + } +} + INSTANTIATE_TEST_CASE_P(AllFamlies, SocketMultiProtocolInetLoopbackTest, ::testing::Values(ProtocolTestParam{"TCP", SOCK_STREAM}, ProtocolTestParam{"UDP", SOCK_DGRAM}), diff --git a/test/syscalls/syscall_test_runner.go b/test/syscalls/syscall_test_runner.go index 9ee0361ee..ec048f10f 100644 --- a/test/syscalls/syscall_test_runner.go +++ b/test/syscalls/syscall_test_runner.go @@ -118,6 +118,7 @@ func runTestCaseRunsc(testBin string, tc gtest.TestCase, t *testing.T) { // Mark the root as writeable, as some tests attempt to // write to the rootfs, and expect EACCES, not EROFS. spec.Root.Readonly = false + spec.Mounts = nil // Set environment variable that indicates we are // running in gVisor and with the given platform. -- cgit v1.2.3 From ff1c3bb0b577a4ea55a64de39415a8d31142b741 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Tue, 29 Jan 2019 16:22:34 -0800 Subject: Fix NIC endpoint forwarding. Also adds a test for regular NIC forwarding. PiperOrigin-RevId: 231495279 Change-Id: Ic7edec249568e9ad0280cea77eac14478c9073e1 --- pkg/tcpip/stack/BUILD | 1 + pkg/tcpip/stack/nic.go | 2 + pkg/tcpip/stack/stack_test.go | 39 +++++++++++++ pkg/tcpip/stack/transport_test.go | 112 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 148 insertions(+), 6 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD index 9ff1c8731..8a598c57d 100644 --- a/pkg/tcpip/stack/BUILD +++ b/pkg/tcpip/stack/BUILD @@ -43,6 +43,7 @@ go_test( "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/link/channel", + "//pkg/tcpip/link/loopback", "//pkg/waiter", ], ) diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 770d288cf..586ca873e 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -428,6 +428,8 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr ref, ok := n.endpoints[NetworkEndpointID{dst}] n.mu.RUnlock() if ok && ref.tryIncRef() { + r.RemoteAddress = src + // TODO: Update the source NIC as well. ref.ep.HandlePacket(&r, vv) ref.decRef() } else { diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 391319f35..163fadded 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -1039,6 +1039,45 @@ func TestGetMainNICAddressAddRemove(t *testing.T) { } } +func TestNICForwarding(t *testing.T) { + // Create a stack with the fake network protocol, two NICs, each with + // an address. + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) + s.SetForwarding(true) + + id1, linkEP1 := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id1); err != nil { + t.Fatalf("CreateNIC #1 failed: %v", err) + } + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress #1 failed: %v", err) + } + + id2, linkEP2 := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(2, id2); err != nil { + t.Fatalf("CreateNIC #2 failed: %v", err) + } + if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil { + t.Fatalf("AddAddress #2 failed: %v", err) + } + + // Route all packets to address 3 to NIC 2. + s.SetRouteTable([]tcpip.Route{ + {"\x03", "\xff", "\x00", 2}, + }) + + // Send a packet to address 3. + buf := buffer.NewView(30) + buf[0] = 3 + linkEP1.Inject(fakeNetNumber, buf.ToVectorisedView()) + + select { + case <-linkEP2.C: + default: + t.Fatal("Packet not forwarded") + } +} + func init() { stack.RegisterNetworkProtocolFactory("fakeNet", func() stack.NetworkProtocol { return &fakeNetworkProtocol{} diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 022207081..da460db77 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -20,6 +20,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/link/channel" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/loopback" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" "gvisor.googlesource.com/gvisor/pkg/waiter" ) @@ -42,6 +43,9 @@ type fakeTransportEndpoint struct { proto *fakeTransportProtocol peerAddr tcpip.Address route stack.Route + + // acceptQueue is non-nil iff bound. + acceptQueue []fakeTransportEndpoint } func newFakeTransportEndpoint(stack *stack.Stack, proto *fakeTransportProtocol, netProto tcpip.NetworkProtocolNumber) tcpip.Endpoint { @@ -132,11 +136,27 @@ func (*fakeTransportEndpoint) Listen(int) *tcpip.Error { return nil } -func (*fakeTransportEndpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) { - return nil, nil, nil -} - -func (*fakeTransportEndpoint) Bind(_ tcpip.FullAddress, commit func() *tcpip.Error) *tcpip.Error { +func (f *fakeTransportEndpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) { + if len(f.acceptQueue) == 0 { + return nil, nil, nil + } + a := f.acceptQueue[0] + f.acceptQueue = f.acceptQueue[1:] + return &a, nil, nil +} + +func (f *fakeTransportEndpoint) Bind(a tcpip.FullAddress, commit func() *tcpip.Error) *tcpip.Error { + if err := f.stack.RegisterTransportEndpoint( + a.NIC, + []tcpip.NetworkProtocolNumber{fakeNetNumber}, + fakeTransNumber, + stack.TransportEndpointID{LocalAddress: a.Addr}, + f, + false, + ); err != nil { + return err + } + f.acceptQueue = []fakeTransportEndpoint{} return commit() } @@ -148,9 +168,19 @@ func (*fakeTransportEndpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Erro return tcpip.FullAddress{}, nil } -func (f *fakeTransportEndpoint) HandlePacket(*stack.Route, stack.TransportEndpointID, buffer.VectorisedView) { +func (f *fakeTransportEndpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, _ buffer.VectorisedView) { // Increment the number of received packets. f.proto.packetCount++ + if f.acceptQueue != nil { + f.acceptQueue = append(f.acceptQueue, fakeTransportEndpoint{ + id: id, + stack: f.stack, + netProto: f.netProto, + proto: f.proto, + peerAddr: r.RemoteAddress, + route: r.Clone(), + }) + } } func (f *fakeTransportEndpoint) HandleControlPacket(stack.TransportEndpointID, stack.ControlType, uint32, buffer.VectorisedView) { @@ -415,6 +445,76 @@ func TestTransportOptions(t *testing.T) { } } +func TestTransportForwarding(t *testing.T) { + s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}, stack.Options{}) + s.SetForwarding(true) + + // TODO: Change this to a channel NIC. + id1 := loopback.New() + if err := s.CreateNIC(1, id1); err != nil { + t.Fatalf("CreateNIC #1 failed: %v", err) + } + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress #1 failed: %v", err) + } + + id2, linkEP2 := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(2, id2); err != nil { + t.Fatalf("CreateNIC #2 failed: %v", err) + } + if err := s.AddAddress(2, fakeNetNumber, "\x02"); err != nil { + t.Fatalf("AddAddress #2 failed: %v", err) + } + + // Route all packets to address 3 to NIC 2 and all packets to address + // 1 to NIC 1. + s.SetRouteTable([]tcpip.Route{ + {"\x03", "\xff", "\x00", 2}, + {"\x01", "\xff", "\x00", 1}, + }) + + wq := waiter.Queue{} + ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq) + if err != nil { + t.Fatalf("NewEndpoint failed: %v", err) + } + + if err := ep.Bind(tcpip.FullAddress{Addr: "\x01", NIC: 1}, func() *tcpip.Error { return nil }); err != nil { + t.Fatalf("Bind failed: %v", err) + } + + // Send a packet to address 1 from address 3. + req := buffer.NewView(30) + req[0] = 1 + req[1] = 3 + req[2] = byte(fakeTransNumber) + linkEP2.Inject(fakeNetNumber, req.ToVectorisedView()) + + aep, _, err := ep.Accept() + if err != nil || aep == nil { + t.Fatalf("Accept failed: %v, %v", aep, err) + } + + resp := buffer.NewView(30) + if _, _, err := aep.Write(tcpip.SlicePayload(resp), tcpip.WriteOptions{}); err != nil { + t.Fatalf("Write failed: %v", err) + } + + var p channel.PacketInfo + select { + case p = <-linkEP2.C: + default: + t.Fatal("Response packet not forwarded") + } + + if dst := p.Header[0]; dst != 3 { + t.Errorf("Response packet has incorrect destination addresss: got = %d, want = 3", dst) + } + if src := p.Header[1]; src != 1 { + t.Errorf("Response packet has incorrect source addresss: got = %d, want = 3", src) + } +} + func init() { stack.RegisterTransportProtocolFactory("fakeTrans", func() stack.TransportProtocol { return &fakeTransportProtocol{} -- cgit v1.2.3 From 2a0c69b19f4b55c3f9777f0098a72af123ccff3c Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 31 Jan 2019 11:11:44 -0800 Subject: Remove license comments Nothing reads them and they can simply get stale. Generated with: $ sed -i "s/licenses(\(.*\)).*/licenses(\1)/" **/BUILD PiperOrigin-RevId: 231818945 Change-Id: Ibc3f9838546b7e94f13f217060d31f4ada9d4bf0 --- pkg/abi/BUILD | 2 +- pkg/abi/linux/BUILD | 2 +- pkg/amutex/BUILD | 2 +- pkg/atomicbitops/BUILD | 2 +- pkg/binary/BUILD | 2 +- pkg/bits/BUILD | 2 +- pkg/bpf/BUILD | 2 +- pkg/compressio/BUILD | 2 +- pkg/control/client/BUILD | 2 +- pkg/control/server/BUILD | 2 +- pkg/cpuid/BUILD | 2 +- pkg/dhcp/BUILD | 2 +- pkg/eventchannel/BUILD | 2 +- pkg/fd/BUILD | 2 +- pkg/fdnotifier/BUILD | 2 +- pkg/gate/BUILD | 2 +- pkg/ilist/BUILD | 2 +- pkg/linewriter/BUILD | 2 +- pkg/log/BUILD | 2 +- pkg/metric/BUILD | 2 +- pkg/p9/BUILD | 2 +- pkg/p9/local_server/BUILD | 2 +- pkg/p9/p9test/BUILD | 2 +- pkg/rand/BUILD | 2 +- pkg/refs/BUILD | 2 +- pkg/seccomp/BUILD | 2 +- pkg/secio/BUILD | 2 +- pkg/segment/BUILD | 2 +- pkg/segment/test/BUILD | 2 +- pkg/sentry/BUILD | 2 +- pkg/sentry/arch/BUILD | 2 +- pkg/sentry/context/BUILD | 2 +- pkg/sentry/context/contexttest/BUILD | 2 +- pkg/sentry/control/BUILD | 2 +- pkg/sentry/device/BUILD | 2 +- pkg/sentry/fs/BUILD | 2 +- pkg/sentry/fs/anon/BUILD | 2 +- pkg/sentry/fs/ashmem/BUILD | 2 +- pkg/sentry/fs/binder/BUILD | 2 +- pkg/sentry/fs/dev/BUILD | 2 +- pkg/sentry/fs/fdpipe/BUILD | 2 +- pkg/sentry/fs/filetest/BUILD | 2 +- pkg/sentry/fs/fsutil/BUILD | 2 +- pkg/sentry/fs/gofer/BUILD | 2 +- pkg/sentry/fs/host/BUILD | 2 +- pkg/sentry/fs/lock/BUILD | 2 +- pkg/sentry/fs/proc/BUILD | 2 +- pkg/sentry/fs/proc/device/BUILD | 2 +- pkg/sentry/fs/proc/seqfile/BUILD | 2 +- pkg/sentry/fs/ramfs/BUILD | 2 +- pkg/sentry/fs/sys/BUILD | 2 +- pkg/sentry/fs/timerfd/BUILD | 2 +- pkg/sentry/fs/tmpfs/BUILD | 2 +- pkg/sentry/fs/tty/BUILD | 2 +- pkg/sentry/hostcpu/BUILD | 2 +- pkg/sentry/inet/BUILD | 2 +- pkg/sentry/kernel/BUILD | 2 +- pkg/sentry/kernel/auth/BUILD | 2 +- pkg/sentry/kernel/contexttest/BUILD | 2 +- pkg/sentry/kernel/epoll/BUILD | 2 +- pkg/sentry/kernel/eventfd/BUILD | 2 +- pkg/sentry/kernel/fasync/BUILD | 2 +- pkg/sentry/kernel/futex/BUILD | 2 +- pkg/sentry/kernel/kdefs/BUILD | 2 +- pkg/sentry/kernel/memevent/BUILD | 2 +- pkg/sentry/kernel/pipe/BUILD | 2 +- pkg/sentry/kernel/sched/BUILD | 2 +- pkg/sentry/kernel/semaphore/BUILD | 2 +- pkg/sentry/kernel/shm/BUILD | 2 +- pkg/sentry/kernel/time/BUILD | 2 +- pkg/sentry/limits/BUILD | 2 +- pkg/sentry/loader/BUILD | 2 +- pkg/sentry/memmap/BUILD | 2 +- pkg/sentry/memutil/BUILD | 2 +- pkg/sentry/mm/BUILD | 2 +- pkg/sentry/platform/BUILD | 2 +- pkg/sentry/platform/filemem/BUILD | 2 +- pkg/sentry/platform/interrupt/BUILD | 2 +- pkg/sentry/platform/kvm/BUILD | 2 +- pkg/sentry/platform/kvm/testutil/BUILD | 2 +- pkg/sentry/platform/procid/BUILD | 2 +- pkg/sentry/platform/ptrace/BUILD | 2 +- pkg/sentry/platform/ring0/BUILD | 2 +- pkg/sentry/platform/ring0/gen_offsets/BUILD | 2 +- pkg/sentry/platform/ring0/pagetables/BUILD | 2 +- pkg/sentry/platform/safecopy/BUILD | 2 +- pkg/sentry/safemem/BUILD | 2 +- pkg/sentry/sighandling/BUILD | 2 +- pkg/sentry/socket/BUILD | 2 +- pkg/sentry/socket/control/BUILD | 2 +- pkg/sentry/socket/epsocket/BUILD | 2 +- pkg/sentry/socket/hostinet/BUILD | 2 +- pkg/sentry/socket/netlink/BUILD | 2 +- pkg/sentry/socket/netlink/port/BUILD | 2 +- pkg/sentry/socket/netlink/route/BUILD | 2 +- pkg/sentry/socket/rpcinet/BUILD | 2 +- pkg/sentry/socket/rpcinet/conn/BUILD | 2 +- pkg/sentry/socket/rpcinet/notifier/BUILD | 2 +- pkg/sentry/socket/unix/BUILD | 2 +- pkg/sentry/socket/unix/transport/BUILD | 2 +- pkg/sentry/state/BUILD | 2 +- pkg/sentry/strace/BUILD | 2 +- pkg/sentry/syscalls/BUILD | 2 +- pkg/sentry/syscalls/linux/BUILD | 2 +- pkg/sentry/time/BUILD | 2 +- pkg/sentry/unimpl/BUILD | 2 +- pkg/sentry/uniqueid/BUILD | 2 +- pkg/sentry/usage/BUILD | 2 +- pkg/sentry/usermem/BUILD | 2 +- pkg/sentry/watchdog/BUILD | 2 +- pkg/sleep/BUILD | 2 +- pkg/state/BUILD | 2 +- pkg/state/statefile/BUILD | 2 +- pkg/sync/BUILD | 2 +- pkg/sync/atomicptrtest/BUILD | 2 +- pkg/sync/seqatomictest/BUILD | 2 +- pkg/syserr/BUILD | 2 +- pkg/syserror/BUILD | 2 +- pkg/tcpip/BUILD | 2 +- pkg/tcpip/adapters/gonet/BUILD | 2 +- pkg/tcpip/buffer/BUILD | 2 +- pkg/tcpip/checker/BUILD | 2 +- pkg/tcpip/hash/jenkins/BUILD | 2 +- pkg/tcpip/header/BUILD | 2 +- pkg/tcpip/link/channel/BUILD | 2 +- pkg/tcpip/link/fdbased/BUILD | 2 +- pkg/tcpip/link/loopback/BUILD | 2 +- pkg/tcpip/link/rawfile/BUILD | 2 +- pkg/tcpip/link/sharedmem/BUILD | 2 +- pkg/tcpip/link/sharedmem/pipe/BUILD | 2 +- pkg/tcpip/link/sharedmem/queue/BUILD | 2 +- pkg/tcpip/link/sniffer/BUILD | 2 +- pkg/tcpip/link/tun/BUILD | 2 +- pkg/tcpip/link/waitable/BUILD | 2 +- pkg/tcpip/network/BUILD | 2 +- pkg/tcpip/network/arp/BUILD | 2 +- pkg/tcpip/network/fragmentation/BUILD | 2 +- pkg/tcpip/network/hash/BUILD | 2 +- pkg/tcpip/network/ipv4/BUILD | 2 +- pkg/tcpip/network/ipv6/BUILD | 2 +- pkg/tcpip/ports/BUILD | 2 +- pkg/tcpip/sample/tun_tcp_connect/BUILD | 2 +- pkg/tcpip/sample/tun_tcp_echo/BUILD | 2 +- pkg/tcpip/seqnum/BUILD | 2 +- pkg/tcpip/stack/BUILD | 2 +- pkg/tcpip/transport/ping/BUILD | 2 +- pkg/tcpip/transport/tcp/BUILD | 2 +- pkg/tcpip/transport/tcp/testing/context/BUILD | 2 +- pkg/tcpip/transport/tcpconntrack/BUILD | 2 +- pkg/tcpip/transport/udp/BUILD | 2 +- pkg/tmutex/BUILD | 2 +- pkg/unet/BUILD | 2 +- pkg/urpc/BUILD | 2 +- pkg/waiter/BUILD | 2 +- runsc/boot/BUILD | 2 +- runsc/boot/filter/BUILD | 2 +- runsc/cgroup/BUILD | 2 +- runsc/cmd/BUILD | 2 +- runsc/console/BUILD | 2 +- runsc/container/BUILD | 2 +- runsc/fsgofer/BUILD | 2 +- runsc/fsgofer/filter/BUILD | 2 +- runsc/sandbox/BUILD | 2 +- runsc/specutils/BUILD | 2 +- runsc/test/image/BUILD | 2 +- runsc/test/integration/BUILD | 2 +- runsc/test/root/BUILD | 2 +- runsc/test/root/testdata/BUILD | 2 +- runsc/test/testutil/BUILD | 2 +- runsc/tools/dockercfg/BUILD | 2 +- test/syscalls/BUILD | 2 +- test/syscalls/gtest/BUILD | 2 +- test/syscalls/linux/BUILD | 2 +- test/util/BUILD | 2 +- tools/go_generics/BUILD | 2 +- tools/go_generics/globals/BUILD | 2 +- tools/go_generics/go_merge/BUILD | 2 +- tools/go_generics/rules_tests/BUILD | 2 +- tools/go_stateify/BUILD | 2 +- vdso/BUILD | 2 +- 180 files changed, 180 insertions(+), 180 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD index 1ba4f3a46..323263ebf 100644 --- a/pkg/abi/BUILD +++ b/pkg/abi/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index e6043abf4..7648c9469 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -2,7 +2,7 @@ # Linux kernel. It should be used instead of syscall or golang.org/x/sys/unix # when the host OS may not be Linux. -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/amutex/BUILD b/pkg/amutex/BUILD index 7cda07418..bdb6e8f2c 100644 --- a/pkg/amutex/BUILD +++ b/pkg/amutex/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "amutex", diff --git a/pkg/atomicbitops/BUILD b/pkg/atomicbitops/BUILD index 235188531..9555bf645 100644 --- a/pkg/atomicbitops/BUILD +++ b/pkg/atomicbitops/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "atomicbitops", diff --git a/pkg/binary/BUILD b/pkg/binary/BUILD index 571151f72..bd37376b0 100644 --- a/pkg/binary/BUILD +++ b/pkg/binary/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "binary", diff --git a/pkg/bits/BUILD b/pkg/bits/BUILD index 46794bdb8..5214b2c24 100644 --- a/pkg/bits/BUILD +++ b/pkg/bits/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/pkg/bpf/BUILD b/pkg/bpf/BUILD index 564df3af5..3c7ae3103 100644 --- a/pkg/bpf/BUILD +++ b/pkg/bpf/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/compressio/BUILD b/pkg/compressio/BUILD index 72952d735..3a0ac64e6 100644 --- a/pkg/compressio/BUILD +++ b/pkg/compressio/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "compressio", diff --git a/pkg/control/client/BUILD b/pkg/control/client/BUILD index 32853875d..22a4a4a5a 100644 --- a/pkg/control/client/BUILD +++ b/pkg/control/client/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "client", diff --git a/pkg/control/server/BUILD b/pkg/control/server/BUILD index ba2b1be9f..76b2e9787 100644 --- a/pkg/control/server/BUILD +++ b/pkg/control/server/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "server", diff --git a/pkg/cpuid/BUILD b/pkg/cpuid/BUILD index 46fc4703b..29cc38778 100644 --- a/pkg/cpuid/BUILD +++ b/pkg/cpuid/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/dhcp/BUILD b/pkg/dhcp/BUILD index c97dfc14b..003620b48 100644 --- a/pkg/dhcp/BUILD +++ b/pkg/dhcp/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "dhcp", diff --git a/pkg/eventchannel/BUILD b/pkg/eventchannel/BUILD index 18348ef54..5c2a44aa1 100644 --- a/pkg/eventchannel/BUILD +++ b/pkg/eventchannel/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "eventchannel", diff --git a/pkg/fd/BUILD b/pkg/fd/BUILD index 06cfd445e..ab1109157 100644 --- a/pkg/fd/BUILD +++ b/pkg/fd/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "fd", diff --git a/pkg/fdnotifier/BUILD b/pkg/fdnotifier/BUILD index 27d378d5b..8c8d193cc 100644 --- a/pkg/fdnotifier/BUILD +++ b/pkg/fdnotifier/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "fdnotifier", diff --git a/pkg/gate/BUILD b/pkg/gate/BUILD index 9a87a3a31..83679f2da 100644 --- a/pkg/gate/BUILD +++ b/pkg/gate/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "gate", diff --git a/pkg/ilist/BUILD b/pkg/ilist/BUILD index a67aa2cff..dbd65ab12 100644 --- a/pkg/ilist/BUILD +++ b/pkg/ilist/BUILD @@ -1,7 +1,7 @@ load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ilist", diff --git a/pkg/linewriter/BUILD b/pkg/linewriter/BUILD index 3f28ba867..d1aa2e7d6 100644 --- a/pkg/linewriter/BUILD +++ b/pkg/linewriter/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "linewriter", diff --git a/pkg/log/BUILD b/pkg/log/BUILD index 94ac66db3..b2d18eddb 100644 --- a/pkg/log/BUILD +++ b/pkg/log/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "log", diff --git a/pkg/metric/BUILD b/pkg/metric/BUILD index d96e5563b..4b2c7a00e 100644 --- a/pkg/metric/BUILD +++ b/pkg/metric/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "metric", diff --git a/pkg/p9/BUILD b/pkg/p9/BUILD index 2c224e65b..5d972309d 100644 --- a/pkg/p9/BUILD +++ b/pkg/p9/BUILD @@ -2,7 +2,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:public"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) go_library( diff --git a/pkg/p9/local_server/BUILD b/pkg/p9/local_server/BUILD index b17ebb79d..aa6db186c 100644 --- a/pkg/p9/local_server/BUILD +++ b/pkg/p9/local_server/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "local_server", diff --git a/pkg/p9/p9test/BUILD b/pkg/p9/p9test/BUILD index 7c4b875ce..cf22edde8 100644 --- a/pkg/p9/p9test/BUILD +++ b/pkg/p9/p9test/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) alias( name = "mockgen", diff --git a/pkg/rand/BUILD b/pkg/rand/BUILD index 0c9efc709..4eec3a4dd 100644 --- a/pkg/rand/BUILD +++ b/pkg/rand/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "rand", diff --git a/pkg/refs/BUILD b/pkg/refs/BUILD index 98150ba8f..fc562f821 100644 --- a/pkg/refs/BUILD +++ b/pkg/refs/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/seccomp/BUILD b/pkg/seccomp/BUILD index 657f923ed..0e9c4692d 100644 --- a/pkg/seccomp/BUILD +++ b/pkg/seccomp/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_embed_data") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "victim", diff --git a/pkg/secio/BUILD b/pkg/secio/BUILD index 29f751725..2b4b87c61 100644 --- a/pkg/secio/BUILD +++ b/pkg/secio/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "secio", diff --git a/pkg/segment/BUILD b/pkg/segment/BUILD index 964d73af8..700385907 100644 --- a/pkg/segment/BUILD +++ b/pkg/segment/BUILD @@ -1,6 +1,6 @@ package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) load("//tools/go_generics:defs.bzl", "go_template") diff --git a/pkg/segment/test/BUILD b/pkg/segment/test/BUILD index bdf53e24e..81e929b8c 100644 --- a/pkg/segment/test/BUILD +++ b/pkg/segment/test/BUILD @@ -2,7 +2,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:private"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/BUILD b/pkg/sentry/BUILD index d18cf3555..53989301f 100644 --- a/pkg/sentry/BUILD +++ b/pkg/sentry/BUILD @@ -1,7 +1,7 @@ # This BUILD file defines a package_group that allows for interdependencies for # sentry-internal packages. -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) package_group( name = "internal", diff --git a/pkg/sentry/arch/BUILD b/pkg/sentry/arch/BUILD index 9bf04360a..0c044bc33 100644 --- a/pkg/sentry/arch/BUILD +++ b/pkg/sentry/arch/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/context/BUILD b/pkg/sentry/context/BUILD index 02d24defd..a3c8d0177 100644 --- a/pkg/sentry/context/BUILD +++ b/pkg/sentry/context/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "context", diff --git a/pkg/sentry/context/contexttest/BUILD b/pkg/sentry/context/contexttest/BUILD index 01bb40b04..bed156b70 100644 --- a/pkg/sentry/context/contexttest/BUILD +++ b/pkg/sentry/context/contexttest/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/control/BUILD b/pkg/sentry/control/BUILD index c3b682d6f..f54e01ee8 100644 --- a/pkg/sentry/control/BUILD +++ b/pkg/sentry/control/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "control", diff --git a/pkg/sentry/device/BUILD b/pkg/sentry/device/BUILD index bebdb2939..01de708d3 100644 --- a/pkg/sentry/device/BUILD +++ b/pkg/sentry/device/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "device", diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 6f368b0da..e58333da3 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/anon/BUILD b/pkg/sentry/fs/anon/BUILD index 4bd912e95..2111df2e8 100644 --- a/pkg/sentry/fs/anon/BUILD +++ b/pkg/sentry/fs/anon/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "anon", diff --git a/pkg/sentry/fs/ashmem/BUILD b/pkg/sentry/fs/ashmem/BUILD index e5bb661b5..dcf620dca 100644 --- a/pkg/sentry/fs/ashmem/BUILD +++ b/pkg/sentry/fs/ashmem/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/fs/binder/BUILD b/pkg/sentry/fs/binder/BUILD index 27155819e..8a448175f 100644 --- a/pkg/sentry/fs/binder/BUILD +++ b/pkg/sentry/fs/binder/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD index 85371032a..e5b962c8c 100644 --- a/pkg/sentry/fs/dev/BUILD +++ b/pkg/sentry/fs/dev/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index 8a0937cda..098463e97 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/filetest/BUILD b/pkg/sentry/fs/filetest/BUILD index d137fee4c..05ca72aa0 100644 --- a/pkg/sentry/fs/filetest/BUILD +++ b/pkg/sentry/fs/filetest/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index d4767642b..7dff970ea 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD index 35ffadd13..f2c79b475 100644 --- a/pkg/sentry/fs/gofer/BUILD +++ b/pkg/sentry/fs/gofer/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 6877eb161..ea2ca11bf 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD index 3159ff1da..7164744b8 100644 --- a/pkg/sentry/fs/lock/BUILD +++ b/pkg/sentry/fs/lock/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index 74954f213..f6bc90634 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/proc/device/BUILD b/pkg/sentry/fs/proc/device/BUILD index ff7dacf07..64b0c5a3a 100644 --- a/pkg/sentry/fs/proc/device/BUILD +++ b/pkg/sentry/fs/proc/device/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "device", diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD index b4ba64e10..6b44c0075 100644 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ b/pkg/sentry/fs/proc/seqfile/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index 4a629e38e..f36e4a5e8 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD index 7de928e16..42e98230e 100644 --- a/pkg/sentry/fs/sys/BUILD +++ b/pkg/sentry/fs/sys/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/timerfd/BUILD b/pkg/sentry/fs/timerfd/BUILD index ffdd7e0dc..0e06a5028 100644 --- a/pkg/sentry/fs/timerfd/BUILD +++ b/pkg/sentry/fs/timerfd/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD index c5ec85460..bf5b68869 100644 --- a/pkg/sentry/fs/tmpfs/BUILD +++ b/pkg/sentry/fs/tmpfs/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index 011cb6955..bee2db3f3 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/hostcpu/BUILD b/pkg/sentry/hostcpu/BUILD index 33197cf14..b5067ae6d 100644 --- a/pkg/sentry/hostcpu/BUILD +++ b/pkg/sentry/hostcpu/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "hostcpu", diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD index 159c50efb..e288d34e9 100644 --- a/pkg/sentry/inet/BUILD +++ b/pkg/sentry/inet/BUILD @@ -1,6 +1,6 @@ package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 7d41626dc..b230aff98 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index a81085372..abd4f2dae 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/contexttest/BUILD b/pkg/sentry/kernel/contexttest/BUILD index 391986291..5769a3b28 100644 --- a/pkg/sentry/kernel/contexttest/BUILD +++ b/pkg/sentry/kernel/contexttest/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 5e8b36ed6..1567d5050 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index d96803fc9..f2f1a1223 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/fasync/BUILD b/pkg/sentry/kernel/fasync/BUILD index 17749c0de..5faf95909 100644 --- a/pkg/sentry/kernel/fasync/BUILD +++ b/pkg/sentry/kernel/fasync/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index afd35985f..da24c36c1 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/kdefs/BUILD b/pkg/sentry/kernel/kdefs/BUILD index 3f8fa206c..38aaca134 100644 --- a/pkg/sentry/kernel/kdefs/BUILD +++ b/pkg/sentry/kernel/kdefs/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "kdefs", diff --git a/pkg/sentry/kernel/memevent/BUILD b/pkg/sentry/kernel/memevent/BUILD index dfd8dd062..347a69062 100644 --- a/pkg/sentry/kernel/memevent/BUILD +++ b/pkg/sentry/kernel/memevent/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "memevent", diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 19b23c6d2..011a3f349 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/sched/BUILD b/pkg/sentry/kernel/sched/BUILD index 52e226a39..184e8a35b 100644 --- a/pkg/sentry/kernel/sched/BUILD +++ b/pkg/sentry/kernel/sched/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sched", diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD index bdcf4ce5c..840943ca8 100644 --- a/pkg/sentry/kernel/semaphore/BUILD +++ b/pkg/sentry/kernel/semaphore/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD index 40e641355..f45770eef 100644 --- a/pkg/sentry/kernel/shm/BUILD +++ b/pkg/sentry/kernel/shm/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD index 5d8db2273..584f7c7cc 100644 --- a/pkg/sentry/kernel/time/BUILD +++ b/pkg/sentry/kernel/time/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/limits/BUILD b/pkg/sentry/limits/BUILD index 90f4395d4..800166675 100644 --- a/pkg/sentry/limits/BUILD +++ b/pkg/sentry/limits/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index 24e734b49..1ea260a4e 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_embed_data") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/memmap/BUILD b/pkg/sentry/memmap/BUILD index c9e0b95a0..9c2cbd18b 100644 --- a/pkg/sentry/memmap/BUILD +++ b/pkg/sentry/memmap/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/memutil/BUILD b/pkg/sentry/memutil/BUILD index 88738d65d..68b03d4cc 100644 --- a/pkg/sentry/memutil/BUILD +++ b/pkg/sentry/memutil/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "memutil", diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 0997ec0a7..f679262d0 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/platform/BUILD b/pkg/sentry/platform/BUILD index af9ba5394..ac8a6cb7f 100644 --- a/pkg/sentry/platform/BUILD +++ b/pkg/sentry/platform/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/platform/filemem/BUILD b/pkg/sentry/platform/filemem/BUILD index 2a5982763..1a61cfaa5 100644 --- a/pkg/sentry/platform/filemem/BUILD +++ b/pkg/sentry/platform/filemem/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/platform/interrupt/BUILD b/pkg/sentry/platform/interrupt/BUILD index dbafa3204..eeccd4d0e 100644 --- a/pkg/sentry/platform/interrupt/BUILD +++ b/pkg/sentry/platform/interrupt/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "interrupt", diff --git a/pkg/sentry/platform/kvm/BUILD b/pkg/sentry/platform/kvm/BUILD index 1b71e629f..6e40b3177 100644 --- a/pkg/sentry/platform/kvm/BUILD +++ b/pkg/sentry/platform/kvm/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/platform/kvm/testutil/BUILD b/pkg/sentry/platform/kvm/testutil/BUILD index 1dffe94a4..e10087e8e 100644 --- a/pkg/sentry/platform/kvm/testutil/BUILD +++ b/pkg/sentry/platform/kvm/testutil/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "testutil", diff --git a/pkg/sentry/platform/procid/BUILD b/pkg/sentry/platform/procid/BUILD index 20c8bc02c..277509624 100644 --- a/pkg/sentry/platform/procid/BUILD +++ b/pkg/sentry/platform/procid/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "procid", diff --git a/pkg/sentry/platform/ptrace/BUILD b/pkg/sentry/platform/ptrace/BUILD index 2eb354ad4..f86790942 100644 --- a/pkg/sentry/platform/ptrace/BUILD +++ b/pkg/sentry/platform/ptrace/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ptrace", diff --git a/pkg/sentry/platform/ring0/BUILD b/pkg/sentry/platform/ring0/BUILD index c35d49f2d..ecb3e9a9c 100644 --- a/pkg/sentry/platform/ring0/BUILD +++ b/pkg/sentry/platform/ring0/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/pkg/sentry/platform/ring0/gen_offsets/BUILD b/pkg/sentry/platform/ring0/gen_offsets/BUILD index b76d7974e..d7029d5a9 100644 --- a/pkg/sentry/platform/ring0/gen_offsets/BUILD +++ b/pkg/sentry/platform/ring0/gen_offsets/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/platform/ring0/pagetables/BUILD b/pkg/sentry/platform/ring0/pagetables/BUILD index de1b920af..fe93d3030 100644 --- a/pkg/sentry/platform/ring0/pagetables/BUILD +++ b/pkg/sentry/platform/ring0/pagetables/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/pkg/sentry/platform/safecopy/BUILD b/pkg/sentry/platform/safecopy/BUILD index cb8347dd8..05a6a61ae 100644 --- a/pkg/sentry/platform/safecopy/BUILD +++ b/pkg/sentry/platform/safecopy/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0, portions BSD, MIT +package(licenses = ["notice"]) go_library( name = "safecopy", diff --git a/pkg/sentry/safemem/BUILD b/pkg/sentry/safemem/BUILD index 87a9bff12..3ab453718 100644 --- a/pkg/sentry/safemem/BUILD +++ b/pkg/sentry/safemem/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "safemem", diff --git a/pkg/sentry/sighandling/BUILD b/pkg/sentry/sighandling/BUILD index 41313d334..cec3af92e 100644 --- a/pkg/sentry/sighandling/BUILD +++ b/pkg/sentry/sighandling/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sighandling", diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD index 3a8044b5f..076f953e7 100644 --- a/pkg/sentry/socket/BUILD +++ b/pkg/sentry/socket/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD index d3a63f15f..9f4763906 100644 --- a/pkg/sentry/socket/control/BUILD +++ b/pkg/sentry/socket/control/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index da4aaf510..45e418db3 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/hostinet/BUILD b/pkg/sentry/socket/hostinet/BUILD index b8dceb102..a469af7ac 100644 --- a/pkg/sentry/socket/hostinet/BUILD +++ b/pkg/sentry/socket/hostinet/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD index cff922cb8..148306329 100644 --- a/pkg/sentry/socket/netlink/BUILD +++ b/pkg/sentry/socket/netlink/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/netlink/port/BUILD b/pkg/sentry/socket/netlink/port/BUILD index 3a7dbc5ed..a7370a4ec 100644 --- a/pkg/sentry/socket/netlink/port/BUILD +++ b/pkg/sentry/socket/netlink/port/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/socket/netlink/route/BUILD b/pkg/sentry/socket/netlink/route/BUILD index e1bcfe252..be0419679 100644 --- a/pkg/sentry/socket/netlink/route/BUILD +++ b/pkg/sentry/socket/netlink/route/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/rpcinet/BUILD b/pkg/sentry/socket/rpcinet/BUILD index 06e121946..4da14a1e0 100644 --- a/pkg/sentry/socket/rpcinet/BUILD +++ b/pkg/sentry/socket/rpcinet/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "rpcinet", diff --git a/pkg/sentry/socket/rpcinet/conn/BUILD b/pkg/sentry/socket/rpcinet/conn/BUILD index a16977f29..4336ae9b4 100644 --- a/pkg/sentry/socket/rpcinet/conn/BUILD +++ b/pkg/sentry/socket/rpcinet/conn/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) go_library( name = "conn", diff --git a/pkg/sentry/socket/rpcinet/notifier/BUILD b/pkg/sentry/socket/rpcinet/notifier/BUILD index 2bab01774..b0b107ddb 100644 --- a/pkg/sentry/socket/rpcinet/notifier/BUILD +++ b/pkg/sentry/socket/rpcinet/notifier/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) go_library( name = "notifier", diff --git a/pkg/sentry/socket/unix/BUILD b/pkg/sentry/socket/unix/BUILD index a12fa93db..fe6871cc6 100644 --- a/pkg/sentry/socket/unix/BUILD +++ b/pkg/sentry/socket/unix/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/unix/transport/BUILD b/pkg/sentry/socket/unix/transport/BUILD index 5a90837bc..5a2de0c4c 100644 --- a/pkg/sentry/socket/unix/transport/BUILD +++ b/pkg/sentry/socket/unix/transport/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/state/BUILD b/pkg/sentry/state/BUILD index f1f6fdb7d..42c459acc 100644 --- a/pkg/sentry/state/BUILD +++ b/pkg/sentry/state/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "state", diff --git a/pkg/sentry/strace/BUILD b/pkg/sentry/strace/BUILD index 8517db1ac..552e79686 100644 --- a/pkg/sentry/strace/BUILD +++ b/pkg/sentry/strace/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "strace", diff --git a/pkg/sentry/syscalls/BUILD b/pkg/sentry/syscalls/BUILD index 35192ff49..6b5469e45 100644 --- a/pkg/sentry/syscalls/BUILD +++ b/pkg/sentry/syscalls/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "syscalls", diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index 7621bfdbd..846601881 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/time/BUILD b/pkg/sentry/time/BUILD index 1191010e6..c4b6dcc63 100644 --- a/pkg/sentry/time/BUILD +++ b/pkg/sentry/time/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0, portions BSD +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/unimpl/BUILD b/pkg/sentry/unimpl/BUILD index 42e24ace5..b608867a9 100644 --- a/pkg/sentry/unimpl/BUILD +++ b/pkg/sentry/unimpl/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) proto_library( name = "unimplemented_syscall_proto", diff --git a/pkg/sentry/uniqueid/BUILD b/pkg/sentry/uniqueid/BUILD index 0929497c3..ccc5a28d3 100644 --- a/pkg/sentry/uniqueid/BUILD +++ b/pkg/sentry/uniqueid/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "uniqueid", diff --git a/pkg/sentry/usage/BUILD b/pkg/sentry/usage/BUILD index 868dfd400..09198496b 100644 --- a/pkg/sentry/usage/BUILD +++ b/pkg/sentry/usage/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/usermem/BUILD b/pkg/sentry/usermem/BUILD index dae41ed0e..1a560b6f3 100644 --- a/pkg/sentry/usermem/BUILD +++ b/pkg/sentry/usermem/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/watchdog/BUILD b/pkg/sentry/watchdog/BUILD index b2c687b20..0bbf3705c 100644 --- a/pkg/sentry/watchdog/BUILD +++ b/pkg/sentry/watchdog/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "watchdog", diff --git a/pkg/sleep/BUILD b/pkg/sleep/BUILD index 338fd9336..2b005bf66 100644 --- a/pkg/sleep/BUILD +++ b/pkg/sleep/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sleep", diff --git a/pkg/state/BUILD b/pkg/state/BUILD index dd0f250fa..0a975e162 100644 --- a/pkg/state/BUILD +++ b/pkg/state/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/state/statefile/BUILD b/pkg/state/statefile/BUILD index 66c8f3807..5967781e8 100644 --- a/pkg/state/statefile/BUILD +++ b/pkg/state/statefile/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "statefile", diff --git a/pkg/sync/BUILD b/pkg/sync/BUILD index 6ddc6e812..1624e681c 100644 --- a/pkg/sync/BUILD +++ b/pkg/sync/BUILD @@ -2,7 +2,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0, portions BSD + licenses = ["notice"], ) load("//tools/go_generics:defs.bzl", "go_template") diff --git a/pkg/sync/atomicptrtest/BUILD b/pkg/sync/atomicptrtest/BUILD index 9cb7f66fe..198fbb895 100644 --- a/pkg/sync/atomicptrtest/BUILD +++ b/pkg/sync/atomicptrtest/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sync/seqatomictest/BUILD b/pkg/sync/seqatomictest/BUILD index 54f8e59b1..23132650a 100644 --- a/pkg/sync/seqatomictest/BUILD +++ b/pkg/sync/seqatomictest/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/syserr/BUILD b/pkg/syserr/BUILD index 30ae20772..0d65115ef 100644 --- a/pkg/syserr/BUILD +++ b/pkg/syserr/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "syserr", diff --git a/pkg/syserror/BUILD b/pkg/syserror/BUILD index d4c6da97a..ac478d0ff 100644 --- a/pkg/syserror/BUILD +++ b/pkg/syserror/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "syserror", diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index daff9a0a0..83524cc8a 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/adapters/gonet/BUILD b/pkg/tcpip/adapters/gonet/BUILD index 723ad668f..ee2417238 100644 --- a/pkg/tcpip/adapters/gonet/BUILD +++ b/pkg/tcpip/adapters/gonet/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "gonet", diff --git a/pkg/tcpip/buffer/BUILD b/pkg/tcpip/buffer/BUILD index 11a725423..648d12cdf 100644 --- a/pkg/tcpip/buffer/BUILD +++ b/pkg/tcpip/buffer/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/checker/BUILD b/pkg/tcpip/checker/BUILD index a1de808b9..f597d0b24 100644 --- a/pkg/tcpip/checker/BUILD +++ b/pkg/tcpip/checker/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "checker", diff --git a/pkg/tcpip/hash/jenkins/BUILD b/pkg/tcpip/hash/jenkins/BUILD index bbb764db8..ce2194a4d 100644 --- a/pkg/tcpip/hash/jenkins/BUILD +++ b/pkg/tcpip/hash/jenkins/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "jenkins", diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 8e455fe1e..a5c7290ee 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/link/channel/BUILD b/pkg/tcpip/link/channel/BUILD index 25f6c1457..ae285e495 100644 --- a/pkg/tcpip/link/channel/BUILD +++ b/pkg/tcpip/link/channel/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "channel", diff --git a/pkg/tcpip/link/fdbased/BUILD b/pkg/tcpip/link/fdbased/BUILD index a4aa3feec..0d78c9b15 100644 --- a/pkg/tcpip/link/fdbased/BUILD +++ b/pkg/tcpip/link/fdbased/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "fdbased", diff --git a/pkg/tcpip/link/loopback/BUILD b/pkg/tcpip/link/loopback/BUILD index a46ba7f11..710a05ede 100644 --- a/pkg/tcpip/link/loopback/BUILD +++ b/pkg/tcpip/link/loopback/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "loopback", diff --git a/pkg/tcpip/link/rawfile/BUILD b/pkg/tcpip/link/rawfile/BUILD index 2746d4ced..f01bb2c07 100644 --- a/pkg/tcpip/link/rawfile/BUILD +++ b/pkg/tcpip/link/rawfile/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "rawfile", diff --git a/pkg/tcpip/link/sharedmem/BUILD b/pkg/tcpip/link/sharedmem/BUILD index d7f1e66ef..dc8f1543e 100644 --- a/pkg/tcpip/link/sharedmem/BUILD +++ b/pkg/tcpip/link/sharedmem/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sharedmem", diff --git a/pkg/tcpip/link/sharedmem/pipe/BUILD b/pkg/tcpip/link/sharedmem/pipe/BUILD index 12e813509..85deafa38 100644 --- a/pkg/tcpip/link/sharedmem/pipe/BUILD +++ b/pkg/tcpip/link/sharedmem/pipe/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "pipe", diff --git a/pkg/tcpip/link/sharedmem/queue/BUILD b/pkg/tcpip/link/sharedmem/queue/BUILD index 661037bb2..d7dc631eb 100644 --- a/pkg/tcpip/link/sharedmem/queue/BUILD +++ b/pkg/tcpip/link/sharedmem/queue/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "queue", diff --git a/pkg/tcpip/link/sniffer/BUILD b/pkg/tcpip/link/sniffer/BUILD index 52e237c25..7d0d1781e 100644 --- a/pkg/tcpip/link/sniffer/BUILD +++ b/pkg/tcpip/link/sniffer/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sniffer", diff --git a/pkg/tcpip/link/tun/BUILD b/pkg/tcpip/link/tun/BUILD index 5ec01cec9..e54852d3f 100644 --- a/pkg/tcpip/link/tun/BUILD +++ b/pkg/tcpip/link/tun/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "tun", diff --git a/pkg/tcpip/link/waitable/BUILD b/pkg/tcpip/link/waitable/BUILD index ba495c437..89a9eee23 100644 --- a/pkg/tcpip/link/waitable/BUILD +++ b/pkg/tcpip/link/waitable/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "waitable", diff --git a/pkg/tcpip/network/BUILD b/pkg/tcpip/network/BUILD index a2a07f533..f36f49453 100644 --- a/pkg/tcpip/network/BUILD +++ b/pkg/tcpip/network/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_test( name = "ip_test", diff --git a/pkg/tcpip/network/arp/BUILD b/pkg/tcpip/network/arp/BUILD index f6fb7daf7..ef18bb93d 100644 --- a/pkg/tcpip/network/arp/BUILD +++ b/pkg/tcpip/network/arp/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "arp", diff --git a/pkg/tcpip/network/fragmentation/BUILD b/pkg/tcpip/network/fragmentation/BUILD index aaabfcb9a..bf0a7b99c 100644 --- a/pkg/tcpip/network/fragmentation/BUILD +++ b/pkg/tcpip/network/fragmentation/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/network/hash/BUILD b/pkg/tcpip/network/hash/BUILD index 401dce646..ea520c6ed 100644 --- a/pkg/tcpip/network/hash/BUILD +++ b/pkg/tcpip/network/hash/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "hash", diff --git a/pkg/tcpip/network/ipv4/BUILD b/pkg/tcpip/network/ipv4/BUILD index e72317e9f..7a5341def 100644 --- a/pkg/tcpip/network/ipv4/BUILD +++ b/pkg/tcpip/network/ipv4/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ipv4", diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index 808c37df3..000e00dba 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ipv6", diff --git a/pkg/tcpip/ports/BUILD b/pkg/tcpip/ports/BUILD index a2fa9b84a..3ee80c62b 100644 --- a/pkg/tcpip/ports/BUILD +++ b/pkg/tcpip/ports/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ports", diff --git a/pkg/tcpip/sample/tun_tcp_connect/BUILD b/pkg/tcpip/sample/tun_tcp_connect/BUILD index 32baf2115..996939581 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/BUILD +++ b/pkg/tcpip/sample/tun_tcp_connect/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "tun_tcp_connect", diff --git a/pkg/tcpip/sample/tun_tcp_echo/BUILD b/pkg/tcpip/sample/tun_tcp_echo/BUILD index 760445843..dad8ef399 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/BUILD +++ b/pkg/tcpip/sample/tun_tcp_echo/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "tun_tcp_echo", diff --git a/pkg/tcpip/seqnum/BUILD b/pkg/tcpip/seqnum/BUILD index c5c889239..a63665efc 100644 --- a/pkg/tcpip/seqnum/BUILD +++ b/pkg/tcpip/seqnum/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD index 8a598c57d..551c3c73e 100644 --- a/pkg/tcpip/stack/BUILD +++ b/pkg/tcpip/stack/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/transport/ping/BUILD b/pkg/tcpip/transport/ping/BUILD index 982b6795c..4d4241d4b 100644 --- a/pkg/tcpip/transport/ping/BUILD +++ b/pkg/tcpip/transport/ping/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 726107739..e5c05f8c0 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/transport/tcp/testing/context/BUILD b/pkg/tcpip/transport/tcp/testing/context/BUILD index 814e5c1ea..1584e4095 100644 --- a/pkg/tcpip/transport/tcp/testing/context/BUILD +++ b/pkg/tcpip/transport/tcp/testing/context/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "context", diff --git a/pkg/tcpip/transport/tcpconntrack/BUILD b/pkg/tcpip/transport/tcpconntrack/BUILD index ac1a94d4d..31a845dee 100644 --- a/pkg/tcpip/transport/tcpconntrack/BUILD +++ b/pkg/tcpip/transport/tcpconntrack/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "tcpconntrack", diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 4225e28dc..8ccb79c48 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tmutex/BUILD b/pkg/tmutex/BUILD index c20df7005..69035044d 100644 --- a/pkg/tmutex/BUILD +++ b/pkg/tmutex/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "tmutex", diff --git a/pkg/unet/BUILD b/pkg/unet/BUILD index f90e43c89..5e177e78e 100644 --- a/pkg/unet/BUILD +++ b/pkg/unet/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "unet", diff --git a/pkg/urpc/BUILD b/pkg/urpc/BUILD index 21008cf6c..36cae67e1 100644 --- a/pkg/urpc/BUILD +++ b/pkg/urpc/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "urpc", diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index 5e611c54f..b748246da 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/runsc/boot/BUILD b/runsc/boot/BUILD index 15a7cdae1..540e99151 100644 --- a/runsc/boot/BUILD +++ b/runsc/boot/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "boot", diff --git a/runsc/boot/filter/BUILD b/runsc/boot/filter/BUILD index 004222242..3b6020cf3 100644 --- a/runsc/boot/filter/BUILD +++ b/runsc/boot/filter/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "filter", diff --git a/runsc/cgroup/BUILD b/runsc/cgroup/BUILD index 4f9a25a25..620d33a19 100644 --- a/runsc/cgroup/BUILD +++ b/runsc/cgroup/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "cgroup", diff --git a/runsc/cmd/BUILD b/runsc/cmd/BUILD index a908172af..9e2be0d37 100644 --- a/runsc/cmd/BUILD +++ b/runsc/cmd/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "cmd", diff --git a/runsc/console/BUILD b/runsc/console/BUILD index ff4ccff69..3ff9eba27 100644 --- a/runsc/console/BUILD +++ b/runsc/console/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "console", diff --git a/runsc/container/BUILD b/runsc/container/BUILD index 354ce2661..3b25ff79a 100644 --- a/runsc/container/BUILD +++ b/runsc/container/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "container", diff --git a/runsc/fsgofer/BUILD b/runsc/fsgofer/BUILD index 756c20ad7..4adc9c1bc 100644 --- a/runsc/fsgofer/BUILD +++ b/runsc/fsgofer/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "fsgofer", diff --git a/runsc/fsgofer/filter/BUILD b/runsc/fsgofer/filter/BUILD index c7848d10c..78c5b526c 100644 --- a/runsc/fsgofer/filter/BUILD +++ b/runsc/fsgofer/filter/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "filter", diff --git a/runsc/sandbox/BUILD b/runsc/sandbox/BUILD index 899fd99de..2ed793333 100644 --- a/runsc/sandbox/BUILD +++ b/runsc/sandbox/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sandbox", diff --git a/runsc/specutils/BUILD b/runsc/specutils/BUILD index 77a10e2b6..372799850 100644 --- a/runsc/specutils/BUILD +++ b/runsc/specutils/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "specutils", diff --git a/runsc/test/image/BUILD b/runsc/test/image/BUILD index 22b3ebd2a..e8b629c6a 100644 --- a/runsc/test/image/BUILD +++ b/runsc/test/image/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_test( name = "image_test", diff --git a/runsc/test/integration/BUILD b/runsc/test/integration/BUILD index e7204dc66..779d30ec9 100644 --- a/runsc/test/integration/BUILD +++ b/runsc/test/integration/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_test( name = "integration_test", diff --git a/runsc/test/root/BUILD b/runsc/test/root/BUILD index 77dcbd79e..75826a521 100644 --- a/runsc/test/root/BUILD +++ b/runsc/test/root/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "root", diff --git a/runsc/test/root/testdata/BUILD b/runsc/test/root/testdata/BUILD index 6c9fe0aea..7f272dcd3 100644 --- a/runsc/test/root/testdata/BUILD +++ b/runsc/test/root/testdata/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "testdata", diff --git a/runsc/test/testutil/BUILD b/runsc/test/testutil/BUILD index 8c3919320..ddec81444 100644 --- a/runsc/test/testutil/BUILD +++ b/runsc/test/testutil/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "testutil", diff --git a/runsc/tools/dockercfg/BUILD b/runsc/tools/dockercfg/BUILD index a80b3abab..fd406ab93 100644 --- a/runsc/tools/dockercfg/BUILD +++ b/runsc/tools/dockercfg/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "dockercfg", diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index 8c391c8a6..148d9c366 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -1,7 +1,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") load("//test/syscalls:build_defs.bzl", "syscall_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) syscall_test(test = "//test/syscalls/linux:32bit_test") diff --git a/test/syscalls/gtest/BUILD b/test/syscalls/gtest/BUILD index d078fd3d5..22e061652 100644 --- a/test/syscalls/gtest/BUILD +++ b/test/syscalls/gtest/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "gtest", diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index e70742875..a311ca12c 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1,6 +1,6 @@ package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) cc_binary( diff --git a/test/util/BUILD b/test/util/BUILD index f2e563507..fac0730b4 100644 --- a/test/util/BUILD +++ b/test/util/BUILD @@ -1,6 +1,6 @@ package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) cc_library( diff --git a/tools/go_generics/BUILD b/tools/go_generics/BUILD index 2d97d99dc..39318b877 100644 --- a/tools/go_generics/BUILD +++ b/tools/go_generics/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "go_generics", diff --git a/tools/go_generics/globals/BUILD b/tools/go_generics/globals/BUILD index c26ac56d2..6628132f5 100644 --- a/tools/go_generics/globals/BUILD +++ b/tools/go_generics/globals/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "globals", diff --git a/tools/go_generics/go_merge/BUILD b/tools/go_generics/go_merge/BUILD index a60437962..02b09120e 100644 --- a/tools/go_generics/go_merge/BUILD +++ b/tools/go_generics/go_merge/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "go_merge", diff --git a/tools/go_generics/rules_tests/BUILD b/tools/go_generics/rules_tests/BUILD index 23b2d656d..a6f8cdd3c 100644 --- a/tools/go_generics/rules_tests/BUILD +++ b/tools/go_generics/rules_tests/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/tools/go_stateify/BUILD b/tools/go_stateify/BUILD index 68d37f5d7..bb53f8ae9 100644 --- a/tools/go_stateify/BUILD +++ b/tools/go_stateify/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "stateify", diff --git a/vdso/BUILD b/vdso/BUILD index fd395511c..c43d24070 100644 --- a/vdso/BUILD +++ b/vdso/BUILD @@ -3,7 +3,7 @@ # normal system VDSO (time, gettimeofday, clock_gettimeofday) but which uses # timekeeping parameters managed by the sandbox kernel. -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) genrule( name = "vdso", -- cgit v1.2.3 From e0afa8789963c18c1afed7d222754ef4b7415a7d Mon Sep 17 00:00:00 2001 From: Googler Date: Thu, 7 Feb 2019 13:44:57 -0800 Subject: Internal change. PiperOrigin-RevId: 232937200 Change-Id: I5c3709cc8f1313313ff618a45e48c14a3a111cb4 --- pkg/tcpip/link/muxed/BUILD | 31 ++++++++++ pkg/tcpip/link/muxed/injectable.go | 103 ++++++++++++++++++++++++++++++++ pkg/tcpip/link/muxed/injectable_test.go | 78 ++++++++++++++++++++++++ pkg/tcpip/stack/registration.go | 9 +++ 4 files changed, 221 insertions(+) create mode 100644 pkg/tcpip/link/muxed/BUILD create mode 100644 pkg/tcpip/link/muxed/injectable.go create mode 100644 pkg/tcpip/link/muxed/injectable_test.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/muxed/BUILD b/pkg/tcpip/link/muxed/BUILD new file mode 100644 index 000000000..92d2e3290 --- /dev/null +++ b/pkg/tcpip/link/muxed/BUILD @@ -0,0 +1,31 @@ +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") + +package(licenses = ["notice"]) # Apache 2.0 + +go_library( + name = "injectable", + srcs = ["injectable.go"], + importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/link/injectable", + visibility = [ + "//visibility:public", + ], + deps = [ + "//pkg/tcpip", + "//pkg/tcpip/buffer", + "//pkg/tcpip/stack", + ], +) + +go_test( + name = "injectable_test", + size = "small", + srcs = ["injectable_test.go"], + embed = [":injectable"], + deps = [ + "//pkg/tcpip", + "//pkg/tcpip/buffer", + "//pkg/tcpip/link/fdbased", + "//pkg/tcpip/network/ipv4", + "//pkg/tcpip/stack", + ], +) diff --git a/pkg/tcpip/link/muxed/injectable.go b/pkg/tcpip/link/muxed/injectable.go new file mode 100644 index 000000000..1215ba1e7 --- /dev/null +++ b/pkg/tcpip/link/muxed/injectable.go @@ -0,0 +1,103 @@ +// Copyright 2019 Google LLC +// +// 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 injectable provides a muxed injectable endpoint. +package injectable + +import ( + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" +) + +// MuxedInjectableEndpoint is an injectable multi endpoint. The endpoint has +// trivial routing rules that determine which InjectableEndpoint a given packet +// will be written to. Note that HandleLocal works differently for this +// endpoint (see WritePacket). +type MuxedInjectableEndpoint struct { + routes map[tcpip.Address]stack.InjectableLinkEndpoint + dispatcher stack.NetworkDispatcher +} + +// MTU implements stack.LinkEndpoint. +func (m *MuxedInjectableEndpoint) MTU() uint32 { + minMTU := ^uint32(0) + for _, endpoint := range m.routes { + if endpointMTU := endpoint.MTU(); endpointMTU < minMTU { + minMTU = endpointMTU + } + } + return minMTU +} + +// Capabilities implements stack.LinkEndpoint. +func (m *MuxedInjectableEndpoint) Capabilities() stack.LinkEndpointCapabilities { + minCapabilities := stack.LinkEndpointCapabilities(^uint(0)) + for _, endpoint := range m.routes { + minCapabilities &= endpoint.Capabilities() + } + return minCapabilities +} + +// MaxHeaderLength implements stack.LinkEndpoint. +func (m *MuxedInjectableEndpoint) MaxHeaderLength() uint16 { + minHeaderLen := ^uint16(0) + for _, endpoint := range m.routes { + if headerLen := endpoint.MaxHeaderLength(); headerLen < minHeaderLen { + minHeaderLen = headerLen + } + } + return minHeaderLen +} + +// LinkAddress implements stack.LinkEndpoint. +func (m *MuxedInjectableEndpoint) LinkAddress() tcpip.LinkAddress { + return "" +} + +// Attach implements stack.LinkEndpoint. +func (m *MuxedInjectableEndpoint) Attach(dispatcher stack.NetworkDispatcher) { + for _, endpoint := range m.routes { + endpoint.Attach(dispatcher) + } + m.dispatcher = dispatcher +} + +// IsAttached implements stack.LinkEndpoint. +func (m *MuxedInjectableEndpoint) IsAttached() bool { + return m.dispatcher != nil +} + +// Inject implements stack.InjectableLinkEndpoint. +func (m *MuxedInjectableEndpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { + m.dispatcher.DeliverNetworkPacket(m, "" /* remote */, "" /* local */, protocol, vv) +} + +// WritePacket writes outbound packets to the appropriate LinkInjectableEndpoint +// based on the RemoteAddress. HandleLocal only works if r.RemoteAddress has a +// route registered in this endpoint. +func (m *MuxedInjectableEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { + if endpoint, ok := m.routes[r.RemoteAddress]; ok { + return endpoint.WritePacket(r, hdr, payload, protocol) + } + return tcpip.ErrNoRoute +} + +// NewMuxedInjectableEndpoint creates a new multi-fd-based injectable endpoint. +func NewMuxedInjectableEndpoint(routes map[tcpip.Address]stack.InjectableLinkEndpoint, mtu uint32) (tcpip.LinkEndpointID, *MuxedInjectableEndpoint) { + e := &MuxedInjectableEndpoint{ + routes: routes, + } + return stack.RegisterLinkEndpoint(e), e +} diff --git a/pkg/tcpip/link/muxed/injectable_test.go b/pkg/tcpip/link/muxed/injectable_test.go new file mode 100644 index 000000000..8a1a863ff --- /dev/null +++ b/pkg/tcpip/link/muxed/injectable_test.go @@ -0,0 +1,78 @@ +// Copyright 2019 Google LLC +// +// 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 injectable + +import ( + "bytes" + "net" + "os" + "syscall" + "testing" + + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/link/fdbased" + "gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv4" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" +) + +func TestMuxedEndpointDispatch(t *testing.T) { + endpoint, sock, dstIP := makeMuxedTestEndpoint(t) + hdr := buffer.NewPrependable(1) + hdr.Prepend(1)[0] = 0xFA + packetRoute := stack.Route{RemoteAddress: dstIP} + + endpoint.WritePacket(&packetRoute, hdr, + buffer.NewViewFromBytes([]byte{0xFB}).ToVectorisedView(), ipv4.ProtocolNumber) + + buf := make([]byte, 6500) + bytesRead, err := sock.Read(buf) + if err != nil { + t.Fatalf("Unable to read from socketpair: %v", err) + } + if got, want := buf[:bytesRead], []byte{0xFA, 0xFB}; !bytes.Equal(got, want) { + t.Fatalf("Read %v from the socketpair, wanted %v", got, want) + } +} + +func TestMuxedEndpointDispatchHdrOnly(t *testing.T) { + endpoint, sock, dstIP := makeMuxedTestEndpoint(t) + hdr := buffer.NewPrependable(1) + hdr.Prepend(1)[0] = 0xFA + packetRoute := stack.Route{RemoteAddress: dstIP} + endpoint.WritePacket(&packetRoute, hdr, + buffer.NewView(0).ToVectorisedView(), ipv4.ProtocolNumber) + buf := make([]byte, 6500) + bytesRead, err := sock.Read(buf) + if err != nil { + t.Fatalf("Unable to read from socketpair: %v", err) + } + if got, want := buf[:bytesRead], []byte{0xFA}; !bytes.Equal(got, want) { + t.Fatalf("Read %v from the socketpair, wanted %v", got, want) + } +} + +func makeMuxedTestEndpoint(t *testing.T) (*MuxedInjectableEndpoint, *os.File, tcpip.Address) { + dstIP := tcpip.Address(net.ParseIP("1.2.3.4").To4()) + pair, err := syscall.Socketpair(syscall.AF_UNIX, + syscall.SOCK_SEQPACKET|syscall.SOCK_CLOEXEC|syscall.SOCK_NONBLOCK, 0) + if err != nil { + t.Fatal("Failed to create socket pair:", err) + } + _, underlyingEndpoint := fdbased.NewInjectable(pair[1], 6500) + routes := map[tcpip.Address]stack.InjectableLinkEndpoint{dstIP: underlyingEndpoint} + _, endpoint := NewMuxedInjectableEndpoint(routes, 6500) + return endpoint, os.NewFile(uintptr(pair[0]), "test route end"), dstIP +} diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 6becd9426..010d51886 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -253,6 +253,15 @@ type LinkEndpoint interface { IsAttached() bool } +// InjectableLinkEndpoint is a LinkEndpoint where inbound packets are +// delivered via the Inject method. +type InjectableLinkEndpoint interface { + LinkEndpoint + + // Inject injects an inbound packet. + Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) +} + // A LinkAddressResolver is an extension to a NetworkProtocol that // can resolve link addresses. type LinkAddressResolver interface { -- cgit v1.2.3 From 80f901b16b8bb8fe397cc44578035173f5155b24 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Thu, 7 Feb 2019 23:14:06 -0800 Subject: Plumb IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP to netstack. Also includes a few fixes for IPv4 multicast support. IPv6 support is coming in a followup CL. PiperOrigin-RevId: 233008638 Change-Id: If7dae6222fef43fda48033f0292af77832d95e82 --- pkg/abi/linux/socket.go | 21 +- pkg/sentry/socket/epsocket/epsocket.go | 46 ++- pkg/tcpip/stack/stack.go | 7 + pkg/tcpip/transport/udp/endpoint.go | 16 +- pkg/tcpip/transport/udp/endpoint_state.go | 6 + test/syscalls/BUILD | 2 + test/syscalls/linux/BUILD | 34 ++ test/syscalls/linux/ip_socket_test_util.cc | 33 +- test/syscalls/linux/ip_socket_test_util.h | 7 + test/syscalls/linux/socket_ip_udp_generic.cc | 14 + test/syscalls/linux/socket_ipv4_udp_unbound.cc | 424 +++++++++++++++++++++ test/syscalls/linux/socket_ipv4_udp_unbound.h | 29 ++ .../linux/socket_ipv4_udp_unbound_loopback.cc | 35 ++ test/syscalls/linux/socket_test_util.cc | 38 +- test/syscalls/linux/socket_test_util.h | 5 + 15 files changed, 694 insertions(+), 23 deletions(-) create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound.cc create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound.h create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc (limited to 'pkg/tcpip/stack') diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index a5f78506a..906776525 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -204,15 +204,30 @@ const ( // uapi/linux/socket.h. const SockAddrMax = 128 -// SockAddrInt is struct sockaddr_in, from uapi/linux/in.h. +// InetAddr is struct in_addr, from uapi/linux/in.h. +type InetAddr [4]byte + +// SockAddrInet is struct sockaddr_in, from uapi/linux/in.h. type SockAddrInet struct { Family uint16 Port uint16 - Addr [4]byte + Addr InetAddr Zero [8]uint8 // pad to sizeof(struct sockaddr). } -// SockAddrInt6 is struct sockaddr_in6, from uapi/linux/in6.h. +// InetMulticastRequest is struct ip_mreq, from uapi/linux/in.h. +type InetMulticastRequest struct { + MulticastAddr InetAddr + InterfaceAddr InetAddr +} + +// InetMulticastRequestWithNIC is struct ip_mreqn, from uapi/linux/in.h. +type InetMulticastRequestWithNIC struct { + InetMulticastRequest + InterfaceIndex int32 +} + +// SockAddrInet6 is struct sockaddr_in6, from uapi/linux/in6.h. type SockAddrInet6 struct { Family uint16 Port uint16 diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index ca865b111..16720456a 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -1078,6 +1078,25 @@ func setSockOptIPv6(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) return syserr.TranslateNetstackError(ep.SetSockOpt(struct{}{})) } +var ( + inetMulticastRequestSize = int(binary.Size(linux.InetMulticastRequest{})) + inetMulticastRequestWithNICSize = int(binary.Size(linux.InetMulticastRequestWithNIC{})) +) + +func copyInMulticastRequest(optVal []byte) (linux.InetMulticastRequestWithNIC, *syserr.Error) { + if len(optVal) < inetMulticastRequestSize { + return linux.InetMulticastRequestWithNIC{}, syserr.ErrInvalidArgument + } + + var req linux.InetMulticastRequestWithNIC + if len(optVal) >= inetMulticastRequestWithNICSize { + binary.Unmarshal(optVal[:inetMulticastRequestWithNICSize], usermem.ByteOrder, &req) + } else { + binary.Unmarshal(optVal[:inetMulticastRequestSize], usermem.ByteOrder, &req.InetMulticastRequest) + } + return req, nil +} + // setSockOptIP implements SetSockOpt when level is SOL_IP. func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *syserr.Error { switch name { @@ -1096,7 +1115,31 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s } return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.MulticastTTLOption(v))) - case linux.IP_ADD_MEMBERSHIP, linux.MCAST_JOIN_GROUP, linux.IP_MULTICAST_IF: + case linux.IP_ADD_MEMBERSHIP: + req, err := copyInMulticastRequest(optVal) + if err != nil { + return err + } + + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.AddMembershipOption{ + NIC: tcpip.NICID(req.InterfaceIndex), + InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]), + MulticastAddr: tcpip.Address(req.MulticastAddr[:]), + })) + + case linux.IP_DROP_MEMBERSHIP: + req, err := copyInMulticastRequest(optVal) + if err != nil { + return err + } + + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.RemoveMembershipOption{ + NIC: tcpip.NICID(req.InterfaceIndex), + InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]), + MulticastAddr: tcpip.Address(req.MulticastAddr[:]), + })) + + case linux.MCAST_JOIN_GROUP, linux.IP_MULTICAST_IF: // FIXME: Disallow IP-level multicast group options by // default. These will need to be supported by appropriately plumbing // the level through to the network stack (if at all). However, we @@ -1108,7 +1151,6 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s linux.IP_BIND_ADDRESS_NO_PORT, linux.IP_BLOCK_SOURCE, linux.IP_CHECKSUM, - linux.IP_DROP_MEMBERSHIP, linux.IP_DROP_SOURCE_MEMBERSHIP, linux.IP_FREEBIND, linux.IP_HDRINCL, diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 7aa9dbd46..854ebe1bb 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -742,6 +742,9 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n return Route{}, tcpip.ErrNoRoute } + // TODO: Route multicast packets with no specified local + // address or NIC. + for i := range s.routeTable { if (id != 0 && id != s.routeTable[i].NIC) || (len(remoteAddr) != 0 && !s.routeTable[i].Match(remoteAddr)) { continue @@ -768,6 +771,10 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n return r, nil } + if isMulticast { + return Route{}, tcpip.ErrNetworkUnreachable + } + return Route{}, tcpip.ErrNoRoute } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index b2a27a7cb..d46bf0ade 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -99,6 +99,7 @@ type endpoint struct { effectiveNetProtos []tcpip.NetworkProtocolNumber } +// +stateify savable type multicastMembership struct { nicID tcpip.NICID multicastAddr tcpip.Address @@ -412,6 +413,8 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { nicID = e.stack.CheckLocalAddress(nicID, e.netProto, v.InterfaceAddr) } if nicID == 0 { + // TODO: Allow adding memberships without + // specifing an interface. return tcpip.ErrNoRoute } @@ -766,9 +769,11 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error } } + nicid := addr.NIC if len(addr.Addr) != 0 { // A local address was specified, verify that it's valid. - if e.stack.CheckLocalAddress(addr.NIC, netProto, addr.Addr) == 0 { + nicid = e.stack.CheckLocalAddress(addr.NIC, netProto, addr.Addr) + if nicid == 0 { return tcpip.ErrBadLocalAddress } } @@ -777,21 +782,21 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error LocalPort: addr.Port, LocalAddress: addr.Addr, } - id, err = e.registerWithStack(addr.NIC, netProtos, id) + id, err = e.registerWithStack(nicid, netProtos, id) if err != nil { return err } if commit != nil { if err := commit(); err != nil { // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, ProtocolNumber, id, e) + e.stack.UnregisterTransportEndpoint(nicid, netProtos, ProtocolNumber, id, e) e.stack.ReleasePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort) return err } } e.id = id - e.regNICID = addr.NIC + e.regNICID = nicid e.effectiveNetProtos = netProtos // Mark endpoint as bound. @@ -815,7 +820,8 @@ func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) *tcp return err } - e.bindNICID = addr.NIC + // Save the effective NICID generated by bindLocked. + e.bindNICID = e.regNICID return nil } diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index db1e281ad..4d8210294 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -103,4 +103,10 @@ func (e *endpoint) afterLoad() { if err != nil { panic(*err) } + + for _, m := range e.multicastMemberships { + if err := e.stack.JoinGroup(e.netProto, m.nicID, m.multicastAddr); err != nil { + panic(err) + } + } } diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index 53da121ec..a5abf8013 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -361,6 +361,8 @@ syscall_test( test = "//test/syscalls/linux:socket_ip_udp_loopback_test", ) +syscall_test(test = "//test/syscalls/linux:socket_ipv4_udp_unbound_loopback_test") + syscall_test(test = "//test/syscalls/linux:socket_netdevice_test") syscall_test(test = "//test/syscalls/linux:socket_netlink_route_test") diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 590ee1659..75fa52a57 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1931,6 +1931,24 @@ cc_library( alwayslink = 1, ) +cc_library( + name = "socket_ipv4_udp_unbound_test_cases", + testonly = 1, + srcs = [ + "socket_ipv4_udp_unbound.cc", + ], + hdrs = [ + "socket_ipv4_udp_unbound.h", + ], + deps = [ + ":ip_socket_test_util", + ":socket_test_util", + "//test/util:test_util", + "@com_google_googletest//:gtest", + ], + alwayslink = 1, +) + cc_binary( name = "socket_abstract_test", testonly = 1, @@ -2124,6 +2142,22 @@ cc_binary( ], ) +cc_binary( + name = "socket_ipv4_udp_unbound_loopback_test", + testonly = 1, + srcs = [ + "socket_ipv4_udp_unbound_loopback.cc", + ], + linkstatic = 1, + deps = [ + ":ip_socket_test_util", + ":socket_ipv4_udp_unbound_test_cases", + ":socket_test_util", + "//test/util:test_main", + "//test/util:test_util", + ], +) + cc_binary( name = "socket_domain_test", testonly = 1, diff --git a/test/syscalls/linux/ip_socket_test_util.cc b/test/syscalls/linux/ip_socket_test_util.cc index 1659d3d83..f8232fc24 100644 --- a/test/syscalls/linux/ip_socket_test_util.cc +++ b/test/syscalls/linux/ip_socket_test_util.cc @@ -12,11 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include + #include "test/syscalls/linux/ip_socket_test_util.h" namespace gvisor { namespace testing { +PosixErrorOr InterfaceIndex(std::string name) { + // TODO: Consider using netlink. + ifreq req = {}; + memcpy(req.ifr_name, name.c_str(), name.size()); + ASSIGN_OR_RETURN_ERRNO(auto sock, Socket(AF_INET, SOCK_DGRAM, 0)); + RETURN_ERROR_IF_SYSCALL_FAIL(ioctl(sock.get(), SIOCGIFINDEX, &req)); + return req.ifr_ifindex; +} + namespace { std::string DescribeSocketType(int type) { @@ -28,7 +41,7 @@ std::string DescribeSocketType(int type) { SocketPairKind IPv6TCPAcceptBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "IPv6 TCP socket"); + absl::StrCat(DescribeSocketType(type), "connected IPv6 TCP socket"); return SocketPairKind{ description, TCPAcceptBindSocketPairCreator(AF_INET6, type | SOCK_STREAM, 0, /* dual_stack = */ false)}; @@ -36,7 +49,7 @@ SocketPairKind IPv6TCPAcceptBindSocketPair(int type) { SocketPairKind IPv4TCPAcceptBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "IPv4 TCP socket"); + absl::StrCat(DescribeSocketType(type), "connected IPv4 TCP socket"); return SocketPairKind{ description, TCPAcceptBindSocketPairCreator(AF_INET, type | SOCK_STREAM, 0, /* dual_stack = */ false)}; @@ -44,7 +57,7 @@ SocketPairKind IPv4TCPAcceptBindSocketPair(int type) { SocketPairKind DualStackTCPAcceptBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "dual stack TCP socket"); + absl::StrCat(DescribeSocketType(type), "connected dual stack TCP socket"); return SocketPairKind{ description, TCPAcceptBindSocketPairCreator(AF_INET6, type | SOCK_STREAM, 0, /* dual_stack = */ true)}; @@ -52,7 +65,7 @@ SocketPairKind DualStackTCPAcceptBindSocketPair(int type) { SocketPairKind IPv6UDPBidirectionalBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "IPv6 UDP socket"); + absl::StrCat(DescribeSocketType(type), "connected IPv6 UDP socket"); return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator( AF_INET6, type | SOCK_DGRAM, 0, /* dual_stack = */ false)}; @@ -60,7 +73,7 @@ SocketPairKind IPv6UDPBidirectionalBindSocketPair(int type) { SocketPairKind IPv4UDPBidirectionalBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "IPv4 UDP socket"); + absl::StrCat(DescribeSocketType(type), "connected IPv4 UDP socket"); return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator( AF_INET, type | SOCK_DGRAM, 0, /* dual_stack = */ false)}; @@ -68,11 +81,19 @@ SocketPairKind IPv4UDPBidirectionalBindSocketPair(int type) { SocketPairKind DualStackUDPBidirectionalBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "dual stack UDP socket"); + absl::StrCat(DescribeSocketType(type), "connected dual stack UDP socket"); return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator( AF_INET6, type | SOCK_DGRAM, 0, /* dual_stack = */ true)}; } +SocketPairKind IPv4UDPUnboundSocketPair(int type) { + std::string description = + absl::StrCat(DescribeSocketType(type), "IPv4 UDP socket"); + return SocketPairKind{ + description, UDPUnboundSocketPairCreator(AF_INET, type | SOCK_DGRAM, 0, + /* dual_stack = */ false)}; +} + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/ip_socket_test_util.h b/test/syscalls/linux/ip_socket_test_util.h index 1e1400ecd..a6721091a 100644 --- a/test/syscalls/linux/ip_socket_test_util.h +++ b/test/syscalls/linux/ip_socket_test_util.h @@ -21,6 +21,9 @@ namespace gvisor { namespace testing { +// InterfaceIndex returns the index of the named interface. +PosixErrorOr InterfaceIndex(std::string name); + // IPv6TCPAcceptBindSocketPair returns a SocketPairKind that represents // SocketPairs created with bind() and accept() syscalls with AF_INET6 and the // given type bound to the IPv6 loopback. @@ -51,6 +54,10 @@ SocketPairKind IPv4UDPBidirectionalBindSocketPair(int type); // AF_INET6 and the given type bound to the IPv4 loopback. SocketPairKind DualStackUDPBidirectionalBindSocketPair(int type); +// IPv4UDPUnboundSocketPair returns a SocketPairKind that represents +// SocketPairs created with AF_INET and the given type. +SocketPairKind IPv4UDPUnboundSocketPair(int type); + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/socket_ip_udp_generic.cc b/test/syscalls/linux/socket_ip_udp_generic.cc index 789154fb3..58d1c846d 100644 --- a/test/syscalls/linux/socket_ip_udp_generic.cc +++ b/test/syscalls/linux/socket_ip_udp_generic.cc @@ -117,5 +117,19 @@ TEST_P(UDPSocketPairTest, SetUDPMulticastTTLAboveMax) { SyscallFailsWithErrno(EINVAL)); } +TEST_P(UDPSocketPairTest, SetEmptyIPAddMembership) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + struct ip_mreqn req = {}; + int ret = setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, + sizeof(req)); + // FIXME: gVisor returns the incorrect errno. + if (IsRunningOnGvisor()) { + EXPECT_THAT(ret, SyscallFails()); + } else { + EXPECT_THAT(ret, SyscallFailsWithErrno(EINVAL)); + } +} + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc new file mode 100644 index 000000000..1b47139e4 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc @@ -0,0 +1,424 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include "test/syscalls/linux/socket_ipv4_udp_unbound.h" + +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "gtest/gtest.h" +#include "test/syscalls/linux/ip_socket_test_util.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +// Check that packets are not received without a group memebership. Default send +// interface configured by bind. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNoGroup) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address. If multicast worked like unicast, + // this would ensure that we get the packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Send the multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that not setting a default send interface prevents multicast packets +// from being sent. Group membership interface configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddrNoDefaultSendIf) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the second FD to the v4 any address to ensure that we can receive any + // unicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallFailsWithErrno(ENETUNREACH)); +} + +// Check that not setting a default send interface prevents multicast packets +// from being sent. Group membership interface configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNicNoDefaultSendIf) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the second FD to the v4 any address to ensure that we can receive any + // unicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallFailsWithErrno(ENETUNREACH)); +} + +// Check that multicast works when the default send interface is configured by +// bind and the group membership is configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddr) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast works when the default send interface is confgured by +// bind and the group membership is configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that dropping a group membership that does not exist fails. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastInvalidDrop) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Unregister from a membership that we didn't have. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallFailsWithErrno(EADDRNOTAVAIL)); +} + +// Check that dropping a group membership prevents multicast packets from being +// delivered. Default send address configured by bind and group membership +// interface configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastDropAddr) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register and unregister to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that dropping a group membership prevents multicast packets from being +// delivered. Default send address configured by bind and group membership +// interface configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastDropNic) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register and unregister to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.h b/test/syscalls/linux/socket_ipv4_udp_unbound.h new file mode 100644 index 000000000..a780c0144 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.h @@ -0,0 +1,29 @@ +// Copyright 2019 Google LLC +// +// 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. + +#ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_H_ +#define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_H_ + +#include "test/syscalls/linux/socket_test_util.h" + +namespace gvisor { +namespace testing { + +// Test fixture for tests that apply to pairs of IPv4 UDP sockets. +using IPv4UDPUnboundSocketPairTest = SocketPairTest; + +} // namespace testing +} // namespace gvisor + +#endif // GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_H_ diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc new file mode 100644 index 000000000..b70faa33d --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc @@ -0,0 +1,35 @@ +// Copyright 2018 Google LLC +// +// 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. + +#include + +#include "test/syscalls/linux/ip_socket_test_util.h" +#include "test/syscalls/linux/socket_ipv4_udp_unbound.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +std::vector GetSocketPairs() { + return ApplyVec( + IPv4UDPUnboundSocketPair, + AllBitwiseCombinations(List{0, SOCK_NONBLOCK})); +} + +INSTANTIATE_TEST_CASE_P(IPv4UDPSockets, IPv4UDPUnboundSocketPairTest, + ::testing::ValuesIn(GetSocketPairs())); + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc index 80a59df7e..49b8c583f 100644 --- a/test/syscalls/linux/socket_test_util.cc +++ b/test/syscalls/linux/socket_test_util.cc @@ -388,24 +388,33 @@ Creator TCPAcceptBindSocketPairCreator(int domain, int type, }; } +template +PosixErrorOr> CreateUDPBoundSocketPair( + int sock1, int sock2, int type, bool dual_stack) { + ASSIGN_OR_RETURN_ERRNO(T addr1, BindIP(sock1, dual_stack)); + ASSIGN_OR_RETURN_ERRNO(T addr2, BindIP(sock2, dual_stack)); + + return absl::make_unique(sock1, sock2, addr1, addr2); +} + template PosixErrorOr> CreateUDPBidirectionalBindSocketPair(int sock1, int sock2, int type, bool dual_stack) { - ASSIGN_OR_RETURN_ERRNO(T addr1, BindIP(sock1, dual_stack)); - ASSIGN_OR_RETURN_ERRNO(T addr2, BindIP(sock2, dual_stack)); + ASSIGN_OR_RETURN_ERRNO( + auto socks, CreateUDPBoundSocketPair(sock1, sock2, type, dual_stack)); // Connect sock1 to sock2. - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock1, reinterpret_cast(&addr2), sizeof(addr2))); + RETURN_ERROR_IF_SYSCALL_FAIL(connect(socks->first_fd(), socks->second_addr(), + socks->second_addr_size())); MaybeSave(); // Successful connection. // Connect sock2 to sock1. - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock2, reinterpret_cast(&addr1), sizeof(addr1))); + RETURN_ERROR_IF_SYSCALL_FAIL(connect(socks->second_fd(), socks->first_addr(), + socks->first_addr_size())); MaybeSave(); // Successful connection. - return absl::make_unique(sock1, sock2, addr1, addr2); + return socks; } Creator UDPBidirectionalBindSocketPairCreator(int domain, int type, @@ -429,6 +438,21 @@ Creator UDPBidirectionalBindSocketPairCreator(int domain, int type, }; } +Creator UDPUnboundSocketPairCreator(int domain, int type, + int protocol, bool dual_stack) { + return [=]() -> PosixErrorOr> { + int sock1; + RETURN_ERROR_IF_SYSCALL_FAIL(sock1 = socket(domain, type, protocol)); + MaybeSave(); // Successful socket creation. + + int sock2; + RETURN_ERROR_IF_SYSCALL_FAIL(sock2 = socket(domain, type, protocol)); + MaybeSave(); // Successful socket creation. + + return absl::make_unique(sock1, sock2); + }; +} + SocketPairKind Reversed(SocketPairKind const& base) { auto const& creator = base.creator; return SocketPairKind{ diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h index 6d84b3fa8..826374dc6 100644 --- a/test/syscalls/linux/socket_test_util.h +++ b/test/syscalls/linux/socket_test_util.h @@ -273,6 +273,11 @@ Creator UDPBidirectionalBindSocketPairCreator(int domain, int type, int protocol, bool dual_stack); +// UDPUnboundSocketPairCreator returns a Creator that obtains file +// descriptors by creating UDP sockets. +Creator UDPUnboundSocketPairCreator(int domain, int type, + int protocol, bool dual_stack); + // A SocketPairKind couples a human-readable description of a socket pair with // a function that creates such a socket pair. struct SocketPairKind { -- cgit v1.2.3 From c611dbc5a7399922588e3fd99b22bda19f684afe Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Fri, 15 Feb 2019 18:39:10 -0800 Subject: Implement IP_MULTICAST_IF. This allows setting a default send interface for IPv4 multicast. IPv6 support will come later. PiperOrigin-RevId: 234251379 Change-Id: I65922341cd8b8880f690fae3eeb7ddfa47c8c173 --- pkg/sentry/socket/epsocket/epsocket.go | 66 +++++-- pkg/tcpip/stack/stack.go | 11 ++ pkg/tcpip/tcpip.go | 7 + pkg/tcpip/transport/udp/endpoint.go | 115 ++++++++--- test/syscalls/linux/socket_ipv4_udp_unbound.cc | 261 +++++++++++++++++++++++++ 5 files changed, 418 insertions(+), 42 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 3a9d1182f..3392ac645 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -27,7 +27,6 @@ package epsocket import ( "bytes" "math" - "strings" "sync" "syscall" "time" @@ -191,6 +190,15 @@ func New(t *kernel.Task, family int, skType transport.SockType, queue *waiter.Qu var sockAddrInetSize = int(binary.Size(linux.SockAddrInet{})) var sockAddrInet6Size = int(binary.Size(linux.SockAddrInet6{})) +// bytesToIPAddress converts an IPv4 or IPv6 address from the user to the +// netstack representation taking any addresses into account. +func bytesToIPAddress(addr []byte) tcpip.Address { + if bytes.Equal(addr, make([]byte, 4)) || bytes.Equal(addr, make([]byte, 16)) { + return "" + } + return tcpip.Address(addr) +} + // GetAddress reads an sockaddr struct from the given address and converts it // to the FullAddress format. It supports AF_UNIX, AF_INET and AF_INET6 // addresses. @@ -231,12 +239,9 @@ func GetAddress(sfamily int, addr []byte) (tcpip.FullAddress, *syserr.Error) { binary.Unmarshal(addr[:sockAddrInetSize], usermem.ByteOrder, &a) out := tcpip.FullAddress{ - Addr: tcpip.Address(a.Addr[:]), + Addr: bytesToIPAddress(a.Addr[:]), Port: ntohs(a.Port), } - if out.Addr == "\x00\x00\x00\x00" { - out.Addr = "" - } return out, nil case linux.AF_INET6: @@ -247,15 +252,12 @@ func GetAddress(sfamily int, addr []byte) (tcpip.FullAddress, *syserr.Error) { binary.Unmarshal(addr[:sockAddrInet6Size], usermem.ByteOrder, &a) out := tcpip.FullAddress{ - Addr: tcpip.Address(a.Addr[:]), + Addr: bytesToIPAddress(a.Addr[:]), Port: ntohs(a.Port), } if isLinkLocal(out.Addr) { out.NIC = tcpip.NICID(a.Scope_id) } - if out.Addr == tcpip.Address(strings.Repeat("\x00", 16)) { - out.Addr = "" - } return out, nil default: @@ -864,6 +866,30 @@ func getSockOptIP(t *kernel.Task, ep commonEndpoint, name, outLen int) (interfac return int32(v), nil + case linux.IP_MULTICAST_IF: + if outLen < inetMulticastRequestSize { + return nil, syserr.ErrInvalidArgument + } + + var v tcpip.MulticastInterfaceOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + a, _ := ConvertAddress(linux.AF_INET, tcpip.FullAddress{Addr: v.InterfaceAddr}) + + rv := linux.InetMulticastRequestWithNIC{ + linux.InetMulticastRequest{ + InterfaceAddr: a.(linux.SockAddrInet).Addr, + }, + int32(v.NIC), + } + + if outLen >= inetMulticastRequestWithNICSize { + return rv, nil + } + return rv.InetMulticastRequest, nil + default: emitUnimplementedEventIP(t, name) } @@ -1148,7 +1174,9 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s } return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.AddMembershipOption{ - NIC: tcpip.NICID(req.InterfaceIndex), + NIC: tcpip.NICID(req.InterfaceIndex), + // TODO: Change AddMembership to use the standard + // any address representation. InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]), MulticastAddr: tcpip.Address(req.MulticastAddr[:]), })) @@ -1160,19 +1188,29 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s } return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.RemoveMembershipOption{ - NIC: tcpip.NICID(req.InterfaceIndex), + NIC: tcpip.NICID(req.InterfaceIndex), + // TODO: Change DropMembership to use the standard + // any address representation. InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]), MulticastAddr: tcpip.Address(req.MulticastAddr[:]), })) case linux.IP_MULTICAST_IF: + req, err := copyInMulticastRequest(optVal) + if err != nil { + return err + } + + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.MulticastInterfaceOption{ + NIC: tcpip.NICID(req.InterfaceIndex), + InterfaceAddr: bytesToIPAddress(req.InterfaceAddr[:]), + })) + + case linux.MCAST_JOIN_GROUP: // FIXME: Disallow IP-level multicast group options by // default. These will need to be supported by appropriately plumbing // the level through to the network stack (if at all). However, we // still allow setting TTL, and multicast-enable/disable type options. - fallthrough - case linux.MCAST_JOIN_GROUP: - // FIXME: Implement MCAST_JOIN_GROUP. t.Kernel().EmitUnimplementedEvent(t) return syserr.ErrInvalidArgument diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 854ebe1bb..252c79317 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -565,6 +565,17 @@ func (s *Stack) EnableNIC(id tcpip.NICID) *tcpip.Error { return nil } +// CheckNIC checks if a NIC is usable. +func (s *Stack) CheckNIC(id tcpip.NICID) bool { + s.mu.RLock() + nic, ok := s.nics[id] + s.mu.RUnlock() + if ok { + return nic.linkEP.IsAttached() + } + return false +} + // NICSubnets returns a map of NICIDs to their associated subnets. func (s *Stack) NICSubnets() map[tcpip.NICID][]tcpip.Subnet { s.mu.RLock() diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 3cd431d4c..a6e47397a 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -473,6 +473,13 @@ type KeepaliveCountOption int // TTL value for multicast messages. The default is 1. type MulticastTTLOption uint8 +// MulticastInterfaceOption is used by SetSockOpt/GetSockOpt to specify a +// default interface for multicast. +type MulticastInterfaceOption struct { + NIC NICID + InterfaceAddr Address +} + // MembershipOption is used by SetSockOpt/GetSockOpt as an argument to // AddMembershipOption and RemoveMembershipOption. type MembershipOption struct { diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index fa8f02e46..9c3881d63 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -69,17 +69,19 @@ type endpoint struct { rcvClosed bool // The following fields are protected by the mu mutex. - mu sync.RWMutex `state:"nosave"` - sndBufSize int - id stack.TransportEndpointID - state endpointState - bindNICID tcpip.NICID - regNICID tcpip.NICID - route stack.Route `state:"manual"` - dstPort uint16 - v6only bool - multicastTTL uint8 - reusePort bool + mu sync.RWMutex `state:"nosave"` + sndBufSize int + id stack.TransportEndpointID + state endpointState + bindNICID tcpip.NICID + regNICID tcpip.NICID + route stack.Route `state:"manual"` + dstPort uint16 + v6only bool + multicastTTL uint8 + multicastAddr tcpip.Address + multicastNICID tcpip.NICID + reusePort bool // shutdownFlags represent the current shutdown state of the endpoint. shutdownFlags tcpip.ShutdownFlags @@ -251,6 +253,33 @@ func (e *endpoint) prepareForWrite(to *tcpip.FullAddress) (retry bool, err *tcpi return true, nil } +// connectRoute establishes a route to the specified interface or the +// configured multicast interface if no interface is specified and the +// specified address is a multicast address. +func (e *endpoint) connectRoute(nicid tcpip.NICID, addr tcpip.FullAddress) (stack.Route, tcpip.NICID, tcpip.NetworkProtocolNumber, *tcpip.Error) { + netProto, err := e.checkV4Mapped(&addr, false) + if err != nil { + return stack.Route{}, 0, 0, err + } + + localAddr := e.id.LocalAddress + if header.IsV4MulticastAddress(addr.Addr) || header.IsV6MulticastAddress(addr.Addr) { + if nicid == 0 { + nicid = e.multicastNICID + } + if localAddr == "" { + localAddr = e.multicastAddr + } + } + + // Find a route to the desired destination. + r, err := e.stack.FindRoute(nicid, localAddr, addr.Addr, netProto) + if err != nil { + return stack.Route{}, 0, 0, err + } + return r, nicid, netProto, nil +} + // Write writes data to the endpoint's peer. This method does not block // if the data cannot be written. func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-chan struct{}, *tcpip.Error) { @@ -318,15 +347,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c nicid = e.bindNICID } - toCopy := *to - to = &toCopy - netProto, err := e.checkV4Mapped(to, false) - if err != nil { - return 0, nil, err - } - - // Find the enpoint. - r, err := e.stack.FindRoute(nicid, e.id.LocalAddress, to.Addr, netProto) + r, _, _, err := e.connectRoute(nicid, *to) if err != nil { return 0, nil, err } @@ -394,6 +415,42 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { e.multicastTTL = uint8(v) e.mu.Unlock() + case tcpip.MulticastInterfaceOption: + e.mu.Lock() + defer e.mu.Unlock() + + fa := tcpip.FullAddress{Addr: v.InterfaceAddr} + netProto, err := e.checkV4Mapped(&fa, false) + if err != nil { + return err + } + nic := v.NIC + addr := fa.Addr + + if nic == 0 && addr == "" { + e.multicastAddr = "" + e.multicastNICID = 0 + break + } + + if nic != 0 { + if !e.stack.CheckNIC(nic) { + return tcpip.ErrBadLocalAddress + } + } else { + nic = e.stack.CheckLocalAddress(0, netProto, addr) + if nic == 0 { + return tcpip.ErrBadLocalAddress + } + } + + if e.bindNICID != 0 && e.bindNICID != nic { + return tcpip.ErrInvalidEndpointState + } + + e.multicastNICID = nic + e.multicastAddr = addr + case tcpip.AddMembershipOption: nicID := v.NIC if v.InterfaceAddr != header.IPv4Any { @@ -445,7 +502,6 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { e.mu.Lock() e.reusePort = v != 0 e.mu.Unlock() - return nil } return nil } @@ -501,6 +557,15 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { e.mu.Unlock() return nil + case *tcpip.MulticastInterfaceOption: + e.mu.Lock() + *o = tcpip.MulticastInterfaceOption{ + e.multicastNICID, + e.multicastAddr, + } + e.mu.Unlock() + return nil + case *tcpip.ReusePortOption: e.mu.RLock() v := e.reusePort @@ -610,13 +675,7 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { return tcpip.ErrInvalidEndpointState } - netProto, err := e.checkV4Mapped(&addr, false) - if err != nil { - return err - } - - // Find a route to the desired destination. - r, err := e.stack.FindRoute(nicid, e.id.LocalAddress, addr.Addr, netProto) + r, nicid, netProto, err := e.connectRoute(nicid, addr) if err != nil { return err } diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc index 4058324a2..2d702179e 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc @@ -278,6 +278,238 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); } +// Check that multicast works when the default send interface is confgured by +// IP_MULTICAST_IF, the send address is specified in sendto, and the group +// membership is configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddr) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreq iface = {}; + iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + EXPECT_THAT(bind(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + EXPECT_THAT(getsockname(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast works when the default send interface is confgured by +// IP_MULTICAST_IF, the send address is specified in sendto, and the group +// membership is configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNic) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreqn iface = {}; + iface.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + EXPECT_THAT(bind(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + EXPECT_THAT(getsockname(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast works when the default send interface is confgured by +// IP_MULTICAST_IF, the send address is specified in connect, and the group +// membership is configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrConnect) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreq iface = {}; + iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + EXPECT_THAT(bind(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + EXPECT_THAT(getsockname(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto connect_addr = V4Multicast(); + reinterpret_cast(&connect_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + EXPECT_THAT( + RetryEINTR(connect)(sockets->first_fd(), + reinterpret_cast(&connect_addr.addr), + connect_addr.addr_len), + SyscallSucceeds()); + + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT( + RetryEINTR(send)(sockets->first_fd(), send_buf, sizeof(send_buf), 0), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast works when the default send interface is confgured by +// IP_MULTICAST_IF, the send address is specified in connect, and the group +// membership is configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicConnect) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreqn iface = {}; + iface.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + EXPECT_THAT(bind(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + EXPECT_THAT(getsockname(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto connect_addr = V4Multicast(); + reinterpret_cast(&connect_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + EXPECT_THAT( + RetryEINTR(connect)(sockets->first_fd(), + reinterpret_cast(&connect_addr.addr), + connect_addr.addr_len), + SyscallSucceeds()); + + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT( + RetryEINTR(send)(sockets->first_fd(), send_buf, sizeof(send_buf), 0), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + // Check that dropping a group membership that does not exist fails. TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastInvalidDrop) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -407,5 +639,34 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastDropNic) { SyscallFailsWithErrno(EAGAIN)); } +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastIfZero) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + ip_mreqn iface = {}; + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); +} + +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastIfInvalidNic) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + ip_mreqn iface = {}; + iface.imr_ifindex = -1; + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallFailsWithErrno(EADDRNOTAVAIL)); +} + +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastIfInvalidAddr) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + ip_mreq iface = {}; + iface.imr_interface.s_addr = inet_addr("255.255.255"); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallFailsWithErrno(EADDRNOTAVAIL)); +} + } // namespace testing } // namespace gvisor -- cgit v1.2.3 From ea070b9d5f4be0b25b028e90ab4518ef2e4df16b Mon Sep 17 00:00:00 2001 From: Amanda Tait Date: Wed, 20 Feb 2019 12:53:07 -0800 Subject: Implement Broadcast support This change adds support for the SO_BROADCAST socket option in gVisor Netstack. This support includes getsockopt()/setsockopt() functionality for both UDP and TCP endpoints (the latter being a NOOP), dispatching broadcast messages up and down the stack, and route finding/creation for broadcast packets. Finally, a suite of tests have been implemented, exercising this functionality through the Linux syscall API. PiperOrigin-RevId: 234850781 Change-Id: If3e666666917d39f55083741c78314a06defb26c --- pkg/dhcp/client.go | 3 + pkg/dhcp/dhcp_test.go | 3 + pkg/dhcp/server.go | 3 + pkg/sentry/socket/epsocket/epsocket.go | 21 ++ pkg/syserr/netstack.go | 2 + pkg/tcpip/stack/nic.go | 15 ++ pkg/tcpip/stack/transport_demuxer.go | 70 ++++++- pkg/tcpip/tcpip.go | 11 + pkg/tcpip/transport/tcp/endpoint.go | 20 ++ pkg/tcpip/transport/tcp/endpoint_state.go | 1 + pkg/tcpip/transport/udp/endpoint.go | 23 ++ test/syscalls/linux/BUILD | 69 ++++++ test/syscalls/linux/ip_socket_test_util.cc | 16 ++ test/syscalls/linux/ip_socket_test_util.h | 8 + .../socket_ipv4_tcp_unbound_external_networking.cc | 66 ++++++ .../socket_ipv4_tcp_unbound_external_networking.h | 30 +++ ...et_ipv4_tcp_unbound_external_networking_test.cc | 35 ++++ .../socket_ipv4_udp_unbound_external_networking.cc | 231 +++++++++++++++++++++ .../socket_ipv4_udp_unbound_external_networking.h | 30 +++ ...et_ipv4_udp_unbound_external_networking_test.cc | 35 ++++ test/syscalls/linux/socket_test_util.cc | 12 ++ test/syscalls/linux/socket_test_util.h | 5 + 22 files changed, 698 insertions(+), 11 deletions(-) create mode 100644 test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc create mode 100644 test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h create mode 100644 test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 3330c4998..6d48eec7e 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -141,6 +141,9 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg }, nil); err != nil { return Config{}, fmt.Errorf("dhcp: connect failed: %v", err) } + if err := ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil { + return Config{}, fmt.Errorf("dhcp: setsockopt SO_BROADCAST: %v", err) + } epin, err := c.stack.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq) if err != nil { diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index a21dce6bc..026064394 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -287,6 +287,9 @@ func TestTwoServers(t *testing.T) { if err = ep.Bind(tcpip.FullAddress{Port: ServerPort}, nil); err != nil { t.Fatalf("dhcp: server bind: %v", err) } + if err = ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil { + t.Fatalf("dhcp: setsockopt: %v", err) + } serverCtx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index 3e06ab4c7..c72c3b70d 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -123,6 +123,9 @@ func newEPConnServer(ctx context.Context, stack *stack.Stack, addrs []tcpip.Addr if err := ep.Bind(tcpip.FullAddress{Port: ServerPort}, nil); err != nil { return nil, fmt.Errorf("dhcp: server bind: %v", err) } + if err := ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil { + return nil, fmt.Errorf("dhcp: server setsockopt: %v", err) + } c := newEPConn(ctx, wq, ep) return NewServer(ctx, c, addrs, cfg) } diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index a97db5348..e24e58aed 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -582,6 +582,7 @@ func GetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, // getSockOptSocket implements GetSockOpt when level is SOL_SOCKET. func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, skType transport.SockType, name, outLen int) (interface{}, *syserr.Error) { + // TODO: Stop rejecting short optLen values in getsockopt. switch name { case linux.SO_TYPE: if outLen < sizeOfInt32 { @@ -681,6 +682,18 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family return int32(v), nil + case linux.SO_BROADCAST: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + + var v tcpip.BroadcastOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + return int32(v), nil + case linux.SO_KEEPALIVE: if outLen < sizeOfInt32 { return nil, syserr.ErrInvalidArgument @@ -982,6 +995,14 @@ func setSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name i v := usermem.ByteOrder.Uint32(optVal) return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.ReusePortOption(v))) + case linux.SO_BROADCAST: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.BroadcastOption(v))) + case linux.SO_PASSCRED: if len(optVal) < sizeOfInt32 { return syserr.ErrInvalidArgument diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go index 20e756edb..05ca475d1 100644 --- a/pkg/syserr/netstack.go +++ b/pkg/syserr/netstack.go @@ -43,6 +43,7 @@ var ( ErrQueueSizeNotSupported = New(tcpip.ErrQueueSizeNotSupported.String(), linux.ENOTTY) ErrNoSuchFile = New(tcpip.ErrNoSuchFile.String(), linux.ENOENT) ErrInvalidOptionValue = New(tcpip.ErrInvalidOptionValue.String(), linux.EINVAL) + ErrBroadcastDisabled = New(tcpip.ErrBroadcastDisabled.String(), linux.EACCES) ) var netstackErrorTranslations = map[*tcpip.Error]*Error{ @@ -80,6 +81,7 @@ var netstackErrorTranslations = map[*tcpip.Error]*Error{ tcpip.ErrNetworkUnreachable: ErrNetworkUnreachable, tcpip.ErrMessageTooLong: ErrMessageTooLong, tcpip.ErrNoBufferSpace: ErrNoBufferSpace, + tcpip.ErrBroadcastDisabled: ErrBroadcastDisabled, } // TranslateNetstackError converts an error from the tcpip package to a sentry diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 586ca873e..43d7c2ec4 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -399,6 +399,21 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr src, dst := netProto.ParseAddresses(vv.First()) + // If the packet is destined to the IPv4 Broadcast address, then make a + // route to each IPv4 network endpoint and let each endpoint handle the + // packet. + if dst == header.IPv4Broadcast { + for _, ref := range n.endpoints { + if ref.protocol == header.IPv4ProtocolNumber && ref.tryIncRef() { + r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) + r.RemoteLinkAddress = remote + ref.ep.HandlePacket(&r, vv) + ref.decRef() + } + } + return + } + if ref := n.getRef(protocol, dst); ref != nil { r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) r.RemoteLinkAddress = remote diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index a5ff2159a..c18208dc0 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -132,7 +132,22 @@ func (ep *multiPortEndpoint) selectEndpoint(id TransportEndpointID) TransportEnd // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. func (ep *multiPortEndpoint) HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) { - ep.selectEndpoint(id).HandlePacket(r, id, vv) + // If this is a broadcast datagram, deliver the datagram to all endpoints + // managed by ep. + if id.LocalAddress == header.IPv4Broadcast { + for i, endpoint := range ep.endpointsArr { + // HandlePacket modifies vv, so each endpoint needs its own copy. + if i == len(ep.endpointsArr)-1 { + endpoint.HandlePacket(r, id, vv) + break + } + vvCopy := buffer.NewView(vv.Size()) + copy(vvCopy, vv.ToView()) + endpoint.HandlePacket(r, id, vvCopy.ToVectorisedView()) + } + } else { + ep.selectEndpoint(id).HandlePacket(r, id, vv) + } } // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. @@ -224,20 +239,47 @@ func (d *transportDemuxer) unregisterEndpoint(netProtos []tcpip.NetworkProtocolN } } -// deliverPacket attempts to deliver the given packet. Returns true if it found -// an endpoint, false otherwise. +var loopbackSubnet = func() tcpip.Subnet { + sn, err := tcpip.NewSubnet("\x7f\x00\x00\x00", "\xff\x00\x00\x00") + if err != nil { + panic(err) + } + return sn +}() + +// deliverPacket attempts to find one or more matching transport endpoints, and +// then, if matches are found, delivers the packet to them. Returns true if it +// found one or more endpoints, false otherwise. func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView, id TransportEndpointID) bool { eps, ok := d.protocol[protocolIDs{r.NetProto, protocol}] if !ok { return false } + // If a sender bound to the Loopback interface sends a broadcast, + // that broadcast must not be delivered to the sender. + if loopbackSubnet.Contains(r.RemoteAddress) && r.LocalAddress == header.IPv4Broadcast && id.LocalPort == id.RemotePort { + return false + } + + // If the packet is a broadcast, then find all matching transport endpoints. + // Otherwise, try to find a single matching transport endpoint. + destEps := make([]TransportEndpoint, 0, 1) eps.mu.RLock() - ep := d.findEndpointLocked(eps, vv, id) + + if protocol == header.UDPProtocolNumber && id.LocalAddress == header.IPv4Broadcast { + for epID, endpoint := range eps.endpoints { + if epID.LocalPort == id.LocalPort { + destEps = append(destEps, endpoint) + } + } + } else if ep := d.findEndpointLocked(eps, vv, id); ep != nil { + destEps = append(destEps, ep) + } eps.mu.RUnlock() - // Fail if we didn't find one. - if ep == nil { + // Fail if we didn't find at least one matching transport endpoint. + if len(destEps) == 0 { // UDP packet could not be delivered to an unknown destination port. if protocol == header.UDPProtocolNumber { r.Stats().UDP.UnknownPortErrors.Increment() @@ -246,7 +288,9 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto } // Deliver the packet. - ep.HandlePacket(r, id, vv) + for _, ep := range destEps { + ep.HandlePacket(r, id, vv) + } return true } @@ -277,7 +321,7 @@ func (d *transportDemuxer) deliverControlPacket(net tcpip.NetworkProtocolNumber, func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv buffer.VectorisedView, id TransportEndpointID) TransportEndpoint { // Try to find a match with the id as provided. - if ep := eps.endpoints[id]; ep != nil { + if ep, ok := eps.endpoints[id]; ok { return ep } @@ -285,7 +329,7 @@ func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv buffer nid := id nid.LocalAddress = "" - if ep := eps.endpoints[nid]; ep != nil { + if ep, ok := eps.endpoints[nid]; ok { return ep } @@ -293,11 +337,15 @@ func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv buffer nid.LocalAddress = id.LocalAddress nid.RemoteAddress = "" nid.RemotePort = 0 - if ep := eps.endpoints[nid]; ep != nil { + if ep, ok := eps.endpoints[nid]; ok { return ep } // Try to find a match with only the local port. nid.LocalAddress = "" - return eps.endpoints[nid] + if ep, ok := eps.endpoints[nid]; ok { + return ep + } + + return nil } diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index a6e47397a..89e9d6741 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -100,6 +100,7 @@ var ( ErrNetworkUnreachable = &Error{msg: "network is unreachable"} ErrMessageTooLong = &Error{msg: "message too long"} ErrNoBufferSpace = &Error{msg: "no buffer space available"} + ErrBroadcastDisabled = &Error{msg: "broadcast socket option disabled"} ) // Errors related to Subnet @@ -502,6 +503,10 @@ type RemoveMembershipOption MembershipOption // TCP out-of-band data is delivered along with the normal in-band data. type OutOfBandInlineOption int +// BroadcastOption is used by SetSockOpt/GetSockOpt to specify whether +// datagram sockets are allowed to send packets to a broadcast address. +type BroadcastOption int + // Route is a row in the routing table. It specifies through which NIC (and // gateway) sets of packets should be routed. A row is considered viable if the // masked target address matches the destination adddress in the row. @@ -527,6 +532,12 @@ func (r *Route) Match(addr Address) bool { return false } + // Using header.Ipv4Broadcast would introduce an import cycle, so + // we'll use a literal instead. + if addr == "\xff\xff\xff\xff" { + return true + } + for i := 0; i < len(r.Destination); i++ { if (addr[i] & r.Mask[i]) != r.Destination[i] { return false diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 1ee9f8d25..aa31a78af 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -116,6 +116,9 @@ type endpoint struct { route stack.Route `state:"manual"` v6only bool isConnectNotified bool + // TCP should never broadcast but Linux nevertheless supports enabling/ + // disabling SO_BROADCAST, albeit as a NOOP. + broadcast bool // effectiveNetProtos contains the network protocols actually in use. In // most cases it will only contain "netProto", but in cases like IPv6 @@ -813,6 +816,12 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { e.notifyProtocolGoroutine(notifyKeepaliveChanged) return nil + case tcpip.BroadcastOption: + e.mu.Lock() + e.broadcast = v != 0 + e.mu.Unlock() + return nil + default: return nil } @@ -971,6 +980,17 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { *o = 1 return nil + case *tcpip.BroadcastOption: + e.mu.Lock() + v := e.broadcast + e.mu.Unlock() + + *o = 0 + if v { + *o = 1 + } + return nil + default: return tcpip.ErrUnknownProtocolOption } diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index 4891c7941..a07cd9011 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -336,6 +336,7 @@ func loadError(s string) *tcpip.Error { tcpip.ErrNetworkUnreachable, tcpip.ErrMessageTooLong, tcpip.ErrNoBufferSpace, + tcpip.ErrBroadcastDisabled, } messageToError = make(map[string]*tcpip.Error) diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 9c3881d63..05d35e526 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -82,6 +82,7 @@ type endpoint struct { multicastAddr tcpip.Address multicastNICID tcpip.NICID reusePort bool + broadcast bool // shutdownFlags represent the current shutdown state of the endpoint. shutdownFlags tcpip.ShutdownFlags @@ -347,6 +348,10 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c nicid = e.bindNICID } + if to.Addr == header.IPv4Broadcast && !e.broadcast { + return 0, nil, tcpip.ErrBroadcastDisabled + } + r, _, _, err := e.connectRoute(nicid, *to) if err != nil { return 0, nil, err @@ -502,6 +507,13 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { e.mu.Lock() e.reusePort = v != 0 e.mu.Unlock() + + case tcpip.BroadcastOption: + e.mu.Lock() + e.broadcast = v != 0 + e.mu.Unlock() + + return nil } return nil } @@ -581,6 +593,17 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { *o = 0 return nil + case *tcpip.BroadcastOption: + e.mu.RLock() + v := e.broadcast + e.mu.RUnlock() + + *o = 0 + if v { + *o = 1 + } + return nil + default: return tcpip.ErrUnknownProtocolOption } diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 9da5204c1..beece8930 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -148,6 +148,7 @@ cc_library( hdrs = ["ip_socket_test_util.h"], deps = [ ":socket_test_util", + "@com_google_absl//absl/strings", ], ) @@ -1970,6 +1971,42 @@ cc_library( alwayslink = 1, ) +cc_library( + name = "socket_ipv4_udp_unbound_external_networking_test_cases", + testonly = 1, + srcs = [ + "socket_ipv4_udp_unbound_external_networking.cc", + ], + hdrs = [ + "socket_ipv4_udp_unbound_external_networking.h", + ], + deps = [ + ":ip_socket_test_util", + ":socket_test_util", + "//test/util:test_util", + "@com_google_googletest//:gtest", + ], + alwayslink = 1, +) + +cc_library( + name = "socket_ipv4_tcp_unbound_external_networking_test_cases", + testonly = 1, + srcs = [ + "socket_ipv4_tcp_unbound_external_networking.cc", + ], + hdrs = [ + "socket_ipv4_tcp_unbound_external_networking.h", + ], + deps = [ + ":ip_socket_test_util", + ":socket_test_util", + "//test/util:test_util", + "@com_google_googletest//:gtest", + ], + alwayslink = 1, +) + cc_binary( name = "socket_abstract_test", testonly = 1, @@ -2147,6 +2184,38 @@ cc_binary( ], ) +cc_binary( + name = "socket_ipv4_udp_unbound_external_networking_test", + testonly = 1, + srcs = [ + "socket_ipv4_udp_unbound_external_networking_test.cc", + ], + linkstatic = 1, + deps = [ + ":ip_socket_test_util", + ":socket_ipv4_udp_unbound_external_networking_test_cases", + ":socket_test_util", + "//test/util:test_main", + "//test/util:test_util", + ], +) + +cc_binary( + name = "socket_ipv4_tcp_unbound_external_networking_test", + testonly = 1, + srcs = [ + "socket_ipv4_tcp_unbound_external_networking_test.cc", + ], + linkstatic = 1, + deps = [ + ":ip_socket_test_util", + ":socket_ipv4_tcp_unbound_external_networking_test_cases", + ":socket_test_util", + "//test/util:test_main", + "//test/util:test_util", + ], +) + cc_binary( name = "socket_ip_udp_loopback_non_blocking_test", testonly = 1, diff --git a/test/syscalls/linux/ip_socket_test_util.cc b/test/syscalls/linux/ip_socket_test_util.cc index f8232fc24..4ad787cc0 100644 --- a/test/syscalls/linux/ip_socket_test_util.cc +++ b/test/syscalls/linux/ip_socket_test_util.cc @@ -13,7 +13,9 @@ // limitations under the License. #include +#include #include +#include #include #include "test/syscalls/linux/ip_socket_test_util.h" @@ -95,5 +97,19 @@ SocketPairKind IPv4UDPUnboundSocketPair(int type) { /* dual_stack = */ false)}; } +SocketKind IPv4UDPUnboundSocket(int type) { + std::string description = + absl::StrCat(DescribeSocketType(type), "IPv4 UDP socket"); + return SocketKind{description, UnboundSocketCreator( + AF_INET, type | SOCK_DGRAM, IPPROTO_UDP)}; +} + +SocketKind IPv4TCPUnboundSocket(int type) { + std::string description = + absl::StrCat(DescribeSocketType(type), "IPv4 TCP socket"); + return SocketKind{description, UnboundSocketCreator( + AF_INET, type | SOCK_STREAM, IPPROTO_TCP)}; +} + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/ip_socket_test_util.h b/test/syscalls/linux/ip_socket_test_util.h index a6721091a..cac790e64 100644 --- a/test/syscalls/linux/ip_socket_test_util.h +++ b/test/syscalls/linux/ip_socket_test_util.h @@ -58,6 +58,14 @@ SocketPairKind DualStackUDPBidirectionalBindSocketPair(int type); // SocketPairs created with AF_INET and the given type. SocketPairKind IPv4UDPUnboundSocketPair(int type); +// IPv4UDPUnboundSocketPair returns a SocketKind that represents +// a SimpleSocket created with AF_INET, SOCK_DGRAM, and the given type. +SocketKind IPv4UDPUnboundSocket(int type); + +// IPv4TCPUnboundSocketPair returns a SocketKind that represents +// a SimpleSocket created with AF_INET, SOCK_STREAM and the given type. +SocketKind IPv4TCPUnboundSocket(int type); + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc new file mode 100644 index 000000000..8e1c13ff4 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc @@ -0,0 +1,66 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include "test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h" + +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "gtest/gtest.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +// Verifies that a newly instantiated TCP socket does not have the +// broadcast socket option enabled. +TEST_P(IPv4TCPUnboundExternalNetworkingSocketTest, TCPBroadcastDefault) { + auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + int get = -1; + socklen_t get_sz = sizeof(get); + EXPECT_THAT( + getsockopt(socket->get(), SOL_SOCKET, SO_BROADCAST, &get, &get_sz), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get, kSockOptOff); + EXPECT_EQ(get_sz, sizeof(get)); +} + +// Verifies that a newly instantiated TCP socket returns true after enabling +// the broadcast socket option. +TEST_P(IPv4TCPUnboundExternalNetworkingSocketTest, SetTCPBroadcast) { + auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + EXPECT_THAT(setsockopt(socket->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceedsWithValue(0)); + + int get = -1; + socklen_t get_sz = sizeof(get); + EXPECT_THAT( + getsockopt(socket->get(), SOL_SOCKET, SO_BROADCAST, &get, &get_sz), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get, kSockOptOn); + EXPECT_EQ(get_sz, sizeof(get)); +} + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h new file mode 100644 index 000000000..b23de08d1 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h @@ -0,0 +1,30 @@ +// Copyright 2019 Google LLC +// +// 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. + +#ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_TCP_UNBOUND_EXTERNAL_NETWORKING_H_ +#define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_TCP_UNBOUND_EXTERNAL_NETWORKING_H_ + +#include "test/syscalls/linux/socket_test_util.h" + +namespace gvisor { +namespace testing { + +// Test fixture for tests that apply to unbound IPv4 TCP sockets in a sandbox +// with external networking support. +using IPv4TCPUnboundExternalNetworkingSocketTest = SimpleSocketTest; + +} // namespace testing +} // namespace gvisor + +#endif // GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_TCP_UNBOUND_EXTERNAL_NETWORKING_H_ diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc new file mode 100644 index 000000000..c6fb42641 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc @@ -0,0 +1,35 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include + +#include "test/syscalls/linux/ip_socket_test_util.h" +#include "test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +std::vector GetSockets() { + return ApplyVec( + IPv4TCPUnboundSocket, + AllBitwiseCombinations(List{0, SOCK_NONBLOCK})); +} + +INSTANTIATE_TEST_CASE_P(IPv4TCPSockets, + IPv4TCPUnboundExternalNetworkingSocketTest, + ::testing::ValuesIn(GetSockets())); +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc new file mode 100644 index 000000000..7d561b991 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc @@ -0,0 +1,231 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include "test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h" + +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "gtest/gtest.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +// Verifies that a newly instantiated UDP socket does not have the +// broadcast socket option enabled. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, UDPBroadcastDefault) { + auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + int get = -1; + socklen_t get_sz = sizeof(get); + EXPECT_THAT( + getsockopt(socket->get(), SOL_SOCKET, SO_BROADCAST, &get, &get_sz), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get, kSockOptOff); + EXPECT_EQ(get_sz, sizeof(get)); +} + +// Verifies that a newly instantiated UDP socket returns true after enabling +// the broadcast socket option. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, SetUDPBroadcast) { + auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + EXPECT_THAT(setsockopt(socket->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceedsWithValue(0)); + + int get = -1; + socklen_t get_sz = sizeof(get); + EXPECT_THAT( + getsockopt(socket->get(), SOL_SOCKET, SO_BROADCAST, &get, &get_sz), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get, kSockOptOn); + EXPECT_EQ(get_sz, sizeof(get)); +} + +// Verifies that a broadcast UDP packet will arrive at all UDP sockets with +// the destination port number. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, + UDPBroadcastReceivedOnAllExpectedEndpoints) { + auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + auto rcvr1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + auto rcvr2 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + auto norcv = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + // Enable SO_BROADCAST on the sending socket. + ASSERT_THAT(setsockopt(sender->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceedsWithValue(0)); + + // Enable SO_REUSEPORT on the receiving sockets so that they may both be bound + // to the broadcast messages destination port. + ASSERT_THAT(setsockopt(rcvr1->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceedsWithValue(0)); + ASSERT_THAT(setsockopt(rcvr2->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceedsWithValue(0)); + + sockaddr_in rcv_addr = {}; + socklen_t rcv_addr_sz = sizeof(rcv_addr); + rcv_addr.sin_family = AF_INET; + rcv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + ASSERT_THAT(bind(rcvr1->get(), reinterpret_cast(&rcv_addr), + rcv_addr_sz), + SyscallSucceedsWithValue(0)); + // Retrieve port number from first socket so that it can be bound to the + // second socket. + rcv_addr = {}; + ASSERT_THAT( + getsockname(rcvr1->get(), reinterpret_cast(&rcv_addr), + &rcv_addr_sz), + SyscallSucceedsWithValue(0)); + ASSERT_THAT(bind(rcvr2->get(), reinterpret_cast(&rcv_addr), + rcv_addr_sz), + SyscallSucceedsWithValue(0)); + + // Bind the non-receiving socket to an ephemeral port. + sockaddr_in norcv_addr = {}; + norcv_addr.sin_family = AF_INET; + norcv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + ASSERT_THAT( + bind(norcv->get(), reinterpret_cast(&norcv_addr), + sizeof(norcv_addr)), + SyscallSucceedsWithValue(0)); + + // Broadcast a test message. + sockaddr_in dst_addr = {}; + dst_addr.sin_family = AF_INET; + dst_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); + dst_addr.sin_port = rcv_addr.sin_port; + constexpr char kTestMsg[] = "hello, world"; + EXPECT_THAT( + sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, + reinterpret_cast(&dst_addr), sizeof(dst_addr)), + SyscallSucceedsWithValue(sizeof(kTestMsg))); + + // Verify that the receiving sockets received the test message. + char buf[sizeof(kTestMsg)] = {}; + EXPECT_THAT(read(rcvr1->get(), buf, sizeof(buf)), + SyscallSucceedsWithValue(sizeof(kTestMsg))); + EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); + memset(buf, 0, sizeof(buf)); + EXPECT_THAT(read(rcvr2->get(), buf, sizeof(buf)), + SyscallSucceedsWithValue(sizeof(kTestMsg))); + EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); + + // Verify that the non-receiving socket did not receive the test message. + memset(buf, 0, sizeof(buf)); + EXPECT_THAT(RetryEINTR(recv)(norcv->get(), buf, sizeof(buf), MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Verifies that a UDP broadcast sent via the loopback interface is not received +// by the sender. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, + UDPBroadcastViaLoopbackFails) { + auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + // Enable SO_BROADCAST. + ASSERT_THAT(setsockopt(sender->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceedsWithValue(0)); + + // Bind the sender to the loopback interface. + sockaddr_in src = {}; + socklen_t src_sz = sizeof(src); + src.sin_family = AF_INET; + src.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + ASSERT_THAT( + bind(sender->get(), reinterpret_cast(&src), src_sz), + SyscallSucceedsWithValue(0)); + ASSERT_THAT(getsockname(sender->get(), + reinterpret_cast(&src), &src_sz), + SyscallSucceedsWithValue(0)); + ASSERT_EQ(src.sin_addr.s_addr, htonl(INADDR_LOOPBACK)); + + // Send the message. + sockaddr_in dst = {}; + dst.sin_family = AF_INET; + dst.sin_addr.s_addr = htonl(INADDR_BROADCAST); + dst.sin_port = src.sin_port; + constexpr char kTestMsg[] = "hello, world"; + EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, + reinterpret_cast(&dst), sizeof(dst)), + SyscallSucceedsWithValue(sizeof(kTestMsg))); + + // Verify that the message was not received by the sender (loopback). + char buf[sizeof(kTestMsg)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sender->get(), buf, sizeof(buf), MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Verifies that a UDP broadcast fails to send on a socket with SO_BROADCAST +// disabled. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendBroadcast) { + auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + // Broadcast a test message without having enabled SO_BROADCAST on the sending + // socket. + sockaddr_in addr = {}; + socklen_t addr_sz = sizeof(addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(12345); + addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); + constexpr char kTestMsg[] = "hello, world"; + + EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, + reinterpret_cast(&addr), addr_sz), + SyscallFailsWithErrno(EACCES)); +} + +// Verifies that a UDP unicast on an unbound socket reaches its destination. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendUnicastOnUnbound) { + auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + auto rcvr = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + // Bind the receiver and retrieve its address and port number. + sockaddr_in addr = {}; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(0); + ASSERT_THAT(bind(rcvr->get(), reinterpret_cast(&addr), + sizeof(addr)), + SyscallSucceedsWithValue(0)); + memset(&addr, 0, sizeof(addr)); + socklen_t addr_sz = sizeof(addr); + ASSERT_THAT(getsockname(rcvr->get(), + reinterpret_cast(&addr), &addr_sz), + SyscallSucceedsWithValue(0)); + + // Send a test message to the receiver. + constexpr char kTestMsg[] = "hello, world"; + ASSERT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, + reinterpret_cast(&addr), addr_sz), + SyscallSucceedsWithValue(sizeof(kTestMsg))); + char buf[sizeof(kTestMsg)] = {}; + ASSERT_THAT(read(rcvr->get(), buf, sizeof(buf)), + SyscallSucceedsWithValue(sizeof(kTestMsg))); +} + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h new file mode 100644 index 000000000..5cf9fa8eb --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h @@ -0,0 +1,30 @@ +// Copyright 2019 Google LLC +// +// 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. + +#ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_EXTERNAL_NETWORKING_H_ +#define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_EXTERNAL_NETWORKING_H_ + +#include "test/syscalls/linux/socket_test_util.h" + +namespace gvisor { +namespace testing { + +// Test fixture for tests that apply to unbound IPv4 UDP sockets in a sandbox +// with external networking support. +using IPv4UDPUnboundExternalNetworkingSocketTest = SimpleSocketTest; + +} // namespace testing +} // namespace gvisor + +#endif // GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_EXTERNAL_NETWORKING_H_ diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc new file mode 100644 index 000000000..e07385134 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc @@ -0,0 +1,35 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include + +#include "test/syscalls/linux/ip_socket_test_util.h" +#include "test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +std::vector GetSockets() { + return ApplyVec( + IPv4UDPUnboundSocket, + AllBitwiseCombinations(List{0, SOCK_NONBLOCK})); +} + +INSTANTIATE_TEST_CASE_P(IPv4UDPSockets, + IPv4UDPUnboundExternalNetworkingSocketTest, + ::testing::ValuesIn(GetSockets())); +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc index 8d19f79ac..035087566 100644 --- a/test/syscalls/linux/socket_test_util.cc +++ b/test/syscalls/linux/socket_test_util.cc @@ -22,6 +22,7 @@ #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" #include "absl/time/clock.h" +#include "test/util/file_descriptor.h" #include "test/util/posix_error.h" #include "test/util/temp_path.h" #include "test/util/thread_util.h" @@ -463,6 +464,17 @@ SocketPairKind Reversed(SocketPairKind const& base) { }}; } +Creator UnboundSocketCreator(int domain, int type, + int protocol) { + return [=]() -> PosixErrorOr> { + int sock; + RETURN_ERROR_IF_SYSCALL_FAIL(sock = socket(domain, type, protocol)); + MaybeSave(); // Successful socket creation. + + return absl::make_unique(sock); + }; +} + std::vector IncludeReversals(std::vector vec) { return ApplyVecToVec(std::vector{NoOp, Reversed}, vec); diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h index 906b3e929..dfabdf179 100644 --- a/test/syscalls/linux/socket_test_util.h +++ b/test/syscalls/linux/socket_test_util.h @@ -278,6 +278,11 @@ Creator UDPBidirectionalBindSocketPairCreator(int domain, int type, Creator UDPUnboundSocketPairCreator(int domain, int type, int protocol, bool dual_stack); +// UnboundSocketCreator returns a Creator that obtains a file +// descriptor by creating a socket. +Creator UnboundSocketCreator(int domain, int type, + int protocol); + // A SocketPairKind couples a human-readable description of a socket pair with // a function that creates such a socket pair. struct SocketPairKind { -- cgit v1.2.3 From c14a1a161869804af5ae2f1f73fd8eeb135ff043 Mon Sep 17 00:00:00 2001 From: Amanda Tait Date: Mon, 25 Feb 2019 10:01:25 -0800 Subject: Fix race condition in NIC.DeliverNetworkPacket cl/234850781 introduced a race condition in NIC.DeliverNetworkPacket by failing to hold a lock. This change fixes this regressesion by acquiring a read lock before iterating through n.endpoints, and then releasing the lock once iteration is complete. PiperOrigin-RevId: 235549770 Change-Id: Ib0133288be512d478cf759c3314dc95ec3205d4b --- pkg/tcpip/stack/nic.go | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 43d7c2ec4..a6b04faaf 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -403,14 +403,19 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr // route to each IPv4 network endpoint and let each endpoint handle the // packet. if dst == header.IPv4Broadcast { + // n.endpoints is mutex protected so acquire lock. + n.mu.RLock() for _, ref := range n.endpoints { + n.mu.RUnlock() if ref.protocol == header.IPv4ProtocolNumber && ref.tryIncRef() { r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) r.RemoteLinkAddress = remote ref.ep.HandlePacket(&r, vv) ref.decRef() } + n.mu.RLock() } + n.mu.RUnlock() return } -- cgit v1.2.3 From 33d0e824c73a918ad59586084b47cd53fe07ca36 Mon Sep 17 00:00:00 2001 From: Amanda Tait Date: Tue, 26 Feb 2019 09:09:42 -0800 Subject: Use more conservative locking in NIC.DeliverNetworkPacket An earlier CL excessively minimizes the period in which it holds a lock on NIC. This earlier CL had done this out of the mistaken impression it fixed a broken test, when in fact it just reduced the rate of failure of a flaky test in tcp_test.go. This new change holds the lock on NIC for the duration of the loop over n.endpoints. PiperOrigin-RevId: 235732487 Change-Id: I53ee6df264f093ddc4d29e9acdcba6b4838cb112 --- pkg/tcpip/stack/nic.go | 2 -- 1 file changed, 2 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index a6b04faaf..2278fbf65 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -406,14 +406,12 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr // n.endpoints is mutex protected so acquire lock. n.mu.RLock() for _, ref := range n.endpoints { - n.mu.RUnlock() if ref.protocol == header.IPv4ProtocolNumber && ref.tryIncRef() { r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) r.RemoteLinkAddress = remote ref.ep.HandlePacket(&r, vv) ref.decRef() } - n.mu.RLock() } n.mu.RUnlock() return -- cgit v1.2.3 From 12d9cf6fabb53d18da3602564f45ff6fbbf032d6 Mon Sep 17 00:00:00 2001 From: Googler Date: Tue, 26 Feb 2019 14:57:27 -0800 Subject: Adds a WriteRawPacket method to the InjectableLinkEndpoint interface. Also exposes ipv4.MaxTotalSize since it is a generally useful constant. PiperOrigin-RevId: 235799755 Change-Id: I1fa8d5294bf355acf5527cfdf274b3687d3c8b13 --- pkg/tcpip/link/fdbased/endpoint.go | 5 +++++ pkg/tcpip/link/muxed/injectable.go | 12 +++++++++++- pkg/tcpip/link/muxed/injectable_test.go | 16 ++++++++++++++++ pkg/tcpip/network/ipv4/ipv4.go | 8 ++++---- pkg/tcpip/stack/registration.go | 5 +++++ 5 files changed, 41 insertions(+), 5 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 20f379ab0..fa980716d 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -288,6 +288,11 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b return rawfile.NonBlockingWrite2(e.fd, hdr.View(), payload.ToView()) } +// WriteRawPacket writes a raw packet directly to the file descriptor. +func (e *endpoint) WriteRawPacket(dest tcpip.Address, packet []byte) *tcpip.Error { + return rawfile.NonBlockingWrite(e.fd, packet) +} + func (e *endpoint) capViews(k, n int, buffers []int) int { c := 0 for i, s := range buffers { diff --git a/pkg/tcpip/link/muxed/injectable.go b/pkg/tcpip/link/muxed/injectable.go index 9d85bda60..29073afae 100644 --- a/pkg/tcpip/link/muxed/injectable.go +++ b/pkg/tcpip/link/muxed/injectable.go @@ -94,7 +94,17 @@ func (m *InjectableEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, return tcpip.ErrNoRoute } -// NewInjectableEndpoint creates a new multi-fd-based injectable endpoint. +// WriteRawPacket writes outbound packets to the appropriate +// LinkInjectableEndpoint based on the dest address. +func (m *InjectableEndpoint) WriteRawPacket(dest tcpip.Address, packet []byte) *tcpip.Error { + endpoint, ok := m.routes[dest] + if !ok { + return tcpip.ErrNoRoute + } + return endpoint.WriteRawPacket(dest, packet) +} + +// NewInjectableEndpoint creates a new multi-endpoint injectable endpoint. func NewInjectableEndpoint(routes map[tcpip.Address]stack.InjectableLinkEndpoint, mtu uint32) (tcpip.LinkEndpointID, *InjectableEndpoint) { e := &InjectableEndpoint{ routes: routes, diff --git a/pkg/tcpip/link/muxed/injectable_test.go b/pkg/tcpip/link/muxed/injectable_test.go index 65db14b5d..d1d2875cc 100644 --- a/pkg/tcpip/link/muxed/injectable_test.go +++ b/pkg/tcpip/link/muxed/injectable_test.go @@ -28,8 +28,24 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" ) +func TestInjectableEndpointRawDispatch(t *testing.T) { + endpoint, sock, dstIP := makeTestInjectableEndpoint(t) + + endpoint.WriteRawPacket(dstIP, []byte{0xFA}) + + buf := make([]byte, ipv4.MaxTotalSize) + bytesRead, err := sock.Read(buf) + if err != nil { + t.Fatalf("Unable to read from socketpair: %v", err) + } + if got, want := buf[:bytesRead], []byte{0xFA}; !bytes.Equal(got, want) { + t.Fatalf("Read %v from the socketpair, wanted %v", got, want) + } +} + func TestInjectableEndpointDispatch(t *testing.T) { endpoint, sock, dstIP := makeTestInjectableEndpoint(t) + hdr := buffer.NewPrependable(1) hdr.Prepend(1)[0] = 0xFA packetRoute := stack.Route{RemoteAddress: dstIP} diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index c0d334b56..0c41519df 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -38,9 +38,9 @@ const ( // ProtocolNumber is the ipv4 protocol number. ProtocolNumber = header.IPv4ProtocolNumber - // maxTotalSize is maximum size that can be encoded in the 16-bit + // MaxTotalSize is maximum size that can be encoded in the 16-bit // TotalLength field of the ipv4 header. - maxTotalSize = 0xffff + MaxTotalSize = 0xffff // buckets is the number of identifier buckets. buckets = 2048 @@ -204,8 +204,8 @@ func (p *protocol) Option(option interface{}) *tcpip.Error { // calculateMTU calculates the network-layer payload MTU based on the link-layer // payload mtu. func calculateMTU(mtu uint32) uint32 { - if mtu > maxTotalSize { - mtu = maxTotalSize + if mtu > MaxTotalSize { + mtu = MaxTotalSize } return mtu - header.IPv4MinimumSize } diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 010d51886..5accffa1b 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -260,6 +260,11 @@ type InjectableLinkEndpoint interface { // Inject injects an inbound packet. Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) + + // WriteRawPacket writes a fully formed outbound packet directly to the link. + // + // dest is used by endpoints with multiple raw destinations. + WriteRawPacket(dest tcpip.Address, packet []byte) *tcpip.Error } // A LinkAddressResolver is an extension to a NetworkProtocol that -- cgit v1.2.3 From 121db29a93c651b8b62e8701bb0f16c231b08257 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Wed, 27 Feb 2019 14:30:20 -0800 Subject: Ping support via IPv4 raw sockets. Broadly, this change: * Enables sockets to be created via `socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)`. * Passes the network-layer (IP) header up the stack to the transport endpoint, which can pass it up to the socket layer. This allows a raw socket to return the entire IP packet to users. * Adds functions to stack.TransportProtocol, stack.Stack, stack.transportDemuxer that enable incoming packets to be delivered to raw endpoints. New raw sockets of other protocols (not ICMP) just need to register with the stack. * Enables ping.endpoint to return IP headers when created via SOCK_RAW. PiperOrigin-RevId: 235993280 Change-Id: I60ed994f5ff18b2cbd79f063a7fdf15d093d845a --- pkg/sentry/socket/epsocket/BUILD | 1 + pkg/sentry/socket/epsocket/provider.go | 28 +++- pkg/tcpip/network/ip_test.go | 2 +- pkg/tcpip/network/ipv4/icmp.go | 11 +- pkg/tcpip/network/ipv4/ipv4.go | 8 +- pkg/tcpip/network/ipv6/icmp.go | 4 +- pkg/tcpip/network/ipv6/ipv6.go | 7 +- pkg/tcpip/stack/nic.go | 8 +- pkg/tcpip/stack/registration.go | 10 +- pkg/tcpip/stack/stack.go | 52 ++++++- pkg/tcpip/stack/stack_test.go | 2 +- pkg/tcpip/stack/transport_demuxer.go | 78 +++++++++-- pkg/tcpip/stack/transport_test.go | 6 +- pkg/tcpip/transport/icmp/endpoint.go | 81 ++++++++--- pkg/tcpip/transport/icmp/protocol.go | 15 +- pkg/tcpip/transport/tcp/endpoint.go | 2 +- pkg/tcpip/transport/tcp/forwarder.go | 2 +- pkg/tcpip/transport/tcp/protocol.go | 6 + pkg/tcpip/transport/udp/endpoint.go | 2 +- pkg/tcpip/transport/udp/protocol.go | 6 + test/syscalls/linux/BUILD | 16 +++ test/syscalls/linux/raw_socket_ipv4.cc | 245 +++++++++++++++++++++++++++++++++ 22 files changed, 533 insertions(+), 59 deletions(-) create mode 100644 test/syscalls/linux/raw_socket_ipv4.cc (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index 45e418db3..44bb97b5b 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -27,6 +27,7 @@ go_library( "//pkg/sentry/fs/fsutil", "//pkg/sentry/inet", "//pkg/sentry/kernel", + "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/time", "//pkg/sentry/safemem", diff --git a/pkg/sentry/socket/epsocket/provider.go b/pkg/sentry/socket/epsocket/provider.go index 0184d8e3e..0d9c2df24 100644 --- a/pkg/sentry/socket/epsocket/provider.go +++ b/pkg/sentry/socket/epsocket/provider.go @@ -18,8 +18,10 @@ import ( "syscall" "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/socket" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" "gvisor.googlesource.com/gvisor/pkg/syserr" @@ -38,9 +40,9 @@ type provider struct { netProto tcpip.NetworkProtocolNumber } -// GetTransportProtocol figures out transport protocol. Currently only TCP, +// getTransportProtocol figures out transport protocol. Currently only TCP, // UDP, and ICMP are supported. -func GetTransportProtocol(stype transport.SockType, protocol int) (tcpip.TransportProtocolNumber, *syserr.Error) { +func getTransportProtocol(ctx context.Context, stype transport.SockType, protocol int) (tcpip.TransportProtocolNumber, *syserr.Error) { switch stype { case linux.SOCK_STREAM: if protocol != 0 && protocol != syscall.IPPROTO_TCP { @@ -57,6 +59,18 @@ func GetTransportProtocol(stype transport.SockType, protocol int) (tcpip.Transpo case syscall.IPPROTO_ICMPV6: return header.ICMPv6ProtocolNumber, nil } + + case linux.SOCK_RAW: + // Raw sockets require CAP_NET_RAW. + creds := auth.CredentialsFromContext(ctx) + if !creds.HasCapability(linux.CAP_NET_RAW) { + return 0, syserr.ErrPermissionDenied + } + + switch protocol { + case syscall.IPPROTO_ICMP: + return header.ICMPv4ProtocolNumber, nil + } } return 0, syserr.ErrInvalidArgument } @@ -76,14 +90,20 @@ func (p *provider) Socket(t *kernel.Task, stype transport.SockType, protocol int } // Figure out the transport protocol. - transProto, err := GetTransportProtocol(stype, protocol) + transProto, err := getTransportProtocol(t, stype, protocol) if err != nil { return nil, err } // Create the endpoint. + var ep tcpip.Endpoint + var e *tcpip.Error wq := &waiter.Queue{} - ep, e := eps.Stack.NewEndpoint(transProto, p.netProto, wq) + if stype == linux.SOCK_RAW { + ep, e = eps.Stack.NewRawEndpoint(transProto, p.netProto, wq) + } else { + ep, e = eps.Stack.NewEndpoint(transProto, p.netProto, wq) + } if e != nil { return nil, syserr.TranslateNetstackError(e) } diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 5c1e88e56..97a43aece 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -94,7 +94,7 @@ func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv buff // DeliverTransportPacket is called by network endpoints after parsing incoming // packets. This is used by the test object to verify that the results of the // parsing are expected. -func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView) { +func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.TransportProtocolNumber, netHeader buffer.View, vv buffer.VectorisedView) { t.checkValues(protocol, vv, r.RemoteAddress, r.LocalAddress) t.dataCalls++ } diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index f82dc098f..ea8392c98 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -55,7 +55,7 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer. e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv) } -func (e *endpoint) handleICMP(r *stack.Route, vv buffer.VectorisedView) { +func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.VectorisedView) { v := vv.First() if len(v) < header.ICMPv4MinimumSize { return @@ -67,19 +67,22 @@ func (e *endpoint) handleICMP(r *stack.Route, vv buffer.VectorisedView) { if len(v) < header.ICMPv4EchoMinimumSize { return } - vv.TrimFront(header.ICMPv4MinimumSize) - req := echoRequest{r: r.Clone(), v: vv.ToView()} + echoPayload := vv.ToView() + echoPayload.TrimFront(header.ICMPv4MinimumSize) + req := echoRequest{r: r.Clone(), v: echoPayload} select { case e.echoRequests <- req: default: req.r.Release() } + // It's possible that a raw socket expects to receive this. + e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, netHeader, vv) case header.ICMPv4EchoReply: if len(v) < header.ICMPv4EchoMinimumSize { return } - e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, vv) + e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, netHeader, vv) case header.ICMPv4DstUnreachable: if len(v) < header.ICMPv4DstUnreachableMinimumSize { diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index 0c41519df..bfc3c08fa 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -131,7 +131,8 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b // HandlePacket is called by the link layer when new ipv4 packets arrive for // this endpoint. func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { - h := header.IPv4(vv.First()) + headerView := vv.First() + h := header.IPv4(headerView) if !h.IsValid(vv.Size()) { return } @@ -153,11 +154,12 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { } p := h.TransportProtocol() if p == header.ICMPv4ProtocolNumber { - e.handleICMP(r, vv) + headerView.CapLength(hlen) + e.handleICMP(r, headerView, vv) return } r.Stats().IP.PacketsDelivered.Increment() - e.dispatcher.DeliverTransportPacket(r, p, vv) + e.dispatcher.DeliverTransportPacket(r, p, headerView, vv) } // Close cleans up resources associated with the endpoint. diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 14107443b..5a3c17768 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -62,7 +62,7 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer. e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv) } -func (e *endpoint) handleICMP(r *stack.Route, vv buffer.VectorisedView) { +func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.VectorisedView) { v := vv.First() if len(v) < header.ICMPv6MinimumSize { return @@ -148,7 +148,7 @@ func (e *endpoint) handleICMP(r *stack.Route, vv buffer.VectorisedView) { if len(v) < header.ICMPv6EchoMinimumSize { return } - e.dispatcher.DeliverTransportPacket(r, header.ICMPv6ProtocolNumber, vv) + e.dispatcher.DeliverTransportPacket(r, header.ICMPv6ProtocolNumber, netHeader, vv) } } diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 4d0b6ee9c..5f68ef7d5 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -102,7 +102,8 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b // HandlePacket is called by the link layer when new ipv6 packets arrive for // this endpoint. func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { - h := header.IPv6(vv.First()) + headerView := vv.First() + h := header.IPv6(headerView) if !h.IsValid(vv.Size()) { return } @@ -112,12 +113,12 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { p := h.TransportProtocol() if p == header.ICMPv6ProtocolNumber { - e.handleICMP(r, vv) + e.handleICMP(r, headerView, vv) return } r.Stats().IP.PacketsDelivered.Increment() - e.dispatcher.DeliverTransportPacket(r, p, vv) + e.dispatcher.DeliverTransportPacket(r, p, headerView, vv) } // Close cleans up resources associated with the endpoint. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 2278fbf65..79f845225 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -505,7 +505,7 @@ func (n *NIC) getRef(protocol tcpip.NetworkProtocolNumber, dst tcpip.Address) *r // DeliverTransportPacket delivers the packets to the appropriate transport // protocol endpoint. -func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView) { +func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, netHeader buffer.View, vv buffer.VectorisedView) { state, ok := n.stack.transportProtocols[protocol] if !ok { n.stack.stats.UnknownProtocolRcvdPackets.Increment() @@ -525,16 +525,16 @@ func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolN } id := TransportEndpointID{dstPort, r.LocalAddress, srcPort, r.RemoteAddress} - if n.demux.deliverPacket(r, protocol, vv, id) { + if n.demux.deliverPacket(r, protocol, netHeader, vv, id) { return } - if n.stack.demux.deliverPacket(r, protocol, vv, id) { + if n.stack.demux.deliverPacket(r, protocol, netHeader, vv, id) { return } // Try to deliver to per-stack default handler. if state.defaultHandler != nil { - if state.defaultHandler(r, id, vv) { + if state.defaultHandler(r, id, netHeader, vv) { return } } diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 5accffa1b..62acd5919 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -64,7 +64,7 @@ const ( type TransportEndpoint interface { // HandlePacket is called by the stack when new packets arrive to // this transport endpoint. - HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) + HandlePacket(r *Route, id TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) // HandleControlPacket is called by the stack when new control (e.g., // ICMP) packets arrive to this transport endpoint. @@ -80,6 +80,9 @@ type TransportProtocol interface { // NewEndpoint creates a new endpoint of the transport protocol. NewEndpoint(stack *Stack, netProto tcpip.NetworkProtocolNumber, waitQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) + // NewRawEndpoint creates a new raw endpoint of the transport protocol. + NewRawEndpoint(stack *Stack, netProto tcpip.NetworkProtocolNumber, waitQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) + // MinimumPacketSize returns the minimum valid packet size of this // transport protocol. The stack automatically drops any packets smaller // than this targeted at this protocol. @@ -113,8 +116,9 @@ type TransportProtocol interface { // the network layer. type TransportDispatcher interface { // DeliverTransportPacket delivers packets to the appropriate - // transport protocol endpoint. - DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView) + // transport protocol endpoint. It also returns the network layer + // header for the enpoint to inspect or pass up the stack. + DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, netHeader buffer.View, vv buffer.VectorisedView) // DeliverTransportControlPacket delivers control packets to the // appropriate transport protocol endpoint. diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 252c79317..797489ad9 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -48,7 +48,7 @@ const ( type transportProtocolState struct { proto TransportProtocol - defaultHandler func(*Route, TransportEndpointID, buffer.VectorisedView) bool + defaultHandler func(r *Route, id TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) bool } // TCPProbeFunc is the expected function type for a TCP probe function to be @@ -437,7 +437,7 @@ func (s *Stack) TransportProtocolOption(transport tcpip.TransportProtocolNumber, // // It must be called only during initialization of the stack. Changing it as the // stack is operating is not supported. -func (s *Stack) SetTransportProtocolHandler(p tcpip.TransportProtocolNumber, h func(*Route, TransportEndpointID, buffer.VectorisedView) bool) { +func (s *Stack) SetTransportProtocolHandler(p tcpip.TransportProtocolNumber, h func(*Route, TransportEndpointID, buffer.View, buffer.VectorisedView) bool) { state := s.transportProtocols[p] if state != nil { state.defaultHandler = h @@ -499,6 +499,18 @@ func (s *Stack) NewEndpoint(transport tcpip.TransportProtocolNumber, network tcp return t.proto.NewEndpoint(s, network, waiterQueue) } +// NewRawEndpoint creates a new raw transport layer endpoint of the given +// protocol. Raw endpoints receive all traffic for a given protocol regardless +// of address. +func (s *Stack) NewRawEndpoint(transport tcpip.TransportProtocolNumber, network tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + t, ok := s.transportProtocols[transport] + if !ok { + return nil, tcpip.ErrUnknownProtocol + } + + return t.proto.NewRawEndpoint(s, network, waiterQueue) +} + // createNIC creates a NIC with the provided id and link-layer endpoint, and // optionally enable it. func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID, enabled bool) *tcpip.Error { @@ -934,6 +946,42 @@ func (s *Stack) UnregisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip } } +// RegisterRawTransportEndpoint registers the given endpoint with the stack +// transport dispatcher. Received packets that match the provided protocol will +// be delivered to the given endpoint. +func (s *Stack) RegisterRawTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint, reusePort bool) *tcpip.Error { + if nicID == 0 { + return s.demux.registerRawEndpoint(netProtos, protocol, ep, reusePort) + } + + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[nicID] + if nic == nil { + return tcpip.ErrUnknownNICID + } + + return nic.demux.registerRawEndpoint(netProtos, protocol, ep, reusePort) +} + +// UnregisterRawTransportEndpoint removes the endpoint for the protocol from +// the stack transport dispatcher. +func (s *Stack) UnregisterRawTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint) { + if nicID == 0 { + s.demux.unregisterRawEndpoint(netProtos, protocol, ep) + return + } + + s.mu.RLock() + defer s.mu.RUnlock() + + nic := s.nics[nicID] + if nic != nil { + nic.demux.unregisterRawEndpoint(netProtos, protocol, ep) + } +} + // NetworkProtocolInstance returns the protocol instance in the stack for the // specified network protocol. This method is public for protocol implementers // and tests to use. diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 163fadded..28743f3d5 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -97,7 +97,7 @@ func (f *fakeNetworkEndpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedV } // Dispatch the packet to the transport protocol. - f.dispatcher.DeliverTransportPacket(r, tcpip.TransportProtocolNumber(b[2]), vv) + f.dispatcher.DeliverTransportPacket(r, tcpip.TransportProtocolNumber(b[2]), buffer.View([]byte{}), vv) } func (f *fakeNetworkEndpoint) MaxHeaderLength() uint16 { diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index c18208dc0..9ab314188 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -32,8 +32,12 @@ type protocolIDs struct { // transportEndpoints manages all endpoints of a given protocol. It has its own // mutex so as to reduce interference between protocols. type transportEndpoints struct { + // mu protects all fields of the transportEndpoints. mu sync.RWMutex endpoints map[TransportEndpointID]TransportEndpoint + // rawEndpoints contains endpoints for raw sockets, which receive all + // traffic of a given protocol regardless of port. + rawEndpoints []TransportEndpoint } // unregisterEndpoint unregisters the endpoint with the given id such that it @@ -67,7 +71,9 @@ func newTransportDemuxer(stack *Stack) *transportDemuxer { // Add each network and transport pair to the demuxer. for netProto := range stack.networkProtocols { for proto := range stack.transportProtocols { - d.protocol[protocolIDs{netProto, proto}] = &transportEndpoints{endpoints: make(map[TransportEndpointID]TransportEndpoint)} + d.protocol[protocolIDs{netProto, proto}] = &transportEndpoints{ + endpoints: make(map[TransportEndpointID]TransportEndpoint), + } } } @@ -131,22 +137,22 @@ func (ep *multiPortEndpoint) selectEndpoint(id TransportEndpointID) TransportEnd // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (ep *multiPortEndpoint) HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) { +func (ep *multiPortEndpoint) HandlePacket(r *Route, id TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) { // If this is a broadcast datagram, deliver the datagram to all endpoints // managed by ep. if id.LocalAddress == header.IPv4Broadcast { for i, endpoint := range ep.endpointsArr { // HandlePacket modifies vv, so each endpoint needs its own copy. if i == len(ep.endpointsArr)-1 { - endpoint.HandlePacket(r, id, vv) + endpoint.HandlePacket(r, id, netHeader, vv) break } vvCopy := buffer.NewView(vv.Size()) copy(vvCopy, vv.ToView()) - endpoint.HandlePacket(r, id, vvCopy.ToVectorisedView()) + endpoint.HandlePacket(r, id, buffer.NewViewFromBytes(netHeader), vvCopy.ToVectorisedView()) } } else { - ep.selectEndpoint(id).HandlePacket(r, id, vv) + ep.selectEndpoint(id).HandlePacket(r, id, netHeader, vv) } } @@ -250,7 +256,7 @@ var loopbackSubnet = func() tcpip.Subnet { // deliverPacket attempts to find one or more matching transport endpoints, and // then, if matches are found, delivers the packet to them. Returns true if it // found one or more endpoints, false otherwise. -func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView, id TransportEndpointID) bool { +func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProtocolNumber, netHeader buffer.View, vv buffer.VectorisedView, id TransportEndpointID) bool { eps, ok := d.protocol[protocolIDs{r.NetProto, protocol}] if !ok { return false @@ -276,10 +282,21 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto } else if ep := d.findEndpointLocked(eps, vv, id); ep != nil { destEps = append(destEps, ep) } + + // As in net/ipv4/ip_input.c:ip_local_deliver, attempt to deliver via + // raw endpoint first. If there are multipe raw endpoints, they all + // receive the packet. + found := false + for _, rawEP := range eps.rawEndpoints { + // Each endpoint gets its own copy of the packet for the sake + // of save/restore. + rawEP.HandlePacket(r, id, buffer.NewViewFromBytes(netHeader), vv.ToView().ToVectorisedView()) + found = true + } eps.mu.RUnlock() // Fail if we didn't find at least one matching transport endpoint. - if len(destEps) == 0 { + if len(destEps) == 0 && !found { // UDP packet could not be delivered to an unknown destination port. if protocol == header.UDPProtocolNumber { r.Stats().UDP.UnknownPortErrors.Increment() @@ -289,7 +306,7 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto // Deliver the packet. for _, ep := range destEps { - ep.HandlePacket(r, id, vv) + ep.HandlePacket(r, id, netHeader, vv) } return true @@ -349,3 +366,48 @@ func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv buffer return nil } + +// registerRawEndpoint registers the given endpoint with the dispatcher such +// that packets of the appropriate protocol are delivered to it. A single +// packet can be sent to one or more raw endpoints along with a non-raw +// endpoint. +func (d *transportDemuxer) registerRawEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint, reusePort bool) *tcpip.Error { + for i, n := range netProtos { + if err := d.singleRegisterRawEndpoint(n, protocol, ep); err != nil { + d.unregisterRawEndpoint(netProtos[:i], protocol, ep) + return err + } + } + + return nil +} + +func (d *transportDemuxer) singleRegisterRawEndpoint(netProto tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint) *tcpip.Error { + eps, ok := d.protocol[protocolIDs{netProto, protocol}] + if !ok { + return nil + } + + eps.mu.Lock() + defer eps.mu.Unlock() + eps.rawEndpoints = append(eps.rawEndpoints, ep) + + return nil +} + +// unregisterRawEndpoint unregisters the raw endpoint for the given protocol +// such that it won't receive any more packets. +func (d *transportDemuxer) unregisterRawEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint) { + for _, n := range netProtos { + if eps, ok := d.protocol[protocolIDs{n, protocol}]; ok { + eps.mu.Lock() + defer eps.mu.Unlock() + for i, rawEP := range eps.rawEndpoints { + if rawEP == ep { + eps.rawEndpoints = append(eps.rawEndpoints[:i], eps.rawEndpoints[i+1:]...) + return + } + } + } + } +} diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index da460db77..3347b5599 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -168,7 +168,7 @@ func (*fakeTransportEndpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Erro return tcpip.FullAddress{}, nil } -func (f *fakeTransportEndpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, _ buffer.VectorisedView) { +func (f *fakeTransportEndpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, _ buffer.View, _ buffer.VectorisedView) { // Increment the number of received packets. f.proto.packetCount++ if f.acceptQueue != nil { @@ -214,6 +214,10 @@ func (f *fakeTransportProtocol) NewEndpoint(stack *stack.Stack, netProto tcpip.N return newFakeTransportEndpoint(stack, f, netProto), nil } +func (f *fakeTransportProtocol) NewRawEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, _ *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + return nil, tcpip.ErrUnknownProtocol +} + func (*fakeTransportProtocol) MinimumPacketSize() int { return fakeTransHeaderLen } diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index d87bfe048..b3b7a1d0e 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -46,17 +46,23 @@ const ( stateClosed ) -// endpoint represents an ICMP (ping) endpoint. This struct serves as the -// interface between users of the endpoint and the protocol implementation; it -// is legal to have concurrent goroutines make calls into the endpoint, they -// are properly synchronized. +// endpoint represents an ICMP endpoint. This struct serves as the interface +// between users of the endpoint and the protocol implementation; it is legal to +// have concurrent goroutines make calls into the endpoint, they are properly +// synchronized. +// +// +stateify savable type endpoint struct { - // The following fields are initialized at creation time and do not - // change throughout the lifetime of the endpoint. + // The following fields are initialized at creation time and are + // immutable. stack *stack.Stack `state:"manual"` netProto tcpip.NetworkProtocolNumber transProto tcpip.TransportProtocolNumber waiterQueue *waiter.Queue + // raw indicates whether the endpoint is intended for use by a raw + // socket, which returns the network layer header along with the + // payload. It is immutable. + raw bool // The following fields are used to manage the receive queue, and are // protected by rcvMu. @@ -80,15 +86,26 @@ type endpoint struct { route stack.Route `state:"manual"` } -func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) *endpoint { - return &endpoint{ +func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue, raw bool) (*endpoint, *tcpip.Error) { + e := &endpoint{ stack: stack, netProto: netProto, transProto: transProto, waiterQueue: waiterQueue, rcvBufSizeMax: 32 * 1024, sndBufSize: 32 * 1024, + raw: raw, + } + + // Raw endpoints must be immediately bound because they receive all + // ICMP traffic starting from when they're created via socket(). + if raw { + if err := e.bindLocked(tcpip.FullAddress{}, nil); err != nil { + return nil, err + } } + + return e, nil } // Close puts the endpoint in a closed state and frees all resources @@ -98,7 +115,11 @@ func (e *endpoint) Close() { e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite switch e.state { case stateBound, stateConnected: - e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id, e) + if e.raw { + e.stack.UnregisterRawTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e) + } else { + e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id, e) + } } // Close the receive list and drain it. @@ -285,10 +306,10 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c switch e.netProto { case header.IPv4ProtocolNumber: - err = sendPing4(route, e.id.LocalPort, v) + err = e.send4(route, v) case header.IPv6ProtocolNumber: - err = sendPing6(route, e.id.LocalPort, v) + err = send6(route, e.id.LocalPort, v) } if err != nil { @@ -346,13 +367,19 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { } } -func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { +func (e *endpoint) send4(r *stack.Route, data buffer.View) *tcpip.Error { + if e.raw { + hdr := buffer.NewPrependable(len(data) + int(r.MaxHeaderLength())) + return r.WritePacket(hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) + } + if len(data) < header.ICMPv4EchoMinimumSize { return tcpip.ErrInvalidEndpointState } - // Set the ident. Sequence number is provided by the user. - binary.BigEndian.PutUint16(data[header.ICMPv4MinimumSize:], ident) + // Set the ident to the user-specified port. Sequence number should + // already be set by the user. + binary.BigEndian.PutUint16(data[header.ICMPv4MinimumSize:], e.id.LocalPort) hdr := buffer.NewPrependable(header.ICMPv4EchoMinimumSize + int(r.MaxHeaderLength())) @@ -371,7 +398,7 @@ func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { return r.WritePacket(hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) } -func sendPing6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { +func send6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { if len(data) < header.ICMPv6EchoMinimumSize { return tcpip.ErrInvalidEndpointState } @@ -412,6 +439,11 @@ func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (t // Connect connects the endpoint to its peer. Specifying a NIC is optional. func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { + // TODO: We don't yet support connect on a raw socket. + if e.raw { + return tcpip.ErrNotSupported + } + e.mu.Lock() defer e.mu.Unlock() @@ -515,6 +547,11 @@ func (*endpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) { } func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, id stack.TransportEndpointID) (stack.TransportEndpointID, *tcpip.Error) { + if e.raw { + err := e.stack.RegisterRawTransportEndpoint(nicid, netProtos, e.transProto, e, false) + return stack.TransportEndpointID{}, err + } + if id.LocalPort != 0 { // The endpoint already has a local port, just attempt to // register it. @@ -657,7 +694,7 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) { e.rcvMu.Lock() // Drop the packet if our buffer is currently full. @@ -675,9 +712,17 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv Addr: id.RemoteAddress, }, } - pkt.data = vv.Clone(pkt.views[:]) + + if e.raw { + combinedVV := netHeader.ToVectorisedView() + combinedVV.Append(vv) + pkt.data = combinedVV.Clone(pkt.views[:]) + } else { + pkt.data = vv.Clone(pkt.views[:]) + } + e.rcvList.PushBack(pkt) - e.rcvBufSize += vv.Size() + e.rcvBufSize += pkt.data.Size() pkt.timestamp = e.stack.NowNanoseconds() diff --git a/pkg/tcpip/transport/icmp/protocol.go b/pkg/tcpip/transport/icmp/protocol.go index 9f0a2bf71..36b70988a 100644 --- a/pkg/tcpip/transport/icmp/protocol.go +++ b/pkg/tcpip/transport/icmp/protocol.go @@ -47,6 +47,7 @@ const ( ProtocolNumber6 = header.ICMPv6ProtocolNumber ) +// protocol implements stack.TransportProtocol. type protocol struct { number tcpip.TransportProtocolNumber } @@ -66,12 +67,22 @@ func (p *protocol) netProto() tcpip.NetworkProtocolNumber { panic(fmt.Sprint("unknown protocol number: ", p.number)) } -// NewEndpoint creates a new icmp endpoint. +// NewEndpoint creates a new icmp endpoint. It implements +// stack.TransportProtocol.NewEndpoint. func (p *protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { if netProto != p.netProto() { return nil, tcpip.ErrUnknownProtocol } - return newEndpoint(stack, netProto, p.number, waiterQueue), nil + return newEndpoint(stack, netProto, p.number, waiterQueue, false) +} + +// NewRawEndpoint creates a new raw icmp endpoint. It implements +// stack.TransportProtocol.NewRawEndpoint. +func (p *protocol) NewRawEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + if netProto != p.netProto() { + return nil, tcpip.ErrUnknownProtocol + } + return newEndpoint(stack, netProto, p.number, waiterQueue, true) } // MinimumPacketSize returns the minimum valid icmp packet size. diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index a8618bb4a..c48a27d8f 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1441,7 +1441,7 @@ func (e *endpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) { s := newSegment(r, id, vv) if !s.parse() { e.stack.Stats().MalformedRcvdPackets.Increment() diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index 2f90839e9..ca53a076f 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -63,7 +63,7 @@ func NewForwarder(s *stack.Stack, rcvWnd, maxInFlight int, handler func(*Forward // // This function is expected to be passed as an argument to the // stack.SetTransportProtocolHandler function. -func (f *Forwarder) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) bool { +func (f *Forwarder) HandlePacket(r *stack.Route, id stack.TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) bool { s := newSegment(r, id, vv) defer s.decRef() diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index 753e1419e..639ad3fae 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -101,6 +101,12 @@ func (*protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolN return newEndpoint(stack, netProto, waiterQueue), nil } +// NewRawEndpoint creates a new raw TCP endpoint. Raw TCP sockets are currently +// unsupported. It implements stack.TransportProtocol.NewRawEndpoint. +func (p *protocol) NewRawEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + return nil, tcpip.ErrUnknownProtocol +} + // MinimumPacketSize returns the minimum valid tcp packet size. func (*protocol) MinimumPacketSize() int { return header.TCPMinimumSize diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 05d35e526..44b9cdf6a 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -934,7 +934,7 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) { // Get the header then trim it from the view. hdr := header.UDP(vv.First()) if int(hdr.Length()) > vv.Size() { diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index b3fbed6e4..616a9f388 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -48,6 +48,12 @@ func (*protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolN return newEndpoint(stack, netProto, waiterQueue), nil } +// NewRawEndpoint creates a new raw UDP endpoint. Raw UDP sockets are currently +// unsupported. It implements stack.TransportProtocol.NewRawEndpoint. +func (p *protocol) NewRawEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + return nil, tcpip.ErrUnknownProtocol +} + // MinimumPacketSize returns the minimum valid udp packet size. func (*protocol) MinimumPacketSize() int { return header.UDPMinimumSize diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index beece8930..4c818238b 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1529,6 +1529,22 @@ cc_binary( ], ) +cc_binary( + name = "raw_socket_ipv4_test", + testonly = 1, + srcs = ["raw_socket_ipv4.cc"], + linkstatic = 1, + deps = [ + ":socket_test_util", + "//test/util:capability_util", + "//test/util:file_descriptor", + "//test/util:test_main", + "//test/util:test_util", + "@com_google_absl//absl/base:core_headers", + "@com_google_googletest//:gtest", + ], +) + cc_binary( name = "read_test", testonly = 1, diff --git a/test/syscalls/linux/raw_socket_ipv4.cc b/test/syscalls/linux/raw_socket_ipv4.cc new file mode 100644 index 000000000..c6749321c --- /dev/null +++ b/test/syscalls/linux/raw_socket_ipv4.cc @@ -0,0 +1,245 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/capability_util.h" +#include "test/util/file_descriptor.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +namespace { + +// Fixture for tests parameterized by address family (currently only AF_INET). +class RawSocketTest : public ::testing::Test { + protected: + // Creates a socket to be used in tests. + void SetUp() override; + + // Closes the socket created by SetUp(). + void TearDown() override; + + // The socket used for both reading and writing. + int s_; + + // The loopback address. + struct sockaddr_in addr_; + + void sendEmptyICMP(struct icmphdr *icmp); + + void sendEmptyICMPTo(int sock, struct sockaddr_in *addr, + struct icmphdr *icmp); + + void receiveICMP(char *recv_buf, size_t recv_buf_len, size_t expected_size, + struct sockaddr_in *src); + + void receiveICMPFrom(char *recv_buf, size_t recv_buf_len, + size_t expected_size, struct sockaddr_in *src, int sock); +}; + +void RawSocketTest::SetUp() { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT(s_ = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), SyscallSucceeds()); + + addr_ = {}; + + // We don't set ports because raw sockets don't have a notion of ports. + addr_.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr_.sin_family = AF_INET; +} + +void RawSocketTest::TearDown() { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + EXPECT_THAT(close(s_), SyscallSucceeds()); +} + +// We should be able to create multiple raw sockets for the same protocol. +// BasicRawSocket::Setup creates the first one, so we only have to create one +// more here. +TEST_F(RawSocketTest, MultipleCreation) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + int s2; + ASSERT_THAT(s2 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), SyscallSucceeds()); + + ASSERT_THAT(close(s2), SyscallSucceeds()); +} + +// Send and receive an ICMP packet. +TEST_F(RawSocketTest, SendAndReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = *(unsigned short *)&icmp.checksum; + icmp.un.echo.sequence = *(unsigned short *)&icmp.un.echo.sequence; + icmp.un.echo.id = *(unsigned short *)&icmp.un.echo.id; + ASSERT_NO_FATAL_FAILURE(sendEmptyICMP(&icmp)); + + // Receive the packet and make sure it's identical. + char recv_buf[512]; + struct sockaddr_in src; + ASSERT_NO_FATAL_FAILURE(receiveICMP(recv_buf, ABSL_ARRAYSIZE(recv_buf), + sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0); + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &icmp, sizeof(icmp)), 0); + + // We should also receive the automatically generated echo reply. + ASSERT_NO_FATAL_FAILURE(receiveICMP(recv_buf, ABSL_ARRAYSIZE(recv_buf), + sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0); + struct icmphdr *reply_icmp = + (struct icmphdr *)(recv_buf + sizeof(struct iphdr)); + // Most fields should be the same. + EXPECT_EQ(reply_icmp->code, icmp.code); + EXPECT_EQ(reply_icmp->un.echo.sequence, icmp.un.echo.sequence); + EXPECT_EQ(reply_icmp->un.echo.id, icmp.un.echo.id); + // A couple are different. + EXPECT_EQ(reply_icmp->type, ICMP_ECHOREPLY); + // The checksum is computed in such a way that it is guaranteed to have + // changed. + EXPECT_NE(reply_icmp->checksum, icmp.checksum); +} + +// We should be able to create multiple raw sockets for the same protocol and +// receive the same packet on both. +TEST_F(RawSocketTest, MultipleSocketReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + FileDescriptor s2 = + ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = *(unsigned short *)&icmp.checksum; + icmp.un.echo.sequence = *(unsigned short *)&icmp.un.echo.sequence; + icmp.un.echo.id = *(unsigned short *)&icmp.un.echo.id; + ASSERT_NO_FATAL_FAILURE(sendEmptyICMP(&icmp)); + + // Receive it on socket 1. + char recv_buf1[512]; + struct sockaddr_in src; + ASSERT_NO_FATAL_FAILURE(receiveICMP(recv_buf1, ABSL_ARRAYSIZE(recv_buf1), + sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0); + + // Receive it on socket 2. + char recv_buf2[512]; + ASSERT_NO_FATAL_FAILURE(receiveICMPFrom(recv_buf2, ABSL_ARRAYSIZE(recv_buf2), + sizeof(struct icmphdr), &src, + s2.get())); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0); + + EXPECT_EQ(memcmp(recv_buf1 + sizeof(struct iphdr), + recv_buf2 + sizeof(struct iphdr), sizeof(icmp)), + 0); +} + +// A raw ICMP socket and ping socket should both receive the ICMP packets +// indended for the ping socket. +TEST_F(RawSocketTest, RawAndPingSockets) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + FileDescriptor ping_sock = + ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)); + + // Ping sockets take care of the ICMP ID and checksum. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.un.echo.sequence = *(unsigned short *)&icmp.un.echo.sequence; + ASSERT_THAT(RetryEINTR(sendto)(ping_sock.get(), &icmp, sizeof(icmp), 0, + (struct sockaddr *)&addr_, sizeof(addr_)), + SyscallSucceedsWithValue(sizeof(icmp))); + + // Receive the packet via raw socket. + char recv_buf[512]; + struct sockaddr_in src; + ASSERT_NO_FATAL_FAILURE(receiveICMP(recv_buf, ABSL_ARRAYSIZE(recv_buf), + sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0); + + // Receive the packet via ping socket. + struct icmphdr ping_header; + ASSERT_THAT( + RetryEINTR(recv)(ping_sock.get(), &ping_header, sizeof(ping_header), 0), + SyscallSucceedsWithValue(sizeof(ping_header))); + + // Packets should be the same. + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &ping_header, + sizeof(struct icmphdr)), + 0); +} + +void RawSocketTest::sendEmptyICMP(struct icmphdr *icmp) { + ASSERT_NO_FATAL_FAILURE(sendEmptyICMPTo(s_, &addr_, icmp)); +} + +void RawSocketTest::sendEmptyICMPTo(int sock, struct sockaddr_in *addr, + struct icmphdr *icmp) { + struct iovec iov = {.iov_base = icmp, .iov_len = sizeof(*icmp)}; + struct msghdr msg { + .msg_name = addr, .msg_namelen = sizeof(*addr), .msg_iov = &iov, + .msg_iovlen = 1, .msg_control = NULL, .msg_controllen = 0, .msg_flags = 0, + }; + ASSERT_THAT(sendmsg(sock, &msg, 0), SyscallSucceedsWithValue(sizeof(*icmp))); +} + +void RawSocketTest::receiveICMP(char *recv_buf, size_t recv_buf_len, + size_t expected_size, struct sockaddr_in *src) { + ASSERT_NO_FATAL_FAILURE( + receiveICMPFrom(recv_buf, recv_buf_len, expected_size, src, s_)); +} + +void RawSocketTest::receiveICMPFrom(char *recv_buf, size_t recv_buf_len, + size_t expected_size, + struct sockaddr_in *src, int sock) { + struct iovec iov = {.iov_base = recv_buf, .iov_len = recv_buf_len}; + struct msghdr msg = { + .msg_name = src, + .msg_namelen = sizeof(*src), + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = NULL, + .msg_controllen = 0, + .msg_flags = 0, + }; + // We should receive the ICMP packet plus 20 bytes of IP header. + ASSERT_THAT(recvmsg(sock, &msg, 0), + SyscallSucceedsWithValue(expected_size + sizeof(struct iphdr))); +} + +} // namespace + +} // namespace testing +} // namespace gvisor -- cgit v1.2.3 From 383078688353feb4ae3714aa4b1d79aea519f7a4 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 28 Feb 2019 14:37:42 -0800 Subject: Map IPv{4,6} addresses to ethernet addresses ...in accordance with RFCs 1112 and 2464. Fixes IPv4 multicast when IP_MULTICAST_IF is specified. Don't return ErrNoRoute when no route is needed. Don't set Route.NextHop when no route is needed. PiperOrigin-RevId: 236199813 Change-Id: I48ed33e1b7f760deaa37e18ad7f1b8b62819ab43 --- pkg/tcpip/network/arp/arp.go | 20 ++++++++++++++- pkg/tcpip/network/ipv6/icmp.go | 19 ++++++++++++++ pkg/tcpip/stack/stack.go | 56 +++++++++++++++++------------------------- pkg/tcpip/stack/stack_test.go | 24 ++++++++++-------- 4 files changed, 75 insertions(+), 44 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 2e0024925..ed39640c1 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -160,9 +160,27 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. // ResolveStaticAddress implements stack.LinkAddressResolver. func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) { - if addr == "\xff\xff\xff\xff" { + if addr == header.IPv4Broadcast { return broadcastMAC, true } + if header.IsV4MulticastAddress(addr) { + // RFC 1112 Host Extensions for IP Multicasting + // + // 6.4. Extensions to an Ethernet Local Network Module: + // + // An IP host group address is mapped to an Ethernet multicast + // address by placing the low-order 23-bits of the IP address + // into the low-order 23 bits of the Ethernet multicast address + // 01-00-5E-00-00-00 (hex). + return tcpip.LinkAddress([]byte{ + 0x01, + 0x00, + 0x5e, + addr[header.IPv4AddressSize-3] & 0x7f, + addr[header.IPv4AddressSize-2], + addr[header.IPv4AddressSize-1], + }), true + } return "", false } diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 5a3c17768..e43253d3e 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -206,6 +206,25 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. // ResolveStaticAddress implements stack.LinkAddressResolver. func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) { + if header.IsV6MulticastAddress(addr) { + // RFC 2464 Transmission of IPv6 Packets over Ethernet Networks + // + // 7. Address Mapping -- Multicast + // + // An IPv6 packet with a multicast destination address DST, + // consisting of the sixteen octets DST[1] through DST[16], is + // transmitted to the Ethernet multicast address whose first + // two octets are the value 3333 hexadecimal and whose last + // four octets are the last four octets of DST. + return tcpip.LinkAddress([]byte{ + 0x33, + 0x33, + addr[header.IPv6AddressSize-4], + addr[header.IPv6AddressSize-3], + addr[header.IPv6AddressSize-2], + addr[header.IPv6AddressSize-1], + }), true + } return "", false } diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 797489ad9..cfda7ec3c 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -752,49 +752,39 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n s.mu.RLock() defer s.mu.RUnlock() - // We don't require a route in the table to send a broadcast, multicast or - // IPv6 link-local packet out on a NIC. isBroadcast := remoteAddr == header.IPv4Broadcast isMulticast := header.IsV4MulticastAddress(remoteAddr) || header.IsV6MulticastAddress(remoteAddr) - if id != 0 && (isBroadcast || isMulticast || header.IsV6LinkLocalAddress(remoteAddr)) { + needRoute := !(isBroadcast || isMulticast || header.IsV6LinkLocalAddress(remoteAddr)) + if id != 0 && !needRoute { if nic, ok := s.nics[id]; ok { if ref := s.getRefEP(nic, localAddr, netProto); ref != nil { return makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref), nil } } - return Route{}, tcpip.ErrNoRoute - } - - // TODO: Route multicast packets with no specified local - // address or NIC. - - for i := range s.routeTable { - if (id != 0 && id != s.routeTable[i].NIC) || (len(remoteAddr) != 0 && !s.routeTable[i].Match(remoteAddr)) { - continue - } - - nic := s.nics[s.routeTable[i].NIC] - if nic == nil { - continue - } - - ref := s.getRefEP(nic, localAddr, netProto) - if ref == nil { - continue - } - - if len(remoteAddr) == 0 { - // If no remote address was provided, then the route - // provided will refer to the link local address. - remoteAddr = ref.ep.ID().LocalAddress + } else { + for _, route := range s.routeTable { + if (id != 0 && id != route.NIC) || (len(remoteAddr) != 0 && !route.Match(remoteAddr)) { + continue + } + if nic, ok := s.nics[route.NIC]; ok { + if ref := s.getRefEP(nic, localAddr, netProto); ref != nil { + if len(remoteAddr) == 0 { + // If no remote address was provided, then the route + // provided will refer to the link local address. + remoteAddr = ref.ep.ID().LocalAddress + } + + r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref) + if needRoute { + r.NextHop = route.Gateway + } + return r, nil + } + } } - - r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref) - r.NextHop = s.routeTable[i].Gateway - return r, nil } - if isMulticast { + if !needRoute { return Route{}, tcpip.ErrNetworkUnreachable } diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index 28743f3d5..aba1e984c 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -654,8 +654,8 @@ func TestBroadcastNeedsNoRoute(t *testing.T) { s.SetRouteTable([]tcpip.Route{}) // If there is no endpoint, it won't work. - if _, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber); err != tcpip.ErrNoRoute { - t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, tcpip.ErrNoRoute) + if _, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber); err != tcpip.ErrNetworkUnreachable { + t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, tcpip.ErrNetworkUnreachable) } if err := s.AddAddress(1, fakeNetNumber, header.IPv4Any); err != nil { @@ -675,8 +675,8 @@ func TestBroadcastNeedsNoRoute(t *testing.T) { } // If the NIC doesn't exist, it won't work. - if _, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber); err != tcpip.ErrNoRoute { - t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, tcpip.ErrNoRoute) + if _, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber); err != tcpip.ErrNetworkUnreachable { + t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, tcpip.ErrNetworkUnreachable) } } @@ -732,17 +732,21 @@ func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) { anyAddr = header.IPv6Any } + want := tcpip.ErrNetworkUnreachable + if tc.routeNeeded { + want = tcpip.ErrNoRoute + } + // If there is no endpoint, it won't work. - if _, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber); err != tcpip.ErrNoRoute { - t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute) + if _, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber); err != want { + t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, want) } if err := s.AddAddress(1, fakeNetNumber, anyAddr); err != nil { t.Fatalf("AddAddress(%v, %v) failed: %v", fakeNetNumber, anyAddr, err) } - r, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber) - if tc.routeNeeded { + if r, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber); tc.routeNeeded { // Route table is empty but we need a route, this should cause an error. if err != tcpip.ErrNoRoute { t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute) @@ -759,8 +763,8 @@ func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) { } } // If the NIC doesn't exist, it won't work. - if _, err := s.FindRoute(2, anyAddr, tc.address, fakeNetNumber); err != tcpip.ErrNoRoute { - t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute) + if _, err := s.FindRoute(2, anyAddr, tc.address, fakeNetNumber); err != want { + t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", anyAddr, tc.address, fakeNetNumber, err, want) } }) } -- cgit v1.2.3 From 23e66ee96d159a774ecac9f89fab8cff463174a4 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Tue, 5 Mar 2019 14:52:35 -0800 Subject: Remove unused commit() function argument to Bind. PiperOrigin-RevId: 236926132 Change-Id: I5cf103f22766e6e65a581de780c7bb9ca0fa3181 --- pkg/dhcp/client.go | 2 +- pkg/dhcp/dhcp_test.go | 2 +- pkg/dhcp/server.go | 2 +- pkg/sentry/socket/epsocket/epsocket.go | 2 +- pkg/tcpip/adapters/gonet/gonet.go | 4 +-- pkg/tcpip/network/ipv4/ipv4_test.go | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 2 +- pkg/tcpip/stack/transport_test.go | 6 ++-- pkg/tcpip/tcpip.go | 6 +--- pkg/tcpip/transport/icmp/endpoint.go | 17 ++++-------- pkg/tcpip/transport/tcp/dual_stack_test.go | 24 ++++++++-------- pkg/tcpip/transport/tcp/endpoint.go | 10 +------ pkg/tcpip/transport/tcp/endpoint_state.go | 2 +- pkg/tcpip/transport/tcp/tcp_test.go | 32 +++++++++++----------- pkg/tcpip/transport/tcp/testing/context/context.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 16 +++-------- pkg/tcpip/transport/udp/udp_test.go | 28 +++++++++---------- 18 files changed, 67 insertions(+), 94 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index fb3ae5b49..354205e63 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -140,7 +140,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg Addr: tcpipHeader.IPv4Any, Port: ClientPort, NIC: c.nicid, - }, nil); err != nil { + }); err != nil { return Config{}, fmt.Errorf("dhcp: Bind(): %s", err) } diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index 026064394..e1d8ef603 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -284,7 +284,7 @@ func TestTwoServers(t *testing.T) { if err != nil { t.Fatalf("dhcp: server endpoint: %v", err) } - if err = ep.Bind(tcpip.FullAddress{Port: ServerPort}, nil); err != nil { + if err = ep.Bind(tcpip.FullAddress{Port: ServerPort}); err != nil { t.Fatalf("dhcp: server bind: %v", err) } if err = ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil { diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index c72c3b70d..9549ff705 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -120,7 +120,7 @@ func newEPConnServer(ctx context.Context, stack *stack.Stack, addrs []tcpip.Addr if err != nil { return nil, fmt.Errorf("dhcp: server endpoint: %v", err) } - if err := ep.Bind(tcpip.FullAddress{Port: ServerPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: ServerPort}); err != nil { return nil, fmt.Errorf("dhcp: server bind: %v", err) } if err := ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil { diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 8aec97e72..8fa108bea 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -423,7 +423,7 @@ func (s *SocketOperations) Bind(t *kernel.Task, sockaddr []byte) *syserr.Error { } // Issue the bind request to the endpoint. - return syserr.TranslateNetstackError(s.Endpoint.Bind(addr, nil)) + return syserr.TranslateNetstackError(s.Endpoint.Bind(addr)) } // Listen implements the linux syscall listen(2) for sockets backed by diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index 8b077156c..560b8ac4b 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -60,7 +60,7 @@ func NewListener(s *stack.Stack, addr tcpip.FullAddress, network tcpip.NetworkPr return nil, errors.New(err.String()) } - if err := ep.Bind(addr, nil); err != nil { + if err := ep.Bind(addr); err != nil { ep.Close() return nil, &net.OpError{ Op: "bind", @@ -524,7 +524,7 @@ func NewPacketConn(s *stack.Stack, addr tcpip.FullAddress, network tcpip.Network return nil, errors.New(err.String()) } - if err := ep.Bind(addr, nil); err != nil { + if err := ep.Bind(addr); err != nil { ep.Close() return nil, &net.OpError{ Op: "bind", diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go index 190d548eb..42e85564e 100644 --- a/pkg/tcpip/network/ipv4/ipv4_test.go +++ b/pkg/tcpip/network/ipv4/ipv4_test.go @@ -69,7 +69,7 @@ func TestExcludeBroadcast(t *testing.T) { } // However, we can bind to a broadcast address to listen. - if err := ep.Bind(tcpip.FullAddress{Addr: header.IPv4Broadcast, Port: 53, NIC: 1}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Addr: header.IPv4Broadcast, Port: 53, NIC: 1}); err != nil { t.Errorf("Bind failed: %v", err) } }) diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index 67e8f0b9e..327a79f48 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -165,7 +165,7 @@ func main() { // Bind if a port is specified. if localPort != 0 { - if err := ep.Bind(tcpip.FullAddress{0, "", localPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{0, "", localPort}); err != nil { log.Fatal("Bind failed: ", err) } } diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index ab40e9e0b..b23dc13e7 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -165,7 +165,7 @@ func main() { defer ep.Close() - if err := ep.Bind(tcpip.FullAddress{0, "", uint16(localPort)}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{0, "", uint16(localPort)}); err != nil { log.Fatal("Bind failed: ", err) } diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 3347b5599..a9e844e3d 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -145,7 +145,7 @@ func (f *fakeTransportEndpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip. return &a, nil, nil } -func (f *fakeTransportEndpoint) Bind(a tcpip.FullAddress, commit func() *tcpip.Error) *tcpip.Error { +func (f *fakeTransportEndpoint) Bind(a tcpip.FullAddress) *tcpip.Error { if err := f.stack.RegisterTransportEndpoint( a.NIC, []tcpip.NetworkProtocolNumber{fakeNetNumber}, @@ -157,7 +157,7 @@ func (f *fakeTransportEndpoint) Bind(a tcpip.FullAddress, commit func() *tcpip.E return err } f.acceptQueue = []fakeTransportEndpoint{} - return commit() + return nil } func (*fakeTransportEndpoint) GetLocalAddress() (tcpip.FullAddress, *tcpip.Error) { @@ -483,7 +483,7 @@ func TestTransportForwarding(t *testing.T) { t.Fatalf("NewEndpoint failed: %v", err) } - if err := ep.Bind(tcpip.FullAddress{Addr: "\x01", NIC: 1}, func() *tcpip.Error { return nil }); err != nil { + if err := ep.Bind(tcpip.FullAddress{Addr: "\x01", NIC: 1}); err != nil { t.Fatalf("Bind failed: %v", err) } diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 89e9d6741..49cc8705a 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -356,11 +356,7 @@ type Endpoint interface { // Bind binds the endpoint to a specific local address and port. // Specifying a NIC is optional. - // - // An optional commit function will be executed atomically with respect - // to binding the endpoint. If this returns an error, the bind will not - // occur and the error will be propagated back to the caller. - Bind(address FullAddress, commit func() *Error) *Error + Bind(address FullAddress) *Error // GetLocalAddress returns the address to which the endpoint is bound. GetLocalAddress() (FullAddress, *Error) diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index b3b7a1d0e..05c4b532a 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -100,7 +100,7 @@ func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, trans // Raw endpoints must be immediately bound because they receive all // ICMP traffic starting from when they're created via socket(). if raw { - if err := e.bindLocked(tcpip.FullAddress{}, nil); err != nil { + if err := e.bindLocked(tcpip.FullAddress{}); err != nil { return nil, err } } @@ -202,7 +202,7 @@ func (e *endpoint) prepareForWrite(to *tcpip.FullAddress) (retry bool, err *tcpi } // The state is still 'initial', so try to bind the endpoint. - if err := e.bindLocked(tcpip.FullAddress{}, nil); err != nil { + if err := e.bindLocked(tcpip.FullAddress{}); err != nil { return false, err } @@ -576,7 +576,7 @@ func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.Networ return id, err } -func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error) *tcpip.Error { +func (e *endpoint) bindLocked(addr tcpip.FullAddress) *tcpip.Error { // Don't allow binding once endpoint is not in the initial state // anymore. if e.state != stateInitial { @@ -608,13 +608,6 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error if err != nil { return err } - if commit != nil { - if err := commit(); err != nil { - // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, e.transProto, id, e) - return err - } - } e.id = id e.regNICID = addr.NIC @@ -631,11 +624,11 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error // Bind binds the endpoint to a specific local address and port. // Specifying a NIC is optional. -func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) *tcpip.Error { +func (e *endpoint) Bind(addr tcpip.FullAddress) *tcpip.Error { e.mu.Lock() defer e.mu.Unlock() - err := e.bindLocked(addr, commit) + err := e.bindLocked(addr) if err != nil { return err } diff --git a/pkg/tcpip/transport/tcp/dual_stack_test.go b/pkg/tcpip/transport/tcp/dual_stack_test.go index d3120c1d8..52f20bef1 100644 --- a/pkg/tcpip/transport/tcp/dual_stack_test.go +++ b/pkg/tcpip/transport/tcp/dual_stack_test.go @@ -113,7 +113,7 @@ func TestV4ConnectWhenBoundToWildcard(t *testing.T) { c.CreateV6Endpoint(false) // Bind to wildcard. - if err := c.EP.Bind(tcpip.FullAddress{}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -128,7 +128,7 @@ func TestV4ConnectWhenBoundToV4MappedWildcard(t *testing.T) { c.CreateV6Endpoint(false) // Bind to v4 mapped wildcard. - if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -143,7 +143,7 @@ func TestV4ConnectWhenBoundToV4Mapped(t *testing.T) { c.CreateV6Endpoint(false) // Bind to v4 mapped address. - if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -233,7 +233,7 @@ func TestV6ConnectWhenBoundToWildcard(t *testing.T) { c.CreateV6Endpoint(false) // Bind to wildcard. - if err := c.EP.Bind(tcpip.FullAddress{}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -248,7 +248,7 @@ func TestV6ConnectWhenBoundToLocalAddress(t *testing.T) { c.CreateV6Endpoint(false) // Bind to local address. - if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV6Addr}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV6Addr}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -263,7 +263,7 @@ func TestV4RefuseOnV6Only(t *testing.T) { c.CreateV6Endpoint(true) // Bind to wildcard. - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -300,7 +300,7 @@ func TestV6RefuseOnBoundToV4Mapped(t *testing.T) { c.CreateV6Endpoint(false) // Bind and listen. - if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -415,7 +415,7 @@ func TestV4AcceptOnV6(t *testing.T) { c.CreateV6Endpoint(false) // Bind to wildcard. - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -430,7 +430,7 @@ func TestV4AcceptOnBoundToV4MappedWildcard(t *testing.T) { c.CreateV6Endpoint(false) // Bind to v4 mapped wildcard. - if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -445,7 +445,7 @@ func TestV4AcceptOnBoundToV4Mapped(t *testing.T) { c.CreateV6Endpoint(false) // Bind and listen. - if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr, Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr, Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -460,7 +460,7 @@ func TestV6AcceptOnV6(t *testing.T) { c.CreateV6Endpoint(false) // Bind and listen. - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -551,7 +551,7 @@ func TestV4AcceptOnV4(t *testing.T) { } // Bind to wildcard. - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index c48a27d8f..ae99f0f8e 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1336,7 +1336,7 @@ func (e *endpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) { } // Bind binds the endpoint to a specific local port and optionally address. -func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) (err *tcpip.Error) { +func (e *endpoint) Bind(addr tcpip.FullAddress) (err *tcpip.Error) { e.mu.Lock() defer e.mu.Unlock() @@ -1397,14 +1397,6 @@ func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) (err e.id.LocalAddress = addr.Addr } - // Check the commit function. - if commit != nil { - if err := commit(); err != nil { - // The defer takes care of unwind. - return err - } - } - // Mark endpoint as bound. e.state = stateBound diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index ca7852d04..87e988afa 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -185,7 +185,7 @@ func (e *endpoint) afterLoad() { if len(e.bindAddress) == 0 { e.bindAddress = e.id.LocalAddress } - if err := e.Bind(tcpip.FullAddress{Addr: e.bindAddress, Port: e.id.LocalPort}, nil); err != nil { + if err := e.Bind(tcpip.FullAddress{Addr: e.bindAddress, Port: e.id.LocalPort}); err != nil { panic("endpoint binding failed: " + err.String()) } } diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index 557cc258d..2011189b7 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -135,7 +135,7 @@ func TestPassiveConnectionAttemptIncrement(t *testing.T) { t.Fatalf("NewEndpoint failed: %v", err) } - if err := ep.Bind(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Addr: context.StackAddr, Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } if err := ep.Listen(1); err != nil { @@ -193,7 +193,7 @@ func TestTCPResetsSentIncrement(t *testing.T) { } want := stats.TCP.SegmentsSent.Value() + 1 - if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -1042,7 +1042,7 @@ func TestScaledWindowAccept(t *testing.T) { t.Fatalf("SetSockOpt failed failed: %v", err) } - if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -1115,7 +1115,7 @@ func TestNonScaledWindowAccept(t *testing.T) { t.Fatalf("SetSockOpt failed failed: %v", err) } - if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -1618,7 +1618,7 @@ func TestPassiveSendMSSLessThanMTU(t *testing.T) { t.Fatalf("SetSockOpt failed failed: %v", err) } - if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -1675,7 +1675,7 @@ func TestSynCookiePassiveSendMSSLessThanMTU(t *testing.T) { } defer ep.Close() - if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -1840,7 +1840,7 @@ func TestCloseListener(t *testing.T) { t.Fatalf("NewEndpoint failed: %v", err) } - if err := ep.Bind(tcpip.FullAddress{}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -2824,7 +2824,7 @@ func TestUpdateListenBacklog(t *testing.T) { t.Fatalf("NewEndpoint failed: %v", err) } - if err := ep.Bind(tcpip.FullAddress{}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -3096,7 +3096,7 @@ func TestReusePort(t *testing.T) { if err != nil { t.Fatalf("NewEndpoint failed; %v", err) } - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -3105,7 +3105,7 @@ func TestReusePort(t *testing.T) { if err != nil { t.Fatalf("NewEndpoint failed; %v", err) } - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } c.EP.Close() @@ -3115,7 +3115,7 @@ func TestReusePort(t *testing.T) { if err != nil { t.Fatalf("NewEndpoint failed; %v", err) } - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } if err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort}); err != tcpip.ErrConnectStarted { @@ -3127,7 +3127,7 @@ func TestReusePort(t *testing.T) { if err != nil { t.Fatalf("NewEndpoint failed; %v", err) } - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } c.EP.Close() @@ -3137,7 +3137,7 @@ func TestReusePort(t *testing.T) { if err != nil { t.Fatalf("NewEndpoint failed; %v", err) } - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } if err := c.EP.Listen(10); err != nil { @@ -3149,7 +3149,7 @@ func TestReusePort(t *testing.T) { if err != nil { t.Fatalf("NewEndpoint failed; %v", err) } - if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } if err := c.EP.Listen(10); err != nil { @@ -3337,7 +3337,7 @@ func TestSelfConnect(t *testing.T) { } defer ep.Close() - if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { t.Fatalf("Bind failed: %v", err) } @@ -3508,7 +3508,7 @@ func TestConnectAvoidsBoundPorts(t *testing.T) { } for i := ports.FirstEphemeral; i <= math.MaxUint16; i++ { - if makeEP(exhaustedNetwork).Bind(tcpip.FullAddress{Addr: address(t, exhaustedAddressType, isAny), Port: uint16(i)}, nil); err != nil { + if makeEP(exhaustedNetwork).Bind(tcpip.FullAddress{Addr: address(t, exhaustedAddressType, isAny), Port: uint16(i)}); err != nil { t.Fatalf("Bind(%d) failed: %v", i, err) } } diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 0695e8150..fb4ae4a1b 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -796,7 +796,7 @@ func (c *Context) AcceptWithOptions(wndScale int, synOptions header.TCPSynOption } defer ep.Close() - if err := ep.Bind(tcpip.FullAddress{Port: StackPort}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: StackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 44b9cdf6a..4108cb09c 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -247,7 +247,7 @@ func (e *endpoint) prepareForWrite(to *tcpip.FullAddress) (retry bool, err *tcpi } // The state is still 'initial', so try to bind the endpoint. - if err := e.bindLocked(tcpip.FullAddress{}, nil); err != nil { + if err := e.bindLocked(tcpip.FullAddress{}); err != nil { return false, err } @@ -806,7 +806,7 @@ func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.Networ return id, err } -func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error) *tcpip.Error { +func (e *endpoint) bindLocked(addr tcpip.FullAddress) *tcpip.Error { // Don't allow binding once endpoint is not in the initial state // anymore. if e.state != stateInitial { @@ -846,14 +846,6 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error if err != nil { return err } - if commit != nil { - if err := commit(); err != nil { - // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(nicid, netProtos, ProtocolNumber, id, e) - e.stack.ReleasePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort) - return err - } - } e.id = id e.regNICID = nicid @@ -871,11 +863,11 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error // Bind binds the endpoint to a specific local address and port. // Specifying a NIC is optional. -func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) *tcpip.Error { +func (e *endpoint) Bind(addr tcpip.FullAddress) *tcpip.Error { e.mu.Lock() defer e.mu.Unlock() - err := e.bindLocked(addr, commit) + err := e.bindLocked(addr) if err != nil { return err } diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 2a9cf4b57..884a76b04 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -289,7 +289,7 @@ func TestBindPortReuse(t *testing.T) { if err := eps[i].SetSockOpt(reusePortOpt); err != nil { c.t.Fatalf("SetSockOpt failed failed: %v", err) } - if err := eps[i].Bind(tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort}, nil); err != nil { + if err := eps[i].Bind(tcpip.FullAddress{Addr: stackV6Addr, Port: stackPort}); err != nil { t.Fatalf("ep.Bind(...) failed: %v", err) } } @@ -385,7 +385,7 @@ func TestBindEphemeralPort(t *testing.T) { c.createV6Endpoint(false) - if err := c.ep.Bind(tcpip.FullAddress{}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{}); err != nil { t.Fatalf("ep.Bind(...) failed: %v", err) } } @@ -412,7 +412,7 @@ func TestBindReservedPort(t *testing.T) { t.Fatalf("NewEndpoint failed: %v", err) } defer ep.Close() - if got, want := ep.Bind(addr, nil), tcpip.ErrPortInUse; got != want { + if got, want := ep.Bind(addr), tcpip.ErrPortInUse; got != want { t.Fatalf("got ep.Bind(...) = %v, want = %v", got, want) } } @@ -425,11 +425,11 @@ func TestBindReservedPort(t *testing.T) { defer ep.Close() // We can't bind ipv4-any on the port reserved by the connected endpoint // above, since the endpoint is dual-stack. - if got, want := ep.Bind(tcpip.FullAddress{Port: addr.Port}, nil), tcpip.ErrPortInUse; got != want { + if got, want := ep.Bind(tcpip.FullAddress{Port: addr.Port}), tcpip.ErrPortInUse; got != want { t.Fatalf("got ep.Bind(...) = %v, want = %v", got, want) } // We can bind an ipv4 address on this port, though. - if err := ep.Bind(tcpip.FullAddress{Addr: stackAddr, Port: addr.Port}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Addr: stackAddr, Port: addr.Port}); err != nil { t.Fatalf("ep.Bind(...) failed: %v", err) } }() @@ -443,7 +443,7 @@ func TestBindReservedPort(t *testing.T) { t.Fatalf("NewEndpoint failed: %v", err) } defer ep.Close() - if err := ep.Bind(tcpip.FullAddress{Port: addr.Port}, nil); err != nil { + if err := ep.Bind(tcpip.FullAddress{Port: addr.Port}); err != nil { t.Fatalf("ep.Bind(...) failed: %v", err) } }() @@ -456,7 +456,7 @@ func TestV4ReadOnV6(t *testing.T) { c.createV6Endpoint(false) // Bind to wildcard. - if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } @@ -471,7 +471,7 @@ func TestV4ReadOnBoundToV4MappedWildcard(t *testing.T) { c.createV6Endpoint(false) // Bind to v4 mapped wildcard. - if err := c.ep.Bind(tcpip.FullAddress{Addr: V4MappedWildcardAddr, Port: stackPort}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{Addr: V4MappedWildcardAddr, Port: stackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } @@ -486,7 +486,7 @@ func TestV4ReadOnBoundToV4Mapped(t *testing.T) { c.createV6Endpoint(false) // Bind to local address. - if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } @@ -501,7 +501,7 @@ func TestV6ReadOnV6(t *testing.T) { c.createV6Endpoint(false) // Bind to wildcard. - if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } @@ -556,7 +556,7 @@ func TestV4ReadOnV4(t *testing.T) { } // Bind to wildcard. - if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } @@ -650,7 +650,7 @@ func TestDualWriteBoundToWildcard(t *testing.T) { c.createV6Endpoint(false) // Bind to wildcard. - if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } @@ -729,7 +729,7 @@ func TestV6WriteOnBoundToV4Mapped(t *testing.T) { c.createV6Endpoint(false) // Bind to v4 mapped address. - if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{Addr: stackV4MappedAddr, Port: stackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } @@ -827,7 +827,7 @@ func TestReadIncrementsPacketsReceived(t *testing.T) { } // Bind to wildcard. - if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}, nil); err != nil { + if err := c.ep.Bind(tcpip.FullAddress{Port: stackPort}); err != nil { c.t.Fatalf("Bind failed: %v", err) } -- cgit v1.2.3 From 56a61282953b46c8f8b707d5948a2d3958dced0c Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Fri, 8 Mar 2019 15:48:16 -0800 Subject: Implement IP_MULTICAST_LOOP. IP_MULTICAST_LOOP controls whether or not multicast packets sent on the default route are looped back. In order to implement this switch, support for sending and looping back multicast packets on the default route had to be implemented. For now we only support IPv4 multicast. PiperOrigin-RevId: 237534603 Change-Id: I490ac7ff8e8ebef417c7eb049a919c29d156ac1c --- pkg/sentry/socket/epsocket/epsocket.go | 37 +- pkg/syserr/netstack.go | 2 + pkg/tcpip/network/arp/arp.go | 2 +- pkg/tcpip/network/ip_test.go | 8 +- pkg/tcpip/network/ipv4/ipv4.go | 15 +- pkg/tcpip/network/ipv6/icmp_test.go | 2 +- pkg/tcpip/network/ipv6/ipv6.go | 15 +- pkg/tcpip/stack/nic.go | 18 +- pkg/tcpip/stack/registration.go | 14 +- pkg/tcpip/stack/route.go | 12 +- pkg/tcpip/stack/stack.go | 24 +- pkg/tcpip/stack/stack_test.go | 40 +- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/tcpip.go | 5 + pkg/tcpip/transport/icmp/endpoint.go | 4 +- pkg/tcpip/transport/icmp/endpoint_state.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 2 +- pkg/tcpip/transport/tcp/endpoint_state.go | 1 + pkg/tcpip/transport/udp/BUILD | 1 + pkg/tcpip/transport/udp/endpoint.go | 43 +- pkg/tcpip/transport/udp/endpoint_state.go | 2 +- runsc/boot/network.go | 16 +- test/syscalls/linux/socket_ipv4_udp_unbound.cc | 451 +++++++++++++++++++-- .../socket_ipv4_udp_unbound_external_networking.cc | 332 +++++++++++++++ 24 files changed, 946 insertions(+), 104 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 4e547ea33..f7636e056 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -911,6 +911,21 @@ func getSockOptIP(t *kernel.Task, ep commonEndpoint, name, outLen int) (interfac } return rv.InetMulticastRequest, nil + case linux.IP_MULTICAST_LOOP: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + + var v tcpip.MulticastLoopOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + if v { + return int32(1), nil + } + return int32(0), nil + default: emitUnimplementedEventIP(t, name) } @@ -1178,6 +1193,15 @@ func copyInMulticastRequest(optVal []byte) (linux.InetMulticastRequestWithNIC, * return req, nil } +// reduceToByte ORs all of the bytes in the input. +func reduceToByte(buf []byte) byte { + var out byte + for _, b := range buf { + out |= b + } + return out +} + // setSockOptIP implements SetSockOpt when level is SOL_IP. func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *syserr.Error { switch name { @@ -1235,6 +1259,18 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s InterfaceAddr: bytesToIPAddress(req.InterfaceAddr[:]), })) + case linux.IP_MULTICAST_LOOP: + if len(optVal) < 1 { + return syserr.ErrInvalidArgument + } + if len(optVal) > sizeOfInt32 { + optVal = optVal[:sizeOfInt32] + } + + return syserr.TranslateNetstackError(ep.SetSockOpt( + tcpip.MulticastLoopOption(reduceToByte(optVal) != 0), + )) + case linux.MCAST_JOIN_GROUP: // FIXME: Implement MCAST_JOIN_GROUP. t.Kernel().EmitUnimplementedEvent(t) @@ -1252,7 +1288,6 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s linux.IP_MSFILTER, linux.IP_MTU_DISCOVER, linux.IP_MULTICAST_ALL, - linux.IP_MULTICAST_LOOP, linux.IP_NODEFRAG, linux.IP_OPTIONS, linux.IP_PASSSEC, diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go index 05ca475d1..c5a628c7d 100644 --- a/pkg/syserr/netstack.go +++ b/pkg/syserr/netstack.go @@ -23,6 +23,7 @@ import ( var ( ErrUnknownProtocol = New(tcpip.ErrUnknownProtocol.String(), linux.EINVAL) ErrUnknownNICID = New(tcpip.ErrUnknownNICID.String(), linux.EINVAL) + ErrUnknownDevice = New(tcpip.ErrUnknownDevice.String(), linux.ENODEV) ErrUnknownProtocolOption = New(tcpip.ErrUnknownProtocolOption.String(), linux.ENOPROTOOPT) ErrDuplicateNICID = New(tcpip.ErrDuplicateNICID.String(), linux.EEXIST) ErrDuplicateAddress = New(tcpip.ErrDuplicateAddress.String(), linux.EEXIST) @@ -49,6 +50,7 @@ var ( var netstackErrorTranslations = map[*tcpip.Error]*Error{ tcpip.ErrUnknownProtocol: ErrUnknownProtocol, tcpip.ErrUnknownNICID: ErrUnknownNICID, + tcpip.ErrUnknownDevice: ErrUnknownDevice, tcpip.ErrUnknownProtocolOption: ErrUnknownProtocolOption, tcpip.ErrDuplicateNICID: ErrDuplicateNICID, tcpip.ErrDuplicateAddress: ErrDuplicateAddress, diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index ed39640c1..5ab542f2c 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -79,7 +79,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { func (e *endpoint) Close() {} -func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { +func (e *endpoint) WritePacket(*stack.Route, buffer.Prependable, buffer.VectorisedView, tcpip.TransportProtocolNumber, uint8, stack.PacketLooping) *tcpip.Error { return tcpip.ErrNotSupported } diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 97a43aece..7eb0e697d 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -177,7 +177,7 @@ func buildIPv4Route(local, remote tcpip.Address) (stack.Route, *tcpip.Error) { NIC: 1, }}) - return s.FindRoute(1, local, remote, ipv4.ProtocolNumber) + return s.FindRoute(1, local, remote, ipv4.ProtocolNumber, false /* multicastLoop */) } func buildIPv6Route(local, remote tcpip.Address) (stack.Route, *tcpip.Error) { @@ -191,7 +191,7 @@ func buildIPv6Route(local, remote tcpip.Address) (stack.Route, *tcpip.Error) { NIC: 1, }}) - return s.FindRoute(1, local, remote, ipv6.ProtocolNumber) + return s.FindRoute(1, local, remote, ipv6.ProtocolNumber, false /* multicastLoop */) } func TestIPv4Send(t *testing.T) { @@ -221,7 +221,7 @@ func TestIPv4Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - if err := ep.WritePacket(&r, hdr, payload.ToVectorisedView(), 123, 123); err != nil { + if err := ep.WritePacket(&r, hdr, payload.ToVectorisedView(), 123, 123, stack.PacketOut); err != nil { t.Fatalf("WritePacket failed: %v", err) } } @@ -450,7 +450,7 @@ func TestIPv6Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - if err := ep.WritePacket(&r, hdr, payload.ToVectorisedView(), 123, 123); err != nil { + if err := ep.WritePacket(&r, hdr, payload.ToVectorisedView(), 123, 123, stack.PacketOut); err != nil { t.Fatalf("WritePacket failed: %v", err) } } diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index bfc3c08fa..545684032 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -104,7 +104,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { } // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop stack.PacketLooping) *tcpip.Error { ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize)) length := uint16(hdr.UsedLength() + payload.Size()) id := uint32(0) @@ -123,8 +123,19 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b DstAddr: r.RemoteAddress, }) ip.SetChecksum(^ip.CalculateChecksum()) - r.Stats().IP.PacketsSent.Increment() + if loop&stack.PacketLoop != 0 { + views := make([]buffer.View, 1, 1+len(payload.Views())) + views[0] = hdr.View() + views = append(views, payload.Views()...) + vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) + e.HandlePacket(r, vv) + } + if loop&stack.PacketOut == 0 { + return nil + } + + r.Stats().IP.PacketsSent.Increment() return e.linkEP.WritePacket(r, hdr, payload, ProtocolNumber) } diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index 797176243..15574bab1 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -161,7 +161,7 @@ func (c *testContext) cleanup() { func TestLinkResolution(t *testing.T) { c := newTestContext(t) defer c.cleanup() - r, err := c.s0.FindRoute(1, lladdr0, lladdr1, ProtocolNumber) + r, err := c.s0.FindRoute(1, lladdr0, lladdr1, ProtocolNumber, false /* multicastLoop */) if err != nil { t.Fatal(err) } diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 5f68ef7d5..df3b64c98 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -84,7 +84,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { } // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop stack.PacketLooping) *tcpip.Error { length := uint16(hdr.UsedLength() + payload.Size()) ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) ip.Encode(&header.IPv6Fields{ @@ -94,8 +94,19 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b SrcAddr: r.LocalAddress, DstAddr: r.RemoteAddress, }) - r.Stats().IP.PacketsSent.Increment() + if loop&stack.PacketLoop != 0 { + views := make([]buffer.View, 1, 1+len(payload.Views())) + views[0] = hdr.View() + views = append(views, payload.Views()...) + vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) + e.HandlePacket(r, vv) + } + if loop&stack.PacketOut == 0 { + return nil + } + + r.Stats().IP.PacketsSent.Increment() return e.linkEP.WritePacket(r, hdr, payload, ProtocolNumber) } diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 79f845225..14267bb48 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -28,10 +28,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 + loopback bool demux *transportDemuxer @@ -62,12 +63,13 @@ const ( NeverPrimaryEndpoint ) -func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint) *NIC { +func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint, loopback bool) *NIC { return &NIC{ stack: stack, id: id, name: name, linkEP: ep, + loopback: loopback, demux: newTransportDemuxer(stack), primary: make(map[tcpip.NetworkProtocolNumber]*ilist.List), endpoints: make(map[NetworkEndpointID]*referencedNetworkEndpoint), @@ -407,7 +409,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr n.mu.RLock() for _, ref := range n.endpoints { if ref.protocol == header.IPv4ProtocolNumber && ref.tryIncRef() { - r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) + r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref, false /* multicastLoop */) r.RemoteLinkAddress = remote ref.ep.HandlePacket(&r, vv) ref.decRef() @@ -418,7 +420,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr } if ref := n.getRef(protocol, dst); ref != nil { - r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref) + r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref, false /* multicastLoop */) r.RemoteLinkAddress = remote ref.ep.HandlePacket(&r, vv) ref.decRef() @@ -430,7 +432,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr // // TODO: Should we be forwarding the packet even if promiscuous? if n.stack.Forwarding() { - r, err := n.stack.FindRoute(0, "", dst, protocol) + r, err := n.stack.FindRoute(0, "", dst, protocol, false /* multicastLoop */) if err != nil { n.stack.stats.IP.InvalidAddressesReceived.Increment() return diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 62acd5919..cf4d52fe9 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -125,6 +125,18 @@ type TransportDispatcher interface { DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv buffer.VectorisedView) } +// PacketLooping specifies where an outbound packet should be sent. +type PacketLooping byte + +const ( + // PacketOut indicates that the packet should be passed to the link + // endpoint. + PacketOut PacketLooping = 1 << iota + + // PacketLoop indicates that the packet should be handled locally. + PacketLoop +) + // NetworkEndpoint is the interface that needs to be implemented by endpoints // of network layer protocols (e.g., ipv4, ipv6). type NetworkEndpoint interface { @@ -149,7 +161,7 @@ type NetworkEndpoint interface { // WritePacket writes a packet to the given destination address and // protocol. - WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error + WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop PacketLooping) *tcpip.Error // ID returns the network protocol endpoint ID. ID() *NetworkEndpointID diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 2b4185014..c9603ad5e 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -46,17 +46,20 @@ type Route struct { // ref a reference to the network endpoint through which the route // starts. ref *referencedNetworkEndpoint + + multicastLoop bool } // makeRoute initializes a new route. It takes ownership of the provided // reference to a network endpoint. -func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, localLinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint) Route { +func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, localLinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint, multicastLoop bool) Route { return Route{ NetProto: netProto, LocalAddress: localAddr, LocalLinkAddress: localLinkAddr, RemoteAddress: remoteAddr, ref: ref, + multicastLoop: multicastLoop, } } @@ -134,7 +137,12 @@ func (r *Route) IsResolutionRequired() bool { // WritePacket writes the packet through the given route. func (r *Route) WritePacket(hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { - err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl) + loop := PacketOut + if r.multicastLoop && (header.IsV4MulticastAddress(r.RemoteAddress) || header.IsV6MulticastAddress(r.RemoteAddress)) { + loop |= PacketLoop + } + + err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl, loop) if err == tcpip.ErrNoRoute { r.Stats().IP.OutgoingPacketErrors.Increment() } diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index cfda7ec3c..047b704e0 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -513,7 +513,7 @@ func (s *Stack) NewRawEndpoint(transport tcpip.TransportProtocolNumber, network // createNIC creates a NIC with the provided id and link-layer endpoint, and // optionally enable it. -func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID, enabled bool) *tcpip.Error { +func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID, enabled, loopback bool) *tcpip.Error { ep := FindLinkEndpoint(linkEP) if ep == nil { return tcpip.ErrBadLinkEndpoint @@ -527,7 +527,7 @@ func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpoint return tcpip.ErrDuplicateNICID } - n := newNIC(s, id, name, ep) + n := newNIC(s, id, name, ep, loopback) s.nics[id] = n if enabled { @@ -539,26 +539,32 @@ func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpoint // CreateNIC creates a NIC with the provided id and link-layer endpoint. func (s *Stack) CreateNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error { - return s.createNIC(id, "", linkEP, true) + return s.createNIC(id, "", linkEP, true, false) } // CreateNamedNIC creates a NIC with the provided id and link-layer endpoint, // and a human-readable name. func (s *Stack) CreateNamedNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID) *tcpip.Error { - return s.createNIC(id, name, linkEP, true) + return s.createNIC(id, name, linkEP, true, false) +} + +// CreateNamedLoopbackNIC creates a NIC with the provided id and link-layer +// endpoint, and a human-readable name. +func (s *Stack) CreateNamedLoopbackNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID) *tcpip.Error { + return s.createNIC(id, name, linkEP, true, true) } // CreateDisabledNIC creates a NIC with the provided id and link-layer endpoint, // but leave it disable. Stack.EnableNIC must be called before the link-layer // endpoint starts delivering packets to it. func (s *Stack) CreateDisabledNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error { - return s.createNIC(id, "", linkEP, false) + return s.createNIC(id, "", linkEP, false, false) } // CreateDisabledNamedNIC is a combination of CreateNamedNIC and // CreateDisabledNIC. func (s *Stack) CreateDisabledNamedNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID) *tcpip.Error { - return s.createNIC(id, name, linkEP, false) + return s.createNIC(id, name, linkEP, false, false) } // EnableNIC enables the given NIC so that the link-layer endpoint can start @@ -748,7 +754,7 @@ func (s *Stack) getRefEP(nic *NIC, localAddr tcpip.Address, netProto tcpip.Netwo // FindRoute creates a route to the given destination address, leaving through // the given nic and local address (if provided). -func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber) (Route, *tcpip.Error) { +func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber, multicastLoop bool) (Route, *tcpip.Error) { s.mu.RLock() defer s.mu.RUnlock() @@ -758,7 +764,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n if id != 0 && !needRoute { if nic, ok := s.nics[id]; ok { if ref := s.getRefEP(nic, localAddr, netProto); ref != nil { - return makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref), nil + return makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref, multicastLoop && !nic.loopback), nil } } } else { @@ -774,7 +780,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n remoteAddr = ref.ep.ID().LocalAddress } - r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref) + r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref, multicastLoop && !nic.loopback) if needRoute { r.NextHop = route.Gateway } diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index aba1e984c..b366de21d 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -112,7 +112,7 @@ func (f *fakeNetworkEndpoint) Capabilities() stack.LinkEndpointCapabilities { return f.linkEP.Capabilities() } -func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, _ uint8) *tcpip.Error { +func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, _ uint8, loop stack.PacketLooping) *tcpip.Error { // Increment the sent packet count in the protocol descriptor. f.proto.sendPacketCount[int(r.RemoteAddress[0])%len(f.proto.sendPacketCount)]++ @@ -122,6 +122,18 @@ func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable b[0] = r.RemoteAddress[0] b[1] = f.id.LocalAddress[0] b[2] = byte(protocol) + + if loop&stack.PacketLoop != 0 { + views := make([]buffer.View, 1, 1+len(payload.Views())) + views[0] = hdr.View() + views = append(views, payload.Views()...) + vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) + f.HandlePacket(r, vv) + } + if loop&stack.PacketOut == 0 { + return nil + } + return f.linkEP.WritePacket(r, hdr, payload, fakeNetNumber) } @@ -262,7 +274,7 @@ func TestNetworkReceive(t *testing.T) { } func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address) { - r, err := s.FindRoute(0, "", addr, fakeNetNumber) + r, err := s.FindRoute(0, "", addr, fakeNetNumber, false /* multicastLoop */) if err != nil { t.Fatalf("FindRoute failed: %v", err) } @@ -354,7 +366,7 @@ func TestNetworkSendMultiRoute(t *testing.T) { } func testRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr, expectedSrcAddr tcpip.Address) { - r, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber) + r, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */) if err != nil { t.Fatalf("FindRoute failed: %v", err) } @@ -371,7 +383,7 @@ func testRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr, } func testNoRoute(t *testing.T, s *stack.Stack, nic tcpip.NICID, srcAddr, dstAddr tcpip.Address) { - _, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber) + _, err := s.FindRoute(nic, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */) if err != tcpip.ErrNoRoute { t.Fatalf("FindRoute returned unexpected error, expected tcpip.ErrNoRoute, got %v", err) } @@ -514,7 +526,7 @@ func TestDelayedRemovalDueToRoute(t *testing.T) { } // Get a route, check that packet is still deliverable. - r, err := s.FindRoute(0, "", "\x02", fakeNetNumber) + r, err := s.FindRoute(0, "", "\x02", fakeNetNumber, false /* multicastLoop */) if err != nil { t.Fatalf("FindRoute failed: %v", err) } @@ -584,7 +596,7 @@ func TestPromiscuousMode(t *testing.T) { } // Check that we can't get a route as there is no local address. - _, err := s.FindRoute(0, "", "\x02", fakeNetNumber) + _, err := s.FindRoute(0, "", "\x02", fakeNetNumber, false /* multicastLoop */) if err != tcpip.ErrNoRoute { t.Fatalf("FindRoute returned unexpected status: expected %v, got %v", tcpip.ErrNoRoute, err) } @@ -622,7 +634,7 @@ func TestAddressSpoofing(t *testing.T) { // With address spoofing disabled, FindRoute does not permit an address // that was not added to the NIC to be used as the source. - r, err := s.FindRoute(0, srcAddr, dstAddr, fakeNetNumber) + r, err := s.FindRoute(0, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */) if err == nil { t.Errorf("FindRoute succeeded with route %+v when it should have failed", r) } @@ -632,7 +644,7 @@ func TestAddressSpoofing(t *testing.T) { if err := s.SetSpoofing(1, true); err != nil { t.Fatalf("SetSpoofing failed: %v", err) } - r, err = s.FindRoute(0, srcAddr, dstAddr, fakeNetNumber) + r, err = s.FindRoute(0, srcAddr, dstAddr, fakeNetNumber, false /* multicastLoop */) if err != nil { t.Fatalf("FindRoute failed: %v", err) } @@ -654,14 +666,14 @@ func TestBroadcastNeedsNoRoute(t *testing.T) { s.SetRouteTable([]tcpip.Route{}) // If there is no endpoint, it won't work. - if _, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber); err != tcpip.ErrNetworkUnreachable { + if _, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */); err != tcpip.ErrNetworkUnreachable { t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, tcpip.ErrNetworkUnreachable) } if err := s.AddAddress(1, fakeNetNumber, header.IPv4Any); err != nil { t.Fatalf("AddAddress(%v, %v) failed: %v", fakeNetNumber, header.IPv4Any, err) } - r, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber) + r, err := s.FindRoute(1, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */) if err != nil { t.Fatalf("FindRoute(1, %v, %v, %v) failed: %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err) } @@ -675,7 +687,7 @@ func TestBroadcastNeedsNoRoute(t *testing.T) { } // If the NIC doesn't exist, it won't work. - if _, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber); err != tcpip.ErrNetworkUnreachable { + if _, err := s.FindRoute(2, header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, false /* multicastLoop */); err != tcpip.ErrNetworkUnreachable { t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", header.IPv4Any, header.IPv4Broadcast, fakeNetNumber, err, tcpip.ErrNetworkUnreachable) } } @@ -738,7 +750,7 @@ func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) { } // If there is no endpoint, it won't work. - if _, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber); err != want { + if _, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); err != want { t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, want) } @@ -746,7 +758,7 @@ func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) { t.Fatalf("AddAddress(%v, %v) failed: %v", fakeNetNumber, anyAddr, err) } - if r, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber); tc.routeNeeded { + if r, err := s.FindRoute(1, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); tc.routeNeeded { // Route table is empty but we need a route, this should cause an error. if err != tcpip.ErrNoRoute { t.Fatalf("got FindRoute(1, %v, %v, %v) = %v, want = %v", anyAddr, tc.address, fakeNetNumber, err, tcpip.ErrNoRoute) @@ -763,7 +775,7 @@ func TestMulticastOrIPv6LinkLocalNeedsNoRoute(t *testing.T) { } } // If the NIC doesn't exist, it won't work. - if _, err := s.FindRoute(2, anyAddr, tc.address, fakeNetNumber); err != want { + if _, err := s.FindRoute(2, anyAddr, tc.address, fakeNetNumber, false /* multicastLoop */); err != want { t.Fatalf("got FindRoute(2, %v, %v, %v) = %v want = %v", anyAddr, tc.address, fakeNetNumber, err, want) } }) diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index a9e844e3d..279ab3c56 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -103,7 +103,7 @@ func (f *fakeTransportEndpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { f.peerAddr = addr.Addr // Find the route. - r, err := f.stack.FindRoute(addr.NIC, "", addr.Addr, fakeNetNumber) + r, err := f.stack.FindRoute(addr.NIC, "", addr.Addr, fakeNetNumber, false /* multicastLoop */) if err != nil { return tcpip.ErrNoRoute } diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 7010d1b68..825854148 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -68,6 +68,7 @@ func (e *Error) IgnoreStats() bool { var ( ErrUnknownProtocol = &Error{msg: "unknown protocol"} ErrUnknownNICID = &Error{msg: "unknown nic id"} + ErrUnknownDevice = &Error{msg: "unknown device"} ErrUnknownProtocolOption = &Error{msg: "unknown option for protocol"} ErrDuplicateNICID = &Error{msg: "duplicate nic id"} ErrDuplicateAddress = &Error{msg: "duplicate address"} @@ -477,6 +478,10 @@ type MulticastInterfaceOption struct { InterfaceAddr Address } +// MulticastLoopOption is used by SetSockOpt/GetSockOpt to specify whether +// multicast packets sent over a non-loopback interface will be looped back. +type MulticastLoopOption bool + // MembershipOption is used by SetSockOpt/GetSockOpt as an argument to // AddMembershipOption and RemoveMembershipOption. type MembershipOption struct { diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index 05c4b532a..d876005fe 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -277,7 +277,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c } // Find the enpoint. - r, err := e.stack.FindRoute(nicid, e.bindAddr, to.Addr, netProto) + r, err := e.stack.FindRoute(nicid, e.bindAddr, to.Addr, netProto, false /* multicastLoop */) if err != nil { return 0, nil, err } @@ -471,7 +471,7 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { } // Find a route to the desired destination. - r, err := e.stack.FindRoute(nicid, e.bindAddr, addr.Addr, netProto) + r, err := e.stack.FindRoute(nicid, e.bindAddr, addr.Addr, netProto, false /* multicastLoop */) if err != nil { return err } diff --git a/pkg/tcpip/transport/icmp/endpoint_state.go b/pkg/tcpip/transport/icmp/endpoint_state.go index 21008d089..8a7909246 100644 --- a/pkg/tcpip/transport/icmp/endpoint_state.go +++ b/pkg/tcpip/transport/icmp/endpoint_state.go @@ -71,7 +71,7 @@ func (e *endpoint) afterLoad() { var err *tcpip.Error if e.state == stateConnected { - e.route, err = e.stack.FindRoute(e.regNICID, e.bindAddr, e.id.RemoteAddress, e.netProto) + e.route, err = e.stack.FindRoute(e.regNICID, e.bindAddr, e.id.RemoteAddress, e.netProto, false /* multicastLoop */) if err != nil { panic(*err) } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index ae99f0f8e..fc4f82402 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1091,7 +1091,7 @@ func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) (er } // Find a route to the desired destination. - r, err := e.stack.FindRoute(nicid, e.id.LocalAddress, addr.Addr, netProto) + r, err := e.stack.FindRoute(nicid, e.id.LocalAddress, addr.Addr, netProto, false /* multicastLoop */) if err != nil { return err } diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index 87e988afa..a42e09b8c 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -307,6 +307,7 @@ func loadError(s string) *tcpip.Error { var errors = []*tcpip.Error{ tcpip.ErrUnknownProtocol, tcpip.ErrUnknownNICID, + tcpip.ErrUnknownDevice, tcpip.ErrUnknownProtocolOption, tcpip.ErrDuplicateNICID, tcpip.ErrDuplicateAddress, diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 8ccb79c48..d271490c1 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -27,6 +27,7 @@ go_library( imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ + "//pkg/log", "//pkg/sleep", "//pkg/tcpip", "//pkg/tcpip/buffer", diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 4108cb09c..3693abae5 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -81,6 +81,7 @@ type endpoint struct { multicastTTL uint8 multicastAddr tcpip.Address multicastNICID tcpip.NICID + multicastLoop bool reusePort bool broadcast bool @@ -124,6 +125,7 @@ func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waite // // Linux defaults to TTL=1. multicastTTL: 1, + multicastLoop: true, rcvBufSizeMax: 32 * 1024, sndBufSize: 32 * 1024, } @@ -274,7 +276,7 @@ func (e *endpoint) connectRoute(nicid tcpip.NICID, addr tcpip.FullAddress) (stac } // Find a route to the desired destination. - r, err := e.stack.FindRoute(nicid, localAddr, addr.Addr, netProto) + r, err := e.stack.FindRoute(nicid, localAddr, addr.Addr, netProto, e.multicastLoop) if err != nil { return stack.Route{}, 0, 0, err } @@ -458,13 +460,19 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { case tcpip.AddMembershipOption: nicID := v.NIC - if v.InterfaceAddr != header.IPv4Any { + if v.InterfaceAddr == header.IPv4Any { + if nicID == 0 { + r, err := e.stack.FindRoute(0, "", v.MulticastAddr, header.IPv4ProtocolNumber, false /* multicastLoop */) + if err == nil { + nicID = r.NICID() + r.Release() + } + } + } else { nicID = e.stack.CheckLocalAddress(nicID, e.netProto, v.InterfaceAddr) } if nicID == 0 { - // TODO: Allow adding memberships without - // specifing an interface. - return tcpip.ErrNoRoute + return tcpip.ErrUnknownDevice } // TODO: check that v.MulticastAddr is a multicast address. @@ -479,11 +487,19 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { case tcpip.RemoveMembershipOption: nicID := v.NIC - if v.InterfaceAddr != header.IPv4Any { + if v.InterfaceAddr == header.IPv4Any { + if nicID == 0 { + r, err := e.stack.FindRoute(0, "", v.MulticastAddr, header.IPv4ProtocolNumber, false /* multicastLoop */) + if err == nil { + nicID = r.NICID() + r.Release() + } + } + } else { nicID = e.stack.CheckLocalAddress(nicID, e.netProto, v.InterfaceAddr) } if nicID == 0 { - return tcpip.ErrNoRoute + return tcpip.ErrUnknownDevice } // TODO: check that v.MulticastAddr is a multicast address. @@ -503,6 +519,11 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { } } + case tcpip.MulticastLoopOption: + e.mu.Lock() + e.multicastLoop = bool(v) + e.mu.Unlock() + case tcpip.ReusePortOption: e.mu.Lock() e.reusePort = v != 0 @@ -578,6 +599,14 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { e.mu.Unlock() return nil + case *tcpip.MulticastLoopOption: + e.mu.RLock() + v := e.multicastLoop + e.mu.RUnlock() + + *o = tcpip.MulticastLoopOption(v) + return nil + case *tcpip.ReusePortOption: e.mu.RLock() v := e.reusePort diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index 4d8210294..b2daaf751 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -82,7 +82,7 @@ func (e *endpoint) afterLoad() { var err *tcpip.Error if e.state == stateConnected { - e.route, err = e.stack.FindRoute(e.regNICID, e.id.LocalAddress, e.id.RemoteAddress, netProto) + e.route, err = e.stack.FindRoute(e.regNICID, e.id.LocalAddress, e.id.RemoteAddress, netProto, e.multicastLoop) if err != nil { panic(*err) } diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 0cadf48d6..40bc147ca 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -112,7 +112,7 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct linkEP := loopback.New() log.Infof("Enabling loopback interface %q with id %d on addresses %+v", link.Name, nicID, link.Addresses) - if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses); err != nil { + if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses, true /* loopback */); err != nil { return err } @@ -144,7 +144,7 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct }) log.Infof("Enabling interface %q with id %d on addresses %+v (%v)", link.Name, nicID, link.Addresses, mac) - if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses); err != nil { + if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses, false /* loopback */); err != nil { return err } @@ -169,9 +169,15 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct // createNICWithAddrs creates a NIC in the network stack and adds the given // addresses. -func (n *Network) createNICWithAddrs(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID, addrs []net.IP) error { - if err := n.Stack.CreateNamedNIC(id, name, sniffer.New(linkEP)); err != nil { - return fmt.Errorf("CreateNamedNIC(%v, %v, %v) failed: %v", id, name, linkEP, err) +func (n *Network) createNICWithAddrs(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID, addrs []net.IP, loopback bool) error { + if loopback { + if err := n.Stack.CreateNamedLoopbackNIC(id, name, sniffer.New(linkEP)); err != nil { + return fmt.Errorf("CreateNamedLoopbackNIC(%v, %v, %v) failed: %v", id, name, linkEP, err) + } + } else { + if err := n.Stack.CreateNamedNIC(id, name, sniffer.New(linkEP)); err != nil { + return fmt.Errorf("CreateNamedNIC(%v, %v, %v) failed: %v", id, name, linkEP, err) + } } // Always start with an arp address for the NIC. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc index 2d702179e..38bc85ce9 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc @@ -61,7 +61,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNoGroup) { receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -99,7 +99,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddrNoDefaultSendIf) { receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -134,12 +134,12 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNicNoDefaultSendIf) { // Bind the second FD to the v4 any address to ensure that we can receive any // unicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT(bind(sockets->second_fd(), + ASSERT_THAT(bind(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -174,7 +174,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddr) { // Bind the first FD to the loopback. This is an alternative to // IP_MULTICAST_IF for setting the default send interface. auto sender_addr = V4Loopback(); - EXPECT_THAT( + ASSERT_THAT( bind(sockets->first_fd(), reinterpret_cast(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); @@ -182,12 +182,12 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddr) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT(bind(sockets->second_fd(), + ASSERT_THAT(bind(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -197,7 +197,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddr) { ip_mreq group = {}; group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); - EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), SyscallSucceeds()); @@ -207,7 +207,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddr) { reinterpret_cast(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT( + ASSERT_THAT( RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, reinterpret_cast(&send_addr.addr), send_addr.addr_len), @@ -222,7 +222,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddr) { EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); } -// Check that multicast works when the default send interface is confgured by +// Check that multicast works when the default send interface is configured by // bind and the group membership is configured by NIC ID. TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -230,7 +230,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { // Bind the first FD to the loopback. This is an alternative to // IP_MULTICAST_IF for setting the default send interface. auto sender_addr = V4Loopback(); - EXPECT_THAT( + ASSERT_THAT( bind(sockets->first_fd(), reinterpret_cast(&sender_addr.addr), sender_addr.addr_len), SyscallSucceeds()); @@ -238,12 +238,12 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT(bind(sockets->second_fd(), + ASSERT_THAT(bind(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -253,7 +253,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { ip_mreqn group = {}; group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); - EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), SyscallSucceeds()); @@ -263,7 +263,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { reinterpret_cast(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT( + ASSERT_THAT( RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, reinterpret_cast(&send_addr.addr), send_addr.addr_len), @@ -278,7 +278,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); } -// Check that multicast works when the default send interface is confgured by +// Check that multicast works when the default send interface is configured by // IP_MULTICAST_IF, the send address is specified in sendto, and the group // membership is configured by address. TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddr) { @@ -287,19 +287,19 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddr) { // Set the default send interface. ip_mreq iface = {}; iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); - EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, &iface, sizeof(iface)), SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT(bind(sockets->second_fd(), + ASSERT_THAT(bind(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -309,7 +309,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddr) { ip_mreq group = {}; group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); - EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), SyscallSucceeds()); @@ -319,7 +319,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddr) { reinterpret_cast(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT( + ASSERT_THAT( RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, reinterpret_cast(&send_addr.addr), send_addr.addr_len), @@ -334,7 +334,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddr) { EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); } -// Check that multicast works when the default send interface is confgured by +// Check that multicast works when the default send interface is configured by // IP_MULTICAST_IF, the send address is specified in sendto, and the group // membership is configured by NIC ID. TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNic) { @@ -343,19 +343,19 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNic) { // Set the default send interface. ip_mreqn iface = {}; iface.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); - EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, &iface, sizeof(iface)), SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT(bind(sockets->second_fd(), + ASSERT_THAT(bind(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -365,7 +365,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNic) { ip_mreqn group = {}; group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); - EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), SyscallSucceeds()); @@ -375,7 +375,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNic) { reinterpret_cast(&receiver_addr.addr)->sin_port; char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT( + ASSERT_THAT( RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, reinterpret_cast(&send_addr.addr), send_addr.addr_len), @@ -390,7 +390,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNic) { EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); } -// Check that multicast works when the default send interface is confgured by +// Check that multicast works when the default send interface is configured by // IP_MULTICAST_IF, the send address is specified in connect, and the group // membership is configured by address. TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrConnect) { @@ -399,19 +399,19 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrConnect) { // Set the default send interface. ip_mreq iface = {}; iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); - EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, &iface, sizeof(iface)), SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT(bind(sockets->second_fd(), + ASSERT_THAT(bind(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -421,7 +421,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrConnect) { ip_mreq group = {}; group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); - EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), SyscallSucceeds()); @@ -429,7 +429,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrConnect) { auto connect_addr = V4Multicast(); reinterpret_cast(&connect_addr.addr)->sin_port = reinterpret_cast(&receiver_addr.addr)->sin_port; - EXPECT_THAT( + ASSERT_THAT( RetryEINTR(connect)(sockets->first_fd(), reinterpret_cast(&connect_addr.addr), connect_addr.addr_len), @@ -437,7 +437,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrConnect) { char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT( + ASSERT_THAT( RetryEINTR(send)(sockets->first_fd(), send_buf, sizeof(send_buf), 0), SyscallSucceedsWithValue(sizeof(send_buf))); @@ -450,7 +450,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrConnect) { EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); } -// Check that multicast works when the default send interface is confgured by +// Check that multicast works when the default send interface is configured by // IP_MULTICAST_IF, the send address is specified in connect, and the group // membership is configured by NIC ID. TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicConnect) { @@ -459,19 +459,19 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicConnect) { // Set the default send interface. ip_mreqn iface = {}; iface.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); - EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, &iface, sizeof(iface)), SyscallSucceeds()); // Bind the second FD to the v4 any address to ensure that we can receive the // multicast packet. auto receiver_addr = V4Any(); - EXPECT_THAT(bind(sockets->second_fd(), + ASSERT_THAT(bind(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), receiver_addr.addr_len), SyscallSucceeds()); socklen_t receiver_addr_len = receiver_addr.addr_len; - EXPECT_THAT(getsockname(sockets->second_fd(), + ASSERT_THAT(getsockname(sockets->second_fd(), reinterpret_cast(&receiver_addr.addr), &receiver_addr_len), SyscallSucceeds()); @@ -481,7 +481,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicConnect) { ip_mreqn group = {}; group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); - EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), SyscallSucceeds()); @@ -489,7 +489,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicConnect) { auto connect_addr = V4Multicast(); reinterpret_cast(&connect_addr.addr)->sin_port = reinterpret_cast(&receiver_addr.addr)->sin_port; - EXPECT_THAT( + ASSERT_THAT( RetryEINTR(connect)(sockets->first_fd(), reinterpret_cast(&connect_addr.addr), connect_addr.addr_len), @@ -497,7 +497,7 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicConnect) { char send_buf[200]; RandomizeBuffer(send_buf, sizeof(send_buf)); - EXPECT_THAT( + ASSERT_THAT( RetryEINTR(send)(sockets->first_fd(), send_buf, sizeof(send_buf), 0), SyscallSucceedsWithValue(sizeof(send_buf))); @@ -510,6 +510,354 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicConnect) { EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); } +// Check that multicast works when the default send interface is configured by +// IP_MULTICAST_IF, the send address is specified in sendto, and the group +// membership is configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrSelf) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreq iface = {}; + iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + // Bind the first FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT(bind(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->first_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast works when the default send interface is configured by +// IP_MULTICAST_IF, the send address is specified in sendto, and the group +// membership is configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicSelf) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreqn iface = {}; + iface.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + // Bind the first FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT(bind(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->first_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast works when the default send interface is configured by +// IP_MULTICAST_IF, the send address is specified in connect, and the group +// membership is configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrSelfConnect) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreq iface = {}; + iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + // Bind the first FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT(bind(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto connect_addr = V4Multicast(); + reinterpret_cast(&connect_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + EXPECT_THAT( + RetryEINTR(connect)(sockets->first_fd(), + reinterpret_cast(&connect_addr.addr), + connect_addr.addr_len), + SyscallSucceeds()); + + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT( + RetryEINTR(send)(sockets->first_fd(), send_buf, sizeof(send_buf), 0), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sockets->first_fd(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that multicast works when the default send interface is configured by +// IP_MULTICAST_IF, the send address is specified in connect, and the group +// membership is configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicSelfConnect) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreqn iface = {}; + iface.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + // Bind the first FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT(bind(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto connect_addr = V4Multicast(); + reinterpret_cast(&connect_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + ASSERT_THAT( + RetryEINTR(connect)(sockets->first_fd(), + reinterpret_cast(&connect_addr.addr), + connect_addr.addr_len), + SyscallSucceeds()); + + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT( + RetryEINTR(send)(sockets->first_fd(), send_buf, sizeof(send_buf), 0), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sockets->first_fd(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that multicast works when the default send interface is configured by +// IP_MULTICAST_IF, the send address is specified in sendto, and the group +// membership is configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfAddrSelfNoLoop) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreq iface = {}; + iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, + &kSockOptOff, sizeof(kSockOptOff)), + SyscallSucceeds()); + + // Bind the first FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT(bind(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->first_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast works when the default send interface is configured by +// IP_MULTICAST_IF, the send address is specified in sendto, and the group +// membership is configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackIfNicSelfNoLoop) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Set the default send interface. + ip_mreqn iface = {}; + iface.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, + &kSockOptOff, sizeof(kSockOptOff)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT(bind(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(sockets->first_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->first_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + // Check that dropping a group membership that does not exist fails. TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastInvalidDrop) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -668,5 +1016,26 @@ TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastIfInvalidAddr) { SyscallFailsWithErrno(EADDRNOTAVAIL)); } +TEST_P(IPv4UDPUnboundSocketPairTest, TestJoinGroupNoIf) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallFailsWithErrno(ENODEV)); +} + +TEST_P(IPv4UDPUnboundSocketPairTest, TestJoinGroupInvalidIf) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + ip_mreqn group = {}; + group.imr_address.s_addr = inet_addr("255.255.255"); + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallFailsWithErrno(ENODEV)); +} + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc index 7d561b991..8b4fc57b6 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc @@ -14,6 +14,7 @@ #include "test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h" +#include #include #include #include @@ -24,6 +25,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "gtest/gtest.h" +#include "test/syscalls/linux/ip_socket_test_util.h" #include "test/syscalls/linux/socket_test_util.h" #include "test/util/test_util.h" @@ -227,5 +229,335 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendUnicastOnUnbound) { SyscallSucceedsWithValue(sizeof(kTestMsg))); } +constexpr char kMulticastAddress[] = "224.0.2.1"; + +TestAddress V4Multicast() { + TestAddress t("V4Multicast"); + t.addr.ss_family = AF_INET; + t.addr_len = sizeof(sockaddr_in); + reinterpret_cast(&t.addr)->sin_addr.s_addr = + inet_addr(kMulticastAddress); + return t; +} + +// Check that multicast packets won't be delivered to the sending socket with no +// set interface or group membership. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, + TestSendMulticastSelfNoGroup) { + // FIXME: A group membership is not required for external + // multicast on gVisor. + SKIP_IF(IsRunningOnGvisor()); + + auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + auto bind_addr = V4Any(); + ASSERT_THAT(bind(socket->get(), reinterpret_cast(&bind_addr.addr), + bind_addr.addr_len), + SyscallSucceeds()); + socklen_t bind_addr_len = bind_addr.addr_len; + ASSERT_THAT( + getsockname(socket->get(), reinterpret_cast(&bind_addr.addr), + &bind_addr_len), + SyscallSucceeds()); + EXPECT_EQ(bind_addr_len, bind_addr.addr_len); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&bind_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT(RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(socket->get(), recv_buf, sizeof(recv_buf), MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that multicast packets will be delivered to the sending socket without +// setting an interface. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastSelf) { + auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + auto bind_addr = V4Any(); + ASSERT_THAT(bind(socket->get(), reinterpret_cast(&bind_addr.addr), + bind_addr.addr_len), + SyscallSucceeds()); + socklen_t bind_addr_len = bind_addr.addr_len; + ASSERT_THAT( + getsockname(socket->get(), reinterpret_cast(&bind_addr.addr), + &bind_addr_len), + SyscallSucceeds()); + EXPECT_EQ(bind_addr_len, bind_addr.addr_len); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + ASSERT_THAT(setsockopt(socket->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, + sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&bind_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT(RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT(RetryEINTR(recv)(socket->get(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast packets won't be delivered to the sending socket with no +// set interface and IP_MULTICAST_LOOP disabled. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, + TestSendMulticastSelfLoopOff) { + auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + auto bind_addr = V4Any(); + ASSERT_THAT(bind(socket->get(), reinterpret_cast(&bind_addr.addr), + bind_addr.addr_len), + SyscallSucceeds()); + socklen_t bind_addr_len = bind_addr.addr_len; + ASSERT_THAT( + getsockname(socket->get(), reinterpret_cast(&bind_addr.addr), + &bind_addr_len), + SyscallSucceeds()); + EXPECT_EQ(bind_addr_len, bind_addr.addr_len); + + // Disable multicast looping. + EXPECT_THAT(setsockopt(socket->get(), IPPROTO_IP, IP_MULTICAST_LOOP, + &kSockOptOff, sizeof(kSockOptOff)), + SyscallSucceeds()); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + EXPECT_THAT(setsockopt(socket->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, + sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&bind_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT(RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT( + RetryEINTR(recv)(socket->get(), recv_buf, sizeof(recv_buf), MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that multicast packets won't be delivered to another socket with no +// set interface or group membership. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastNoGroup) { + // FIXME: A group membership is not required for external + // multicast on gVisor. + SKIP_IF(IsRunningOnGvisor()); + + auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT( + bind(receiver->get(), reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(receiver->get(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that multicast packets will be delivered to another socket without +// setting an interface. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticast) { + auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT( + bind(receiver->get(), reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(receiver->get(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, + sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast packets won't be delivered to another socket with no +// set interface and IP_MULTICAST_LOOP disabled on the sending socket. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, + TestSendMulticastSenderNoLoop) { + auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT( + bind(receiver->get(), reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(receiver->get(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Disable multicast looping on the sender. + EXPECT_THAT(setsockopt(sender->get(), IPPROTO_IP, IP_MULTICAST_LOOP, + &kSockOptOff, sizeof(kSockOptOff)), + SyscallSucceeds()); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + EXPECT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, + sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that multicast packets will be delivered to the sending socket without +// setting an interface and IP_MULTICAST_LOOP disabled on the receiving socket. +TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, + TestSendMulticastReceiverNoLoop) { + auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + auto receiver_addr = V4Any(); + ASSERT_THAT( + bind(receiver->get(), reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(receiver->get(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + + // Disable multicast looping on the receiver. + ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_MULTICAST_LOOP, + &kSockOptOff, sizeof(kSockOptOff)), + SyscallSucceeds()); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, + sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT(RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + } // namespace testing } // namespace gvisor -- cgit v1.2.3 From a16f6e50c5a6465b94f367d62c7a46b34ef15f66 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Tue, 12 Mar 2019 14:36:58 -0700 Subject: Make HandleLocal apply to all non-loopback interfaces. HandleLocal is very similar conceptually to MULTICAST_LOOP, so we can unify the implementations. This has the benefit of making HandleLocal apply even when the fdbased link endpoint isn't in use. In addition, move looping logic to route creation so that it doesn't need to be run for each packet. This should improve performance. PiperOrigin-RevId: 238099480 Change-Id: I72839f16f25310471453bc9d3fb8544815b25c23 --- pkg/tcpip/link/fdbased/endpoint.go | 15 --------------- pkg/tcpip/stack/nic.go | 4 ++-- pkg/tcpip/stack/route.go | 21 ++++++++++++--------- pkg/tcpip/stack/stack.go | 13 +++++++++++-- runsc/boot/loader.go | 5 +++-- runsc/boot/network.go | 1 - 6 files changed, 28 insertions(+), 31 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index fa980716d..d726551b0 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -100,11 +100,6 @@ type endpoint struct { inboundDispatcher linkDispatcher dispatcher stack.NetworkDispatcher - // handleLocal indicates whether packets destined to itself should be - // handled by the netstack internally (true) or be forwarded to the FD - // endpoint (false). - handleLocal bool - // packetDispatchMode controls the packet dispatcher used by this // endpoint. packetDispatchMode PacketDispatchMode @@ -128,7 +123,6 @@ type Options struct { Address tcpip.LinkAddress SaveRestore bool DisconnectOk bool - HandleLocal bool PacketDispatchMode PacketDispatchMode } @@ -168,7 +162,6 @@ func New(opts *Options) tcpip.LinkEndpointID { closed: opts.ClosedFunc, addr: opts.Address, hdrSize: hdrSize, - handleLocal: opts.HandleLocal, packetDispatchMode: opts.PacketDispatchMode, } @@ -256,14 +249,6 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { - if e.handleLocal && r.LocalAddress != "" && r.LocalAddress == r.RemoteAddress { - views := make([]buffer.View, 1, 1+len(payload.Views())) - views[0] = hdr.View() - views = append(views, payload.Views()...) - vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) - e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, r.LocalLinkAddress, protocol, vv) - return nil - } if e.hdrSize > 0 { // Add ethernet header if needed. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 14267bb48..defa8102a 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -409,7 +409,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr n.mu.RLock() for _, ref := range n.endpoints { if ref.protocol == header.IPv4ProtocolNumber && ref.tryIncRef() { - r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref, false /* multicastLoop */) + r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref, false /* handleLocal */, false /* multicastLoop */) r.RemoteLinkAddress = remote ref.ep.HandlePacket(&r, vv) ref.decRef() @@ -420,7 +420,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr } if ref := n.getRef(protocol, dst); ref != nil { - r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref, false /* multicastLoop */) + r := makeRoute(protocol, dst, src, linkEP.LinkAddress(), ref, false /* handleLocal */, false /* multicastLoop */) r.RemoteLinkAddress = remote ref.ep.HandlePacket(&r, vv) ref.decRef() diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index c9603ad5e..86fb728b2 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -47,19 +47,27 @@ type Route struct { // starts. ref *referencedNetworkEndpoint - multicastLoop bool + // loop controls where WritePacket should send packets. + loop PacketLooping } // makeRoute initializes a new route. It takes ownership of the provided // reference to a network endpoint. -func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, localLinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint, multicastLoop bool) Route { +func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, localLinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint, handleLocal, multicastLoop bool) Route { + loop := PacketOut + if handleLocal && localAddr != "" && remoteAddr == localAddr { + loop = PacketLoop + } else if multicastLoop && (header.IsV4MulticastAddress(remoteAddr) || header.IsV6MulticastAddress(remoteAddr)) { + loop |= PacketLoop + } + return Route{ NetProto: netProto, LocalAddress: localAddr, LocalLinkAddress: localLinkAddr, RemoteAddress: remoteAddr, ref: ref, - multicastLoop: multicastLoop, + loop: loop, } } @@ -137,12 +145,7 @@ func (r *Route) IsResolutionRequired() bool { // WritePacket writes the packet through the given route. func (r *Route) WritePacket(hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { - loop := PacketOut - if r.multicastLoop && (header.IsV4MulticastAddress(r.RemoteAddress) || header.IsV6MulticastAddress(r.RemoteAddress)) { - loop |= PacketLoop - } - - err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl, loop) + err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl, r.loop) if err == tcpip.ErrNoRoute { r.Stats().IP.OutgoingPacketErrors.Increment() } diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 047b704e0..cbfe5c3c7 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -308,6 +308,9 @@ type Stack struct { // clock is used to generate user-visible times. clock tcpip.Clock + + // handleLocal allows non-loopback interfaces to loop packets. + handleLocal bool } // Options contains optional Stack configuration. @@ -319,6 +322,11 @@ type Options struct { // Stats are optional statistic counters. Stats tcpip.Stats + + // HandleLocal indicates whether packets destined to their source + // should be handled by the stack internally (true) or outside the + // stack (false). + HandleLocal bool } // New allocates a new networking stack with only the requested networking and @@ -343,6 +351,7 @@ func New(network []string, transport []string, opts Options) *Stack { PortManager: ports.NewPortManager(), clock: clock, stats: opts.Stats.FillIn(), + handleLocal: opts.HandleLocal, } // Add specified network protocols. @@ -764,7 +773,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n if id != 0 && !needRoute { if nic, ok := s.nics[id]; ok { if ref := s.getRefEP(nic, localAddr, netProto); ref != nil { - return makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref, multicastLoop && !nic.loopback), nil + return makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref, s.handleLocal && !nic.loopback, multicastLoop && !nic.loopback), nil } } } else { @@ -780,7 +789,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n remoteAddr = ref.ep.ID().LocalAddress } - r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref, multicastLoop && !nic.loopback) + r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref, s.handleLocal && !nic.loopback, multicastLoop && !nic.loopback) if needRoute { r.NextHop = route.Gateway } diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 4c7e6abfc..9ebe64dce 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -769,8 +769,9 @@ func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) (inet.Stack, error) { netProtos := []string{ipv4.ProtocolName, ipv6.ProtocolName, arp.ProtocolName} protoNames := []string{tcp.ProtocolName, udp.ProtocolName, icmp.ProtocolName4} s := epsocket.Stack{stack.New(netProtos, protoNames, stack.Options{ - Clock: clock, - Stats: epsocket.Metrics, + Clock: clock, + Stats: epsocket.Metrics, + HandleLocal: true, })} if err := s.Stack.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SACKEnabled(true)); err != nil { return nil, fmt.Errorf("failed to enable SACK: %v", err) diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 40bc147ca..f025a42f1 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -138,7 +138,6 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct FD: newFD, MTU: uint32(link.MTU), EthernetHeader: true, - HandleLocal: true, Address: mac, PacketDispatchMode: fdbased.PacketMMap, }) -- cgit v1.2.3 From 928809fa7d3b682c7e2e06c9f9b1f3fb5d75a0d6 Mon Sep 17 00:00:00 2001 From: Bert Muthalaly Date: Tue, 19 Mar 2019 08:29:37 -0700 Subject: Add layer 2 stats (tx, rx) X (packets, bytes) to netstack PiperOrigin-RevId: 239194420 Change-Id: Ie193e8ac2b7a6db21195ac85824a335930483971 --- pkg/tcpip/stack/nic.go | 36 ++++++++++++++++++++++++++- pkg/tcpip/stack/route.go | 5 +++- pkg/tcpip/stack/stack.go | 3 +++ pkg/tcpip/stack/stack_test.go | 58 ++++++++++++++++++++++++++++++++++++++----- 4 files changed, 94 insertions(+), 8 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index defa8102a..1d032ebf8 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -42,6 +42,20 @@ type NIC struct { primary map[tcpip.NetworkProtocolNumber]*ilist.List endpoints map[NetworkEndpointID]*referencedNetworkEndpoint subnets []tcpip.Subnet + + stats NICStats +} + +// NICStats includes transmitted and received stats. +type NICStats struct { + Tx DirectionStats + Rx DirectionStats +} + +// DirectionStats includes packet and byte counts. +type DirectionStats struct { + Packets *tcpip.StatCounter + Bytes *tcpip.StatCounter } // PrimaryEndpointBehavior is an enumeration of an endpoint's primacy behavior. @@ -73,6 +87,16 @@ func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint, loopback demux: newTransportDemuxer(stack), primary: make(map[tcpip.NetworkProtocolNumber]*ilist.List), endpoints: make(map[NetworkEndpointID]*referencedNetworkEndpoint), + stats: NICStats{ + Tx: DirectionStats{ + Packets: &tcpip.StatCounter{}, + Bytes: &tcpip.StatCounter{}, + }, + Rx: DirectionStats{ + Packets: &tcpip.StatCounter{}, + Bytes: &tcpip.StatCounter{}, + }, + }, } } @@ -384,6 +408,9 @@ func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error { // This rule applies only to the slice itself, not to the items of the slice; // the ownership of the items is not retained by the caller. func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) { + n.stats.Rx.Packets.Increment() + n.stats.Rx.Bytes.IncrementBy(uint64(vv.Size())) + netProto, ok := n.stack.networkProtocols[protocol] if !ok { n.stack.stats.UnknownProtocolRcvdPackets.Increment() @@ -457,7 +484,14 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr // Send the packet out of n. hdr := buffer.NewPrependableFromView(vv.First()) vv.RemoveFirst() - n.linkEP.WritePacket(&r, hdr, vv, protocol) + + // TODO: use route.WritePacket. + if err := n.linkEP.WritePacket(&r, hdr, vv, protocol); err != nil { + r.Stats().IP.OutgoingPacketErrors.Increment() + } else { + n.stats.Tx.Packets.Increment() + n.stats.Tx.Bytes.IncrementBy(uint64(hdr.UsedLength() + vv.Size())) + } } return } diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 86fb728b2..3f2264d16 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -146,8 +146,11 @@ func (r *Route) IsResolutionRequired() bool { // WritePacket writes the packet through the given route. func (r *Route) WritePacket(hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl, r.loop) - if err == tcpip.ErrNoRoute { + if err != nil { r.Stats().IP.OutgoingPacketErrors.Increment() + } else { + r.ref.nic.stats.Tx.Packets.Increment() + r.ref.nic.stats.Tx.Bytes.IncrementBy(uint64(hdr.UsedLength() + payload.Size())) } return err } diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index cbfe5c3c7..15a268b10 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -627,6 +627,8 @@ type NICInfo struct { // MTU is the maximum transmission unit. MTU uint32 + + Stats NICStats } // NICInfo returns a map of NICIDs to their associated information. @@ -648,6 +650,7 @@ func (s *Stack) NICInfo() map[tcpip.NICID]NICInfo { ProtocolAddresses: nic.Addresses(), Flags: flags, MTU: nic.linkEP.MTU(), + Stats: nic.stats, } } return nics diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index b366de21d..da8269999 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -273,7 +273,7 @@ func TestNetworkReceive(t *testing.T) { } } -func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address) { +func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address, payload buffer.View) { r, err := s.FindRoute(0, "", addr, fakeNetNumber, false /* multicastLoop */) if err != nil { t.Fatalf("FindRoute failed: %v", err) @@ -281,9 +281,8 @@ func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address) { defer r.Release() hdr := buffer.NewPrependable(int(r.MaxHeaderLength())) - if err := r.WritePacket(hdr, buffer.VectorisedView{}, fakeTransNumber, 123); err != nil { + if err := r.WritePacket(hdr, payload.ToVectorisedView(), fakeTransNumber, 123); err != nil { t.Errorf("WritePacket failed: %v", err) - return } } @@ -304,7 +303,7 @@ func TestNetworkSend(t *testing.T) { } // Make sure that the link-layer endpoint received the outbound packet. - sendTo(t, s, "\x03") + sendTo(t, s, "\x03", nil) if c := linkEP.Drain(); c != 1 { t.Errorf("packetCount = %d, want %d", c, 1) } @@ -351,14 +350,14 @@ func TestNetworkSendMultiRoute(t *testing.T) { }) // Send a packet to an odd destination. - sendTo(t, s, "\x05") + sendTo(t, s, "\x05", nil) if c := linkEP1.Drain(); c != 1 { t.Errorf("packetCount = %d, want %d", c, 1) } // Send a packet to an even destination. - sendTo(t, s, "\x06") + sendTo(t, s, "\x06", nil) if c := linkEP2.Drain(); c != 1 { t.Errorf("packetCount = %d, want %d", c, 1) @@ -1055,6 +1054,44 @@ func TestGetMainNICAddressAddRemove(t *testing.T) { } } +func TestNICStats(t *testing.T) { + s := stack.New([]string{"fakeNet"}, nil, stack.Options{}) + id1, linkEP1 := channel.New(10, defaultMTU, "") + if err := s.CreateNIC(1, id1); err != nil { + t.Fatalf("CreateNIC failed: %v", err) + } + if err := s.AddAddress(1, fakeNetNumber, "\x01"); err != nil { + t.Fatalf("AddAddress failed: %v", err) + } + // Route all packets for address \x01 to NIC 1. + s.SetRouteTable([]tcpip.Route{ + {"\x01", "\xff", "\x00", 1}, + }) + + // Send a packet to address 1. + buf := buffer.NewView(30) + linkEP1.Inject(fakeNetNumber, buf.ToVectorisedView()) + if got, want := s.NICInfo()[1].Stats.Rx.Packets.Value(), uint64(1); got != want { + t.Errorf("got Rx.Packets.Value() = %d, want = %d", got, want) + } + + if got, want := s.NICInfo()[1].Stats.Rx.Bytes.Value(), uint64(len(buf)); got != want { + t.Errorf("got Rx.Bytes.Value() = %d, want = %d", got, want) + } + + payload := buffer.NewView(10) + // Write a packet out via the address for NIC 1 + sendTo(t, s, "\x01", payload) + want := uint64(linkEP1.Drain()) + if got := s.NICInfo()[1].Stats.Tx.Packets.Value(); got != want { + t.Errorf("got Tx.Packets.Value() = %d, linkEP1.Drain() = %d", got, want) + } + + if got, want := s.NICInfo()[1].Stats.Tx.Bytes.Value(), uint64(len(payload)); got != want { + t.Errorf("got Tx.Bytes.Value() = %d, want = %d", got, want) + } +} + func TestNICForwarding(t *testing.T) { // Create a stack with the fake network protocol, two NICs, each with // an address. @@ -1092,6 +1129,15 @@ func TestNICForwarding(t *testing.T) { default: t.Fatal("Packet not forwarded") } + + // Test that forwarding increments Tx stats correctly. + if got, want := s.NICInfo()[2].Stats.Tx.Packets.Value(), uint64(1); got != want { + t.Errorf("got Tx.Packets.Value() = %d, want = %d", got, want) + } + + if got, want := s.NICInfo()[2].Stats.Tx.Bytes.Value(), uint64(len(buf)); got != want { + t.Errorf("got Tx.Bytes.Value() = %d, want = %d", got, want) + } } func init() { -- cgit v1.2.3 From 654e878abba174d8f7d588f38ecfd5a020bf581e Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Tue, 26 Mar 2019 17:14:04 -0700 Subject: netstack: Don't exclude length when a pseudo-header checksum is calculated This is a preparation for GSO changes (cl/234508902). RELNOTES[gofers]: Refactor checksum code to include length, which it already did, but in a convoluted way. Should be a no-op. PiperOrigin-RevId: 240460794 Change-Id: I537381bc670b5a9f5d70a87aa3eb7252e8f5ace2 --- pkg/tcpip/header/checksum.go | 17 ++++++++++++----- pkg/tcpip/header/tcp.go | 15 ++++----------- pkg/tcpip/header/udp.go | 14 ++++---------- pkg/tcpip/stack/route.go | 4 ++-- pkg/tcpip/transport/tcp/connect.go | 4 ++-- pkg/tcpip/transport/tcp/testing/context/context.go | 6 ++---- pkg/tcpip/transport/udp/endpoint.go | 4 ++-- pkg/tcpip/transport/udp/udp_test.go | 6 ++---- 8 files changed, 30 insertions(+), 40 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/header/checksum.go b/pkg/tcpip/header/checksum.go index 2c2fcbd9b..2e8c65fac 100644 --- a/pkg/tcpip/header/checksum.go +++ b/pkg/tcpip/header/checksum.go @@ -17,6 +17,8 @@ package header import ( + "encoding/binary" + "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" ) @@ -76,12 +78,17 @@ func ChecksumCombine(a, b uint16) uint16 { return uint16(v + v>>16) } -// PseudoHeaderChecksum calculates the pseudo-header checksum for the -// given destination protocol and network address, ignoring the length -// field. Pseudo-headers are needed by transport layers when calculating -// their own checksum. -func PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, srcAddr tcpip.Address, dstAddr tcpip.Address) uint16 { +// PseudoHeaderChecksum calculates the pseudo-header checksum for the given +// destination protocol and network address. Pseudo-headers are needed by +// transport layers when calculating their own checksum. +func PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, srcAddr tcpip.Address, dstAddr tcpip.Address, totalLen uint16) uint16 { xsum := Checksum([]byte(srcAddr), 0) xsum = Checksum([]byte(dstAddr), xsum) + + // Add the length portion of the checksum to the pseudo-checksum. + tmp := make([]byte, 2) + binary.BigEndian.PutUint16(tmp, totalLen) + xsum = Checksum(tmp, xsum) + return Checksum([]byte{0, uint8(protocol)}, xsum) } diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index 207046b36..d37d624fe 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -231,19 +231,12 @@ func (b TCP) SetChecksum(checksum uint16) { binary.BigEndian.PutUint16(b[tcpChecksum:], checksum) } -// CalculateChecksum calculates the checksum of the tcp segment given -// the totalLen and partialChecksum(descriptions below) -// totalLen is the total length of the segment +// CalculateChecksum calculates the checksum of the tcp segment. // partialChecksum is the checksum of the network-layer pseudo-header -// (excluding the total length) and the checksum of the segment data. -func (b TCP) CalculateChecksum(partialChecksum uint16, totalLen uint16) uint16 { - // Add the length portion of the checksum to the pseudo-checksum. - tmp := make([]byte, 2) - binary.BigEndian.PutUint16(tmp, totalLen) - checksum := Checksum(tmp, partialChecksum) - +// and the checksum of the segment data. +func (b TCP) CalculateChecksum(partialChecksum uint16) uint16 { // Calculate the rest of the checksum. - return Checksum(b[:b.DataOffset()], checksum) + return Checksum(b[:b.DataOffset()], partialChecksum) } // Options returns a slice that holds the unparsed TCP options in the segment. diff --git a/pkg/tcpip/header/udp.go b/pkg/tcpip/header/udp.go index 31c8ef456..e8c860436 100644 --- a/pkg/tcpip/header/udp.go +++ b/pkg/tcpip/header/udp.go @@ -94,17 +94,11 @@ func (b UDP) SetChecksum(checksum uint16) { binary.BigEndian.PutUint16(b[udpChecksum:], checksum) } -// CalculateChecksum calculates the checksum of the udp packet, given the total -// length of the packet and the checksum of the network-layer pseudo-header -// (excluding the total length) and the checksum of the payload. -func (b UDP) CalculateChecksum(partialChecksum uint16, totalLen uint16) uint16 { - // Add the length portion of the checksum to the pseudo-checksum. - tmp := make([]byte, 2) - binary.BigEndian.PutUint16(tmp, totalLen) - checksum := Checksum(tmp, partialChecksum) - +// CalculateChecksum calculates the checksum of the udp packet, given the +// checksum of the network-layer pseudo-header and the checksum of the payload. +func (b UDP) CalculateChecksum(partialChecksum uint16) uint16 { // Calculate the rest of the checksum. - return Checksum(b[:UDPMinimumSize], checksum) + return Checksum(b[:UDPMinimumSize], partialChecksum) } // Encode encodes all the fields of the udp header. diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 3f2264d16..ee860eafe 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -88,8 +88,8 @@ func (r *Route) Stats() tcpip.Stats { // PseudoHeaderChecksum forwards the call to the network endpoint's // implementation. -func (r *Route) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber) uint16 { - return header.PseudoHeaderChecksum(protocol, r.LocalAddress, r.RemoteAddress) +func (r *Route) PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, totalLen uint16) uint16 { + return header.PseudoHeaderChecksum(protocol, r.LocalAddress, r.RemoteAddress, totalLen) } // Capabilities returns the link-layer capabilities of the route. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 4d352b23c..c4353718e 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -589,10 +589,10 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.Vectorise // Only calculate the checksum if offloading isn't supported. if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { length := uint16(hdr.UsedLength() + data.Size()) - xsum := r.PseudoHeaderChecksum(ProtocolNumber) + xsum := r.PseudoHeaderChecksum(ProtocolNumber, length) xsum = header.ChecksumVV(data, xsum) - tcp.SetChecksum(^tcp.CalculateChecksum(xsum, length)) + tcp.SetChecksum(^tcp.CalculateChecksum(xsum)) } r.Stats().TCP.SegmentsSent.Increment() diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index fb4ae4a1b..aa2a73829 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -332,9 +332,8 @@ func (c *Context) BuildSegment(payload []byte, h *Headers) buffer.VectorisedView xsum = header.Checksum([]byte{0, uint8(tcp.ProtocolNumber)}, xsum) // Calculate the TCP checksum and set it. - length := uint16(header.TCPMinimumSize + len(h.TCPOpts) + len(payload)) xsum = header.Checksum(payload, xsum) - t.SetChecksum(^t.CalculateChecksum(xsum, length)) + t.SetChecksum(^t.CalculateChecksum(xsum)) // Inject packet. return buf.ToVectorisedView() @@ -487,9 +486,8 @@ func (c *Context) SendV6Packet(payload []byte, h *Headers) { xsum = header.Checksum([]byte{0, uint8(tcp.ProtocolNumber)}, xsum) // Calculate the TCP checksum and set it. - length := uint16(header.TCPMinimumSize + len(payload)) xsum = header.Checksum(payload, xsum) - t.SetChecksum(^t.CalculateChecksum(xsum, length)) + t.SetChecksum(^t.CalculateChecksum(xsum)) // Inject packet. c.linkEP.Inject(ipv6.ProtocolNumber, buf.ToVectorisedView()) diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 82d7f80a3..b68ed8561 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -641,11 +641,11 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u // Only calculate the checksum if offloading isn't supported. if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { - xsum := r.PseudoHeaderChecksum(ProtocolNumber) + xsum := r.PseudoHeaderChecksum(ProtocolNumber, length) for _, v := range data.Views() { xsum = header.Checksum(v, xsum) } - udp.SetChecksum(^udp.CalculateChecksum(xsum, length)) + udp.SetChecksum(^udp.CalculateChecksum(xsum)) } // Track count of packets sent. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 884a76b04..0d5871615 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -200,9 +200,8 @@ func (c *testContext) sendV6Packet(payload []byte, h *headers) { xsum = header.Checksum([]byte{0, uint8(udp.ProtocolNumber)}, xsum) // Calculate the UDP checksum and set it. - length := uint16(header.UDPMinimumSize + len(payload)) xsum = header.Checksum(payload, xsum) - u.SetChecksum(^u.CalculateChecksum(xsum, length)) + u.SetChecksum(^u.CalculateChecksum(xsum)) // Inject packet. c.linkEP.Inject(ipv6.ProtocolNumber, buf.ToVectorisedView()) @@ -239,9 +238,8 @@ func (c *testContext) sendPacket(payload []byte, h *headers) { xsum = header.Checksum([]byte{0, uint8(udp.ProtocolNumber)}, xsum) // Calculate the UDP checksum and set it. - length := uint16(header.UDPMinimumSize + len(payload)) xsum = header.Checksum(payload, xsum) - u.SetChecksum(^u.CalculateChecksum(xsum, length)) + u.SetChecksum(^u.CalculateChecksum(xsum)) // Inject packet. c.linkEP.Inject(ipv4.ProtocolNumber, buf.ToVectorisedView()) -- cgit v1.2.3 From f4105ac21a9f11f5231681239ca92ac814b5149d Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 28 Mar 2019 11:02:23 -0700 Subject: netstack/fdbased: add generic segmentation offload (GSO) support The linux packet socket can handle GSO packets, so we can segment packets to 64K instead of the MTU which is usually 1500. Here are numbers for the nginx-1m test: runsc: 579330.01 [Kbytes/sec] received runsc-gso: 1794121.66 [Kbytes/sec] received runc: 2122139.06 [Kbytes/sec] received and for tcp_benchmark: $ tcp_benchmark --duration 15 --ideal [ 4] 0.0-15.0 sec 86647 MBytes 48456 Mbits/sec $ tcp_benchmark --client --duration 15 --ideal [ 4] 0.0-15.0 sec 2173 MBytes 1214 Mbits/sec $ tcp_benchmark --client --duration 15 --ideal --gso 65536 [ 4] 0.0-15.0 sec 19357 MBytes 10825 Mbits/sec PiperOrigin-RevId: 240809103 Change-Id: I2637f104db28b5d4c64e1e766c610162a195775a --- pkg/tcpip/header/tcp.go | 11 ++ pkg/tcpip/link/channel/channel.go | 2 +- pkg/tcpip/link/fdbased/BUILD | 1 + pkg/tcpip/link/fdbased/endpoint.go | 104 ++++++++++++-- pkg/tcpip/link/fdbased/endpoint_test.go | 160 +++++++++++++-------- pkg/tcpip/link/fdbased/endpoint_unsafe.go | 32 +++++ pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/muxed/injectable.go | 4 +- pkg/tcpip/link/muxed/injectable_test.go | 4 +- pkg/tcpip/link/rawfile/rawfile_unsafe.go | 15 +- pkg/tcpip/link/sharedmem/sharedmem.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_test.go | 24 ++-- pkg/tcpip/link/sniffer/sniffer.go | 12 +- pkg/tcpip/link/waitable/waitable.go | 4 +- pkg/tcpip/link/waitable/waitable_test.go | 8 +- pkg/tcpip/network/arp/arp.go | 6 +- pkg/tcpip/network/ip_test.go | 6 +- pkg/tcpip/network/ipv4/icmp.go | 2 +- pkg/tcpip/network/ipv4/ipv4.go | 12 +- pkg/tcpip/network/ipv6/icmp.go | 6 +- pkg/tcpip/network/ipv6/ipv6.go | 12 +- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/stack/registration.go | 43 +++++- pkg/tcpip/stack/route.go | 12 +- pkg/tcpip/stack/stack_test.go | 6 +- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/transport/icmp/endpoint.go | 6 +- pkg/tcpip/transport/tcp/accept.go | 2 + pkg/tcpip/transport/tcp/connect.go | 21 +-- pkg/tcpip/transport/tcp/endpoint.go | 27 ++++ pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/tcp/snd.go | 45 +++++- pkg/tcpip/transport/tcp/testing/context/context.go | 4 +- pkg/tcpip/transport/udp/endpoint.go | 2 +- 34 files changed, 462 insertions(+), 141 deletions(-) create mode 100644 pkg/tcpip/link/fdbased/endpoint_unsafe.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index d37d624fe..6e3ee2e50 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -167,6 +167,12 @@ const ( // TCPMinimumSize is the minimum size of a valid TCP packet. TCPMinimumSize = 20 + // TCPOptionsMaximumSize is the maximum size of TCP options. + TCPOptionsMaximumSize = 40 + + // TCPHeaderMaximumSize is the maximum header size of a TCP packet. + TCPHeaderMaximumSize = TCPMinimumSize + TCPOptionsMaximumSize + // TCPProtocolNumber is TCP's transport protocol number. TCPProtocolNumber tcpip.TransportProtocolNumber = 6 ) @@ -291,6 +297,11 @@ func (b TCP) EncodePartial(partialChecksum, length uint16, seqnum, acknum uint32 b.SetChecksum(^checksum) } +// TCPChecksumOffset returns offset of the checksum field. +func TCPChecksumOffset() uint16 { + return tcpChecksum +} + // ParseSynOptions parses the options received in a SYN segment and returns the // relevant ones. opts should point to the option part of the TCP Header. func ParseSynOptions(opts []byte, isAck bool) TCPSynOptions { diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 25cffa787..8c0d11288 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -109,7 +109,7 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { } // WritePacket stores outbound packets into the channel. -func (e *Endpoint) WritePacket(_ *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(_ *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { p := PacketInfo{ Header: hdr.View(), Proto: protocol, diff --git a/pkg/tcpip/link/fdbased/BUILD b/pkg/tcpip/link/fdbased/BUILD index bcf9c023e..50ce91a4e 100644 --- a/pkg/tcpip/link/fdbased/BUILD +++ b/pkg/tcpip/link/fdbased/BUILD @@ -6,6 +6,7 @@ go_library( name = "fdbased", srcs = [ "endpoint.go", + "endpoint_unsafe.go", "mmap.go", "mmap_amd64_unsafe.go", ], diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index d726551b0..20e34c5ee 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -111,6 +111,10 @@ type endpoint struct { // ringOffset is the current offset into the ring buffer where the next // inbound packet will be placed by the kernel. ringOffset int + + // gsoMaxSize is the maximum GSO packet size. It is zero if GSO is + // disabled. + gsoMaxSize uint32 } // Options specify the details about the fd-based endpoint to be created. @@ -123,6 +127,7 @@ type Options struct { Address tcpip.LinkAddress SaveRestore bool DisconnectOk bool + GSOMaxSize uint32 PacketDispatchMode PacketDispatchMode } @@ -165,6 +170,10 @@ func New(opts *Options) tcpip.LinkEndpointID { packetDispatchMode: opts.PacketDispatchMode, } + if opts.GSOMaxSize != 0 && isSocketFD(opts.FD) { + e.caps |= stack.CapabilityGSO + e.gsoMaxSize = opts.GSOMaxSize + } if isSocketFD(opts.FD) && e.packetDispatchMode == PacketMMap { if err := e.setupPacketRXRing(); err != nil { // TODO: replace panic with an error return. @@ -185,17 +194,22 @@ func New(opts *Options) tcpip.LinkEndpointID { } e.views = make([][]buffer.View, msgsPerRecv) - for i, _ := range e.views { + for i := range e.views { e.views[i] = make([]buffer.View, len(BufConfig)) } e.iovecs = make([][]syscall.Iovec, msgsPerRecv) - for i, _ := range e.iovecs { - e.iovecs[i] = make([]syscall.Iovec, len(BufConfig)) + iovLen := len(BufConfig) + if e.Capabilities()&stack.CapabilityGSO != 0 { + // virtioNetHdr is prepended before each packet. + iovLen++ + } + for i := range e.iovecs { + e.iovecs[i] = make([]syscall.Iovec, iovLen) } e.msgHdrs = make([]rawfile.MMsgHdr, msgsPerRecv) - for i, _ := range e.msgHdrs { + for i := range e.msgHdrs { e.msgHdrs[i].Msg.Iov = &e.iovecs[i][0] - e.msgHdrs[i].Msg.Iovlen = uint64(len(BufConfig)) + e.msgHdrs[i].Msg.Iovlen = uint64(iovLen) } return stack.RegisterLinkEndpoint(e) @@ -246,9 +260,27 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { return e.addr } +// virtioNetHdr is declared in linux/virtio_net.h. +type virtioNetHdr struct { + flags uint8 + gsoType uint8 + hdrLen uint16 + gsoSize uint16 + csumStart uint16 + csumOffset uint16 +} + +// These constants are declared in linux/virtio_net.h. +const ( + _VIRTIO_NET_HDR_F_NEEDS_CSUM = 1 + + _VIRTIO_NET_HDR_GSO_TCPV4 = 1 + _VIRTIO_NET_HDR_GSO_TCPV6 = 4 +) + // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if e.hdrSize > 0 { // Add ethernet header if needed. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) @@ -266,11 +298,37 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b eth.Encode(ethHdr) } + if e.Capabilities()&stack.CapabilityGSO != 0 { + vnetHdr := virtioNetHdr{} + vnetHdrBuf := vnetHdrToByteSlice(&vnetHdr) + if gso != nil { + vnetHdr.hdrLen = uint16(hdr.UsedLength()) + if gso.NeedsCsum { + vnetHdr.flags = _VIRTIO_NET_HDR_F_NEEDS_CSUM + vnetHdr.csumStart = header.EthernetMinimumSize + gso.L3HdrLen + vnetHdr.csumOffset = gso.CsumOffset + } + if gso.Type != stack.GSONone && uint16(payload.Size()) > gso.MSS { + switch gso.Type { + case stack.GSOTCPv4: + vnetHdr.gsoType = _VIRTIO_NET_HDR_GSO_TCPV4 + case stack.GSOTCPv6: + vnetHdr.gsoType = _VIRTIO_NET_HDR_GSO_TCPV6 + default: + panic(fmt.Sprintf("Unknown gso type: %v", gso.Type)) + } + vnetHdr.gsoSize = gso.MSS + } + } + + return rawfile.NonBlockingWrite3(e.fd, vnetHdrBuf, hdr.View(), payload.ToView()) + } + if payload.Size() == 0 { return rawfile.NonBlockingWrite(e.fd, hdr.View()) } - return rawfile.NonBlockingWrite2(e.fd, hdr.View(), payload.ToView()) + return rawfile.NonBlockingWrite3(e.fd, hdr.View(), payload.ToView(), nil) } // WriteRawPacket writes a raw packet directly to the file descriptor. @@ -292,13 +350,25 @@ func (e *endpoint) capViews(k, n int, buffers []int) int { func (e *endpoint) allocateViews(bufConfig []int) { for k := 0; k < len(e.views); k++ { + var vnetHdr [virtioNetHdrSize]byte + vnetHdrOff := 0 + if e.Capabilities()&stack.CapabilityGSO != 0 { + // The kernel adds virtioNetHdr before each packet, but + // we don't use it, so so we allocate a buffer for it, + // add it in iovecs but don't add it in a view. + e.iovecs[k][0] = syscall.Iovec{ + Base: &vnetHdr[0], + Len: uint64(virtioNetHdrSize), + } + vnetHdrOff++ + } for i := 0; i < len(bufConfig); i++ { if e.views[k][i] != nil { break } b := buffer.NewView(bufConfig[i]) e.views[k][i] = b - e.iovecs[k][i] = syscall.Iovec{ + e.iovecs[k][i+vnetHdrOff] = syscall.Iovec{ Base: &b[0], Len: uint64(len(b)), } @@ -314,7 +384,11 @@ func (e *endpoint) dispatch() (bool, *tcpip.Error) { if err != nil { return false, err } - + if e.Capabilities()&stack.CapabilityGSO != 0 { + // Skip virtioNetHdr which is added before each packet, it + // isn't used and it isn't in a view. + n -= virtioNetHdrSize + } if n <= e.hdrSize { return false, nil } @@ -366,8 +440,11 @@ func (e *endpoint) recvMMsgDispatch() (bool, *tcpip.Error) { } // Process each of received packets. for k := 0; k < nMsgs; k++ { - n := e.msgHdrs[k].Len - if n <= uint32(e.hdrSize) { + n := int(e.msgHdrs[k].Len) + if e.Capabilities()&stack.CapabilityGSO != 0 { + n -= virtioNetHdrSize + } + if n <= e.hdrSize { return false, nil } @@ -425,6 +502,11 @@ func (e *endpoint) dispatchLoop() *tcpip.Error { } } +// GSOMaxSize returns the maximum GSO packet size. +func (e *endpoint) GSOMaxSize() uint32 { + return e.gsoMaxSize +} + // InjectableEndpoint is an injectable fd-based endpoint. The endpoint writes // to the FD, but does not read from it. All reads come from injected packets. type InjectableEndpoint struct { diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 14abacdf2..ecc5b73f3 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -24,6 +24,7 @@ import ( "syscall" "testing" "time" + "unsafe" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" @@ -33,10 +34,12 @@ import ( ) const ( - mtu = 1500 - laddr = tcpip.LinkAddress("\x11\x22\x33\x44\x55\x66") - raddr = tcpip.LinkAddress("\x77\x88\x99\xaa\xbb\xcc") - proto = 10 + mtu = 1500 + laddr = tcpip.LinkAddress("\x11\x22\x33\x44\x55\x66") + raddr = tcpip.LinkAddress("\x77\x88\x99\xaa\xbb\xcc") + proto = 10 + csumOffset = 48 + gsoMSS = 500 ) type packetInfo struct { @@ -130,67 +133,108 @@ func TestAddress(t *testing.T) { } } -func TestWritePacket(t *testing.T) { - lengths := []int{0, 100, 1000} - eths := []bool{true, false} +func testWritePacket(t *testing.T, plen int, eth bool, gsoMaxSize uint32) { + c := newContext(t, &Options{Address: laddr, MTU: mtu, EthernetHeader: eth, GSOMaxSize: gsoMaxSize}) + defer c.cleanup() - for _, eth := range eths { - for _, plen := range lengths { - t.Run(fmt.Sprintf("Eth=%v,PayloadLen=%v", eth, plen), func(t *testing.T) { - c := newContext(t, &Options{Address: laddr, MTU: mtu, EthernetHeader: eth}) - defer c.cleanup() + r := &stack.Route{ + RemoteLinkAddress: raddr, + } - r := &stack.Route{ - RemoteLinkAddress: raddr, - } + // Build header. + hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength()) + 100) + b := hdr.Prepend(100) + for i := range b { + b[i] = uint8(rand.Intn(256)) + } - // Build header. - hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength()) + 100) - b := hdr.Prepend(100) - for i := range b { - b[i] = uint8(rand.Intn(256)) - } + // Build payload and write. + payload := make(buffer.View, plen) + for i := range payload { + payload[i] = uint8(rand.Intn(256)) + } + want := append(hdr.View(), payload...) + var gso *stack.GSO + if gsoMaxSize != 0 { + gso = &stack.GSO{ + Type: stack.GSOTCPv6, + NeedsCsum: true, + CsumOffset: csumOffset, + MSS: gsoMSS, + MaxSize: gsoMaxSize, + } + } + if err := c.ep.WritePacket(r, gso, hdr, payload.ToVectorisedView(), proto); err != nil { + t.Fatalf("WritePacket failed: %v", err) + } - // Build payload and write. - payload := make(buffer.View, plen) - for i := range payload { - payload[i] = uint8(rand.Intn(256)) - } - want := append(hdr.View(), payload...) - if err := c.ep.WritePacket(r, hdr, payload.ToVectorisedView(), proto); err != nil { - t.Fatalf("WritePacket failed: %v", err) - } + // Read from fd, then compare with what we wrote. + b = make([]byte, mtu) + n, err := syscall.Read(c.fds[0], b) + if err != nil { + t.Fatalf("Read failed: %v", err) + } + b = b[:n] + if gsoMaxSize != 0 { + vnetHdr := *(*virtioNetHdr)(unsafe.Pointer(&b[0])) + if vnetHdr.flags&_VIRTIO_NET_HDR_F_NEEDS_CSUM == 0 { + t.Fatalf("virtioNetHdr.flags %v doesn't contain %v", vnetHdr.flags, _VIRTIO_NET_HDR_F_NEEDS_CSUM) + } + csumStart := header.EthernetMinimumSize + gso.L3HdrLen + if vnetHdr.csumStart != csumStart { + t.Fatalf("vnetHdr.csumStart = %v, want %v", vnetHdr.csumStart, csumStart) + } + if vnetHdr.csumOffset != csumOffset { + t.Fatalf("vnetHdr.csumOffset = %v, want %v", vnetHdr.csumOffset, csumOffset) + } + gsoType := uint8(0) + if int(gso.MSS) < plen { + gsoType = _VIRTIO_NET_HDR_GSO_TCPV6 + } + if vnetHdr.gsoType != gsoType { + t.Fatalf("vnetHdr.gsoType = %v, want %v", vnetHdr.gsoType, gsoType) + } + b = b[virtioNetHdrSize:] + } + if eth { + h := header.Ethernet(b) + b = b[header.EthernetMinimumSize:] - // Read from fd, then compare with what we wrote. - b = make([]byte, mtu) - n, err := syscall.Read(c.fds[0], b) - if err != nil { - t.Fatalf("Read failed: %v", err) - } - b = b[:n] - if eth { - h := header.Ethernet(b) - b = b[header.EthernetMinimumSize:] + if a := h.SourceAddress(); a != laddr { + t.Fatalf("SourceAddress() = %v, want %v", a, laddr) + } - if a := h.SourceAddress(); a != laddr { - t.Fatalf("SourceAddress() = %v, want %v", a, laddr) - } + if a := h.DestinationAddress(); a != raddr { + t.Fatalf("DestinationAddress() = %v, want %v", a, raddr) + } - if a := h.DestinationAddress(); a != raddr { - t.Fatalf("DestinationAddress() = %v, want %v", a, raddr) - } + if et := h.Type(); et != proto { + t.Fatalf("Type() = %v, want %v", et, proto) + } + } + if len(b) != len(want) { + t.Fatalf("Read returned %v bytes, want %v", len(b), len(want)) + } + if !bytes.Equal(b, want) { + t.Fatalf("Read returned %x, want %x", b, want) + } +} - if et := h.Type(); et != proto { - t.Fatalf("Type() = %v, want %v", et, proto) - } - } - if len(b) != len(want) { - t.Fatalf("Read returned %v bytes, want %v", len(b), len(want)) - } - if !bytes.Equal(b, want) { - t.Fatalf("Read returned %x, want %x", b, want) - } - }) +func TestWritePacket(t *testing.T) { + lengths := []int{0, 100, 1000} + eths := []bool{true, false} + gsos := []uint32{0, 32768} + + for _, eth := range eths { + for _, plen := range lengths { + for _, gso := range gsos { + t.Run( + fmt.Sprintf("Eth=%v,PayloadLen=%v,GSOMaxSize=%v", eth, plen, gso), + func(t *testing.T) { + testWritePacket(t, plen, eth, gso) + }, + ) + } } } } @@ -210,7 +254,7 @@ func TestPreserveSrcAddress(t *testing.T) { // WritePacket panics given a prependable with anything less than // the minimum size of the ethernet header. hdr := buffer.NewPrependable(header.EthernetMinimumSize) - if err := c.ep.WritePacket(r, hdr, buffer.VectorisedView{}, proto); err != nil { + if err := c.ep.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } diff --git a/pkg/tcpip/link/fdbased/endpoint_unsafe.go b/pkg/tcpip/link/fdbased/endpoint_unsafe.go new file mode 100644 index 000000000..36e7fe5a9 --- /dev/null +++ b/pkg/tcpip/link/fdbased/endpoint_unsafe.go @@ -0,0 +1,32 @@ +// Copyright 2019 Google LLC +// +// 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. + +// +build linux + +package fdbased + +import ( + "reflect" + "unsafe" +) + +const virtioNetHdrSize = int(unsafe.Sizeof(virtioNetHdr{})) + +func vnetHdrToByteSlice(hdr *virtioNetHdr) (slice []byte) { + sh := (*reflect.SliceHeader)(unsafe.Pointer(&slice)) + sh.Data = uintptr(unsafe.Pointer(hdr)) + sh.Len = virtioNetHdrSize + sh.Cap = virtioNetHdrSize + return +} diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index fa54872da..d58c0f885 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -72,7 +72,7 @@ func (*endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements stack.LinkEndpoint.WritePacket. It delivers outbound // packets to the network-layer dispatcher. -func (e *endpoint) WritePacket(_ *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(_ *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { views := make([]buffer.View, 1, 1+len(payload.Views())) views[0] = hdr.View() views = append(views, payload.Views()...) diff --git a/pkg/tcpip/link/muxed/injectable.go b/pkg/tcpip/link/muxed/injectable.go index 29073afae..99edc232d 100644 --- a/pkg/tcpip/link/muxed/injectable.go +++ b/pkg/tcpip/link/muxed/injectable.go @@ -87,9 +87,9 @@ func (m *InjectableEndpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buf // WritePacket writes outbound packets to the appropriate LinkInjectableEndpoint // based on the RemoteAddress. HandleLocal only works if r.RemoteAddress has a // route registered in this endpoint. -func (m *InjectableEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (m *InjectableEndpoint) WritePacket(r *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if endpoint, ok := m.routes[r.RemoteAddress]; ok { - return endpoint.WritePacket(r, hdr, payload, protocol) + return endpoint.WritePacket(r, nil /* gso */, hdr, payload, protocol) } return tcpip.ErrNoRoute } diff --git a/pkg/tcpip/link/muxed/injectable_test.go b/pkg/tcpip/link/muxed/injectable_test.go index d1d2875cc..7d25effad 100644 --- a/pkg/tcpip/link/muxed/injectable_test.go +++ b/pkg/tcpip/link/muxed/injectable_test.go @@ -50,7 +50,7 @@ func TestInjectableEndpointDispatch(t *testing.T) { hdr.Prepend(1)[0] = 0xFA packetRoute := stack.Route{RemoteAddress: dstIP} - endpoint.WritePacket(&packetRoute, hdr, + endpoint.WritePacket(&packetRoute, nil /* gso */, hdr, buffer.NewViewFromBytes([]byte{0xFB}).ToVectorisedView(), ipv4.ProtocolNumber) buf := make([]byte, 6500) @@ -68,7 +68,7 @@ func TestInjectableEndpointDispatchHdrOnly(t *testing.T) { hdr := buffer.NewPrependable(1) hdr.Prepend(1)[0] = 0xFA packetRoute := stack.Route{RemoteAddress: dstIP} - endpoint.WritePacket(&packetRoute, hdr, + endpoint.WritePacket(&packetRoute, nil /* gso */, hdr, buffer.NewView(0).ToVectorisedView(), ipv4.ProtocolNumber) buf := make([]byte, 6500) bytesRead, err := sock.Read(buf) diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go index 5d36ebe57..fe2779125 100644 --- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go +++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go @@ -65,9 +65,9 @@ func NonBlockingWrite(fd int, buf []byte) *tcpip.Error { return nil } -// NonBlockingWrite2 writes up to two byte slices to a file descriptor in a +// NonBlockingWrite3 writes up to three byte slices to a file descriptor in a // single syscall. It fails if partial data is written. -func NonBlockingWrite2(fd int, b1, b2 []byte) *tcpip.Error { +func NonBlockingWrite3(fd int, b1, b2, b3 []byte) *tcpip.Error { // If the is no second buffer, issue a regular write. if len(b2) == 0 { return NonBlockingWrite(fd, b1) @@ -75,7 +75,7 @@ func NonBlockingWrite2(fd int, b1, b2 []byte) *tcpip.Error { // We have two buffers. Build the iovec that represents them and issue // a writev syscall. - iovec := [...]syscall.Iovec{ + iovec := [3]syscall.Iovec{ { Base: &b1[0], Len: uint64(len(b1)), @@ -85,8 +85,15 @@ func NonBlockingWrite2(fd int, b1, b2 []byte) *tcpip.Error { Len: uint64(len(b2)), }, } + iovecLen := uintptr(2) - _, _, e := syscall.RawSyscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovec[0])), uintptr(len(iovec))) + if len(b3) > 0 { + iovecLen++ + iovec[2].Base = &b3[0] + iovec[2].Len = uint64(len(b3)) + } + + _, _, e := syscall.RawSyscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovec[0])), iovecLen) if e != 0 { return TranslateErrno(e) } diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 27d7eb3b9..6e6aa5a13 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -184,7 +184,7 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { // Add the ethernet header here. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) ethHdr := &header.EthernetFields{ diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 4b8061b13..1f44e224c 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -272,7 +272,7 @@ func TestSimpleSend(t *testing.T) { randomFill(buf) proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) - if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), proto); err != nil { + if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } @@ -341,7 +341,7 @@ func TestPreserveSrcAddressInSend(t *testing.T) { hdr := buffer.NewPrependable(header.EthernetMinimumSize) proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) - if err := c.ep.WritePacket(&r, hdr, buffer.VectorisedView{}, proto); err != nil { + if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buffer.VectorisedView{}, proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } @@ -395,7 +395,7 @@ func TestFillTxQueue(t *testing.T) { for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -410,7 +410,7 @@ func TestFillTxQueue(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -435,7 +435,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Send two packets so that the id slice has at least two slots. for i := 2; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } @@ -455,7 +455,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -470,7 +470,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -493,7 +493,7 @@ func TestFillTxMemory(t *testing.T) { ids := make(map[uint64]struct{}) for i := queueDataSize / bufferSize; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -509,7 +509,7 @@ func TestFillTxMemory(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber) + err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber) if want := tcpip.ErrWouldBlock; err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } @@ -534,7 +534,7 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { // until there is only one buffer left. for i := queueDataSize/bufferSize - 1; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -547,7 +547,7 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) uu := buffer.NewView(bufferSize).ToVectorisedView() - if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, hdr, uu, header.IPv4ProtocolNumber); err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, hdr, uu, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -555,7 +555,7 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { // Attempt to write the one-buffer packet again. It must succeed. { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 4768321d3..462a6e3a3 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -185,10 +185,18 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { return e.lower.LinkAddress() } +// GSOMaxSize returns the maximum GSO packet size. +func (e *endpoint) GSOMaxSize() uint32 { + if gso, ok := e.lower.(stack.GSOEndpoint); ok { + return gso.GSOMaxSize() + } + return 0 +} + // WritePacket implements the stack.LinkEndpoint interface. It is called by // higher-level protocols to write packets; it just logs the packet and forwards // the request to the lower endpoint. -func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { logPacket("send", protocol, hdr.View()) } @@ -229,7 +237,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b panic(err) } } - return e.lower.WritePacket(r, hdr, payload, protocol) + return e.lower.WritePacket(r, gso, hdr, payload, protocol) } func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b buffer.View) { diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 39217e49c..bd9f9845b 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -100,12 +100,12 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements stack.LinkEndpoint.WritePacket. It is called by // higher-level protocols to write packets. It only forwards packets to the // lower endpoint if Wait or WaitWrite haven't been called. -func (e *Endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if !e.writeGate.Enter() { return nil } - err := e.lower.WritePacket(r, hdr, payload, protocol) + err := e.lower.WritePacket(r, gso, hdr, payload, protocol) e.writeGate.Leave() return err } diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 6c57e597a..a2df6be95 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -65,7 +65,7 @@ func (e *countedEndpoint) LinkAddress() tcpip.LinkAddress { return e.linkAddr } -func (e *countedEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *countedEndpoint) WritePacket(r *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { e.writeCount++ return nil } @@ -75,21 +75,21 @@ func TestWaitWrite(t *testing.T) { _, wep := New(stack.RegisterLinkEndpoint(ep)) // Write and check that it goes through. - wep.WritePacket(nil, buffer.Prependable{}, buffer.VectorisedView{}, 0) + wep.WritePacket(nil, nil /* gso */, buffer.Prependable{}, buffer.VectorisedView{}, 0) if want := 1; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } // Wait on dispatches, then try to write. It must go through. wep.WaitDispatch() - wep.WritePacket(nil, buffer.Prependable{}, buffer.VectorisedView{}, 0) + wep.WritePacket(nil, nil /* gso */, buffer.Prependable{}, buffer.VectorisedView{}, 0) if want := 2; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } // Wait on writes, then try to write. It must not go through. wep.WaitWrite() - wep.WritePacket(nil, buffer.Prependable{}, buffer.VectorisedView{}, 0) + wep.WritePacket(nil, nil /* gso */, buffer.Prependable{}, buffer.VectorisedView{}, 0) if want := 2; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 5ab542f2c..975919e80 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -79,7 +79,7 @@ func (e *endpoint) MaxHeaderLength() uint16 { func (e *endpoint) Close() {} -func (e *endpoint) WritePacket(*stack.Route, buffer.Prependable, buffer.VectorisedView, tcpip.TransportProtocolNumber, uint8, stack.PacketLooping) *tcpip.Error { +func (e *endpoint) WritePacket(*stack.Route, *stack.GSO, buffer.Prependable, buffer.VectorisedView, tcpip.TransportProtocolNumber, uint8, stack.PacketLooping) *tcpip.Error { return tcpip.ErrNotSupported } @@ -103,7 +103,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) { copy(pkt.HardwareAddressSender(), r.LocalLinkAddress[:]) copy(pkt.ProtocolAddressSender(), h.ProtocolAddressTarget()) copy(pkt.ProtocolAddressTarget(), h.ProtocolAddressSender()) - e.linkEP.WritePacket(r, hdr, buffer.VectorisedView{}, ProtocolNumber) + e.linkEP.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, ProtocolNumber) fallthrough // also fill the cache from requests case header.ARPReply: addr := tcpip.Address(h.ProtocolAddressSender()) @@ -155,7 +155,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. copy(h.ProtocolAddressSender(), localAddr) copy(h.ProtocolAddressTarget(), addr) - return linkEP.WritePacket(r, hdr, buffer.VectorisedView{}, ProtocolNumber) + return linkEP.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, ProtocolNumber) } // ResolveStaticAddress implements stack.LinkAddressResolver. diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 7eb0e697d..d79eba4b0 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -145,7 +145,7 @@ func (*testObject) LinkAddress() tcpip.LinkAddress { // WritePacket is called by network endpoints after producing a packet and // writing it to the link endpoint. This is used by the test object to verify // that the produced packet is as expected. -func (t *testObject) WritePacket(_ *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (t *testObject) WritePacket(_ *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { var prot tcpip.TransportProtocolNumber var srcAddr tcpip.Address var dstAddr tcpip.Address @@ -221,7 +221,7 @@ func TestIPv4Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - if err := ep.WritePacket(&r, hdr, payload.ToVectorisedView(), 123, 123, stack.PacketOut); err != nil { + if err := ep.WritePacket(&r, nil /* gso */, hdr, payload.ToVectorisedView(), 123, 123, stack.PacketOut); err != nil { t.Fatalf("WritePacket failed: %v", err) } } @@ -450,7 +450,7 @@ func TestIPv6Send(t *testing.T) { if err != nil { t.Fatalf("could not find route: %v", err) } - if err := ep.WritePacket(&r, hdr, payload.ToVectorisedView(), 123, 123, stack.PacketOut); err != nil { + if err := ep.WritePacket(&r, nil /* gso */, hdr, payload.ToVectorisedView(), 123, 123, stack.PacketOut); err != nil { t.Fatalf("WritePacket failed: %v", err) } } diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index 8f94246c9..a9650de03 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -76,7 +76,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V copy(pkt, h) pkt.SetType(header.ICMPv4EchoReply) pkt.SetChecksum(^header.Checksum(pkt, header.ChecksumVV(vv, 0))) - r.WritePacket(hdr, vv, header.ICMPv4ProtocolNumber, r.DefaultTTL()) + r.WritePacket(nil /* gso */, hdr, vv, header.ICMPv4ProtocolNumber, r.DefaultTTL()) case header.ICMPv4EchoReply: if len(v) < header.ICMPv4EchoMinimumSize { diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index c2f9a1bcf..cbdca98a5 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -99,8 +99,16 @@ func (e *endpoint) MaxHeaderLength() uint16 { return e.linkEP.MaxHeaderLength() + header.IPv4MinimumSize } +// GSOMaxSize returns the maximum GSO packet size. +func (e *endpoint) GSOMaxSize() uint32 { + if gso, ok := e.linkEP.(stack.GSOEndpoint); ok { + return gso.GSOMaxSize() + } + return 0 +} + // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop stack.PacketLooping) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop stack.PacketLooping) *tcpip.Error { ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize)) length := uint16(hdr.UsedLength() + payload.Size()) id := uint32(0) @@ -132,7 +140,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b } r.Stats().IP.PacketsSent.Increment() - return e.linkEP.WritePacket(r, hdr, payload, ProtocolNumber) + return e.linkEP.WritePacket(r, gso, hdr, payload, ProtocolNumber) } // HandlePacket is called by the link layer when new ipv4 packets arrive for diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index cfc05d9e1..36d98caef 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -118,7 +118,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V defer r.Release() r.LocalAddress = targetAddr pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{})) - r.WritePacket(hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber, r.DefaultTTL()) + r.WritePacket(nil /* gso */, hdr, buffer.VectorisedView{}, header.ICMPv6ProtocolNumber, r.DefaultTTL()) e.linkAddrCache.AddLinkAddress(e.nicid, r.RemoteAddress, r.RemoteLinkAddress) @@ -143,7 +143,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V copy(pkt, h) pkt.SetType(header.ICMPv6EchoReply) pkt.SetChecksum(icmpChecksum(pkt, r.LocalAddress, r.RemoteAddress, vv)) - r.WritePacket(hdr, vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) + r.WritePacket(nil /* gso */, hdr, vv, header.ICMPv6ProtocolNumber, r.DefaultTTL()) case header.ICMPv6EchoReply: if len(v) < header.ICMPv6EchoMinimumSize { @@ -202,7 +202,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. DstAddr: r.RemoteAddress, }) - return linkEP.WritePacket(r, hdr, buffer.VectorisedView{}, ProtocolNumber) + return linkEP.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, ProtocolNumber) } // ResolveStaticAddress implements stack.LinkAddressResolver. diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index df3b64c98..9a743ea80 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -83,8 +83,16 @@ func (e *endpoint) MaxHeaderLength() uint16 { return e.linkEP.MaxHeaderLength() + header.IPv6MinimumSize } +// GSOMaxSize returns the maximum GSO packet size. +func (e *endpoint) GSOMaxSize() uint32 { + if gso, ok := e.linkEP.(stack.GSOEndpoint); ok { + return gso.GSOMaxSize() + } + return 0 +} + // WritePacket writes a packet to the given destination address and protocol. -func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop stack.PacketLooping) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop stack.PacketLooping) *tcpip.Error { length := uint16(hdr.UsedLength() + payload.Size()) ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize)) ip.Encode(&header.IPv6Fields{ @@ -107,7 +115,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload b } r.Stats().IP.PacketsSent.Increment() - return e.linkEP.WritePacket(r, hdr, payload, ProtocolNumber) + return e.linkEP.WritePacket(r, gso, hdr, payload, ProtocolNumber) } // HandlePacket is called by the link layer when new ipv6 packets arrive for diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 1d032ebf8..8b6c17a90 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -486,7 +486,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr vv.RemoveFirst() // TODO: use route.WritePacket. - if err := n.linkEP.WritePacket(&r, hdr, vv, protocol); err != nil { + if err := n.linkEP.WritePacket(&r, nil /* gso */, hdr, vv, protocol); err != nil { r.Stats().IP.OutgoingPacketErrors.Increment() } else { n.stats.Tx.Packets.Increment() diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index cf4d52fe9..ff356ea22 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -161,7 +161,7 @@ type NetworkEndpoint interface { // WritePacket writes a packet to the given destination address and // protocol. - WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop PacketLooping) *tcpip.Error + WritePacket(r *Route, gso *GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8, loop PacketLooping) *tcpip.Error // ID returns the network protocol endpoint ID. ID() *NetworkEndpointID @@ -226,6 +226,7 @@ const ( CapabilitySaveRestore CapabilityDisconnectOk CapabilityLoopback + CapabilityGSO ) // LinkEndpoint is the interface implemented by data link layer protocols (e.g., @@ -258,7 +259,7 @@ type LinkEndpoint interface { // To participate in transparent bridging, a LinkEndpoint implementation // should call eth.Encode with header.EthernetFields.SrcAddr set to // r.LocalLinkAddress if it is provided. - WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error + WritePacket(r *Route, gso *GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error // Attach attaches the data link layer endpoint to the network-layer // dispatcher of the stack. @@ -381,3 +382,41 @@ func FindLinkEndpoint(id tcpip.LinkEndpointID) LinkEndpoint { return linkEndpoints[id] } + +// GSOType is the type of GSO segments. +// +// +stateify savable +type GSOType int + +// Types of gso segments. +const ( + GSONone GSOType = iota + GSOTCPv4 + GSOTCPv6 +) + +// GSO contains generic segmentation offload properties. +// +// +stateify savable +type GSO struct { + // Type is one of GSONone, GSOTCPv4, etc. + Type GSOType + // NeedsCsum is set if the checksum offload is enabled. + NeedsCsum bool + // CsumOffset is offset after that to place checksum. + CsumOffset uint16 + + // Mss is maximum segment size. + MSS uint16 + // L3Len is L3 (IP) header length. + L3HdrLen uint16 + + // MaxSize is maximum GSO packet size. + MaxSize uint32 +} + +// GSOEndpoint provides access to GSO properties. +type GSOEndpoint interface { + // GSOMaxSize returns the maximum GSO packet size. + GSOMaxSize() uint32 +} diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index ee860eafe..8ae562dcd 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -97,6 +97,14 @@ func (r *Route) Capabilities() LinkEndpointCapabilities { return r.ref.ep.Capabilities() } +// GSOMaxSize returns the maximum GSO packet size. +func (r *Route) GSOMaxSize() uint32 { + if gso, ok := r.ref.ep.(GSOEndpoint); ok { + return gso.GSOMaxSize() + } + return 0 +} + // Resolve attempts to resolve the link address if necessary. Returns ErrWouldBlock in // case address resolution requires blocking, e.g. wait for ARP reply. Waker is // notified when address resolution is complete (success or not). @@ -144,8 +152,8 @@ func (r *Route) IsResolutionRequired() bool { } // WritePacket writes the packet through the given route. -func (r *Route) WritePacket(hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { - err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl, r.loop) +func (r *Route) WritePacket(gso *GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error { + err := r.ref.ep.WritePacket(r, gso, hdr, payload, protocol, ttl, r.loop) if err != nil { r.Stats().IP.OutgoingPacketErrors.Increment() } else { diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index da8269999..b5375df3c 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -112,7 +112,7 @@ func (f *fakeNetworkEndpoint) Capabilities() stack.LinkEndpointCapabilities { return f.linkEP.Capabilities() } -func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, _ uint8, loop stack.PacketLooping) *tcpip.Error { +func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, _ uint8, loop stack.PacketLooping) *tcpip.Error { // Increment the sent packet count in the protocol descriptor. f.proto.sendPacketCount[int(r.RemoteAddress[0])%len(f.proto.sendPacketCount)]++ @@ -134,7 +134,7 @@ func (f *fakeNetworkEndpoint) WritePacket(r *stack.Route, hdr buffer.Prependable return nil } - return f.linkEP.WritePacket(r, hdr, payload, fakeNetNumber) + return f.linkEP.WritePacket(r, gso, hdr, payload, fakeNetNumber) } func (*fakeNetworkEndpoint) Close() {} @@ -281,7 +281,7 @@ func sendTo(t *testing.T, s *stack.Stack, addr tcpip.Address, payload buffer.Vie defer r.Release() hdr := buffer.NewPrependable(int(r.MaxHeaderLength())) - if err := r.WritePacket(hdr, payload.ToVectorisedView(), fakeTransNumber, 123); err != nil { + if err := r.WritePacket(nil /* gso */, hdr, payload.ToVectorisedView(), fakeTransNumber, 123); err != nil { t.Errorf("WritePacket failed: %v", err) } } diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 279ab3c56..dfd31557a 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -74,7 +74,7 @@ func (f *fakeTransportEndpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) if err != nil { return 0, nil, err } - if err := f.route.WritePacket(hdr, buffer.View(v).ToVectorisedView(), fakeTransNumber, 123); err != nil { + if err := f.route.WritePacket(nil /* gso */, hdr, buffer.View(v).ToVectorisedView(), fakeTransNumber, 123); err != nil { return 0, nil, err } diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index d876005fe..182097b46 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -370,7 +370,7 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { func (e *endpoint) send4(r *stack.Route, data buffer.View) *tcpip.Error { if e.raw { hdr := buffer.NewPrependable(len(data) + int(r.MaxHeaderLength())) - return r.WritePacket(hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) } if len(data) < header.ICMPv4EchoMinimumSize { @@ -395,7 +395,7 @@ func (e *endpoint) send4(r *stack.Route, data buffer.View) *tcpip.Error { icmpv4.SetChecksum(0) icmpv4.SetChecksum(^header.Checksum(icmpv4, header.Checksum(data, 0))) - return r.WritePacket(hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) } func send6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { @@ -419,7 +419,7 @@ func send6(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { icmpv6.SetChecksum(0) icmpv6.SetChecksum(^header.Checksum(icmpv6, header.Checksum(data, 0))) - return r.WritePacket(hdr, data.ToVectorisedView(), header.ICMPv6ProtocolNumber, r.DefaultTTL()) + return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), header.ICMPv6ProtocolNumber, r.DefaultTTL()) } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index 7a19737c7..a3894ed8f 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -214,6 +214,8 @@ func (l *listenContext) createConnectedEndpoint(s *segment, iss seqnum.Value, ir n.maybeEnableTimestamp(rcvdSynOpts) n.maybeEnableSACKPermitted(rcvdSynOpts) + n.initGSO() + // Register new endpoint so that packets are routed to it. if err := n.stack.RegisterTransportEndpoint(n.boundNICID, n.effectiveNetProtos, ProtocolNumber, n.id, n, n.reusePort); err != nil { n.Close() diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index c4353718e..056e0b09a 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -557,14 +557,14 @@ func sendSynTCP(r *stack.Route, id stack.TransportEndpointID, flags byte, seq, a } options := makeSynOptions(opts) - err := sendTCP(r, id, buffer.VectorisedView{}, r.DefaultTTL(), flags, seq, ack, rcvWnd, options) + err := sendTCP(r, id, buffer.VectorisedView{}, r.DefaultTTL(), flags, seq, ack, rcvWnd, options, nil) putOptions(options) return err } // sendTCP sends a TCP segment with the provided options via the provided // network endpoint and under the provided identity. -func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, ttl uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte) *tcpip.Error { +func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.VectorisedView, ttl uint8, flags byte, seq, ack seqnum.Value, rcvWnd seqnum.Size, opts []byte, gso *stack.GSO) *tcpip.Error { optLen := len(opts) // Allocate a buffer for the TCP header. hdr := buffer.NewPrependable(header.TCPMinimumSize + int(r.MaxHeaderLength()) + optLen) @@ -586,12 +586,17 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.Vectorise }) copy(tcp[header.TCPMinimumSize:], opts) + length := uint16(hdr.UsedLength() + data.Size()) + xsum := r.PseudoHeaderChecksum(ProtocolNumber, length) // Only calculate the checksum if offloading isn't supported. - if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { - length := uint16(hdr.UsedLength() + data.Size()) - xsum := r.PseudoHeaderChecksum(ProtocolNumber, length) + if gso != nil && gso.NeedsCsum { + // This is called CHECKSUM_PARTIAL in the Linux kernel. We + // calculate a checksum of the pseudo-header and save it in the + // TCP header, then the kernel calculate a checksum of the + // header and data and get the right sum of the TCP packet. + tcp.SetChecksum(xsum) + } else if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { xsum = header.ChecksumVV(data, xsum) - tcp.SetChecksum(^tcp.CalculateChecksum(xsum)) } @@ -600,7 +605,7 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.Vectorise r.Stats().TCP.ResetsSent.Increment() } - return r.WritePacket(hdr, data, ProtocolNumber, ttl) + return r.WritePacket(gso, hdr, data, ProtocolNumber, ttl) } // makeOptions makes an options slice. @@ -649,7 +654,7 @@ func (e *endpoint) sendRaw(data buffer.VectorisedView, flags byte, seq, ack seqn sackBlocks = e.sack.Blocks[:e.sack.NumBlocks] } options := e.makeOptions(sackBlocks) - err := sendTCP(&e.route, e.id, data, e.route.DefaultTTL(), flags, seq, ack, rcvWnd, options) + err := sendTCP(&e.route, e.id, data, e.route.DefaultTTL(), flags, seq, ack, rcvWnd, options, e.gso) putOptions(options) return err } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 5656890f6..0427af34f 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -15,6 +15,7 @@ package tcp import ( + "fmt" "math" "sync" "sync/atomic" @@ -265,6 +266,8 @@ type endpoint struct { // The following are only used to assist the restore run to re-connect. bindAddress tcpip.Address connectingAddress tcpip.Address + + gso *stack.GSO } // StopWork halts packet processing. Only to be used in tests. @@ -1155,6 +1158,8 @@ func (e *endpoint) connect(addr tcpip.FullAddress, handshake bool, run bool) (er e.effectiveNetProtos = netProtos e.connectingAddress = connectingAddr + e.initGSO() + // Connect in the restore phase does not perform handshake. Restore its // connection setting here. if !handshake { @@ -1698,3 +1703,25 @@ func (e *endpoint) completeState() stack.TCPEndpointState { } return s } + +func (e *endpoint) initGSO() { + if e.route.Capabilities()&stack.CapabilityGSO == 0 { + return + } + + gso := &stack.GSO{} + switch e.netProto { + case header.IPv4ProtocolNumber: + gso.Type = stack.GSOTCPv4 + gso.L3HdrLen = header.IPv4MinimumSize + case header.IPv6ProtocolNumber: + gso.Type = stack.GSOTCPv6 + gso.L3HdrLen = header.IPv6MinimumSize + default: + panic(fmt.Sprintf("Unknown netProto: %v", e.netProto)) + } + gso.NeedsCsum = true + gso.CsumOffset = header.TCPChecksumOffset() + gso.MaxSize = e.route.GSOMaxSize() + e.gso = gso +} diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index 8a42f8593..230668b5d 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -153,7 +153,7 @@ func replyWithReset(s *segment) { ack := s.sequenceNumber.Add(s.logicalLen()) - sendTCP(&s.route, s.id, buffer.VectorisedView{}, s.route.DefaultTTL(), header.TCPFlagRst|header.TCPFlagAck, seq, ack, 0, nil) + sendTCP(&s.route, s.id, buffer.VectorisedView{}, s.route.DefaultTTL(), header.TCPFlagRst|header.TCPFlagAck, seq, ack, 0, nil /* options */, nil /* gso */) } // SetOption implements TransportProtocol.SetOption. diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index d751c7d8e..6317748cf 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -129,6 +129,9 @@ type sender struct { // It is initialized on demand. maxPayloadSize int + // gso is set if generic segmentation offload is enabled. + gso bool + // sndWndScale is the number of bits to shift left when reading the send // window size from a segment. sndWndScale uint8 @@ -194,6 +197,11 @@ func newSender(ep *endpoint, iss, irs seqnum.Value, sndWnd seqnum.Size, mss uint // See: https://tools.ietf.org/html/rfc6582#section-3.2 Step 1. last: iss, }, + gso: ep.gso != nil, + } + + if s.gso { + s.ep.gso.MSS = uint16(maxPayloadSize) } s.cc = s.initCongestionControl(ep.cc) @@ -244,6 +252,9 @@ func (s *sender) updateMaxPayloadSize(mtu, count int) { } s.maxPayloadSize = m + if s.gso { + s.ep.gso.MSS = uint16(m) + } s.outstanding -= count if s.outstanding < 0 { @@ -338,6 +349,15 @@ func (s *sender) resendSegment() { // Resend the segment. if seg := s.writeList.Front(); seg != nil { + if seg.data.Size() > s.maxPayloadSize { + available := s.maxPayloadSize + // Split this segment up. + nSeg := seg.clone() + nSeg.data.TrimFront(available) + nSeg.sequenceNumber.UpdateForward(seqnum.Size(available)) + s.writeList.InsertAfter(seg, nSeg) + seg.data.CapLength(available) + } s.sendSegment(seg.data, seg.flags, seg.sequenceNumber) s.ep.stack.Stats().TCP.FastRetransmit.Increment() s.ep.stack.Stats().TCP.Retransmits.Increment() @@ -408,11 +428,24 @@ func (s *sender) retransmitTimerExpired() bool { return true } +// pCount returns the number of packets in the segment. Due to GSO, a segment +// can be composed of multiple packets. +func (s *sender) pCount(seg *segment) int { + size := seg.data.Size() + if size == 0 { + return 1 + } + + return (size-1)/s.maxPayloadSize + 1 +} + // sendData sends new data segments. It is called when data becomes available or // when the send window opens up. func (s *sender) sendData() { limit := s.maxPayloadSize - + if s.gso { + limit = int(s.ep.gso.MaxSize - header.TCPHeaderMaximumSize) + } // Reduce the congestion window to min(IW, cwnd) per RFC 5681, page 10. // "A TCP SHOULD set cwnd to no more than RW before beginning // transmission if the TCP has not sent data in the interval exceeding @@ -427,6 +460,10 @@ func (s *sender) sendData() { end := s.sndUna.Add(s.sndWnd) var dataSent bool for ; seg != nil && s.outstanding < s.sndCwnd; seg = seg.Next() { + cwndLimit := (s.sndCwnd - s.outstanding) * s.maxPayloadSize + if cwndLimit < limit { + limit = cwndLimit + } // We abuse the flags field to determine if we have already // assigned a sequence number to this segment. if seg.flags == 0 { @@ -518,7 +555,7 @@ func (s *sender) sendData() { seg.data.CapLength(available) } - s.outstanding++ + s.outstanding += s.pCount(seg) segEnd = seg.sequenceNumber.Add(seqnum.Size(seg.data.Size())) } @@ -744,8 +781,10 @@ func (s *sender) handleRcvdSegment(seg *segment) { datalen := seg.logicalLen() if datalen > ackLeft { + prevCount := s.pCount(seg) seg.data.TrimFront(int(ackLeft)) seg.sequenceNumber.UpdateForward(ackLeft) + s.outstanding -= prevCount - s.pCount(seg) break } @@ -753,7 +792,7 @@ func (s *sender) handleRcvdSegment(seg *segment) { s.writeNext = seg.Next() } s.writeList.Remove(seg) - s.outstanding-- + s.outstanding -= s.pCount(seg) seg.decRef() ackLeft -= datalen } diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index aa2a73829..5cef8ee97 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -699,7 +699,7 @@ func (c *Context) CreateConnectedWithOptions(wantOptions header.TCPSynOptions) * synOptions := header.ParseSynOptions(tcpSeg.Options(), false) // Build options w/ tsVal to be sent in the SYN-ACK. - synAckOptions := make([]byte, 40) + synAckOptions := make([]byte, header.TCPOptionsMaximumSize) offset := 0 if wantOptions.TS { offset += header.EncodeTSOption(wantOptions.TSVal, synOptions.TSVal, synAckOptions[offset:]) @@ -847,7 +847,7 @@ func (c *Context) PassiveConnect(maxPayload, wndScale int, synOptions header.TCP // value of the window scaling option to be sent in the SYN. If synOptions.WS > // 0 then we send the WindowScale option. func (c *Context) PassiveConnectWithOptions(maxPayload, wndScale int, synOptions header.TCPSynOptions) *RawEndpoint { - opts := make([]byte, 40) + opts := make([]byte, header.TCPOptionsMaximumSize) offset := 0 offset += header.EncodeMSSOption(uint32(maxPayload), opts) diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index b68ed8561..5637f46e3 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -651,7 +651,7 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u // Track count of packets sent. r.Stats().UDP.PacketsSent.Increment() - return r.WritePacket(hdr, data, ProtocolNumber, ttl) + return r.WritePacket(nil /* gso */, hdr, data, ProtocolNumber, ttl) } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (tcpip.NetworkProtocolNumber, *tcpip.Error) { -- cgit v1.2.3 From 52a51a8e20b3e5c28eb1e66bd57203216cf644c5 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Tue, 2 Apr 2019 11:12:29 -0700 Subject: Add a raw socket transport endpoint and use it for raw ICMP sockets. Having raw socket code together will make it easier to add support for other raw network protocols. Currently, only ICMP uses the raw endpoint. However, adding support for other protocols such as UDP shouldn't be much more difficult than adding a few switch cases. PiperOrigin-RevId: 241564875 Change-Id: I77e03adafe4ce0fd29ba2d5dfdc547d2ae8f25bf --- pkg/tcpip/stack/registration.go | 13 +- pkg/tcpip/stack/stack.go | 20 +- pkg/tcpip/stack/transport_demuxer.go | 67 ++-- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/transport/icmp/BUILD | 1 + pkg/tcpip/transport/icmp/endpoint.go | 76 ++--- pkg/tcpip/transport/icmp/protocol.go | 5 +- pkg/tcpip/transport/raw/BUILD | 45 +++ pkg/tcpip/transport/raw/raw.go | 558 +++++++++++++++++++++++++++++++++ pkg/tcpip/transport/raw/state.go | 88 ++++++ pkg/tcpip/transport/tcp/endpoint.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 2 +- test/syscalls/linux/raw_socket_ipv4.cc | 421 ++++++++++++++++++++----- 13 files changed, 1106 insertions(+), 194 deletions(-) create mode 100644 pkg/tcpip/transport/raw/BUILD create mode 100644 pkg/tcpip/transport/raw/raw.go create mode 100644 pkg/tcpip/transport/raw/state.go (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index ff356ea22..f3cc849ec 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -64,13 +64,24 @@ const ( type TransportEndpoint interface { // HandlePacket is called by the stack when new packets arrive to // this transport endpoint. - HandlePacket(r *Route, id TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) + HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) // HandleControlPacket is called by the stack when new control (e.g., // ICMP) packets arrive to this transport endpoint. HandleControlPacket(id TransportEndpointID, typ ControlType, extra uint32, vv buffer.VectorisedView) } +// RawTransportEndpoint is the interface that needs to be implemented by raw +// transport protocol endpoints. RawTransportEndpoints receive the entire +// packet - including the link, network, and transport headers - as delivered +// to netstack. +type RawTransportEndpoint interface { + // HandlePacket is called by the stack when new packets arrive to + // this transport endpoint. The packet contains all data from the link + // layer up. + HandlePacket(r *Route, netHeader buffer.View, packet buffer.VectorisedView) +} + // TransportProtocol is the interface that needs to be implemented by transport // protocols (e.g., tcp, udp) that want to be part of the networking stack. type TransportProtocol interface { diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 15a268b10..a74c0a7a0 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -955,11 +955,11 @@ func (s *Stack) UnregisterTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip } // RegisterRawTransportEndpoint registers the given endpoint with the stack -// transport dispatcher. Received packets that match the provided protocol will -// be delivered to the given endpoint. -func (s *Stack) RegisterRawTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint, reusePort bool) *tcpip.Error { +// transport dispatcher. Received packets that match the provided transport +// protocol will be delivered to the given endpoint. +func (s *Stack) RegisterRawTransportEndpoint(nicID tcpip.NICID, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, ep RawTransportEndpoint) *tcpip.Error { if nicID == 0 { - return s.demux.registerRawEndpoint(netProtos, protocol, ep, reusePort) + return s.demux.registerRawEndpoint(netProto, transProto, ep) } s.mu.RLock() @@ -970,14 +970,14 @@ func (s *Stack) RegisterRawTransportEndpoint(nicID tcpip.NICID, netProtos []tcpi return tcpip.ErrUnknownNICID } - return nic.demux.registerRawEndpoint(netProtos, protocol, ep, reusePort) + return nic.demux.registerRawEndpoint(netProto, transProto, ep) } -// UnregisterRawTransportEndpoint removes the endpoint for the protocol from -// the stack transport dispatcher. -func (s *Stack) UnregisterRawTransportEndpoint(nicID tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint) { +// UnregisterRawTransportEndpoint removes the endpoint for the transport +// protocol from the stack transport dispatcher. +func (s *Stack) UnregisterRawTransportEndpoint(nicID tcpip.NICID, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, ep RawTransportEndpoint) { if nicID == 0 { - s.demux.unregisterRawEndpoint(netProtos, protocol, ep) + s.demux.unregisterRawEndpoint(netProto, transProto, ep) return } @@ -986,7 +986,7 @@ func (s *Stack) UnregisterRawTransportEndpoint(nicID tcpip.NICID, netProtos []tc nic := s.nics[nicID] if nic != nil { - nic.demux.unregisterRawEndpoint(netProtos, protocol, ep) + nic.demux.unregisterRawEndpoint(netProto, transProto, ep) } } diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index 9ab314188..a8ac18e72 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -15,6 +15,7 @@ package stack import ( + "fmt" "math/rand" "sync" @@ -37,7 +38,7 @@ type transportEndpoints struct { endpoints map[TransportEndpointID]TransportEndpoint // rawEndpoints contains endpoints for raw sockets, which receive all // traffic of a given protocol regardless of port. - rawEndpoints []TransportEndpoint + rawEndpoints []RawTransportEndpoint } // unregisterEndpoint unregisters the endpoint with the given id such that it @@ -60,8 +61,10 @@ func (eps *transportEndpoints) unregisterEndpoint(id TransportEndpointID, ep Tra // transportDemuxer demultiplexes packets targeted at a transport endpoint // (i.e., after they've been parsed by the network layer). It does two levels // of demultiplexing: first based on the network and transport protocols, then -// based on endpoints IDs. +// based on endpoints IDs. It should only be instantiated via +// newTransportDemuxer. type transportDemuxer struct { + // protocol is immutable. protocol map[protocolIDs]*transportEndpoints } @@ -137,22 +140,22 @@ func (ep *multiPortEndpoint) selectEndpoint(id TransportEndpointID) TransportEnd // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (ep *multiPortEndpoint) HandlePacket(r *Route, id TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) { +func (ep *multiPortEndpoint) HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) { // If this is a broadcast datagram, deliver the datagram to all endpoints // managed by ep. if id.LocalAddress == header.IPv4Broadcast { for i, endpoint := range ep.endpointsArr { // HandlePacket modifies vv, so each endpoint needs its own copy. if i == len(ep.endpointsArr)-1 { - endpoint.HandlePacket(r, id, netHeader, vv) + endpoint.HandlePacket(r, id, vv) break } vvCopy := buffer.NewView(vv.Size()) copy(vvCopy, vv.ToView()) - endpoint.HandlePacket(r, id, buffer.NewViewFromBytes(netHeader), vvCopy.ToVectorisedView()) + endpoint.HandlePacket(r, id, vvCopy.ToVectorisedView()) } } else { - ep.selectEndpoint(id).HandlePacket(r, id, netHeader, vv) + ep.selectEndpoint(id).HandlePacket(r, id, vv) } } @@ -286,17 +289,17 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto // As in net/ipv4/ip_input.c:ip_local_deliver, attempt to deliver via // raw endpoint first. If there are multipe raw endpoints, they all // receive the packet. - found := false + foundRaw := false for _, rawEP := range eps.rawEndpoints { // Each endpoint gets its own copy of the packet for the sake // of save/restore. - rawEP.HandlePacket(r, id, buffer.NewViewFromBytes(netHeader), vv.ToView().ToVectorisedView()) - found = true + rawEP.HandlePacket(r, buffer.NewViewFromBytes(netHeader), vv.ToView().ToVectorisedView()) + foundRaw = true } eps.mu.RUnlock() // Fail if we didn't find at least one matching transport endpoint. - if len(destEps) == 0 && !found { + if len(destEps) == 0 && !foundRaw { // UDP packet could not be delivered to an unknown destination port. if protocol == header.UDPProtocolNumber { r.Stats().UDP.UnknownPortErrors.Increment() @@ -306,7 +309,7 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto // Deliver the packet. for _, ep := range destEps { - ep.HandlePacket(r, id, netHeader, vv) + ep.HandlePacket(r, id, vv) } return true @@ -371,19 +374,8 @@ func (d *transportDemuxer) findEndpointLocked(eps *transportEndpoints, vv buffer // that packets of the appropriate protocol are delivered to it. A single // packet can be sent to one or more raw endpoints along with a non-raw // endpoint. -func (d *transportDemuxer) registerRawEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint, reusePort bool) *tcpip.Error { - for i, n := range netProtos { - if err := d.singleRegisterRawEndpoint(n, protocol, ep); err != nil { - d.unregisterRawEndpoint(netProtos[:i], protocol, ep) - return err - } - } - - return nil -} - -func (d *transportDemuxer) singleRegisterRawEndpoint(netProto tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint) *tcpip.Error { - eps, ok := d.protocol[protocolIDs{netProto, protocol}] +func (d *transportDemuxer) registerRawEndpoint(netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, ep RawTransportEndpoint) *tcpip.Error { + eps, ok := d.protocol[protocolIDs{netProto, transProto}] if !ok { return nil } @@ -395,19 +387,20 @@ func (d *transportDemuxer) singleRegisterRawEndpoint(netProto tcpip.NetworkProto return nil } -// unregisterRawEndpoint unregisters the raw endpoint for the given protocol -// such that it won't receive any more packets. -func (d *transportDemuxer) unregisterRawEndpoint(netProtos []tcpip.NetworkProtocolNumber, protocol tcpip.TransportProtocolNumber, ep TransportEndpoint) { - for _, n := range netProtos { - if eps, ok := d.protocol[protocolIDs{n, protocol}]; ok { - eps.mu.Lock() - defer eps.mu.Unlock() - for i, rawEP := range eps.rawEndpoints { - if rawEP == ep { - eps.rawEndpoints = append(eps.rawEndpoints[:i], eps.rawEndpoints[i+1:]...) - return - } - } +// unregisterRawEndpoint unregisters the raw endpoint for the given transport +// protocol such that it won't receive any more packets. +func (d *transportDemuxer) unregisterRawEndpoint(netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, ep RawTransportEndpoint) { + eps, ok := d.protocol[protocolIDs{netProto, transProto}] + if !ok { + panic(fmt.Errorf("tried to unregister endpoint with unsupported network and transport protocol pair: %d, %d", netProto, transProto)) + } + + eps.mu.Lock() + defer eps.mu.Unlock() + for i, rawEP := range eps.rawEndpoints { + if rawEP == ep { + eps.rawEndpoints = append(eps.rawEndpoints[:i], eps.rawEndpoints[i+1:]...) + return } } } diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index dfd31557a..0c2589083 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -168,7 +168,7 @@ func (*fakeTransportEndpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Erro return tcpip.FullAddress{}, nil } -func (f *fakeTransportEndpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, _ buffer.View, _ buffer.VectorisedView) { +func (f *fakeTransportEndpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, _ buffer.VectorisedView) { // Increment the number of received packets. f.proto.packetCount++ if f.acceptQueue != nil { diff --git a/pkg/tcpip/transport/icmp/BUILD b/pkg/tcpip/transport/icmp/BUILD index 74d9ff253..9aa6f3978 100644 --- a/pkg/tcpip/transport/icmp/BUILD +++ b/pkg/tcpip/transport/icmp/BUILD @@ -32,6 +32,7 @@ go_library( "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/stack", + "//pkg/tcpip/transport/raw", "//pkg/waiter", ], ) diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index 182097b46..8f2e3aa20 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -59,10 +59,6 @@ type endpoint struct { netProto tcpip.NetworkProtocolNumber transProto tcpip.TransportProtocolNumber waiterQueue *waiter.Queue - // raw indicates whether the endpoint is intended for use by a raw - // socket, which returns the network layer header along with the - // payload. It is immutable. - raw bool // The following fields are used to manage the receive queue, and are // protected by rcvMu. @@ -80,32 +76,26 @@ type endpoint struct { shutdownFlags tcpip.ShutdownFlags id stack.TransportEndpointID state endpointState - bindNICID tcpip.NICID - bindAddr tcpip.Address - regNICID tcpip.NICID - route stack.Route `state:"manual"` + // bindNICID and bindAddr are set via calls to Bind(). They are used to + // reject attempts to send data or connect via a different NIC or + // address + bindNICID tcpip.NICID + bindAddr tcpip.Address + // regNICID is the default NIC to be used when callers don't specify a + // NIC. + regNICID tcpip.NICID + route stack.Route `state:"manual"` } -func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue, raw bool) (*endpoint, *tcpip.Error) { - e := &endpoint{ +func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + return &endpoint{ stack: stack, netProto: netProto, transProto: transProto, waiterQueue: waiterQueue, rcvBufSizeMax: 32 * 1024, sndBufSize: 32 * 1024, - raw: raw, - } - - // Raw endpoints must be immediately bound because they receive all - // ICMP traffic starting from when they're created via socket(). - if raw { - if err := e.bindLocked(tcpip.FullAddress{}); err != nil { - return nil, err - } - } - - return e, nil + }, nil } // Close puts the endpoint in a closed state and frees all resources @@ -115,11 +105,7 @@ func (e *endpoint) Close() { e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite switch e.state { case stateBound, stateConnected: - if e.raw { - e.stack.UnregisterRawTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e) - } else { - e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id, e) - } + e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, e.transProto, e.id, e) } // Close the receive list and drain it. @@ -244,8 +230,9 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c route = &e.route if route.IsResolutionRequired() { - // Promote lock to exclusive if using a shared route, given that it may - // need to change in Route.Resolve() call below. + // Promote lock to exclusive if using a shared route, + // given that it may need to change in Route.Resolve() + // call below. e.mu.RUnlock() defer e.mu.RLock() @@ -290,8 +277,9 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c waker := &sleep.Waker{} if ch, err := route.Resolve(waker); err != nil { if err == tcpip.ErrWouldBlock { - // Link address needs to be resolved. Resolution was triggered the - // background. Better luck next time. + // Link address needs to be resolved. + // Resolution was triggered the background. + // Better luck next time. route.RemoveWaker(waker) return 0, ch, tcpip.ErrNoLinkAddress } @@ -368,11 +356,6 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { } func (e *endpoint) send4(r *stack.Route, data buffer.View) *tcpip.Error { - if e.raw { - hdr := buffer.NewPrependable(len(data) + int(r.MaxHeaderLength())) - return r.WritePacket(nil /* gso */, hdr, data.ToVectorisedView(), header.ICMPv4ProtocolNumber, r.DefaultTTL()) - } - if len(data) < header.ICMPv4EchoMinimumSize { return tcpip.ErrInvalidEndpointState } @@ -439,11 +422,6 @@ func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (t // Connect connects the endpoint to its peer. Specifying a NIC is optional. func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { - // TODO: We don't yet support connect on a raw socket. - if e.raw { - return tcpip.ErrNotSupported - } - e.mu.Lock() defer e.mu.Unlock() @@ -547,11 +525,6 @@ func (*endpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) { } func (e *endpoint) registerWithStack(nicid tcpip.NICID, netProtos []tcpip.NetworkProtocolNumber, id stack.TransportEndpointID) (stack.TransportEndpointID, *tcpip.Error) { - if e.raw { - err := e.stack.RegisterRawTransportEndpoint(nicid, netProtos, e.transProto, e, false) - return stack.TransportEndpointID{}, err - } - if id.LocalPort != 0 { // The endpoint already has a local port, just attempt to // register it. @@ -687,11 +660,12 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { e.rcvMu.Lock() // Drop the packet if our buffer is currently full. if !e.rcvReady || e.rcvClosed || e.rcvBufSize >= e.rcvBufSizeMax { + e.stack.Stats().DroppedPackets.Increment() e.rcvMu.Unlock() return } @@ -706,13 +680,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, ne }, } - if e.raw { - combinedVV := netHeader.ToVectorisedView() - combinedVV.Append(vv) - pkt.data = combinedVV.Clone(pkt.views[:]) - } else { - pkt.data = vv.Clone(pkt.views[:]) - } + pkt.data = vv.Clone(pkt.views[:]) e.rcvList.PushBack(pkt) e.rcvBufSize += pkt.data.Size() diff --git a/pkg/tcpip/transport/icmp/protocol.go b/pkg/tcpip/transport/icmp/protocol.go index 36b70988a..09ee2f892 100644 --- a/pkg/tcpip/transport/icmp/protocol.go +++ b/pkg/tcpip/transport/icmp/protocol.go @@ -30,6 +30,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/raw" "gvisor.googlesource.com/gvisor/pkg/waiter" ) @@ -73,7 +74,7 @@ func (p *protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtoco if netProto != p.netProto() { return nil, tcpip.ErrUnknownProtocol } - return newEndpoint(stack, netProto, p.number, waiterQueue, false) + return newEndpoint(stack, netProto, p.number, waiterQueue) } // NewRawEndpoint creates a new raw icmp endpoint. It implements @@ -82,7 +83,7 @@ func (p *protocol) NewRawEndpoint(stack *stack.Stack, netProto tcpip.NetworkProt if netProto != p.netProto() { return nil, tcpip.ErrUnknownProtocol } - return newEndpoint(stack, netProto, p.number, waiterQueue, true) + return raw.NewEndpoint(stack, netProto, p.number, waiterQueue) } // MinimumPacketSize returns the minimum valid icmp packet size. diff --git a/pkg/tcpip/transport/raw/BUILD b/pkg/tcpip/transport/raw/BUILD new file mode 100644 index 000000000..005079639 --- /dev/null +++ b/pkg/tcpip/transport/raw/BUILD @@ -0,0 +1,45 @@ +package(licenses = ["notice"]) # Apache 2.0 + +load("//tools/go_generics:defs.bzl", "go_template_instance") +load("//tools/go_stateify:defs.bzl", "go_library") + +go_template_instance( + name = "packet_list", + out = "packet_list.go", + package = "raw", + prefix = "packet", + template = "//pkg/ilist:generic_list", + types = { + "Element": "*packet", + "Linker": "*packet", + }, +) + +go_library( + name = "raw", + srcs = [ + "packet_list.go", + "raw.go", + "state.go", + ], + importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/raw", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], + visibility = ["//visibility:public"], + deps = [ + "//pkg/log", + "//pkg/sleep", + "//pkg/tcpip", + "//pkg/tcpip/buffer", + "//pkg/tcpip/header", + "//pkg/tcpip/stack", + "//pkg/waiter", + ], +) + +filegroup( + name = "autogen", + srcs = [ + "packet_list.go", + ], + visibility = ["//:sandbox"], +) diff --git a/pkg/tcpip/transport/raw/raw.go b/pkg/tcpip/transport/raw/raw.go new file mode 100644 index 000000000..8dada2e4f --- /dev/null +++ b/pkg/tcpip/transport/raw/raw.go @@ -0,0 +1,558 @@ +// Copyright 2019 Google LLC +// +// 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 raw provides the implementation of raw sockets (see raw(7)). Raw +// sockets allow applications to: +// +// * manually write and inspect transport layer headers and payloads +// * receive all traffic of a given transport protcol (e.g. ICMP or UDP) +// * optionally write and inspect network layer and link layer headers for +// packets +// +// Raw sockets don't have any notion of ports, and incoming packets are +// demultiplexed solely by protocol number. Thus, a raw UDP endpoint will +// receive every UDP packet received by netstack. bind(2) and connect(2) can be +// used to filter incoming packets by source and destination. +package raw + +import ( + "sync" + + "gvisor.googlesource.com/gvisor/pkg/sleep" + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/header" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +// +stateify savable +type packet struct { + packetEntry + // data holds the actual packet data, including any headers and + // payload. + data buffer.VectorisedView `state:".(buffer.VectorisedView)"` + // views is pre-allocated space to back data. As long as the packet is + // made up of fewer than 8 buffer.Views, no extra allocation is + // necessary to store packet data. + views [8]buffer.View `state:"nosave"` + // timestampNS is the unix time at which the packet was received. + timestampNS int64 + // senderAddr is the network address of the sender. + senderAddr tcpip.FullAddress +} + +// endpoint is the raw socket implementation of tcpip.Endpoint. It is legal to +// have goroutines make concurrent calls into the endpoint. +// +// Lock order: +// endpoint.mu +// endpoint.rcvMu +// +// +stateify savable +type endpoint struct { + // The following fields are initialized at creation time and are + // immutable. + stack *stack.Stack `state:"manual"` + netProto tcpip.NetworkProtocolNumber + transProto tcpip.TransportProtocolNumber + waiterQueue *waiter.Queue + + // The following fields are used to manage the receive queue and are + // protected by rcvMu. + rcvMu sync.Mutex `state:"nosave"` + rcvList packetList + rcvBufSizeMax int `state:".(int)"` + rcvBufSize int + rcvClosed bool + + // The following fields are protected by mu. + mu sync.RWMutex `state:"nosave"` + sndBufSize int + // shutdownFlags represent the current shutdown state of the endpoint. + shutdownFlags tcpip.ShutdownFlags + closed bool + connected bool + bound bool + // registeredNIC is the NIC to which th endpoint is explicitly + // registered. Is set when Connect or Bind are used to specify a NIC. + registeredNIC tcpip.NICID + // boundNIC and boundAddr are set on calls to Bind(). When callers + // attempt actions that would invalidate the binding data (e.g. sending + // data via a NIC other than boundNIC), the endpoint will return an + // error. + boundNIC tcpip.NICID + boundAddr tcpip.Address + // route is the route to a remote network endpoint. It is set via + // Connect(), and is valid only when conneted is true. + route stack.Route `state:"manual"` +} + +// NewEndpoint returns a raw endpoint for the given protocols. +// TODO: IP_HDRINCL, IPPROTO_RAW, and AF_PACKET. +func NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + if netProto != header.IPv4ProtocolNumber { + return nil, tcpip.ErrUnknownProtocol + } + + ep := &endpoint{ + stack: stack, + netProto: netProto, + transProto: transProto, + waiterQueue: waiterQueue, + rcvBufSizeMax: 32 * 1024, + sndBufSize: 32 * 1024, + } + + if err := ep.stack.RegisterRawTransportEndpoint(ep.registeredNIC, ep.netProto, ep.transProto, ep); err != nil { + return nil, err + } + + return ep, nil +} + +// Close implements tcpip.Endpoint.Close. +func (ep *endpoint) Close() { + ep.mu.Lock() + defer ep.mu.Unlock() + + if ep.closed { + return + } + + ep.stack.UnregisterRawTransportEndpoint(ep.registeredNIC, ep.netProto, ep.transProto, ep) + + ep.rcvMu.Lock() + defer ep.rcvMu.Unlock() + + // Clear the receive list. + ep.rcvClosed = true + ep.rcvBufSize = 0 + for !ep.rcvList.Empty() { + ep.rcvList.Remove(ep.rcvList.Front()) + } + + if ep.connected { + ep.route.Release() + } + + ep.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.EventIn | waiter.EventOut) +} + +// Read implements tcpip.Endpoint.Read. +func (ep *endpoint) Read(addr *tcpip.FullAddress) (buffer.View, tcpip.ControlMessages, *tcpip.Error) { + ep.rcvMu.Lock() + + // If there's no data to read, return that read would block or that the + // endpoint is closed. + if ep.rcvList.Empty() { + err := tcpip.ErrWouldBlock + if ep.rcvClosed { + err = tcpip.ErrClosedForReceive + } + ep.rcvMu.Unlock() + return buffer.View{}, tcpip.ControlMessages{}, err + } + + packet := ep.rcvList.Front() + ep.rcvList.Remove(packet) + ep.rcvBufSize -= packet.data.Size() + + ep.rcvMu.Unlock() + + if addr != nil { + *addr = packet.senderAddr + } + + return packet.data.ToView(), tcpip.ControlMessages{HasTimestamp: true, Timestamp: packet.timestampNS}, nil +} + +// Write implements tcpip.Endpoint.Write. +func (ep *endpoint) Write(payload tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-chan struct{}, *tcpip.Error) { + // MSG_MORE is unimplemented. This also means that MSG_EOR is a no-op. + if opts.More { + return 0, nil, tcpip.ErrInvalidOptionValue + } + + ep.mu.RLock() + + if ep.closed { + ep.mu.RUnlock() + return 0, nil, tcpip.ErrInvalidEndpointState + } + + // Check whether we've shutdown writing. + if ep.shutdownFlags&tcpip.ShutdownWrite != 0 { + ep.mu.RUnlock() + return 0, nil, tcpip.ErrClosedForSend + } + + // Did the user caller provide a destination? If not, use the connected + // destination. + if opts.To == nil { + // If the user doesn't specify a destination, they should have + // connected to another address. + if !ep.connected { + ep.mu.RUnlock() + return 0, nil, tcpip.ErrNotConnected + } + + if ep.route.IsResolutionRequired() { + savedRoute := &ep.route + // Promote lock to exclusive if using a shared route, + // given that it may need to change in finishWrite. + ep.mu.RUnlock() + ep.mu.Lock() + + // Make sure that the route didn't change during the + // time we didn't hold the lock. + if !ep.connected || savedRoute != &ep.route { + ep.mu.Unlock() + return 0, nil, tcpip.ErrInvalidEndpointState + } + + n, ch, err := ep.finishWrite(payload, savedRoute) + ep.mu.Unlock() + return n, ch, err + } + + n, ch, err := ep.finishWrite(payload, &ep.route) + ep.mu.RUnlock() + return n, ch, err + } + + // The caller provided a destination. Reject destination address if it + // goes through a different NIC than the endpoint was bound to. + nic := opts.To.NIC + if ep.bound && nic != 0 && nic != ep.boundNIC { + ep.mu.RUnlock() + return 0, nil, tcpip.ErrNoRoute + } + + // We don't support IPv6 yet, so this has to be an IPv4 address. + if len(opts.To.Addr) != header.IPv4AddressSize { + ep.mu.RUnlock() + return 0, nil, tcpip.ErrInvalidEndpointState + } + + // Find the route to the destination. If boundAddress is 0, + // FindRoute will choose an appropriate source address. + route, err := ep.stack.FindRoute(nic, ep.boundAddr, opts.To.Addr, ep.netProto, false) + if err != nil { + ep.mu.RUnlock() + return 0, nil, err + } + + n, ch, err := ep.finishWrite(payload, &route) + route.Release() + ep.mu.RUnlock() + return n, ch, err +} + +// finishWrite writes the payload to a route. It resolves the route if +// necessary. It's really just a helper to make defer unnecessary in Write. +func (ep *endpoint) finishWrite(payload tcpip.Payload, route *stack.Route) (uintptr, <-chan struct{}, *tcpip.Error) { + // We may need to resolve the route (match a link layer address to the + // network address). If that requires blocking (e.g. to use ARP), + // return a channel on which the caller can wait. + if route.IsResolutionRequired() { + waker := &sleep.Waker{} + if ch, err := route.Resolve(waker); err != nil { + if err == tcpip.ErrWouldBlock { + // Link address needs to be resolved. + // Resolution was triggered the background. + // Better luck next time. + route.RemoveWaker(waker) + return 0, ch, tcpip.ErrNoLinkAddress + } + return 0, nil, err + } + } + + payloadBytes, err := payload.Get(payload.Size()) + if err != nil { + return 0, nil, err + } + + switch ep.netProto { + case header.IPv4ProtocolNumber: + hdr := buffer.NewPrependable(len(payloadBytes) + int(route.MaxHeaderLength())) + if err := route.WritePacket(nil /* gso */, hdr, buffer.View(payloadBytes).ToVectorisedView(), header.ICMPv4ProtocolNumber, route.DefaultTTL()); err != nil { + return 0, nil, err + } + + default: + return 0, nil, tcpip.ErrUnknownProtocol + } + + return uintptr(len(payloadBytes)), nil, nil +} + +// Peek implements tcpip.Endpoint.Peek. +func (ep *endpoint) Peek([][]byte) (uintptr, tcpip.ControlMessages, *tcpip.Error) { + return 0, tcpip.ControlMessages{}, nil +} + +// Connect implements tcpip.Endpoint.Connect. +func (ep *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { + ep.mu.Lock() + defer ep.mu.Unlock() + + if ep.closed { + return tcpip.ErrInvalidEndpointState + } + + // We don't support IPv6 yet. + if len(addr.Addr) != header.IPv4AddressSize { + return tcpip.ErrInvalidEndpointState + } + + nic := addr.NIC + if ep.bound { + if ep.boundNIC == 0 { + // If we're bound, but not to a specific NIC, the NIC + // in addr will be used. Nothing to do here. + } else if addr.NIC == 0 { + // If we're bound to a specific NIC, but addr doesn't + // specify a NIC, use the bound NIC. + nic = ep.boundNIC + } else if addr.NIC != ep.boundNIC { + // We're bound and addr specifies a NIC. They must be + // the same. + return tcpip.ErrInvalidEndpointState + } + } + + // Find a route to the destination. + route, err := ep.stack.FindRoute(nic, tcpip.Address(""), addr.Addr, ep.netProto, false) + if err != nil { + return err + } + defer route.Release() + + // Re-register the endpoint with the appropriate NIC. + if err := ep.stack.RegisterRawTransportEndpoint(addr.NIC, ep.netProto, ep.transProto, ep); err != nil { + return err + } + ep.stack.UnregisterRawTransportEndpoint(ep.registeredNIC, ep.netProto, ep.transProto, ep) + + // Save the route and NIC we've connected via. + ep.route = route.Clone() + ep.registeredNIC = nic + ep.connected = true + + return nil +} + +// Shutdown implements tcpip.Endpoint.Shutdown. +func (ep *endpoint) Shutdown(flags tcpip.ShutdownFlags) *tcpip.Error { + ep.mu.Lock() + defer ep.mu.Unlock() + + if !ep.connected { + return tcpip.ErrNotConnected + } + + ep.shutdownFlags |= flags + + if flags&tcpip.ShutdownRead != 0 { + ep.rcvMu.Lock() + wasClosed := ep.rcvClosed + ep.rcvClosed = true + ep.rcvMu.Unlock() + + if !wasClosed { + ep.waiterQueue.Notify(waiter.EventIn) + } + } + + return nil +} + +// Listen implements tcpip.Endpoint.Listen. +func (ep *endpoint) Listen(backlog int) *tcpip.Error { + return tcpip.ErrNotSupported +} + +// Accept implements tcpip.Endpoint.Accept. +func (ep *endpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) { + return nil, nil, tcpip.ErrNotSupported +} + +// Bind implements tcpip.Endpoint.Bind. +func (ep *endpoint) Bind(addr tcpip.FullAddress) *tcpip.Error { + ep.mu.Lock() + defer ep.mu.Unlock() + + // Callers must provide an IPv4 address or no network address (for + // binding to a NIC, but not an address). + if len(addr.Addr) != 0 && len(addr.Addr) != 4 { + return tcpip.ErrInvalidEndpointState + } + + // If a local address was specified, verify that it's valid. + if len(addr.Addr) == header.IPv4AddressSize && ep.stack.CheckLocalAddress(addr.NIC, ep.netProto, addr.Addr) == 0 { + return tcpip.ErrBadLocalAddress + } + + // Re-register the endpoint with the appropriate NIC. + if err := ep.stack.RegisterRawTransportEndpoint(addr.NIC, ep.netProto, ep.transProto, ep); err != nil { + return err + } + ep.stack.UnregisterRawTransportEndpoint(ep.registeredNIC, ep.netProto, ep.transProto, ep) + + ep.registeredNIC = addr.NIC + ep.boundNIC = addr.NIC + ep.boundAddr = addr.Addr + ep.bound = true + + return nil +} + +// GetLocalAddress implements tcpip.Endpoint.GetLocalAddress. +func (ep *endpoint) GetLocalAddress() (tcpip.FullAddress, *tcpip.Error) { + return tcpip.FullAddress{}, tcpip.ErrNotSupported +} + +// GetRemoteAddress implements tcpip.Endpoint.GetRemoteAddress. +func (ep *endpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) { + ep.mu.RLock() + defer ep.mu.RUnlock() + + if !ep.connected { + return tcpip.FullAddress{}, tcpip.ErrNotConnected + } + + return tcpip.FullAddress{ + NIC: ep.registeredNIC, + Addr: ep.route.RemoteAddress, + }, nil +} + +// Readiness implements tcpip.Endpoint.Readiness. +func (ep *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { + // The endpoint is always writable. + result := waiter.EventOut & mask + + // Determine whether the endpoint is readable. + if (mask & waiter.EventIn) != 0 { + ep.rcvMu.Lock() + if !ep.rcvList.Empty() || ep.rcvClosed { + result |= waiter.EventIn + } + ep.rcvMu.Unlock() + } + + return result +} + +// SetSockOpt implements tcpip.Endpoint.SetSockOpt. +func (ep *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { + return nil +} + +// GetSockOpt implements tcpip.Endpoint.GetSockOpt. +func (ep *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { + switch o := opt.(type) { + case tcpip.ErrorOption: + return nil + + case *tcpip.SendBufferSizeOption: + ep.mu.Lock() + *o = tcpip.SendBufferSizeOption(ep.sndBufSize) + ep.mu.Unlock() + return nil + + case *tcpip.ReceiveBufferSizeOption: + ep.rcvMu.Lock() + *o = tcpip.ReceiveBufferSizeOption(ep.rcvBufSizeMax) + ep.rcvMu.Unlock() + return nil + + case *tcpip.ReceiveQueueSizeOption: + ep.rcvMu.Lock() + if ep.rcvList.Empty() { + *o = 0 + } else { + p := ep.rcvList.Front() + *o = tcpip.ReceiveQueueSizeOption(p.data.Size()) + } + ep.rcvMu.Unlock() + return nil + + case *tcpip.KeepaliveEnabledOption: + *o = 0 + return nil + + default: + return tcpip.ErrUnknownProtocolOption + } +} + +// HandlePacket implements stack.RawTransportEndpoint.HandlePacket. +func (ep *endpoint) HandlePacket(route *stack.Route, netHeader buffer.View, vv buffer.VectorisedView) { + ep.rcvMu.Lock() + + // Drop the packet if our buffer is currently full. + if ep.rcvClosed || ep.rcvBufSize >= ep.rcvBufSizeMax { + ep.stack.Stats().DroppedPackets.Increment() + ep.rcvMu.Unlock() + return + } + + if ep.bound { + // If bound to a NIC, only accept data for that NIC. + if ep.boundNIC != 0 && ep.boundNIC != route.NICID() { + ep.rcvMu.Unlock() + return + } + // If bound to an address, only accept data for that address. + if ep.boundAddr != "" && ep.boundAddr != route.RemoteAddress { + ep.rcvMu.Unlock() + return + } + } + + // If connected, only accept packets from the remote address we + // connected to. + if ep.connected && ep.route.RemoteAddress != route.RemoteAddress { + ep.rcvMu.Unlock() + return + } + + wasEmpty := ep.rcvBufSize == 0 + + // Push new packet into receive list and increment the buffer size. + packet := &packet{ + senderAddr: tcpip.FullAddress{ + NIC: route.NICID(), + Addr: route.RemoteAddress, + }, + } + + combinedVV := netHeader.ToVectorisedView() + combinedVV.Append(vv) + packet.data = combinedVV.Clone(packet.views[:]) + packet.timestampNS = ep.stack.NowNanoseconds() + + ep.rcvList.PushBack(packet) + ep.rcvBufSize += packet.data.Size() + + ep.rcvMu.Unlock() + + // Notify waiters that there's data to be read. + if wasEmpty { + ep.waiterQueue.Notify(waiter.EventIn) + } +} diff --git a/pkg/tcpip/transport/raw/state.go b/pkg/tcpip/transport/raw/state.go new file mode 100644 index 000000000..e3891a8b8 --- /dev/null +++ b/pkg/tcpip/transport/raw/state.go @@ -0,0 +1,88 @@ +// Copyright 2018 Google LLC +// +// 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 raw + +import ( + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" +) + +// saveData saves packet.data field. +func (p *packet) saveData() buffer.VectorisedView { + // We cannot save p.data directly as p.data.views may alias to p.views, + // which is not allowed by state framework (in-struct pointer). + return p.data.Clone(nil) +} + +// loadData loads packet.data field. +func (p *packet) loadData(data buffer.VectorisedView) { + // NOTE: We cannot do the p.data = data.Clone(p.views[:]) optimization + // here because data.views is not guaranteed to be loaded by now. Plus, + // data.views will be allocated anyway so there really is little point + // of utilizing p.views for data.views. + p.data = data +} + +// beforeSave is invoked by stateify. +func (ep *endpoint) beforeSave() { + // Stop incoming packets from being handled (and mutate endpoint state). + // The lock will be released after saveRcvBufSizeMax(), which would have + // saved ep.rcvBufSizeMax and set it to 0 to continue blocking incoming + // packets. + ep.rcvMu.Lock() +} + +// saveRcvBufSizeMax is invoked by stateify. +func (ep *endpoint) saveRcvBufSizeMax() int { + max := ep.rcvBufSizeMax + // Make sure no new packets will be handled regardless of the lock. + ep.rcvBufSizeMax = 0 + // Release the lock acquired in beforeSave() so regular endpoint closing + // logic can proceed after save. + ep.rcvMu.Unlock() + return max +} + +// loadRcvBufSizeMax is invoked by stateify. +func (ep *endpoint) loadRcvBufSizeMax(max int) { + ep.rcvBufSizeMax = max +} + +// afterLoad is invoked by stateify. +func (ep *endpoint) afterLoad() { + // StackFromEnv is a stack used specifically for save/restore. + ep.stack = stack.StackFromEnv + + // If the endpoint is connected, re-connect via the save/restore stack. + if ep.connected { + var err *tcpip.Error + ep.route, err = ep.stack.FindRoute(ep.registeredNIC, ep.boundAddr, ep.route.RemoteAddress, ep.netProto, false) + if err != nil { + panic(*err) + } + } + + // If the endpoint is bound, re-bind via the save/restore stack. + if ep.bound { + if ep.stack.CheckLocalAddress(ep.registeredNIC, ep.netProto, ep.boundAddr) == 0 { + panic(tcpip.ErrBadLocalAddress) + } + } + + if err := ep.stack.RegisterRawTransportEndpoint(ep.registeredNIC, ep.netProto, ep.transProto, ep); err != nil { + panic(*err) + } +} diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 0427af34f..41c87cc7e 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1438,7 +1438,7 @@ func (e *endpoint) GetRemoteAddress() (tcpip.FullAddress, *tcpip.Error) { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { s := newSegment(r, id, vv) if !s.parse() { e.stack.Stats().MalformedRcvdPackets.Increment() diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 5637f46e3..19e532180 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -940,7 +940,7 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. -func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, netHeader buffer.View, vv buffer.VectorisedView) { +func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv buffer.VectorisedView) { // Get the header then trim it from the view. hdr := header.UDP(vv.First()) if int(hdr.Length()) > vv.Size() { diff --git a/test/syscalls/linux/raw_socket_ipv4.cc b/test/syscalls/linux/raw_socket_ipv4.cc index 19cded07f..b13806dcb 100644 --- a/test/syscalls/linux/raw_socket_ipv4.cc +++ b/test/syscalls/linux/raw_socket_ipv4.cc @@ -16,8 +16,11 @@ #include #include #include +#include #include #include +#include +#include #include "gtest/gtest.h" #include "test/syscalls/linux/socket_test_util.h" @@ -39,22 +42,26 @@ class RawSocketTest : public ::testing::Test { // Closes the socket created by SetUp(). void TearDown() override; - // The socket used for both reading and writing. - int s_; + // Checks that both an ICMP echo request and reply are received. Calls should + // be wrapped in ASSERT_NO_FATAL_FAILURE. + void ExpectICMPSuccess(const struct icmphdr& icmp); - // The loopback address. - struct sockaddr_in addr_; + void SendEmptyICMP(const struct icmphdr& icmp); + + void SendEmptyICMPTo(int sock, struct sockaddr_in* addr, + const struct icmphdr& icmp); - void SendEmptyICMP(struct icmphdr *icmp); + void ReceiveICMP(char* recv_buf, size_t recv_buf_len, size_t expected_size, + struct sockaddr_in* src); - void SendEmptyICMPTo(int sock, struct sockaddr_in *addr, - struct icmphdr *icmp); + void ReceiveICMPFrom(char* recv_buf, size_t recv_buf_len, + size_t expected_size, struct sockaddr_in* src, int sock); - void ReceiveICMP(char *recv_buf, size_t recv_buf_len, size_t expected_size, - struct sockaddr_in *src); + // The socket used for both reading and writing. + int s_; - void ReceiveICMPFrom(char *recv_buf, size_t recv_buf_len, - size_t expected_size, struct sockaddr_in *src, int sock); + // The loopback address. + struct sockaddr_in addr_; }; void RawSocketTest::SetUp() { @@ -100,49 +107,9 @@ TEST_F(RawSocketTest, SendAndReceive) { icmp.checksum = 2011; icmp.un.echo.sequence = 2012; icmp.un.echo.id = 2014; - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(&icmp)); - - // We're going to receive both the echo request and reply, but the order is - // indeterminate. - char recv_buf[512]; - struct sockaddr_in src; - bool received_request = false; - bool received_reply = false; - - for (int i = 0; i < 2; i++) { - // Receive the packet. - ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf, ABSL_ARRAYSIZE(recv_buf), - sizeof(struct icmphdr), &src)); - EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0); - struct icmphdr *recvd_icmp = - reinterpret_cast(recv_buf + sizeof(struct iphdr)); - switch (recvd_icmp->type) { - case ICMP_ECHO: - EXPECT_FALSE(received_request); - received_request = true; - // The packet should be identical to what we sent. - EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &icmp, sizeof(icmp)), - 0); - break; - - case ICMP_ECHOREPLY: - EXPECT_FALSE(received_reply); - received_reply = true; - // Most fields should be the same. - EXPECT_EQ(recvd_icmp->code, icmp.code); - EXPECT_EQ(recvd_icmp->un.echo.sequence, icmp.un.echo.sequence); - EXPECT_EQ(recvd_icmp->un.echo.id, icmp.un.echo.id); - // A couple are different. - EXPECT_EQ(recvd_icmp->type, ICMP_ECHOREPLY); - // The checksum is computed in such a way that it is guaranteed to have - // changed. - EXPECT_NE(recvd_icmp->checksum, icmp.checksum); - break; - } - } + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); - ASSERT_TRUE(received_request); - ASSERT_TRUE(received_reply); + ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); } // We should be able to create multiple raw sockets for the same protocol and @@ -162,7 +129,7 @@ TEST_F(RawSocketTest, MultipleSocketReceive) { icmp.checksum = 2014; icmp.un.echo.sequence = 2016; icmp.un.echo.id = 2018; - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(&icmp)); + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); // Both sockets will receive the echo request and reply in indeterminate // order, so we'll need to read 2 packets from each. @@ -191,12 +158,14 @@ TEST_F(RawSocketTest, MultipleSocketReceive) { int types[] = {ICMP_ECHO, ICMP_ECHOREPLY}; for (int type : types) { auto match_type = [=](char buf[kBufSize]) { - struct icmphdr *icmp = - reinterpret_cast(buf + sizeof(struct iphdr)); + struct icmphdr* icmp = + reinterpret_cast(buf + sizeof(struct iphdr)); return icmp->type == type; }; - char *icmp1 = *std::find_if(recv_buf1.begin(), recv_buf1.end(), match_type); - char *icmp2 = *std::find_if(recv_buf2.begin(), recv_buf2.end(), match_type); + const char* icmp1 = + *std::find_if(recv_buf1.begin(), recv_buf1.end(), match_type); + const char* icmp2 = + *std::find_if(recv_buf2.begin(), recv_buf2.end(), match_type); ASSERT_NE(icmp1, *recv_buf1.end()); ASSERT_NE(icmp2, *recv_buf2.end()); EXPECT_EQ(memcmp(icmp1 + sizeof(struct iphdr), icmp2 + sizeof(struct iphdr), @@ -217,10 +186,10 @@ TEST_F(RawSocketTest, RawAndPingSockets) { struct icmphdr icmp; icmp.type = ICMP_ECHO; icmp.code = 0; - icmp.un.echo.sequence = - *static_cast(&icmp.un.echo.sequence); + icmp.un.echo.sequence = *static_cast(&icmp.un.echo.sequence); ASSERT_THAT(RetryEINTR(sendto)(ping_sock.get(), &icmp, sizeof(icmp), 0, - (struct sockaddr *)&addr_, sizeof(addr_)), + reinterpret_cast(&addr_), + sizeof(addr_)), SyscallSucceedsWithValue(sizeof(icmp))); // Both sockets will receive the echo request and reply in indeterminate @@ -247,12 +216,12 @@ TEST_F(RawSocketTest, RawAndPingSockets) { int types[] = {ICMP_ECHO, ICMP_ECHOREPLY}; for (int type : types) { auto match_type_ping = [=](char buf[kBufSize]) { - struct icmphdr *icmp = reinterpret_cast(buf); + struct icmphdr* icmp = reinterpret_cast(buf); return icmp->type == type; }; auto match_type_raw = [=](char buf[kBufSize]) { - struct icmphdr *icmp = - reinterpret_cast(buf + sizeof(struct iphdr)); + struct icmphdr* icmp = + reinterpret_cast(buf + sizeof(struct iphdr)); return icmp->type == type; }; @@ -266,39 +235,317 @@ TEST_F(RawSocketTest, RawAndPingSockets) { } } -void RawSocketTest::SendEmptyICMP(struct icmphdr *icmp) { +// Test that shutting down an unconnected socket fails. +TEST_F(RawSocketTest, FailShutdownWithoutConnect) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT(shutdown(s_, SHUT_WR), SyscallFailsWithErrno(ENOTCONN)); + ASSERT_THAT(shutdown(s_, SHUT_RD), SyscallFailsWithErrno(ENOTCONN)); +} + +// Test that writing to a shutdown write socket fails. +TEST_F(RawSocketTest, FailWritingToShutdown) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + ASSERT_THAT(shutdown(s_, SHUT_WR), SyscallSucceeds()); + + char c; + ASSERT_THAT(RetryEINTR(write)(s_, &c, sizeof(c)), + SyscallFailsWithErrno(EPIPE)); +} + +// Test that reading from a shutdown read socket gets nothing. +TEST_F(RawSocketTest, FailReadingFromShutdown) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + ASSERT_THAT(shutdown(s_, SHUT_RD), SyscallSucceeds()); + + char c; + ASSERT_THAT(read(s_, &c, sizeof(c)), SyscallSucceedsWithValue(0)); +} + +// Test that listen() fails. +TEST_F(RawSocketTest, FailListen) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT(listen(s_, 1), SyscallFailsWithErrno(ENOTSUP)); +} + +// Test that accept() fails. +TEST_F(RawSocketTest, FailAccept) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + struct sockaddr saddr; + socklen_t addrlen; + ASSERT_THAT(accept(s_, &saddr, &addrlen), SyscallFailsWithErrno(ENOTSUP)); +} + +// Test that getpeername() returns nothing before connect(). +TEST_F(RawSocketTest, FailGetPeerNameBeforeConnect) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + struct sockaddr saddr; + socklen_t addrlen; + ASSERT_THAT(getpeername(s_, &saddr, &addrlen), + SyscallFailsWithErrno(ENOTCONN)); +} + +// Test that getpeername() returns something after connect(). +TEST_F(RawSocketTest, GetPeerName) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + struct sockaddr saddr; + socklen_t addrlen; + ASSERT_THAT(getpeername(s_, &saddr, &addrlen), SyscallSucceeds()); + ASSERT_GT(addrlen, 0); +} + +// Test that the socket is writable immediately. +TEST_F(RawSocketTest, PollWritableImmediately) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + struct pollfd pfd = {}; + pfd.fd = s_; + pfd.events = POLLOUT; + ASSERT_THAT(RetryEINTR(poll)(&pfd, 1, 10000), SyscallSucceedsWithValue(1)); +} + +// Test that the socket isn't readable before receiving anything. +TEST_F(RawSocketTest, PollNotReadableInitially) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + // Try to receive data with MSG_DONTWAIT, which returns immediately if there's + // nothing to be read. + char buf[117]; + ASSERT_THAT(RetryEINTR(recv)(s_, buf, sizeof(buf), MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Test that the socket becomes readable once something is written to it. +TEST_F(RawSocketTest, PollTriggeredOnWrite) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + // Write something so that there's data to be read. + struct icmphdr icmp = {}; + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + + struct pollfd pfd = {}; + pfd.fd = s_; + pfd.events = POLLIN; + ASSERT_THAT(RetryEINTR(poll)(&pfd, 1, 10000), SyscallSucceedsWithValue(1)); +} + +// Test that we can connect() to a valid IP (loopback). +TEST_F(RawSocketTest, ConnectToLoopback) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); +} + +// Test that connect() sends packets to the right place. +TEST_F(RawSocketTest, SendAndReceiveViaConnect) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 2001; + icmp.un.echo.sequence = 2003; + icmp.un.echo.id = 2004; + ASSERT_THAT(send(s_, &icmp, sizeof(icmp), 0), + SyscallSucceedsWithValue(sizeof(icmp))); + + ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); +} + +// Test that calling send() without connect() fails. +TEST_F(RawSocketTest, SendWithoutConnectFails) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 2015; + icmp.un.echo.sequence = 2017; + icmp.un.echo.id = 2019; + ASSERT_THAT(send(s_, &icmp, sizeof(icmp), 0), + SyscallFailsWithErrno(ENOTCONN)); +} + +// Bind to localhost. +TEST_F(RawSocketTest, BindToLocalhost) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + bind(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); +} + +// Bind to a different address. +TEST_F(RawSocketTest, BindToInvalid) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + struct sockaddr_in bind_addr = {}; + bind_addr.sin_family = AF_INET; + bind_addr.sin_addr = {1}; // 1.0.0.0 - An address that we can't bind to. + ASSERT_THAT(bind(s_, reinterpret_cast(&bind_addr), + sizeof(bind_addr)), + SyscallFailsWithErrno(EADDRNOTAVAIL)); +} + +// Bind to localhost, then send and receive packets. +TEST_F(RawSocketTest, BindSendAndReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + bind(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 2001; + icmp.un.echo.sequence = 2004; + icmp.un.echo.id = 2007; + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + + ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); +} + +// Bind and connect to localhost and send/receive packets. +TEST_F(RawSocketTest, BindConnectSendAndReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + bind(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 2009; + icmp.un.echo.sequence = 2010; + icmp.un.echo.id = 7; + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + + ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); +} + +void RawSocketTest::ExpectICMPSuccess(const struct icmphdr& icmp) { + // We're going to receive both the echo request and reply, but the order is + // indeterminate. + char recv_buf[512]; + struct sockaddr_in src; + bool received_request = false; + bool received_reply = false; + + for (int i = 0; i < 2; i++) { + // Receive the packet. + ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf, ABSL_ARRAYSIZE(recv_buf), + sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0); + struct icmphdr* recvd_icmp = + reinterpret_cast(recv_buf + sizeof(struct iphdr)); + switch (recvd_icmp->type) { + case ICMP_ECHO: + EXPECT_FALSE(received_request); + received_request = true; + // The packet should be identical to what we sent. + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &icmp, sizeof(icmp)), + 0); + break; + + case ICMP_ECHOREPLY: + EXPECT_FALSE(received_reply); + received_reply = true; + // Most fields should be the same. + EXPECT_EQ(recvd_icmp->code, icmp.code); + EXPECT_EQ(recvd_icmp->un.echo.sequence, icmp.un.echo.sequence); + EXPECT_EQ(recvd_icmp->un.echo.id, icmp.un.echo.id); + // A couple are different. + EXPECT_EQ(recvd_icmp->type, ICMP_ECHOREPLY); + // The checksum is computed in such a way that it is guaranteed to have + // changed. + EXPECT_NE(recvd_icmp->checksum, icmp.checksum); + break; + } + } + + ASSERT_TRUE(received_request); + ASSERT_TRUE(received_reply); +} + +void RawSocketTest::SendEmptyICMP(const struct icmphdr& icmp) { ASSERT_NO_FATAL_FAILURE(SendEmptyICMPTo(s_, &addr_, icmp)); } -void RawSocketTest::SendEmptyICMPTo(int sock, struct sockaddr_in *addr, - struct icmphdr *icmp) { - struct iovec iov = {.iov_base = icmp, .iov_len = sizeof(*icmp)}; - struct msghdr msg { - .msg_name = addr, .msg_namelen = sizeof(*addr), .msg_iov = &iov, - .msg_iovlen = 1, .msg_control = NULL, .msg_controllen = 0, .msg_flags = 0, - }; - ASSERT_THAT(sendmsg(sock, &msg, 0), SyscallSucceedsWithValue(sizeof(*icmp))); +void RawSocketTest::SendEmptyICMPTo(int sock, struct sockaddr_in* addr, + const struct icmphdr& icmp) { + // It's safe to use const_cast here because sendmsg won't modify the iovec. + struct iovec iov = {}; + iov.iov_base = static_cast(const_cast(&icmp)); + iov.iov_len = sizeof(icmp); + struct msghdr msg = {}; + msg.msg_name = addr; + msg.msg_namelen = sizeof(*addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + ASSERT_THAT(sendmsg(sock, &msg, 0), SyscallSucceedsWithValue(sizeof(icmp))); } -void RawSocketTest::ReceiveICMP(char *recv_buf, size_t recv_buf_len, - size_t expected_size, struct sockaddr_in *src) { +void RawSocketTest::ReceiveICMP(char* recv_buf, size_t recv_buf_len, + size_t expected_size, struct sockaddr_in* src) { ASSERT_NO_FATAL_FAILURE( ReceiveICMPFrom(recv_buf, recv_buf_len, expected_size, src, s_)); } -void RawSocketTest::ReceiveICMPFrom(char *recv_buf, size_t recv_buf_len, +void RawSocketTest::ReceiveICMPFrom(char* recv_buf, size_t recv_buf_len, size_t expected_size, - struct sockaddr_in *src, int sock) { - struct iovec iov = {.iov_base = recv_buf, .iov_len = recv_buf_len}; - struct msghdr msg = { - .msg_name = src, - .msg_namelen = sizeof(*src), - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = NULL, - .msg_controllen = 0, - .msg_flags = 0, - }; + struct sockaddr_in* src, int sock) { + struct iovec iov = {}; + iov.iov_base = recv_buf; + iov.iov_len = recv_buf_len; + struct msghdr msg = {}; + msg.msg_name = src; + msg.msg_namelen = sizeof(*src); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; // We should receive the ICMP packet plus 20 bytes of IP header. ASSERT_THAT(recvmsg(sock, &msg, 0), SyscallSucceedsWithValue(expected_size + sizeof(struct iphdr))); -- cgit v1.2.3 From eaac2806ffadbb3db6317e58c61b855b1350f0aa Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Tue, 9 Apr 2019 11:22:28 -0700 Subject: Add TCP checksum verification. PiperOrigin-RevId: 242704699 Change-Id: I87db368ca343b3b4bf4f969b17d3aa4ce2f8bd4f --- pkg/sentry/socket/epsocket/epsocket.go | 1 + pkg/tcpip/header/tcp.go | 68 ++++++++++++++++----------------- pkg/tcpip/link/fdbased/endpoint.go | 18 ++++++--- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/muxed/injectable.go | 2 +- pkg/tcpip/link/muxed/injectable_test.go | 4 +- pkg/tcpip/stack/registration.go | 10 ++++- pkg/tcpip/tcpip.go | 3 ++ pkg/tcpip/transport/tcp/connect.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 9 ++++- pkg/tcpip/transport/tcp/forwarder.go | 2 +- pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/tcp/segment.go | 31 +++++++++++++-- pkg/tcpip/transport/tcp/tcp_test.go | 29 +++++++++++++- pkg/tcpip/transport/udp/endpoint.go | 2 +- runsc/boot/network.go | 1 + 16 files changed, 129 insertions(+), 57 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index e170da169..5bcafad98 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -154,6 +154,7 @@ var Metrics = tcpip.Stats{ SlowStartRetransmits: mustCreateMetric("/netstack/tcp/slow_start_retransmits", "Number of segments retransmitted in slow start mode."), FastRetransmit: mustCreateMetric("/netstack/tcp/fast_retransmit", "Number of TCP segments which were fast retransmitted."), Timeouts: mustCreateMetric("/netstack/tcp/timeouts", "Number of times RTO expired."), + ChecksumErrors: mustCreateMetric("/netstack/tcp/checksum_errors", "Number of segments dropped due to bad checksums."), }, UDP: tcpip.UDPStats{ PacketsReceived: mustCreateMetric("/netstack/udp/packets_received", "Number of UDP datagrams received via HandlePacket."), diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index 6e3ee2e50..e656ebb15 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -22,16 +22,17 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum" ) +// These constants are the offsets of the respective fields in the TCP header. const ( - srcPort = 0 - dstPort = 2 - seqNum = 4 - ackNum = 8 - dataOffset = 12 - tcpFlags = 13 - winSize = 14 - tcpChecksum = 16 - urgentPtr = 18 + TCPSrcPortOffset = 0 + TCPDstPortOffset = 2 + TCPSeqNumOffset = 4 + TCPAckNumOffset = 8 + TCPDataOffset = 12 + TCPFlagsOffset = 13 + TCPWinSizeOffset = 14 + TCPChecksumOffset = 16 + TCPUrgentPtrOffset = 18 ) const ( @@ -179,27 +180,27 @@ const ( // SourcePort returns the "source port" field of the tcp header. func (b TCP) SourcePort() uint16 { - return binary.BigEndian.Uint16(b[srcPort:]) + return binary.BigEndian.Uint16(b[TCPSrcPortOffset:]) } // DestinationPort returns the "destination port" field of the tcp header. func (b TCP) DestinationPort() uint16 { - return binary.BigEndian.Uint16(b[dstPort:]) + return binary.BigEndian.Uint16(b[TCPDstPortOffset:]) } // SequenceNumber returns the "sequence number" field of the tcp header. func (b TCP) SequenceNumber() uint32 { - return binary.BigEndian.Uint32(b[seqNum:]) + return binary.BigEndian.Uint32(b[TCPSeqNumOffset:]) } // AckNumber returns the "ack number" field of the tcp header. func (b TCP) AckNumber() uint32 { - return binary.BigEndian.Uint32(b[ackNum:]) + return binary.BigEndian.Uint32(b[TCPAckNumOffset:]) } // DataOffset returns the "data offset" field of the tcp header. func (b TCP) DataOffset() uint8 { - return (b[dataOffset] >> 4) * 4 + return (b[TCPDataOffset] >> 4) * 4 } // Payload returns the data in the tcp packet. @@ -209,32 +210,32 @@ func (b TCP) Payload() []byte { // Flags returns the flags field of the tcp header. func (b TCP) Flags() uint8 { - return b[tcpFlags] + return b[TCPFlagsOffset] } // WindowSize returns the "window size" field of the tcp header. func (b TCP) WindowSize() uint16 { - return binary.BigEndian.Uint16(b[winSize:]) + return binary.BigEndian.Uint16(b[TCPWinSizeOffset:]) } // Checksum returns the "checksum" field of the tcp header. func (b TCP) Checksum() uint16 { - return binary.BigEndian.Uint16(b[tcpChecksum:]) + return binary.BigEndian.Uint16(b[TCPChecksumOffset:]) } // SetSourcePort sets the "source port" field of the tcp header. func (b TCP) SetSourcePort(port uint16) { - binary.BigEndian.PutUint16(b[srcPort:], port) + binary.BigEndian.PutUint16(b[TCPSrcPortOffset:], port) } // SetDestinationPort sets the "destination port" field of the tcp header. func (b TCP) SetDestinationPort(port uint16) { - binary.BigEndian.PutUint16(b[dstPort:], port) + binary.BigEndian.PutUint16(b[TCPDstPortOffset:], port) } // SetChecksum sets the checksum field of the tcp header. func (b TCP) SetChecksum(checksum uint16) { - binary.BigEndian.PutUint16(b[tcpChecksum:], checksum) + binary.BigEndian.PutUint16(b[TCPChecksumOffset:], checksum) } // CalculateChecksum calculates the checksum of the tcp segment. @@ -258,20 +259,20 @@ func (b TCP) ParsedOptions() TCPOptions { } func (b TCP) encodeSubset(seq, ack uint32, flags uint8, rcvwnd uint16) { - binary.BigEndian.PutUint32(b[seqNum:], seq) - binary.BigEndian.PutUint32(b[ackNum:], ack) - b[tcpFlags] = flags - binary.BigEndian.PutUint16(b[winSize:], rcvwnd) + binary.BigEndian.PutUint32(b[TCPSeqNumOffset:], seq) + binary.BigEndian.PutUint32(b[TCPAckNumOffset:], ack) + b[TCPFlagsOffset] = flags + binary.BigEndian.PutUint16(b[TCPWinSizeOffset:], rcvwnd) } // Encode encodes all the fields of the tcp header. func (b TCP) Encode(t *TCPFields) { b.encodeSubset(t.SeqNum, t.AckNum, t.Flags, t.WindowSize) - binary.BigEndian.PutUint16(b[srcPort:], t.SrcPort) - binary.BigEndian.PutUint16(b[dstPort:], t.DstPort) - b[dataOffset] = (t.DataOffset / 4) << 4 - binary.BigEndian.PutUint16(b[tcpChecksum:], t.Checksum) - binary.BigEndian.PutUint16(b[urgentPtr:], t.UrgentPointer) + binary.BigEndian.PutUint16(b[TCPSrcPortOffset:], t.SrcPort) + binary.BigEndian.PutUint16(b[TCPDstPortOffset:], t.DstPort) + b[TCPDataOffset] = (t.DataOffset / 4) << 4 + binary.BigEndian.PutUint16(b[TCPChecksumOffset:], t.Checksum) + binary.BigEndian.PutUint16(b[TCPUrgentPtrOffset:], t.UrgentPointer) } // EncodePartial updates a subset of the fields of the tcp header. It is useful @@ -290,18 +291,13 @@ func (b TCP) EncodePartial(partialChecksum, length uint16, seqnum, acknum uint32 b.encodeSubset(seqnum, acknum, flags, rcvwnd) // Add the contributions of the passed-in fields to the checksum. - checksum = Checksum(b[seqNum:seqNum+8], checksum) - checksum = Checksum(b[winSize:winSize+2], checksum) + checksum = Checksum(b[TCPSeqNumOffset:TCPSeqNumOffset+8], checksum) + checksum = Checksum(b[TCPWinSizeOffset:TCPWinSizeOffset+2], checksum) // Encode the checksum. b.SetChecksum(^checksum) } -// TCPChecksumOffset returns offset of the checksum field. -func TCPChecksumOffset() uint16 { - return tcpChecksum -} - // ParseSynOptions parses the options received in a SYN segment and returns the // relevant ones. opts should point to the option part of the TCP Header. func ParseSynOptions(opts []byte, isAck bool) TCPSynOptions { diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 20e34c5ee..84439a9ed 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -122,13 +122,14 @@ type Options struct { FD int MTU uint32 EthernetHeader bool - ChecksumOffload bool ClosedFunc func(*tcpip.Error) Address tcpip.LinkAddress SaveRestore bool DisconnectOk bool GSOMaxSize uint32 PacketDispatchMode PacketDispatchMode + TXChecksumOffload bool + RXChecksumOffload bool } // New creates a new fd-based endpoint. @@ -142,8 +143,12 @@ func New(opts *Options) tcpip.LinkEndpointID { } caps := stack.LinkEndpointCapabilities(0) - if opts.ChecksumOffload { - caps |= stack.CapabilityChecksumOffload + if opts.RXChecksumOffload { + caps |= stack.CapabilityRXChecksumOffload + } + + if opts.TXChecksumOffload { + caps |= stack.CapabilityTXChecksumOffload } hdrSize := 0 @@ -527,12 +532,13 @@ func (e *InjectableEndpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buf } // NewInjectable creates a new fd-based InjectableEndpoint. -func NewInjectable(fd int, mtu uint32) (tcpip.LinkEndpointID, *InjectableEndpoint) { +func NewInjectable(fd int, mtu uint32, capabilities stack.LinkEndpointCapabilities) (tcpip.LinkEndpointID, *InjectableEndpoint) { syscall.SetNonblock(fd, true) e := &InjectableEndpoint{endpoint: endpoint{ - fd: fd, - mtu: mtu, + fd: fd, + mtu: mtu, + caps: capabilities, }} return stack.RegisterLinkEndpoint(e), e diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index d58c0f885..2dc4bcfda 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -56,7 +56,7 @@ func (*endpoint) MTU() uint32 { // Capabilities implements stack.LinkEndpoint.Capabilities. Loopback advertises // itself as supporting checksum offload, but in reality it's just omitted. func (*endpoint) Capabilities() stack.LinkEndpointCapabilities { - return stack.CapabilityChecksumOffload | stack.CapabilitySaveRestore | stack.CapabilityLoopback + return stack.CapabilityRXChecksumOffload | stack.CapabilityTXChecksumOffload | stack.CapabilitySaveRestore | stack.CapabilityLoopback } // MaxHeaderLength implements stack.LinkEndpoint.MaxHeaderLength. Given that the diff --git a/pkg/tcpip/link/muxed/injectable.go b/pkg/tcpip/link/muxed/injectable.go index 99edc232d..b3e71c7fc 100644 --- a/pkg/tcpip/link/muxed/injectable.go +++ b/pkg/tcpip/link/muxed/injectable.go @@ -105,7 +105,7 @@ func (m *InjectableEndpoint) WriteRawPacket(dest tcpip.Address, packet []byte) * } // NewInjectableEndpoint creates a new multi-endpoint injectable endpoint. -func NewInjectableEndpoint(routes map[tcpip.Address]stack.InjectableLinkEndpoint, mtu uint32) (tcpip.LinkEndpointID, *InjectableEndpoint) { +func NewInjectableEndpoint(routes map[tcpip.Address]stack.InjectableLinkEndpoint) (tcpip.LinkEndpointID, *InjectableEndpoint) { e := &InjectableEndpoint{ routes: routes, } diff --git a/pkg/tcpip/link/muxed/injectable_test.go b/pkg/tcpip/link/muxed/injectable_test.go index 7d25effad..031449a05 100644 --- a/pkg/tcpip/link/muxed/injectable_test.go +++ b/pkg/tcpip/link/muxed/injectable_test.go @@ -87,8 +87,8 @@ func makeTestInjectableEndpoint(t *testing.T) (*InjectableEndpoint, *os.File, tc if err != nil { t.Fatal("Failed to create socket pair:", err) } - _, underlyingEndpoint := fdbased.NewInjectable(pair[1], 6500) + _, underlyingEndpoint := fdbased.NewInjectable(pair[1], 6500, stack.CapabilityNone) routes := map[tcpip.Address]stack.InjectableLinkEndpoint{dstIP: underlyingEndpoint} - _, endpoint := NewInjectableEndpoint(routes, 6500) + _, endpoint := NewInjectableEndpoint(routes) return endpoint, os.NewFile(uintptr(pair[0]), "test route end"), dstIP } diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index f3cc849ec..6e1660051 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -232,7 +232,15 @@ type LinkEndpointCapabilities uint // The following are the supported link endpoint capabilities. const ( - CapabilityChecksumOffload LinkEndpointCapabilities = 1 << iota + CapabilityNone LinkEndpointCapabilities = 0 + // CapabilityTXChecksumOffload indicates that the link endpoint supports + // checksum computation for outgoing packets and the stack can skip + // computing checksums when sending packets. + CapabilityTXChecksumOffload LinkEndpointCapabilities = 1 << iota + // CapabilityRXChecksumOffload indicates that the link endpoint supports + // checksum verification on received packets and that it's safe for the + // stack to skip checksum verification. + CapabilityRXChecksumOffload CapabilityResolutionRequired CapabilitySaveRestore CapabilityDisconnectOk diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index e9f73635f..e898dcbca 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -801,6 +801,9 @@ type TCPStats struct { // Timeouts is the number of times the RTO expired. Timeouts *StatCounter + + // ChecksumErrors is the number of segments dropped due to bad checksums. + ChecksumErrors *StatCounter } // UDPStats collects UDP-specific stats. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 056e0b09a..6c4a4d95e 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -595,7 +595,7 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.Vectorise // TCP header, then the kernel calculate a checksum of the // header and data and get the right sum of the TCP packet. tcp.SetChecksum(xsum) - } else if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { + } else if r.Capabilities()&stack.CapabilityTXChecksumOffload == 0 { xsum = header.ChecksumVV(data, xsum) tcp.SetChecksum(^tcp.CalculateChecksum(xsum)) } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 41c87cc7e..b5d05af7d 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1447,6 +1447,13 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv return } + if !s.csumValid { + e.stack.Stats().MalformedRcvdPackets.Increment() + e.stack.Stats().TCP.ChecksumErrors.Increment() + s.decRef() + return + } + e.stack.Stats().TCP.ValidSegmentsReceived.Increment() if (s.flags & header.TCPFlagRst) != 0 { e.stack.Stats().TCP.ResetsReceived.Increment() @@ -1721,7 +1728,7 @@ func (e *endpoint) initGSO() { panic(fmt.Sprintf("Unknown netProto: %v", e.netProto)) } gso.NeedsCsum = true - gso.CsumOffset = header.TCPChecksumOffset() + gso.CsumOffset = header.TCPChecksumOffset gso.MaxSize = e.route.GSOMaxSize() e.gso = gso } diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index 7a6589cfd..6a7efaf1d 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -68,7 +68,7 @@ func (f *Forwarder) HandlePacket(r *stack.Route, id stack.TransportEndpointID, n defer s.decRef() // We only care about well-formed SYN packets. - if !s.parse() || s.flags != header.TCPFlagSyn { + if !s.parse() || !s.csumValid || s.flags != header.TCPFlagSyn { return false } diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index 230668b5d..b5fb160bc 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -130,7 +130,7 @@ func (*protocol) HandleUnknownDestinationPacket(r *stack.Route, id stack.Transpo s := newSegment(r, id, vv) defer s.decRef() - if !s.parse() { + if !s.parse() || !s.csumValid { return false } diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index df8402bf9..c603fe713 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -45,6 +45,10 @@ type segment struct { ackNumber seqnum.Value flags uint8 window seqnum.Size + // csum is only populated for received segments. + csum uint16 + // csumValid is true if the csum in the received segment is valid. + csumValid bool // parsedOptions stores the parsed values from the options in the segment. parsedOptions header.TCPOptions @@ -124,7 +128,13 @@ func (s *segment) logicalLen() seqnum.Size { // parse populates the sequence & ack numbers, flags, and window fields of the // segment from the TCP header stored in the data. It then updates the view to -// skip the data. Returns boolean indicating if the parsing was successful. +// skip the header. +// +// Returns boolean indicating if the parsing was successful. +// +// If checksum verification is not offloaded then parse also verifies the +// TCP checksum and stores the checksum and result of checksum verification in +// the csum and csumValid fields of the segment. func (s *segment) parse() bool { h := header.TCP(s.data.First()) @@ -145,12 +155,27 @@ func (s *segment) parse() bool { s.options = []byte(h[header.TCPMinimumSize:offset]) s.parsedOptions = header.ParseTCPOptions(s.options) - s.data.TrimFront(offset) + + // Query the link capabilities to decide if checksum validation is + // required. + verifyChecksum := true + if s.route.Capabilities()&stack.CapabilityRXChecksumOffload != 0 { + s.csumValid = true + verifyChecksum = false + s.data.TrimFront(offset) + } + if verifyChecksum { + s.csum = h.Checksum() + xsum := s.route.PseudoHeaderChecksum(ProtocolNumber, uint16(s.data.Size())) + xsum = h.CalculateChecksum(xsum) + s.data.TrimFront(offset) + xsum = header.ChecksumVV(s.data, xsum) + s.csumValid = xsum == 0xffff + } s.sequenceNumber = seqnum.Value(h.SequenceNumber()) s.ackNumber = seqnum.Value(h.AckNumber()) s.flags = h.Flags() s.window = seqnum.Size(h.WindowSize()) - return true } diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index 7f2615ca9..af50ac8af 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -2963,8 +2963,7 @@ func TestReceivedInvalidSegmentCountIncrement(t *testing.T) { RcvWnd: 30000, }) tcpbuf := vv.First()[header.IPv4MinimumSize:] - // 12 is the TCP header data offset. - tcpbuf[12] = ((header.TCPMinimumSize - 1) / 4) << 4 + tcpbuf[header.TCPDataOffset] = ((header.TCPMinimumSize - 1) / 4) << 4 c.SendSegment(vv) @@ -2973,6 +2972,32 @@ func TestReceivedInvalidSegmentCountIncrement(t *testing.T) { } } +func TestReceivedIncorrectChecksumIncrement(t *testing.T) { + c := context.New(t, defaultMTU) + defer c.Cleanup() + c.CreateConnected(789, 30000, nil) + stats := c.Stack().Stats() + want := stats.TCP.ChecksumErrors.Value() + 1 + vv := c.BuildSegment([]byte{0x1, 0x2, 0x3}, &context.Headers{ + SrcPort: context.TestPort, + DstPort: c.Port, + Flags: header.TCPFlagAck, + SeqNum: seqnum.Value(790), + AckNum: c.IRS.Add(1), + RcvWnd: 30000, + }) + tcpbuf := vv.First()[header.IPv4MinimumSize:] + // Overwrite a byte in the payload which should cause checksum + // verification to fail. + tcpbuf[(tcpbuf[header.TCPDataOffset]>>4)*4] = 0x4 + + c.SendSegment(vv) + + if got := stats.TCP.ChecksumErrors.Value(); got != want { + t.Errorf("got stats.TCP.ChecksumErrors.Value() = %d, want = %d", got, want) + } +} + func TestReceivedSegmentQueuing(t *testing.T) { // This test sends 200 segments containing a few bytes each to an // endpoint and checks that they're all received and acknowledged by diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 19e532180..1f9251de3 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -640,7 +640,7 @@ func sendUDP(r *stack.Route, data buffer.VectorisedView, localPort, remotePort u }) // Only calculate the checksum if offloading isn't supported. - if r.Capabilities()&stack.CapabilityChecksumOffload == 0 { + if r.Capabilities()&stack.CapabilityTXChecksumOffload == 0 { xsum := r.PseudoHeaderChecksum(ProtocolNumber, length) for _, v := range data.Views() { xsum = header.Checksum(v, xsum) diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 77291415b..3915a021f 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -142,6 +142,7 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct Address: mac, PacketDispatchMode: fdbased.PacketMMap, GSOMaxSize: link.GSOMaxSize, + RXChecksumOffload: true, }) log.Infof("Enabling interface %q with id %d on addresses %+v (%v)", link.Name, nicID, link.Addresses, mac) -- cgit v1.2.3 From 43dff57b878edb5502daf486cbc13b058780dd56 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Fri, 26 Apr 2019 16:50:35 -0700 Subject: Make raw sockets a toggleable feature disabled by default. PiperOrigin-RevId: 245511019 Change-Id: Ia9562a301b46458988a6a1f0bbd5f07cbfcb0615 --- pkg/syserr/netstack.go | 2 ++ pkg/tcpip/stack/stack.go | 12 ++++++++++++ pkg/tcpip/tcpip.go | 1 + pkg/tcpip/transport/tcp/endpoint_state.go | 1 + runsc/boot/config.go | 6 ++++++ runsc/boot/loader.go | 7 +++++-- runsc/cmd/exec.go | 18 +++++++++++++++--- runsc/main.go | 2 ++ runsc/specutils/specutils.go | 22 ++++++++++++++++------ runsc/test/integration/BUILD | 5 ++++- runsc/test/integration/exec_test.go | 26 +++++++++++++++++++++++--- runsc/test/testutil/docker.go | 21 +++++++++++++++++---- 12 files changed, 104 insertions(+), 19 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go index c5a628c7d..1a23919ef 100644 --- a/pkg/syserr/netstack.go +++ b/pkg/syserr/netstack.go @@ -45,6 +45,7 @@ var ( ErrNoSuchFile = New(tcpip.ErrNoSuchFile.String(), linux.ENOENT) ErrInvalidOptionValue = New(tcpip.ErrInvalidOptionValue.String(), linux.EINVAL) ErrBroadcastDisabled = New(tcpip.ErrBroadcastDisabled.String(), linux.EACCES) + ErrNotPermittedNet = New(tcpip.ErrNotPermitted.String(), linux.EPERM) ) var netstackErrorTranslations = map[*tcpip.Error]*Error{ @@ -84,6 +85,7 @@ var netstackErrorTranslations = map[*tcpip.Error]*Error{ tcpip.ErrMessageTooLong: ErrMessageTooLong, tcpip.ErrNoBufferSpace: ErrNoBufferSpace, tcpip.ErrBroadcastDisabled: ErrBroadcastDisabled, + tcpip.ErrNotPermitted: ErrNotPermittedNet, } // TranslateNetstackError converts an error from the tcpip package to a sentry diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index a74c0a7a0..8f7b6f781 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -291,6 +291,10 @@ type Stack struct { linkAddrCache *linkAddrCache + // raw indicates whether raw sockets may be created. It is set during + // Stack creation and is immutable. + raw bool + mu sync.RWMutex nics map[tcpip.NICID]*NIC forwarding bool @@ -327,6 +331,9 @@ type Options struct { // should be handled by the stack internally (true) or outside the // stack (false). HandleLocal bool + + // Raw indicates whether raw sockets may be created. + Raw bool } // New allocates a new networking stack with only the requested networking and @@ -352,6 +359,7 @@ func New(network []string, transport []string, opts Options) *Stack { clock: clock, stats: opts.Stats.FillIn(), handleLocal: opts.HandleLocal, + raw: opts.Raw, } // Add specified network protocols. @@ -512,6 +520,10 @@ func (s *Stack) NewEndpoint(transport tcpip.TransportProtocolNumber, network tcp // protocol. Raw endpoints receive all traffic for a given protocol regardless // of address. func (s *Stack) NewRawEndpoint(transport tcpip.TransportProtocolNumber, network tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { + if !s.raw { + return nil, tcpip.ErrNotPermitted + } + t, ok := s.transportProtocols[transport] if !ok { return nil, tcpip.ErrUnknownProtocol diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index e898dcbca..80cd6b4e5 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -102,6 +102,7 @@ var ( ErrMessageTooLong = &Error{msg: "message too long"} ErrNoBufferSpace = &Error{msg: "no buffer space available"} ErrBroadcastDisabled = &Error{msg: "broadcast socket option disabled"} + ErrNotPermitted = &Error{msg: "operation not permitted"} ) // Errors related to Subnet diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index a42e09b8c..7f9dabb4d 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -341,6 +341,7 @@ func loadError(s string) *tcpip.Error { tcpip.ErrMessageTooLong, tcpip.ErrNoBufferSpace, tcpip.ErrBroadcastDisabled, + tcpip.ErrNotPermitted, } messageToError = make(map[string]*tcpip.Error) diff --git a/runsc/boot/config.go b/runsc/boot/config.go index 2523077fd..ba47effc1 100644 --- a/runsc/boot/config.go +++ b/runsc/boot/config.go @@ -175,6 +175,11 @@ type Config struct { // Network indicates what type of network to use. Network NetworkType + // EnableRaw indicates whether raw sockets should be enabled. Raw + // sockets are disabled by stripping CAP_NET_RAW from the list of + // capabilities. + EnableRaw bool + // GSO indicates that generic segmentation offload is enabled. GSO bool @@ -235,6 +240,7 @@ func (c *Config) ToFlags() []string { "--watchdog-action=" + c.WatchdogAction.String(), "--panic-signal=" + strconv.Itoa(c.PanicSignal), "--profile=" + strconv.FormatBool(c.ProfileEnable), + "--net-raw=" + strconv.FormatBool(c.EnableRaw), } if c.TestOnlyAllowRunAsCurrentUserWithoutChroot { // Only include if set since it is never to be used by users. diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 88a834aa5..48ecb2626 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -227,7 +227,7 @@ func New(args Args) (*Loader, error) { } // Create capabilities. - caps, err := specutils.Capabilities(args.Spec.Process.Capabilities) + caps, err := specutils.Capabilities(args.Conf.EnableRaw, args.Spec.Process.Capabilities) if err != nil { return nil, fmt.Errorf("converting capabilities: %v", err) } @@ -554,7 +554,7 @@ func (l *Loader) createContainer(cid string) error { // this method returns. func (l *Loader) startContainer(k *kernel.Kernel, spec *specs.Spec, conf *Config, cid string, files []*os.File) error { // Create capabilities. - caps, err := specutils.Capabilities(spec.Process.Capabilities) + caps, err := specutils.Capabilities(conf.EnableRaw, spec.Process.Capabilities) if err != nil { return fmt.Errorf("creating capabilities: %v", err) } @@ -800,6 +800,9 @@ func newEmptyNetworkStack(conf *Config, clock tcpip.Clock) (inet.Stack, error) { Clock: clock, Stats: epsocket.Metrics, HandleLocal: true, + // Enable raw sockets for users with sufficient + // privileges. + Raw: true, })} if err := s.Stack.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SACKEnabled(true)); err != nil { return nil, fmt.Errorf("failed to enable SACK: %v", err) diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 9e058ad97..718d01067 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -132,7 +132,11 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } } if e.Capabilities == nil { - e.Capabilities, err = specutils.Capabilities(c.Spec.Process.Capabilities) + // enableRaw is set to true to prevent the filtering out of + // CAP_NET_RAW. This is the opposite of Create() because exec + // requires the capability to be set explicitly, while 'docker + // run' sets it by default. + e.Capabilities, err = specutils.Capabilities(true /* enableRaw */, c.Spec.Process.Capabilities) if err != nil { Fatalf("creating capabilities: %v", err) } @@ -351,7 +355,11 @@ func argsFromProcess(p *specs.Process) (*control.ExecArgs, error) { var caps *auth.TaskCapabilities if p.Capabilities != nil { var err error - caps, err = specutils.Capabilities(p.Capabilities) + // enableRaw is set to true to prevent the filtering out of + // CAP_NET_RAW. This is the opposite of Create() because exec + // requires the capability to be set explicitly, while 'docker + // run' sets it by default. + caps, err = specutils.Capabilities(true /* enableRaw */, p.Capabilities) if err != nil { return nil, fmt.Errorf("error creating capabilities: %v", err) } @@ -413,7 +421,11 @@ func capabilities(cs []string) (*auth.TaskCapabilities, error) { specCaps.Inheritable = append(specCaps.Inheritable, cap) specCaps.Permitted = append(specCaps.Permitted, cap) } - return specutils.Capabilities(&specCaps) + // enableRaw is set to true to prevent the filtering out of + // CAP_NET_RAW. This is the opposite of Create() because exec requires + // the capability to be set explicitly, while 'docker run' sets it by + // default. + return specutils.Capabilities(true /* enableRaw */, &specCaps) } // stringSlice allows a flag to be used multiple times, where each occurrence diff --git a/runsc/main.go b/runsc/main.go index 74253a844..b35726a74 100644 --- a/runsc/main.go +++ b/runsc/main.go @@ -68,6 +68,7 @@ var ( watchdogAction = flag.String("watchdog-action", "log", "sets what action the watchdog takes when triggered: log (default), panic.") panicSignal = flag.Int("panic-signal", -1, "register signal handling that panics. Usually set to SIGUSR2(12) to troubleshoot hangs. -1 disables it.") profile = flag.Bool("profile", false, "prepares the sandbox to use Golang profiler. Note that enabling profiler loosens the seccomp protection added to the sandbox (DO NOT USE IN PRODUCTION).") + netRaw = flag.Bool("net-raw", false, "enable raw sockets. When false, raw sockets are disabled by removing CAP_NET_RAW from containers (`runsc exec` will still be able to utilize raw sockets). Raw sockets allow malicious containers to craft packets and potentially attack the network.") testOnlyAllowRunAsCurrentUserWithoutChroot = flag.Bool("TESTONLY-unsafe-nonroot", false, "TEST ONLY; do not ever use! This skips many security measures that isolate the host from the sandbox.") ) @@ -159,6 +160,7 @@ func main() { WatchdogAction: wa, PanicSignal: *panicSignal, ProfileEnable: *profile, + EnableRaw: *netRaw, TestOnlyAllowRunAsCurrentUserWithoutChroot: *testOnlyAllowRunAsCurrentUserWithoutChroot, } if len(*straceSyscalls) != 0 { diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index af8d34535..32f81b8d4 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -198,20 +198,26 @@ func ReadMounts(f *os.File) ([]specs.Mount, error) { // Capabilities takes in spec and returns a TaskCapabilities corresponding to // the spec. -func Capabilities(specCaps *specs.LinuxCapabilities) (*auth.TaskCapabilities, error) { +func Capabilities(enableRaw bool, specCaps *specs.LinuxCapabilities) (*auth.TaskCapabilities, error) { + // Strip CAP_NET_RAW from all capability sets if necessary. + skipSet := map[linux.Capability]struct{}{} + if !enableRaw { + skipSet[linux.CAP_NET_RAW] = struct{}{} + } + var caps auth.TaskCapabilities if specCaps != nil { var err error - if caps.BoundingCaps, err = capsFromNames(specCaps.Bounding); err != nil { + if caps.BoundingCaps, err = capsFromNames(specCaps.Bounding, skipSet); err != nil { return nil, err } - if caps.EffectiveCaps, err = capsFromNames(specCaps.Effective); err != nil { + if caps.EffectiveCaps, err = capsFromNames(specCaps.Effective, skipSet); err != nil { return nil, err } - if caps.InheritableCaps, err = capsFromNames(specCaps.Inheritable); err != nil { + if caps.InheritableCaps, err = capsFromNames(specCaps.Inheritable, skipSet); err != nil { return nil, err } - if caps.PermittedCaps, err = capsFromNames(specCaps.Permitted); err != nil { + if caps.PermittedCaps, err = capsFromNames(specCaps.Permitted, skipSet); err != nil { return nil, err } // TODO: Support ambient capabilities. @@ -275,13 +281,17 @@ var capFromName = map[string]linux.Capability{ "CAP_AUDIT_READ": linux.CAP_AUDIT_READ, } -func capsFromNames(names []string) (auth.CapabilitySet, error) { +func capsFromNames(names []string, skipSet map[linux.Capability]struct{}) (auth.CapabilitySet, error) { var caps []linux.Capability for _, n := range names { c, ok := capFromName[n] if !ok { return 0, fmt.Errorf("unknown capability %q", n) } + // Should we skip this capabilty? + if _, ok := skipSet[c]; ok { + continue + } caps = append(caps, c) } return auth.CapabilitySetOfMany(caps), nil diff --git a/runsc/test/integration/BUILD b/runsc/test/integration/BUILD index 779d30ec9..0c4e4fa80 100644 --- a/runsc/test/integration/BUILD +++ b/runsc/test/integration/BUILD @@ -15,7 +15,10 @@ go_test( "manual", "local", ], - deps = ["//runsc/test/testutil"], + deps = [ + "//pkg/abi/linux", + "//runsc/test/testutil", + ], ) go_library( diff --git a/runsc/test/integration/exec_test.go b/runsc/test/integration/exec_test.go index fac8337f4..d87957e2d 100644 --- a/runsc/test/integration/exec_test.go +++ b/runsc/test/integration/exec_test.go @@ -27,10 +27,13 @@ package integration import ( + "fmt" + "strconv" "syscall" "testing" "time" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/runsc/test/testutil" ) @@ -46,11 +49,28 @@ func TestExecCapabilities(t *testing.T) { } defer d.CleanUp() - want, err := d.WaitForOutput("CapEff:\t[0-9a-f]+\n", 5*time.Second) + matches, err := d.WaitForOutputSubmatch("CapEff:\t([0-9a-f]+)\n", 5*time.Second) if err != nil { - t.Fatalf("WaitForOutput() timeout: %v", err) + t.Fatalf("WaitForOutputSubmatch() timeout: %v", err) } - t.Log("Root capabilities:", want) + if len(matches) != 2 { + t.Fatalf("There should be a match for the whole line and the capability bitmask") + } + capString := matches[1] + t.Log("Root capabilities:", capString) + + // CAP_NET_RAW was in the capability set for the container, but was + // removed. However, `exec` does not remove it. Verify that it's not + // set in the container, then re-add it for comparison. + caps, err := strconv.ParseUint(capString, 16, 64) + if err != nil { + t.Fatalf("failed to convert capabilities %q: %v", capString, err) + } + if caps&(1< Date: Mon, 29 Apr 2019 14:03:04 -0700 Subject: Allow and document bug ids in gVisor codebase. PiperOrigin-RevId: 245818639 Change-Id: I03703ef0fb9b6675955637b9fe2776204c545789 --- CONTRIBUTING.md | 7 +++ pkg/cpuid/cpuid_test.go | 2 +- pkg/dhcp/client.go | 2 +- pkg/log/glog.go | 2 +- pkg/metric/metric.go | 4 +- pkg/segment/set.go | 2 +- pkg/segment/test/set_functions.go | 2 +- pkg/sentry/arch/arch.go | 2 +- pkg/sentry/arch/arch_amd64.go | 4 +- pkg/sentry/arch/arch_x86.go | 2 +- pkg/sentry/arch/signal_amd64.go | 6 +-- pkg/sentry/arch/stack.go | 6 +-- pkg/sentry/context/context.go | 2 +- pkg/sentry/control/proc.go | 2 +- pkg/sentry/fs/README.md | 2 +- pkg/sentry/fs/ashmem/area.go | 4 +- pkg/sentry/fs/binder/binder.go | 22 ++++---- pkg/sentry/fs/dentry.go | 2 +- pkg/sentry/fs/dirent.go | 8 +-- pkg/sentry/fs/file.go | 2 +- pkg/sentry/fs/file_overlay.go | 4 +- pkg/sentry/fs/fsutil/file.go | 8 +-- pkg/sentry/fs/fsutil/inode_cached.go | 4 +- pkg/sentry/fs/gofer/cache_policy.go | 4 +- pkg/sentry/fs/gofer/file.go | 2 +- pkg/sentry/fs/gofer/file_state.go | 2 +- pkg/sentry/fs/gofer/handles.go | 2 +- pkg/sentry/fs/gofer/inode.go | 6 +-- pkg/sentry/fs/gofer/inode_state.go | 2 +- pkg/sentry/fs/gofer/session.go | 2 +- pkg/sentry/fs/gofer/session_state.go | 2 +- pkg/sentry/fs/host/fs.go | 4 +- pkg/sentry/fs/host/inode.go | 10 ++-- pkg/sentry/fs/inode.go | 6 +-- pkg/sentry/fs/inode_operations.go | 2 +- pkg/sentry/fs/inode_overlay.go | 6 +-- pkg/sentry/fs/mount.go | 4 +- pkg/sentry/fs/mount_test.go | 2 +- pkg/sentry/fs/proc/README.md | 12 ++--- pkg/sentry/fs/proc/fds.go | 2 +- pkg/sentry/fs/proc/loadavg.go | 2 +- pkg/sentry/fs/proc/meminfo.go | 6 +-- pkg/sentry/fs/proc/mounts.go | 2 +- pkg/sentry/fs/proc/net.go | 2 +- pkg/sentry/fs/proc/stat.go | 12 ++--- pkg/sentry/fs/proc/sys_net.go | 2 +- pkg/sentry/fs/proc/task.go | 8 +-- pkg/sentry/fs/proc/version.go | 2 +- pkg/sentry/fs/ramfs/dir.go | 2 +- pkg/sentry/fs/tmpfs/fs.go | 2 +- pkg/sentry/fs/tmpfs/inode_file.go | 2 +- pkg/sentry/fs/tmpfs/tmpfs.go | 2 +- pkg/sentry/fs/tty/dir.go | 6 +-- pkg/sentry/fs/tty/fs.go | 2 +- pkg/sentry/fs/tty/master.go | 6 +-- pkg/sentry/fs/tty/slave.go | 6 +-- pkg/sentry/kernel/auth/credentials.go | 2 +- pkg/sentry/kernel/auth/user_namespace.go | 2 +- pkg/sentry/kernel/pending_signals.go | 2 +- pkg/sentry/kernel/ptrace.go | 4 +- pkg/sentry/kernel/rseq.go | 2 +- pkg/sentry/kernel/sched/cpuset.go | 2 +- pkg/sentry/kernel/semaphore/semaphore.go | 6 +-- pkg/sentry/kernel/shm/shm.go | 2 +- pkg/sentry/kernel/syscalls.go | 2 +- pkg/sentry/kernel/task_context.go | 2 +- pkg/sentry/kernel/task_exec.go | 2 +- pkg/sentry/kernel/task_exit.go | 4 +- pkg/sentry/kernel/task_identity.go | 2 +- pkg/sentry/kernel/task_run.go | 2 +- pkg/sentry/kernel/task_signals.go | 4 +- pkg/sentry/kernel/task_stop.go | 2 +- pkg/sentry/loader/loader.go | 2 +- pkg/sentry/loader/vdso.go | 6 +-- pkg/sentry/memmap/memmap.go | 2 +- pkg/sentry/mm/aio_context.go | 2 +- pkg/sentry/mm/procfs.go | 10 ++-- pkg/sentry/mm/special_mappable.go | 2 +- pkg/sentry/mm/syscalls.go | 6 +-- pkg/sentry/mm/vma.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64_unsafe.go | 2 +- pkg/sentry/platform/platform.go | 2 +- pkg/sentry/platform/ptrace/subprocess.go | 2 +- pkg/sentry/platform/ring0/x86.go | 4 +- pkg/sentry/sighandling/sighandling.go | 2 +- pkg/sentry/sighandling/sighandling_unsafe.go | 2 +- pkg/sentry/socket/epsocket/epsocket.go | 32 ++++++------ pkg/sentry/socket/epsocket/save_restore.go | 2 +- pkg/sentry/socket/epsocket/stack.go | 2 +- pkg/sentry/socket/hostinet/socket.go | 2 +- pkg/sentry/socket/netlink/route/protocol.go | 8 +-- pkg/sentry/socket/netlink/socket.go | 10 ++-- pkg/sentry/socket/rpcinet/conn/conn.go | 2 +- pkg/sentry/socket/rpcinet/notifier/notifier.go | 4 +- pkg/sentry/socket/rpcinet/socket.go | 6 +-- pkg/sentry/socket/rpcinet/syscall_rpc.proto | 2 +- pkg/sentry/strace/strace.go | 2 +- pkg/sentry/syscalls/linux/error.go | 2 +- pkg/sentry/syscalls/linux/linux64.go | 60 +++++++++++----------- pkg/sentry/syscalls/linux/sys_aio.go | 2 +- pkg/sentry/syscalls/linux/sys_file.go | 4 +- pkg/sentry/syscalls/linux/sys_mmap.go | 4 +- pkg/sentry/syscalls/linux/sys_read.go | 2 +- pkg/sentry/syscalls/linux/sys_socket.go | 4 +- pkg/sentry/syscalls/linux/sys_thread.go | 2 +- pkg/sentry/syscalls/linux/sys_write.go | 4 +- pkg/sentry/time/calibrated_clock.go | 6 +-- pkg/sentry/time/parameters.go | 2 +- pkg/sentry/usermem/usermem.go | 4 +- pkg/sentry/watchdog/watchdog.go | 2 +- pkg/syserr/syserr.go | 10 ++-- pkg/tcpip/network/ipv4/icmp.go | 2 +- pkg/tcpip/network/ipv6/icmp.go | 4 +- pkg/tcpip/stack/nic.go | 6 +-- pkg/tcpip/stack/stack.go | 4 +- pkg/tcpip/stack/stack_global_state.go | 2 +- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/tcpip.go | 2 +- pkg/tcpip/transport/raw/raw.go | 2 +- pkg/tcpip/transport/tcp/BUILD | 2 +- pkg/unet/unet.go | 2 +- pkg/unet/unet_test.go | 2 +- runsc/boot/controller.go | 4 +- runsc/boot/fs.go | 6 +-- runsc/boot/loader.go | 2 +- runsc/cmd/checkpoint.go | 2 +- runsc/container/container.go | 2 +- runsc/container/container_test.go | 4 +- runsc/sandbox/sandbox.go | 6 +-- runsc/specutils/specutils.go | 4 +- test/syscalls/BUILD | 6 +-- test/syscalls/build_defs.bzl | 4 +- test/syscalls/linux/32bit.cc | 14 ++--- test/syscalls/linux/aio.cc | 2 +- test/syscalls/linux/chmod.cc | 2 +- test/syscalls/linux/epoll.cc | 2 +- test/syscalls/linux/exec_binary.cc | 12 ++--- test/syscalls/linux/file_base.h | 4 +- test/syscalls/linux/ioctl.cc | 4 +- test/syscalls/linux/ip_socket_test_util.cc | 2 +- test/syscalls/linux/lseek.cc | 2 +- test/syscalls/linux/mkdir.cc | 2 +- test/syscalls/linux/mmap.cc | 18 +++---- test/syscalls/linux/open.cc | 2 +- test/syscalls/linux/partial_bad_buffer.cc | 18 +++---- test/syscalls/linux/pipe.cc | 6 +-- test/syscalls/linux/proc.cc | 32 ++++++------ test/syscalls/linux/proc_pid_smaps.cc | 2 +- test/syscalls/linux/ptrace.cc | 2 +- test/syscalls/linux/pwrite64.cc | 2 +- test/syscalls/linux/readv_socket.cc | 2 +- test/syscalls/linux/rtsignal.cc | 2 +- test/syscalls/linux/socket_inet_loopback.cc | 10 ++-- .../socket_ipv4_udp_unbound_external_networking.cc | 4 +- test/syscalls/linux/socket_netlink_route.cc | 4 +- test/syscalls/linux/socket_stream_blocking.cc | 2 +- test/syscalls/linux/socket_test_util.cc | 2 +- test/syscalls/linux/socket_unix.cc | 16 +++--- test/syscalls/linux/socket_unix_dgram.cc | 2 +- .../linux/socket_unix_dgram_non_blocking.cc | 2 +- test/syscalls/linux/socket_unix_non_stream.cc | 10 ++-- .../linux/socket_unix_unbound_seqpacket.cc | 2 +- test/syscalls/linux/socket_unix_unbound_stream.cc | 4 +- test/syscalls/linux/stat.cc | 2 +- test/syscalls/linux/stat_times.cc | 8 +-- test/syscalls/linux/tcp_socket.cc | 2 +- test/syscalls/linux/tkill.cc | 2 +- test/syscalls/linux/udp_bind.cc | 4 +- test/syscalls/linux/uidgid.cc | 2 +- test/syscalls/linux/utimes.cc | 4 +- test/syscalls/linux/wait.cc | 2 +- test/syscalls/linux/write.cc | 2 +- third_party/gvsync/downgradable_rwmutex_unsafe.go | 2 +- vdso/cycle_clock.h | 2 +- vdso/vdso_amd64.lds | 2 +- vdso/vdso_arm64.lds | 2 +- 176 files changed, 403 insertions(+), 396 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6dafc595..238dd6665 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -126,6 +126,13 @@ change. When approved, the change will be submitted by a team member and automatically merged into the repository. +### Bug IDs + +Some TODOs and NOTEs sprinkled throughout the code have associated IDs of the +form b/1234. These correspond to bugs in our internal bug tracker. Eventually +these bugs will be moved to the GitHub Issues, but until then they can simply be +ignored. + ### The small print Contributions made by corporations are covered by a different agreement than the diff --git a/pkg/cpuid/cpuid_test.go b/pkg/cpuid/cpuid_test.go index 35e7b8e50..64ade1cbe 100644 --- a/pkg/cpuid/cpuid_test.go +++ b/pkg/cpuid/cpuid_test.go @@ -78,7 +78,7 @@ func TestTakeFeatureIntersection(t *testing.T) { } } -// TODO: Run this test on a very old platform, and make sure more +// TODO(b/73346484): Run this test on a very old platform, and make sure more // bits are enabled than just FPU and PAE. This test currently may not detect // if HostFeatureSet gives back junk bits. func TestHostFeatureSet(t *testing.T) { diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 354205e63..2ba79be32 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -120,7 +120,7 @@ func (c *Client) Config() Config { // If the server sets a lease limit a timer is set to automatically // renew it. func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg Config, reterr error) { - // TODO: remove calls to {Add,Remove}Address when they're no + // TODO(b/127321246): remove calls to {Add,Remove}Address when they're no // longer required to send and receive broadcast. if err := c.stack.AddAddressWithOptions(c.nicid, ipv4.ProtocolNumber, tcpipHeader.IPv4Any, stack.NeverPrimaryEndpoint); err != nil && err != tcpip.ErrDuplicateAddress { return Config{}, fmt.Errorf("dhcp: AddAddressWithOptions(): %s", err) diff --git a/pkg/log/glog.go b/pkg/log/glog.go index fbb58501b..24d5390d7 100644 --- a/pkg/log/glog.go +++ b/pkg/log/glog.go @@ -144,7 +144,7 @@ func (g GoogleEmitter) Emit(level Level, timestamp time.Time, format string, arg b.writeAll(pid) b.write(' ') - // FIXME: The caller, fabricated. This really sucks, but it + // FIXME(b/73383460): The caller, fabricated. This really sucks, but it // is unacceptable to put runtime.Callers() in the hot path. b.writeAll(caller) b.write(']') diff --git a/pkg/metric/metric.go b/pkg/metric/metric.go index 02af75974..e5eb95f89 100644 --- a/pkg/metric/metric.go +++ b/pkg/metric/metric.go @@ -44,8 +44,8 @@ var ( // // Metrics are not saved across save/restore and thus reset to zero on restore. // -// TODO: Support non-cumulative metrics. -// TODO: Support metric fields. +// TODO(b/67298402): Support non-cumulative metrics. +// TODO(b/67298427): Support metric fields. // type Uint64Metric struct { // value is the actual value of the metric. It must be accessed diff --git a/pkg/segment/set.go b/pkg/segment/set.go index a9a3b8875..74a916ea3 100644 --- a/pkg/segment/set.go +++ b/pkg/segment/set.go @@ -1270,7 +1270,7 @@ func segmentAfterPosition(n *node, i int) Iterator { } func zeroValueSlice(slice []Value) { - // TODO: check if Go is actually smart enough to optimize a + // TODO(jamieliu): check if Go is actually smart enough to optimize a // ClearValue that assigns nil to a memset here for i := range slice { Functions{}.ClearValue(&slice[i]) diff --git a/pkg/segment/test/set_functions.go b/pkg/segment/test/set_functions.go index 05ba5fbb9..41f649011 100644 --- a/pkg/segment/test/set_functions.go +++ b/pkg/segment/test/set_functions.go @@ -15,7 +15,7 @@ package segment // Basic numeric constants that we define because the math package doesn't. -// TODO: These should be Math.MaxInt64/MinInt64? +// TODO(nlacasse): These should be Math.MaxInt64/MinInt64? const ( maxInt = int(^uint(0) >> 1) minInt = -maxInt - 1 diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index 4cd7a9af5..16d8eb2b2 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -53,7 +53,7 @@ type FloatingPointData byte // Context provides architecture-dependent information for a specific thread. // -// NOTE: Currently we use uintptr here to refer to a generic native +// NOTE(b/34169503): Currently we use uintptr here to refer to a generic native // register value. While this will work for the foreseeable future, it isn't // strictly correct. We may want to create some abstraction that makes this // more clear or enables us to store values of arbitrary widths. This is diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index 2507774f7..7ec2f2c84 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -305,7 +305,7 @@ func (c *context64) PtracePeekUser(addr uintptr) (interface{}, error) { buf := binary.Marshal(nil, usermem.ByteOrder, c.ptraceGetRegs()) return c.Native(uintptr(usermem.ByteOrder.Uint64(buf[addr:]))), nil } - // TODO: debug registers + // TODO(b/34088053): debug registers return c.Native(0), nil } @@ -320,6 +320,6 @@ func (c *context64) PtracePokeUser(addr, data uintptr) error { _, err := c.PtraceSetRegs(bytes.NewBuffer(buf)) return err } - // TODO: debug registers + // TODO(b/34088053): debug registers return nil } diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index c8bf0e7f2..4305fe2cb 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -306,7 +306,7 @@ func (s *State) ptraceGetRegs() syscall.PtraceRegs { // FS/GS_TLS_SEL when fs_base/gs_base is a 64-bit value. (We do the // same in PtraceSetRegs.) // - // TODO: Remove this fixup since newer Linux + // TODO(gvisor.dev/issue/168): Remove this fixup since newer Linux // doesn't have this behavior anymore. if regs.Fs == 0 && regs.Fs_base <= 0xffffffff { regs.Fs = _FS_TLS_SEL diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index c9de36897..7f76eba27 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -319,7 +319,7 @@ func (c *context64) NewSignalStack() NativeSignalStack { // From Linux 'arch/x86/include/uapi/asm/sigcontext.h' the following is the // size of the magic cookie at the end of the xsave frame. // -// NOTE: Currently we don't actually populate the fpstate +// NOTE(b/33003106#comment11): Currently we don't actually populate the fpstate // on the signal stack. const _FP_XSTATE_MAGIC2_SIZE = 4 @@ -392,7 +392,7 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt Sigset: sigset, } - // TODO: Set SignalContext64.Err, Trapno, and Cr2 + // TODO(gvisor.dev/issue/159): Set SignalContext64.Err, Trapno, and Cr2 // based on the fault that caused the signal. For now, leave Err and // Trapno unset and assume CR2 == info.Addr() for SIGSEGVs and // SIGBUSes. @@ -505,7 +505,7 @@ func (c *context64) SignalRestore(st *Stack, rt bool) (linux.SignalSet, SignalSt l := len(c.sigFPState) if l > 0 { c.x86FPState = c.sigFPState[l-1] - // NOTE: State save requires that any slice + // NOTE(cl/133042258): State save requires that any slice // elements from '[len:cap]' to be zero value. c.sigFPState[l-1] = nil c.sigFPState = c.sigFPState[0 : l-1] diff --git a/pkg/sentry/arch/stack.go b/pkg/sentry/arch/stack.go index f2cfb0426..2e33ccdf5 100644 --- a/pkg/sentry/arch/stack.go +++ b/pkg/sentry/arch/stack.go @@ -97,7 +97,7 @@ func (s *Stack) Push(vals ...interface{}) (usermem.Addr, error) { if c < 0 { return 0, fmt.Errorf("bad binary.Size for %T", v) } - // TODO: Use a real context.Context. + // TODO(b/38173783): Use a real context.Context. n, err := usermem.CopyObjectOut(context.Background(), s.IO, s.Bottom-usermem.Addr(c), norm, usermem.IOOpts{}) if err != nil || c != n { return 0, err @@ -121,11 +121,11 @@ func (s *Stack) Pop(vals ...interface{}) (usermem.Addr, error) { var err error if isVaddr { value := s.Arch.Native(uintptr(0)) - // TODO: Use a real context.Context. + // TODO(b/38173783): Use a real context.Context. n, err = usermem.CopyObjectIn(context.Background(), s.IO, s.Bottom, value, usermem.IOOpts{}) *vaddr = usermem.Addr(s.Arch.Value(value)) } else { - // TODO: Use a real context.Context. + // TODO(b/38173783): Use a real context.Context. n, err = usermem.CopyObjectIn(context.Background(), s.IO, s.Bottom, v, usermem.IOOpts{}) } if err != nil { diff --git a/pkg/sentry/context/context.go b/pkg/sentry/context/context.go index 7ed6a5e8a..eefc3e1b4 100644 --- a/pkg/sentry/context/context.go +++ b/pkg/sentry/context/context.go @@ -114,7 +114,7 @@ var bgContext = &logContext{Logger: log.Log()} // Background returns an empty context using the default logger. // // Users should be wary of using a Background context. Please tag any use with -// FIXME and a note to remove this use. +// FIXME(b/38173783) and a note to remove this use. // // Generally, one should use the Task as their context when available, or avoid // having to use a context in places where a Task is unavailable. diff --git a/pkg/sentry/control/proc.go b/pkg/sentry/control/proc.go index e848def14..aca2267a7 100644 --- a/pkg/sentry/control/proc.go +++ b/pkg/sentry/control/proc.go @@ -261,7 +261,7 @@ func (proc *Proc) Ps(args *PsArgs, out *string) error { } // Process contains information about a single process in a Sandbox. -// TODO: Implement TTY field. +// TODO(b/117881927): Implement TTY field. type Process struct { UID auth.KUID `json:"uid"` PID kernel.ThreadID `json:"pid"` diff --git a/pkg/sentry/fs/README.md b/pkg/sentry/fs/README.md index a88a0cd3a..f53ed3eaa 100644 --- a/pkg/sentry/fs/README.md +++ b/pkg/sentry/fs/README.md @@ -59,7 +59,7 @@ two categories: The first is always necessary to save and restore. An application may never have any open file descriptors, but across save and restore it should see a coherent -view of any mount namespace. NOTE: Currently only one "initial" +view of any mount namespace. NOTE(b/63601033): Currently only one "initial" mount namespace is supported. The second is so that system calls across save and restore are coherent with diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index 651cbc164..1f61c5711 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -240,7 +240,7 @@ func (a *Area) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArgume return 0, syserror.EINVAL } - // TODO: If personality flag + // TODO(b/30946773,gvisor.dev/issue/153): If personality flag // READ_IMPLIES_EXEC is set, set PROT_EXEC if PORT_READ is set. a.perms = perms @@ -290,7 +290,7 @@ func (a *Area) pinOperation(pin linux.AshmemPin, op uint32) (uintptr, error) { return linux.AshmemNotPurged, nil case linux.AshmemUnpinIoctl: - // TODO: Implement purge on unpin. + // TODO(b/30946773): Implement purge on unpin. a.pb.UnpinRange(r) return 0, nil diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index a41b5dcae..d9f1559de 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -69,7 +69,7 @@ func NewDevice(ctx context.Context, owner fs.FileOwner, fp fs.FilePermissions) * // GetFile implements fs.InodeOperations.GetFile. // -// TODO: Add functionality to GetFile: Additional fields will be +// TODO(b/30946773): Add functionality to GetFile: Additional fields will be // needed in the Device structure, initialize them here. Also, Device will need // to keep track of the created Procs in order to implement BINDER_READ_WRITE // ioctl. @@ -133,7 +133,7 @@ func (bp *Proc) Write(ctx context.Context, file *fs.File, src usermem.IOSequence // Flush implements fs.FileOperations.Flush. // -// TODO: Implement. +// TODO(b/30946773): Implement. func (bp *Proc) Flush(ctx context.Context, file *fs.File) error { return nil } @@ -149,7 +149,7 @@ func (bp *Proc) ConfigureMMap(ctx context.Context, file *fs.File, opts *memmap.M } opts.MaxPerms.Write = false - // TODO: Binder sets VM_DONTCOPY, preventing the created vma + // TODO(b/30946773): Binder sets VM_DONTCOPY, preventing the created vma // from being copied across fork(), but we don't support this yet. As // a result, MMs containing a Binder mapping cannot be forked (MM.Fork will // fail when AddMapping returns EBUSY). @@ -159,7 +159,7 @@ func (bp *Proc) ConfigureMMap(ctx context.Context, file *fs.File, opts *memmap.M // Ioctl implements fs.FileOperations.Ioctl. // -// TODO: Implement. +// TODO(b/30946773): Implement. func (bp *Proc) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { // Switch on ioctl request. switch uint32(args[1].Int()) { @@ -173,22 +173,22 @@ func (bp *Proc) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArgum }) return 0, err case linux.BinderWriteReadIoctl: - // TODO: Implement. + // TODO(b/30946773): Implement. fallthrough case linux.BinderSetIdleTimeoutIoctl: - // TODO: Implement. + // TODO(b/30946773): Implement. fallthrough case linux.BinderSetMaxThreadsIoctl: - // TODO: Implement. + // TODO(b/30946773): Implement. fallthrough case linux.BinderSetIdlePriorityIoctl: - // TODO: Implement. + // TODO(b/30946773): Implement. fallthrough case linux.BinderSetContextMgrIoctl: - // TODO: Implement. + // TODO(b/30946773): Implement. fallthrough case linux.BinderThreadExitIoctl: - // TODO: Implement. + // TODO(b/30946773): Implement. return 0, syserror.ENOSYS default: // Ioctls irrelevant to Binder. @@ -228,7 +228,7 @@ func (bp *Proc) CopyMapping(ctx context.Context, ms memmap.MappingSpace, srcAR, // Translate implements memmap.Mappable.Translate. func (bp *Proc) Translate(ctx context.Context, required, optional memmap.MappableRange, at usermem.AccessType) ([]memmap.Translation, error) { - // TODO: In addition to the page initially allocated and mapped + // TODO(b/30946773): In addition to the page initially allocated and mapped // in AddMapping (Linux: binder_mmap), Binder allocates and maps pages for // each transaction (Linux: binder_ioctl => binder_ioctl_write_read => // binder_thread_write => binder_transaction => binder_alloc_buf => diff --git a/pkg/sentry/fs/dentry.go b/pkg/sentry/fs/dentry.go index 4879df4d6..29fb155a4 100644 --- a/pkg/sentry/fs/dentry.go +++ b/pkg/sentry/fs/dentry.go @@ -83,7 +83,7 @@ type DirCtx struct { attrs map[string]DentAttr // DirCursor is the directory cursor. - // TODO: Once Handles are removed this can just live in the + // TODO(b/67778717): Once Handles are removed this can just live in the // respective FileOperations implementations and not need to get // plumbed everywhere. DirCursor *string diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index 4bcdf530a..54fc11fe1 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -318,7 +318,7 @@ func (d *Dirent) SyncAll(ctx context.Context) { // There is nothing to sync for a read-only filesystem. if !d.Inode.MountSource.Flags.ReadOnly { - // FIXME: This should be a mount traversal, not a + // FIXME(b/34856369): This should be a mount traversal, not a // Dirent traversal, because some Inodes that need to be synced // may no longer be reachable by name (after sys_unlink). // @@ -1506,7 +1506,7 @@ func Rename(ctx context.Context, root *Dirent, oldParent *Dirent, oldName string } // Are we frozen? - // TODO: Is this the right errno? + // TODO(jamieliu): Is this the right errno? if oldParent.frozen && !oldParent.Inode.IsVirtual() { return syscall.ENOENT } @@ -1565,7 +1565,7 @@ func Rename(ctx context.Context, root *Dirent, oldParent *Dirent, oldName string } else { // Check constraints on the dirent being replaced. - // NOTE: We don't want to keep replaced alive + // NOTE(b/111808347): We don't want to keep replaced alive // across the Rename, so must call DecRef manually (no defer). // Check that we can delete replaced. @@ -1606,7 +1606,7 @@ func Rename(ctx context.Context, root *Dirent, oldParent *Dirent, oldName string // Allow the file system to drop extra references on replaced. replaced.dropExtendedReference() - // NOTE: Keeping a dirent + // NOTE(b/31798319,b/31867149,b/31867671): Keeping a dirent // open across renames is currently broken for multiple // reasons, so we flush all references on the replaced node and // its children. diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 2c2126f17..5d5026661 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -65,7 +65,7 @@ const FileMaxOffset = math.MaxInt64 // under a single abortable mutex which also synchronizes lseek(2), read(2), // and write(2). // -// FIXME: Split synchronization from cancellation. +// FIXME(b/38451980): Split synchronization from cancellation. // // +stateify savable type File struct { diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index e1f02f0f4..6e680f0a4 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -160,7 +160,7 @@ func (f *overlayFileOperations) Seek(ctx context.Context, file *File, whence See // If this was a seek on a directory, we must update the cursor. if seekDir && whence == SeekSet && offset == 0 { // Currently only seeking to 0 on a directory is supported. - // FIXME: Lift directory seeking limitations. + // FIXME(b/33075855): Lift directory seeking limitations. f.dirCursor = "" } return n, nil @@ -329,7 +329,7 @@ func (*overlayFileOperations) ConfigureMMap(ctx context.Context, file *File, opt if !o.isMappableLocked() { return syserror.ENODEV } - // FIXME: This is a copy/paste of fsutil.GenericConfigureMMap, + // FIXME(jamieliu): This is a copy/paste of fsutil.GenericConfigureMMap, // which we can't use because the overlay implementation is in package fs, // so depending on fs/fsutil would create a circular dependency. Move // overlay to fs/overlay. diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go index df34dc788..42afdd11c 100644 --- a/pkg/sentry/fs/fsutil/file.go +++ b/pkg/sentry/fs/fsutil/file.go @@ -36,7 +36,7 @@ func (FileNoopRelease) Release() {} // // Currently only seeking to 0 on a directory is supported. // -// FIXME: Lift directory seeking limitations. +// FIXME(b/33075855): Lift directory seeking limitations. func SeekWithDirCursor(ctx context.Context, file *fs.File, whence fs.SeekWhence, offset int64, dirCursor *string) (int64, error) { inode := file.Dirent.Inode current := file.Offset() @@ -50,7 +50,7 @@ func SeekWithDirCursor(ctx context.Context, file *fs.File, whence fs.SeekWhence, if fs.IsCharDevice(inode.StableAttr) { // Ignore seek requests. // - // FIXME: This preserves existing + // FIXME(b/34716638): This preserves existing // behavior but is not universally correct. return 0, nil } @@ -104,7 +104,7 @@ func SeekWithDirCursor(ctx context.Context, file *fs.File, whence fs.SeekWhence, return current, syserror.EINVAL } return sz + offset, nil - // FIXME: This is not universally correct. + // FIXME(b/34778850): This is not universally correct. // Remove SpecialDirectory. case fs.SpecialDirectory: if offset != 0 { @@ -112,7 +112,7 @@ func SeekWithDirCursor(ctx context.Context, file *fs.File, whence fs.SeekWhence, } // SEEK_END to 0 moves the directory "cursor" to the end. // - // FIXME: The ensures that after the seek, + // FIXME(b/35442290): The ensures that after the seek, // reading on the directory will get EOF. But it is not // correct in general because the directory can grow in // size; attempting to read those new entries will be diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index b690cfe93..ba33b9912 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -479,7 +479,7 @@ func (c *CachingInodeOperations) Read(ctx context.Context, file *fs.File, dst us // common: getting a return value of 0 from a read syscall is the only way // to detect EOF. // - // TODO: Separate out c.attr.Size and use atomics instead of + // TODO(jamieliu): Separate out c.attr.Size and use atomics instead of // c.dataMu. c.dataMu.RLock() size := c.attr.Size @@ -776,7 +776,7 @@ func (c *CachingInodeOperations) Translate(ctx context.Context, required, option var translatedEnd uint64 for seg := c.cache.FindSegment(required.Start); seg.Ok() && seg.Start() < required.End; seg, _ = seg.NextNonEmpty() { segMR := seg.Range().Intersect(optional) - // TODO: Make Translations writable even if writability is + // TODO(jamieliu): Make Translations writable even if writability is // not required if already kept-dirty by another writable translation. perms := usermem.AccessType{ Read: true, diff --git a/pkg/sentry/fs/gofer/cache_policy.go b/pkg/sentry/fs/gofer/cache_policy.go index d7fbb71b7..51c573aef 100644 --- a/pkg/sentry/fs/gofer/cache_policy.go +++ b/pkg/sentry/fs/gofer/cache_policy.go @@ -136,7 +136,7 @@ func (cp cachePolicy) revalidate(ctx context.Context, name string, parent, child // Walk from parent to child again. // - // TODO: If we have a directory FD in the parent + // TODO(b/112031682): If we have a directory FD in the parent // inodeOperations, then we can use fstatat(2) to get the inode // attributes instead of making this RPC. qids, _, mask, attr, err := parentIops.fileState.file.walkGetAttr(ctx, []string{name}) @@ -171,7 +171,7 @@ func (cp cachePolicy) keep(d *fs.Dirent) bool { return false } sattr := d.Inode.StableAttr - // NOTE: Only cache files, directories, and symlinks. + // NOTE(b/31979197): Only cache files, directories, and symlinks. return fs.IsFile(sattr) || fs.IsDir(sattr) || fs.IsSymlink(sattr) } diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 80d1e08a6..35caa42cd 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -297,7 +297,7 @@ func (f *fileOperations) Flush(ctx context.Context, file *fs.File) error { // We do this because some p9 server implementations of Flush are // over-zealous. // - // FIXME: weaken these implementations and remove this check. + // FIXME(edahlgren): weaken these implementations and remove this check. if !file.Flags().Write { return nil } diff --git a/pkg/sentry/fs/gofer/file_state.go b/pkg/sentry/fs/gofer/file_state.go index f770ca4ea..d0c64003c 100644 --- a/pkg/sentry/fs/gofer/file_state.go +++ b/pkg/sentry/fs/gofer/file_state.go @@ -28,7 +28,7 @@ func (f *fileOperations) afterLoad() { // Manually load the open handles. var err error - // TODO: Context is not plumbed to save/restore. + // TODO(b/38173783): Context is not plumbed to save/restore. f.handles, err = f.inodeOperations.fileState.getHandles(context.Background(), f.flags) if err != nil { return fmt.Errorf("failed to re-open handle: %v", err) diff --git a/pkg/sentry/fs/gofer/handles.go b/pkg/sentry/fs/gofer/handles.go index f32e99ce0..0b33e80c3 100644 --- a/pkg/sentry/fs/gofer/handles.go +++ b/pkg/sentry/fs/gofer/handles.go @@ -49,7 +49,7 @@ func (h *handles) DecRef() { log.Warningf("error closing host file: %v", err) } } - // FIXME: Context is not plumbed here. + // FIXME(b/38173783): Context is not plumbed here. if err := h.File.close(context.Background()); err != nil { log.Warningf("error closing p9 file: %v", err) } diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index 29af1010c..1181a24cc 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -570,13 +570,13 @@ func init() { } // AddLink implements InodeOperations.AddLink, but is currently a noop. -// FIXME: Remove this from InodeOperations altogether. +// FIXME(b/63117438): Remove this from InodeOperations altogether. func (*inodeOperations) AddLink() {} // DropLink implements InodeOperations.DropLink, but is currently a noop. -// FIXME: Remove this from InodeOperations altogether. +// FIXME(b/63117438): Remove this from InodeOperations altogether. func (*inodeOperations) DropLink() {} // NotifyStatusChange implements fs.InodeOperations.NotifyStatusChange. -// FIXME: Remove this from InodeOperations altogether. +// FIXME(b/63117438): Remove this from InodeOperations altogether. func (i *inodeOperations) NotifyStatusChange(ctx context.Context) {} diff --git a/pkg/sentry/fs/gofer/inode_state.go b/pkg/sentry/fs/gofer/inode_state.go index ad4d3df58..44d76ba9f 100644 --- a/pkg/sentry/fs/gofer/inode_state.go +++ b/pkg/sentry/fs/gofer/inode_state.go @@ -123,7 +123,7 @@ func (i *inodeFileState) afterLoad() { // beforeSave. return fmt.Errorf("failed to find path for inode number %d. Device %s contains %s", i.sattr.InodeID, i.s.connID, fs.InodeMappings(i.s.inodeMappings)) } - // TODO: Context is not plumbed to save/restore. + // TODO(b/38173783): Context is not plumbed to save/restore. ctx := &dummyClockContext{context.Background()} _, i.file, err = i.s.attach.walk(ctx, splitAbsolutePath(name)) diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go index ed5147c65..4ed688ce5 100644 --- a/pkg/sentry/fs/gofer/session.go +++ b/pkg/sentry/fs/gofer/session.go @@ -134,7 +134,7 @@ type session struct { // socket files. This allows unix domain sockets to be used with paths that // belong to a gofer. // - // TODO: there are few possible races with someone stat'ing the + // TODO(b/77154739): there are few possible races with someone stat'ing the // file and another deleting it concurrently, where the file will not be // reported as socket file. endpoints *endpointMaps `state:"wait"` diff --git a/pkg/sentry/fs/gofer/session_state.go b/pkg/sentry/fs/gofer/session_state.go index 0ad5d63b5..b1f299be5 100644 --- a/pkg/sentry/fs/gofer/session_state.go +++ b/pkg/sentry/fs/gofer/session_state.go @@ -104,7 +104,7 @@ func (s *session) afterLoad() { // If private unix sockets are enabled, create and fill the session's endpoint // maps. if opts.privateunixsocket { - // TODO: Context is not plumbed to save/restore. + // TODO(b/38173783): Context is not plumbed to save/restore. ctx := &dummyClockContext{context.Background()} if err = s.restoreEndpointMaps(ctx); err != nil { diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index 800649211..de349a41a 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -87,7 +87,7 @@ func (f *Filesystem) Mount(ctx context.Context, _ string, flags fs.MountSourceFl options := fs.GenericMountSourceOptions(data) // Grab the whitelist if one was specified. - // TODO: require another option "testonly" in order to allow + // TODO(edahlgren/mpratt/hzy): require another option "testonly" in order to allow // no whitelist. if wl, ok := options[whitelistKey]; ok { f.paths = strings.Split(wl, "|") @@ -320,7 +320,7 @@ func (m *superOperations) SaveInodeMapping(inode *fs.Inode, path string) { // Keep implements fs.MountSourceOperations.Keep. // -// TODO: It is possible to change the permissions on a +// TODO(b/72455313,b/77596690): It is possible to change the permissions on a // host file while it is in the dirent cache (say from RO to RW), but it is not // possible to re-open the file with more relaxed permissions, since the host // FD is already open and stored in the inode. diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index 2030edcb4..69c648f67 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -95,7 +95,7 @@ type inodeFileState struct { // ReadToBlocksAt implements fsutil.CachedFileObject.ReadToBlocksAt. func (i *inodeFileState) ReadToBlocksAt(ctx context.Context, dsts safemem.BlockSeq, offset uint64) (uint64, error) { - // TODO: Using safemem.FromIOReader here is wasteful for two + // TODO(jamieliu): Using safemem.FromIOReader here is wasteful for two // reasons: // // - Using preadv instead of iterated preads saves on host system calls. @@ -325,7 +325,7 @@ func (i *inodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags fs.Fi // canMap returns true if this fs.Inode can be memory mapped. func canMap(inode *fs.Inode) bool { - // FIXME: Some obscure character devices can be mapped. + // FIXME(b/38213152): Some obscure character devices can be mapped. return fs.IsFile(inode.StableAttr) } @@ -428,15 +428,15 @@ func (i *inodeOperations) StatFS(context.Context) (fs.Info, error) { } // AddLink implements fs.InodeOperations.AddLink. -// FIXME: Remove this from InodeOperations altogether. +// FIXME(b/63117438): Remove this from InodeOperations altogether. func (i *inodeOperations) AddLink() {} // DropLink implements fs.InodeOperations.DropLink. -// FIXME: Remove this from InodeOperations altogether. +// FIXME(b/63117438): Remove this from InodeOperations altogether. func (i *inodeOperations) DropLink() {} // NotifyStatusChange implements fs.InodeOperations.NotifyStatusChange. -// FIXME: Remove this from InodeOperations altogether. +// FIXME(b/63117438): Remove this from InodeOperations altogether. func (i *inodeOperations) NotifyStatusChange(ctx context.Context) {} // readdirAll returns all of the directory entries in i. diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index d82f9740e..fe411a766 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -93,10 +93,10 @@ func (i *Inode) DecRef() { // destroy releases the Inode and releases the msrc reference taken. func (i *Inode) destroy() { - // FIXME: Context is not plumbed here. + // FIXME(b/38173783): Context is not plumbed here. ctx := context.Background() if err := i.WriteOut(ctx); err != nil { - // FIXME: Mark as warning again once noatime is + // FIXME(b/65209558): Mark as warning again once noatime is // properly supported. log.Debugf("Inode %+v, failed to sync all metadata: %v", i.StableAttr, err) } @@ -359,7 +359,7 @@ func (i *Inode) Getlink(ctx context.Context) (*Dirent, error) { // AddLink calls i.InodeOperations.AddLink. func (i *Inode) AddLink() { if i.overlay != nil { - // FIXME: Remove this from InodeOperations altogether. + // FIXME(b/63117438): Remove this from InodeOperations altogether. // // This interface is only used by ramfs to update metadata of // children. These filesystems should _never_ have overlay diff --git a/pkg/sentry/fs/inode_operations.go b/pkg/sentry/fs/inode_operations.go index ceacc7659..ff8b75f31 100644 --- a/pkg/sentry/fs/inode_operations.go +++ b/pkg/sentry/fs/inode_operations.go @@ -118,7 +118,7 @@ type InodeOperations interface { // // The caller must ensure that this operation is permitted. // - // TODO: merge Remove and RemoveDirectory, Remove + // TODO(b/67778723): merge Remove and RemoveDirectory, Remove // just needs a type flag. Remove(ctx context.Context, dir *Inode, name string) error diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go index 254646176..bda3e1861 100644 --- a/pkg/sentry/fs/inode_overlay.go +++ b/pkg/sentry/fs/inode_overlay.go @@ -142,7 +142,7 @@ func overlayLookup(ctx context.Context, parent *overlayEntry, inode *Inode, name } else { // If we have something from the upper, we can only use it if the types // match. - // NOTE: Allow SpecialDirectories and Directories to merge. + // NOTE(b/112312863): Allow SpecialDirectories and Directories to merge. // This is needed to allow submounts in /proc and /sys. if upperInode.StableAttr.Type == child.Inode.StableAttr.Type || (IsDir(upperInode.StableAttr) && IsDir(child.Inode.StableAttr)) { @@ -226,7 +226,7 @@ func overlayCreate(ctx context.Context, o *overlayEntry, parent *Dirent, name st return nil, err } - // NOTE: Replace the Dirent with a transient Dirent, since + // NOTE(b/71766861): Replace the Dirent with a transient Dirent, since // we are about to create the real Dirent: an overlay Dirent. // // This ensures the *fs.File returned from overlayCreate is in the same @@ -338,7 +338,7 @@ func overlayRename(ctx context.Context, o *overlayEntry, oldParent *Dirent, rena // directory will appear empty in the upper fs, which will then // allow the rename to proceed when it should return ENOTEMPTY. // - // NOTE: Ideally, we'd just pass in the replaced + // NOTE(b/111808347): Ideally, we'd just pass in the replaced // Dirent from Rename, but we must drop the reference on // replaced before we make the rename call, so Rename can't // pass the Dirent to the Inode without significantly diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index 1e245ae5f..4d1693204 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -42,7 +42,7 @@ type DirentOperations interface { // MountSourceOperations contains filesystem specific operations. type MountSourceOperations interface { - // TODO: Add: + // TODO(b/67778729): Add: // BlockSize() int64 // FS() Filesystem @@ -101,7 +101,7 @@ func (i InodeMappings) String() string { // amalgamation implies that a mount source cannot be shared by multiple mounts // (e.g. cannot be mounted at different locations). // -// TODO: Move mount-specific information out of MountSource. +// TODO(b/63601033): Move mount-specific information out of MountSource. // // +stateify savable type MountSource struct { diff --git a/pkg/sentry/fs/mount_test.go b/pkg/sentry/fs/mount_test.go index 269d6b9da..d7605b2c9 100644 --- a/pkg/sentry/fs/mount_test.go +++ b/pkg/sentry/fs/mount_test.go @@ -33,7 +33,7 @@ func cacheReallyContains(cache *DirentCache, d *Dirent) bool { } // TestMountSourceOnlyCachedOnce tests that a Dirent that is mounted over only ends -// up in a single Dirent Cache. NOTE: Having a dirent in multiple +// up in a single Dirent Cache. NOTE(b/63848693): Having a dirent in multiple // caches causes major consistency issues. func TestMountSourceOnlyCachedOnce(t *testing.T) { ctx := contexttest.Context(t) diff --git a/pkg/sentry/fs/proc/README.md b/pkg/sentry/fs/proc/README.md index 3cc5f197c..5d4ec6c7b 100644 --- a/pkg/sentry/fs/proc/README.md +++ b/pkg/sentry/fs/proc/README.md @@ -91,7 +91,7 @@ CPU.IO utilization in last 10 minutes | Always zero Num currently running processes | Always zero Total num processes | Always zero -TODO: Populate the columns with accurate statistics. +TODO(b/62345059): Populate the columns with accurate statistics. ### meminfo @@ -128,12 +128,12 @@ Field name | Notes Buffers | Always zero, no block devices SwapCache | Always zero, no swap Inactive(anon) | Always zero, see SwapCache -Unevictable | Always zero TODO -Mlocked | Always zero TODO +Unevictable | Always zero TODO(b/31823263) +Mlocked | Always zero TODO(b/31823263) SwapTotal | Always zero, no swap SwapFree | Always zero, no swap -Dirty | Always zero TODO -Writeback | Always zero TODO +Dirty | Always zero TODO(b/31823263) +Writeback | Always zero TODO(b/31823263) MemAvailable | Uses the same value as MemFree since there is no swap. Slab | Missing SReclaimable | Missing @@ -185,7 +185,7 @@ softirq 0 0 0 0 0 0 0 0 0 0 0 All fields except for `btime` are always zero. -TODO: Populate with accurate fields. +TODO(b/37226836): Populate with accurate fields. ### sys diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index 25da06f5d..f2329e623 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -258,7 +258,7 @@ func newFdInfoDir(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { // Lookup loads an fd in /proc/TID/fdinfo into a Dirent. func (fdid *fdInfoDir) Lookup(ctx context.Context, dir *fs.Inode, p string) (*fs.Dirent, error) { inode, err := walkDescriptors(fdid.t, p, func(file *fs.File, fdFlags kernel.FDFlags) *fs.Inode { - // TODO: Using a static inode here means that the + // TODO(b/121266871): Using a static inode here means that the // data can be out-of-date if, for instance, the flags on the // FD change before we read this file. We should switch to // generating the data on Read(). Also, we should include pos, diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go index 78f3a1dc0..3ee0e570a 100644 --- a/pkg/sentry/fs/proc/loadavg.go +++ b/pkg/sentry/fs/proc/loadavg.go @@ -40,7 +40,7 @@ func (d *loadavgData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) var buf bytes.Buffer - // TODO: Include real data in fields. + // TODO(b/62345059): Include real data in fields. // Column 1-3: CPU and IO utilization of the last 1, 5, and 10 minute periods. // Column 4-5: currently running processes and the total number of processes. // Column 6: the last process ID used. diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go index 620e93ce3..75cbf3e77 100644 --- a/pkg/sentry/fs/proc/meminfo.go +++ b/pkg/sentry/fs/proc/meminfo.go @@ -58,7 +58,7 @@ func (d *meminfoData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) fmt.Fprintf(&buf, "MemTotal: %8d kB\n", totalSize/1024) memFree := (totalSize - totalUsage) / 1024 // We use MemFree as MemAvailable because we don't swap. - // TODO: When reclaim is implemented the value of MemAvailable + // TODO(rahat): When reclaim is implemented the value of MemAvailable // should change. fmt.Fprintf(&buf, "MemFree: %8d kB\n", memFree) fmt.Fprintf(&buf, "MemAvailable: %8d kB\n", memFree) @@ -72,8 +72,8 @@ func (d *meminfoData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) fmt.Fprintf(&buf, "Inactive(anon): 0 kB\n") fmt.Fprintf(&buf, "Active(file): %8d kB\n", activeFile/1024) fmt.Fprintf(&buf, "Inactive(file): %8d kB\n", inactiveFile/1024) - fmt.Fprintf(&buf, "Unevictable: 0 kB\n") // TODO - fmt.Fprintf(&buf, "Mlocked: 0 kB\n") // TODO + fmt.Fprintf(&buf, "Unevictable: 0 kB\n") // TODO(b/31823263) + fmt.Fprintf(&buf, "Mlocked: 0 kB\n") // TODO(b/31823263) fmt.Fprintf(&buf, "SwapTotal: 0 kB\n") fmt.Fprintf(&buf, "SwapFree: 0 kB\n") fmt.Fprintf(&buf, "Dirty: 0 kB\n") diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index 1e62af8c6..fe62b167b 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -114,7 +114,7 @@ func (mif *mountInfoFile) ReadSeqFileData(ctx context.Context, handle seqfile.Se // (4) Root: the pathname of the directory in the filesystem // which forms the root of this mount. // - // NOTE: This will always be "/" until we implement + // NOTE(b/78135857): This will always be "/" until we implement // bind mounts. fmt.Fprintf(&buf, "/ ") diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go index 55a958f9e..d24b2d370 100644 --- a/pkg/sentry/fs/proc/net.go +++ b/pkg/sentry/fs/proc/net.go @@ -154,7 +154,7 @@ func (n *netDev) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se contents[1] = " face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n" for _, i := range interfaces { - // TODO: Collect stats from each inet.Stack + // TODO(b/71872867): Collect stats from each inet.Stack // implementation (hostinet, epsocket, and rpcinet). // Implements the same format as diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go index f2bbef375..18bd8e9b6 100644 --- a/pkg/sentry/fs/proc/stat.go +++ b/pkg/sentry/fs/proc/stat.go @@ -83,7 +83,7 @@ func (s *statData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([] var buf bytes.Buffer - // TODO: We currently export only zero CPU stats. We could + // TODO(b/37226836): We currently export only zero CPU stats. We could // at least provide some aggregate stats. var cpu cpuStats fmt.Fprintf(&buf, "cpu %s\n", cpu) @@ -100,7 +100,7 @@ func (s *statData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([] const numInterrupts = 256 // The Kernel doesn't handle real interrupts, so report all zeroes. - // TODO: We could count page faults as #PF. + // TODO(b/37226836): We could count page faults as #PF. fmt.Fprintf(&buf, "intr 0") // total for i := 0; i < numInterrupts; i++ { fmt.Fprintf(&buf, " 0") @@ -108,22 +108,22 @@ func (s *statData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([] fmt.Fprintf(&buf, "\n") // Total number of context switches. - // TODO: Count this. + // TODO(b/37226836): Count this. fmt.Fprintf(&buf, "ctxt 0\n") // CLOCK_REALTIME timestamp from boot, in seconds. fmt.Fprintf(&buf, "btime %d\n", s.k.Timekeeper().BootTime().Seconds()) // Total number of clones. - // TODO: Count this. + // TODO(b/37226836): Count this. fmt.Fprintf(&buf, "processes 0\n") // Number of runnable tasks. - // TODO: Count this. + // TODO(b/37226836): Count this. fmt.Fprintf(&buf, "procs_running 0\n") // Number of tasks waiting on IO. - // TODO: Count this. + // TODO(b/37226836): Count this. fmt.Fprintf(&buf, "procs_blocked 0\n") // Number of each softirq handled. diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index 728a46a74..0ce77f04f 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -39,7 +39,7 @@ const ( // tcpMemInode is used to read/write the size of netstack tcp buffers. // -// TODO: If we have multiple proc mounts, concurrent writes can +// TODO(b/121381035): If we have multiple proc mounts, concurrent writes can // leave netstack and the proc files in an inconsistent state. Since we set the // buffer size from these proc files on restore, we may also race and end up in // an inconsistent state on restore. diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 0edcdfce2..9f65a8337 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -77,7 +77,7 @@ func newTaskDir(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace "fd": newFdDir(t, msrc), "fdinfo": newFdInfoDir(t, msrc), "gid_map": newGIDMap(t, msrc), - // FIXME: create the correct io file for threads. + // FIXME(b/123511468): create the correct io file for threads. "io": newIO(t, msrc), "maps": newMaps(t, msrc), "mountinfo": seqfile.NewSeqFileInode(t, &mountInfoFile{t: t}, msrc), @@ -93,7 +93,7 @@ func newTaskDir(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace contents["task"] = newSubtasks(t, msrc, pidns) } - // TODO: Set EUID/EGID based on dumpability. + // TODO(b/31916171): Set EUID/EGID based on dumpability. d := &taskDir{ Dir: *ramfs.NewDir(t, contents, fs.RootOwner, fs.FilePermsFromMode(0555)), t: t, @@ -245,7 +245,7 @@ func (e *exe) executable() (d *fs.Dirent, err error) { e.t.WithMuLocked(func(t *kernel.Task) { mm := t.MemoryManager() if mm == nil { - // TODO: Check shouldn't allow Readlink once the + // TODO(b/34851096): Check shouldn't allow Readlink once the // Task is zombied. err = syserror.EACCES return @@ -297,7 +297,7 @@ type namespaceSymlink struct { } func newNamespaceSymlink(t *kernel.Task, msrc *fs.MountSource, name string) *fs.Inode { - // TODO: Namespace symlinks should contain the namespace name and the + // TODO(rahat): Namespace symlinks should contain the namespace name and the // inode number for the namespace instance, so for example user:[123456]. We // currently fake the inode number by sticking the symlink inode in its // place. diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go index b6d49d5e9..58e0c793c 100644 --- a/pkg/sentry/fs/proc/version.go +++ b/pkg/sentry/fs/proc/version.go @@ -65,7 +65,7 @@ func (v *versionData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) // Since we don't really want to expose build information to // applications, those fields are omitted. // - // FIXME: Using Version from the init task SyscallTable + // FIXME(mpratt): Using Version from the init task SyscallTable // disregards the different version a task may have (e.g., in a uts // namespace). ver := init.Leader().SyscallTable().Version diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index 159fd2981..c0400b67d 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -358,7 +358,7 @@ func (d *Dir) CreateDirectory(ctx context.Context, dir *fs.Inode, name string, p _, err := d.createInodeOperationsCommon(ctx, name, func() (*fs.Inode, error) { return d.NewDir(ctx, dir, perms) }) - // TODO: Support updating status times, as those should be + // TODO(nlacasse): Support updating status times, as those should be // updated by links. return err } diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index d0c93028f..8e44421b6 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -34,7 +34,7 @@ const ( // GID for the root directory. rootGIDKey = "gid" - // TODO: support a tmpfs size limit. + // TODO(edahlgren/mpratt): support a tmpfs size limit. // size = "size" // Permissions that exceed modeMask will be rejected. diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 7c80d711b..4450e1363 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -309,7 +309,7 @@ func (f *fileInodeOperations) read(ctx context.Context, file *fs.File, dst userm // common: getting a return value of 0 from a read syscall is the only way // to detect EOF. // - // TODO: Separate out f.attr.Size and use atomics instead of + // TODO(jamieliu): Separate out f.attr.Size and use atomics instead of // f.dataMu. f.dataMu.RLock() size := f.attr.Size diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 555692505..5bb4922cb 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -32,7 +32,7 @@ import ( var fsInfo = fs.Info{ Type: linux.TMPFS_MAGIC, - // TODO: allow configuring a tmpfs size and enforce it. + // TODO(b/29637826): allow configuring a tmpfs size and enforce it. TotalBlocks: 0, FreeBlocks: 0, } diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index 33b4c6438..f8713471a 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -66,7 +66,7 @@ type dirInodeOperations struct { // msrc is the super block this directory is on. // - // TODO: Plumb this through instead of storing it here. + // TODO(chrisko): Plumb this through instead of storing it here. msrc *fs.MountSource // mu protects the fields below. @@ -89,7 +89,7 @@ type dirInodeOperations struct { // next is the next pty index to use. // - // TODO: reuse indices when ptys are closed. + // TODO(b/29356795): reuse indices when ptys are closed. next uint32 } @@ -118,7 +118,7 @@ func newDir(ctx context.Context, m *fs.MountSource) *fs.Inode { // N.B. Linux always uses inode id 1 for the directory. See // fs/devpts/inode.c:devpts_fill_super. // - // TODO: Since ptsDevice must be shared between + // TODO(b/75267214): Since ptsDevice must be shared between // different mounts, we must not assign fixed numbers. InodeID: ptsDevice.NextIno(), BlockSize: usermem.PageSize, diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go index 43e0e2a04..a53448c47 100644 --- a/pkg/sentry/fs/tty/fs.go +++ b/pkg/sentry/fs/tty/fs.go @@ -43,7 +43,7 @@ func (*filesystem) Name() string { // AllowUserMount allows users to mount(2) this file system. func (*filesystem) AllowUserMount() bool { - // TODO: Users may mount this once the terminals are in a + // TODO(b/29356795): Users may mount this once the terminals are in a // usable state. return false } diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index 7c256abb0..e2686a074 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -51,7 +51,7 @@ func newMasterInode(ctx context.Context, d *dirInodeOperations, owner fs.FileOwn // N.B. Linux always uses inode id 2 for ptmx. See // fs/devpts/inode.c:mknod_ptmx. // - // TODO: Since ptsDevice must be shared between + // TODO(b/75267214): Since ptsDevice must be shared between // different mounts, we must not assign fixed numbers. InodeID: ptsDevice.NextIno(), Type: fs.CharacterDevice, @@ -157,7 +157,7 @@ func (mf *masterFileOperations) Ioctl(ctx context.Context, io usermem.IO, args a // of the slave end. return mf.t.ld.setTermios(ctx, io, args) case linux.TCSETSW: - // TODO: This should drain the output queue first. + // TODO(b/29356795): This should drain the output queue first. return mf.t.ld.setTermios(ctx, io, args) case linux.TIOCGPTN: _, err := usermem.CopyObjectOut(ctx, io, args[2].Pointer(), uint32(mf.t.n), usermem.IOOpts{ @@ -165,7 +165,7 @@ func (mf *masterFileOperations) Ioctl(ctx context.Context, io usermem.IO, args a }) return 0, err case linux.TIOCSPTLCK: - // TODO: Implement pty locking. For now just pretend we do. + // TODO(b/29356795): Implement pty locking. For now just pretend we do. return 0, nil case linux.TIOCGWINSZ: return 0, mf.t.ld.windowSize(ctx, io, args) diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index e8368bcdd..ed080ca0f 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -56,7 +56,7 @@ func newSlaveInode(ctx context.Context, d *dirInodeOperations, t *Terminal, owne // N.B. Linux always uses inode id = tty index + 3. See // fs/devpts/inode.c:devpts_pty_new. // - // TODO: Since ptsDevice must be shared between + // TODO(b/75267214): Since ptsDevice must be shared between // different mounts, we must not assign fixed numbers. InodeID: ptsDevice.NextIno(), Type: fs.CharacterDevice, @@ -137,7 +137,7 @@ func (sf *slaveFileOperations) Ioctl(ctx context.Context, io usermem.IO, args ar case linux.TCSETS: return sf.si.t.ld.setTermios(ctx, io, args) case linux.TCSETSW: - // TODO: This should drain the output queue first. + // TODO(b/29356795): This should drain the output queue first. return sf.si.t.ld.setTermios(ctx, io, args) case linux.TIOCGPTN: _, err := usermem.CopyObjectOut(ctx, io, args[2].Pointer(), uint32(sf.si.t.n), usermem.IOOpts{ @@ -151,7 +151,7 @@ func (sf *slaveFileOperations) Ioctl(ctx context.Context, io usermem.IO, args ar case linux.TIOCSCTTY: // Make the given terminal the controlling terminal of the // calling process. - // TODO: Implement once we have support for job + // TODO(b/129283598): Implement once we have support for job // control. return 0, nil default: diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index a843b9aab..2055da196 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -125,7 +125,7 @@ func NewUserCredentials(kuid KUID, kgid KGID, extraKGIDs []KGID, capabilities *T creds.EffectiveCaps = capabilities.EffectiveCaps creds.BoundingCaps = capabilities.BoundingCaps creds.InheritableCaps = capabilities.InheritableCaps - // TODO: Support ambient capabilities. + // TODO(nlacasse): Support ambient capabilities. } else { // If no capabilities are specified, grant capabilities consistent with // setresuid + setresgid from NewRootCredentials to the given uid and diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index 30957bb9a..159940a69 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -49,7 +49,7 @@ type UserNamespace struct { gidMapFromParent idMapSet gidMapToParent idMapSet - // TODO: Support disabling setgroups(2). + // TODO(b/27454212): Support disabling setgroups(2). } // NewRootUserNamespace returns a UserNamespace that is appropriate for a diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index 373e11772..deff6def9 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -30,7 +30,7 @@ const ( // rtSignalCap is the maximum number of instances of a given realtime // signal that may be pending. // - // TODO: In Linux, the minimum signal queue size is + // TODO(igudger): In Linux, the minimum signal queue size is // RLIMIT_SIGPENDING, which is by default max_threads/2. rtSignalCap = 32 ) diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index 8d78b2fb3..15f2e2964 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -162,7 +162,7 @@ func (t *Task) CanTrace(target *Task, attach bool) bool { if cgid := callerCreds.RealKGID; cgid != targetCreds.RealKGID || cgid != targetCreds.EffectiveKGID || cgid != targetCreds.SavedKGID { return false } - // TODO: dumpability check + // TODO(b/31916171): dumpability check if callerCreds.UserNamespace != targetCreds.UserNamespace { return false } @@ -396,7 +396,7 @@ func (t *Task) ptraceAttach(target *Task, seize bool, opts uintptr) error { if target.stop == (*groupStop)(nil) { target.trapStopPending = true target.endInternalStopLocked() - // TODO: Linux blocks ptrace_attach() until the task has + // TODO(jamieliu): Linux blocks ptrace_attach() until the task has // entered the ptrace-stop (or exited) via JOBCTL_TRAPPING. } target.tg.signalHandlers.mu.Unlock() diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 0a954bc16..6d3314e81 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -66,7 +66,7 @@ func (t *Task) SetRSEQCriticalRegion(rscr RSEQCriticalRegion) error { if rscr.CriticalSection.Contains(rscr.Restart) { return syserror.EINVAL } - // TODO: check that rscr.CriticalSection and rscr.Restart are in + // TODO(jamieliu): check that rscr.CriticalSection and rscr.Restart are in // the application address range, for consistency with Linux t.tg.rscr.Store(&rscr) return nil diff --git a/pkg/sentry/kernel/sched/cpuset.go b/pkg/sentry/kernel/sched/cpuset.go index 69aee9127..41ac1067d 100644 --- a/pkg/sentry/kernel/sched/cpuset.go +++ b/pkg/sentry/kernel/sched/cpuset.go @@ -29,7 +29,7 @@ type CPUSet []byte // CPUSetSize returns the size in bytes of a CPUSet that can contain num cpus. func CPUSetSize(num uint) uint { - // NOTE: Applications may expect that the size of a CPUSet in + // NOTE(b/68859821): Applications may expect that the size of a CPUSet in // bytes is always a multiple of sizeof(unsigned long), since this is true // in Linux. Thus we always round up. bytes := (num + bitsPerByte - 1) / bitsPerByte diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index 29a2eb804..2b7c1a9bc 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -302,7 +302,7 @@ func (s *Set) SetVal(ctx context.Context, num int32, val int16, creds *auth.Cred return syserror.ERANGE } - // TODO: Clear undo entries in all processes + // TODO(b/29354920): Clear undo entries in all processes sem.value = val sem.pid = pid s.changeTime = ktime.NowFromContext(ctx) @@ -336,7 +336,7 @@ func (s *Set) SetValAll(ctx context.Context, vals []uint16, creds *auth.Credenti for i, val := range vals { sem := &s.sems[i] - // TODO: Clear undo entries in all processes + // TODO(b/29354920): Clear undo entries in all processes sem.value = int16(val) sem.pid = pid sem.wakeWaiters() @@ -481,7 +481,7 @@ func (s *Set) executeOps(ctx context.Context, ops []linux.Sembuf, pid int32) (ch } // All operations succeeded, apply them. - // TODO: handle undo operations. + // TODO(b/29354920): handle undo operations. for i, v := range tmpVals { s.sems[i].value = v s.sems[i].wakeWaiters() diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index 349f2a26e..d4812a065 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -427,7 +427,7 @@ func (s *Shm) AddMapping(ctx context.Context, _ memmap.MappingSpace, _ usermem.A func (s *Shm) RemoveMapping(ctx context.Context, _ memmap.MappingSpace, _ usermem.AddrRange, _ uint64, _ bool) { s.mu.Lock() defer s.mu.Unlock() - // TODO: RemoveMapping may be called during task exit, when ctx + // TODO(b/38173783): RemoveMapping may be called during task exit, when ctx // is context.Background. Gracefully handle missing clocks. Failing to // update the detach time in these cases is ok, since no one can observe the // omission. diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index 7eb99718d..293b21249 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -165,7 +165,7 @@ type Stracer interface { // // The returned private data is passed to SyscallExit. // - // TODO: remove kernel imports from the strace + // TODO(gvisor.dev/issue/155): remove kernel imports from the strace // package so that the type can be used directly. SyscallEnter(t *Task, sysno uintptr, args arch.SyscallArguments, flags uint32) interface{} diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index 1b4d4cf2f..ac38dd157 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -60,7 +60,7 @@ func (tc *TaskContext) release() { // Nil out pointers so that if the task is saved after release, it doesn't // follow the pointers to possibly now-invalid objects. if tc.MemoryManager != nil { - // TODO + // TODO(b/38173783) tc.MemoryManager.DecUsers(context.Background()) tc.MemoryManager = nil } diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index 9fca90a1c..b49f902a5 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -208,7 +208,7 @@ func (r *runSyscallAfterExecStop) execute(t *Task) taskRunState { t.tc = *r.tc t.mu.Unlock() t.unstopVforkParent() - // NOTE: All locks must be dropped prior to calling Activate. + // NOTE(b/30316266): All locks must be dropped prior to calling Activate. t.MemoryManager().Activate() t.ptraceExec(oldTID) diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index 1a0734ab6..a07956208 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -339,7 +339,7 @@ func (t *Task) exitChildren() { }, true /* group */) other.signalHandlers.mu.Unlock() } - // TODO: The init process waits for all processes in the + // TODO(b/37722272): The init process waits for all processes in the // namespace to exit before completing its own exit // (kernel/pid_namespace.c:zap_pid_ns_processes()). Stop until all // other tasks in the namespace are dead, except possibly for this @@ -692,7 +692,7 @@ func (t *Task) exitNotificationSignal(sig linux.Signal, receiver *Task) *arch.Si info.Code = arch.CLD_EXITED info.SetStatus(int32(t.exitStatus.Code)) } - // TODO: Set utime, stime. + // TODO(b/72102453): Set utime, stime. return info } diff --git a/pkg/sentry/kernel/task_identity.go b/pkg/sentry/kernel/task_identity.go index e105eba13..6c9608f8d 100644 --- a/pkg/sentry/kernel/task_identity.go +++ b/pkg/sentry/kernel/task_identity.go @@ -421,7 +421,7 @@ func (t *Task) SetKeepCaps(k bool) { // updateCredsForExec updates t.creds to reflect an execve(). // -// NOTE: We currently do not implement privileged executables +// NOTE(b/30815691): We currently do not implement privileged executables // (set-user/group-ID bits and file capabilities). This allows us to make a lot // of simplifying assumptions: // diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 6b5fe7165..7115aa967 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -110,7 +110,7 @@ func (t *Task) doStop() { return } t.Deactivate() - // NOTE: t.Activate() must be called without any locks held, so + // NOTE(b/30316266): t.Activate() must be called without any locks held, so // this defer must precede the defer for unlocking the signal mutex. defer t.Activate() t.accountTaskGoroutineEnter(TaskGoroutineStopped) diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 3a8e61900..7f2e0df72 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -509,7 +509,7 @@ func (t *Task) canReceiveSignalLocked(sig linux.Signal) bool { if t.stop != nil { return false } - // - TODO: No special case for when t is also the sending task, + // - TODO(b/38173783): No special case for when t is also the sending task, // because the identity of the sender is unknown. // - Do not choose tasks that have already been interrupted, as they may be // busy handling another signal. @@ -895,7 +895,7 @@ func (t *Task) signalStop(target *Task, code int32, status int32) { sigchld.SetPid(int32(t.tg.pidns.tids[target])) sigchld.SetUid(int32(target.Credentials().RealKUID.In(t.UserNamespace()).OrOverflow())) sigchld.SetStatus(status) - // TODO: Set utime, stime. + // TODO(b/72102453): Set utime, stime. t.sendSignalLocked(sigchld, true /* group */) } } diff --git a/pkg/sentry/kernel/task_stop.go b/pkg/sentry/kernel/task_stop.go index 36846484c..1302cadc1 100644 --- a/pkg/sentry/kernel/task_stop.go +++ b/pkg/sentry/kernel/task_stop.go @@ -69,7 +69,7 @@ import ( // A TaskStop is a condition visible to the task control flow graph that // prevents a task goroutine from running or exiting, i.e. an internal stop. // -// NOTE: Most TaskStops don't contain any data; they're +// NOTE(b/30793614): Most TaskStops don't contain any data; they're // distinguished by their type. The obvious way to implement such a TaskStop // is: // diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go index 80ad59dde..79051befa 100644 --- a/pkg/sentry/loader/loader.go +++ b/pkg/sentry/loader/loader.go @@ -70,7 +70,7 @@ func openPath(ctx context.Context, mm *fs.MountNamespace, root, wd *fs.Dirent, m defer d.DecRef() perms := fs.PermMask{ - // TODO: Linux requires only execute + // TODO(gvisor.dev/issue/160): Linux requires only execute // permission, not read. However, our backing filesystems may // prevent us from reading the file without read permission. // diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index 18b7e90d8..8c196df84 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -194,7 +194,7 @@ func validateVDSO(ctx context.Context, f *fs.File, size uint64) (elfInfo, error) // VDSO describes a VDSO. // -// NOTE: to support multiple architectures or operating systems, this +// NOTE(mpratt): to support multiple architectures or operating systems, this // would need to contain a VDSO for each. // // +stateify savable @@ -262,7 +262,7 @@ func PrepareVDSO(mfp pgalloc.MemoryFileProvider) (*VDSO, error) { return &VDSO{ ParamPage: mm.NewSpecialMappable("[vvar]", mfp, paramPage), - // TODO: Don't advertise the VDSO, as + // TODO(gvisor.dev/issue/157): Don't advertise the VDSO, as // some applications may not be able to handle multiple [vdso] // hints. vdso: mm.NewSpecialMappable("", mfp, vdso), @@ -279,7 +279,7 @@ func PrepareVDSO(mfp pgalloc.MemoryFileProvider) (*VDSO, error) { // kernel simply directly maps the entire file into process memory, with very // little real ELF parsing. // -// NOTE: This means that userspace can, and unfortunately does, +// NOTE(b/25323870): This means that userspace can, and unfortunately does, // depend on parts of the ELF that would normally not be mapped. To maintain // compatibility with such binaries, we load the VDSO much like Linux. // diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index 1ef1f0dd8..3f6f7ebd0 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -356,6 +356,6 @@ type MMapOpts struct { // Hint is the name used for the mapping in /proc/[pid]/maps. If Hint is // empty, MappingIdentity.MappedName() will be used instead. // - // TODO: Replace entirely with MappingIdentity? + // TODO(jamieliu): Replace entirely with MappingIdentity? Hint string } diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go index f7ff06de0..7075792e0 100644 --- a/pkg/sentry/mm/aio_context.go +++ b/pkg/sentry/mm/aio_context.go @@ -331,7 +331,7 @@ func (mm *MemoryManager) NewAIOContext(ctx context.Context, events uint32) (uint Length: aioRingBufferSize, MappingIdentity: m, Mappable: m, - // TODO: Linux does "do_mmap_pgoff(..., PROT_READ | + // TODO(fvoznika): Linux does "do_mmap_pgoff(..., PROT_READ | // PROT_WRITE, ...)" in fs/aio.c:aio_setup_ring(); why do we make this // mapping read-only? Perms: usermem.Read, diff --git a/pkg/sentry/mm/procfs.go b/pkg/sentry/mm/procfs.go index 0c4b8895d..7cdbf6e25 100644 --- a/pkg/sentry/mm/procfs.go +++ b/pkg/sentry/mm/procfs.go @@ -69,7 +69,7 @@ func (mm *MemoryManager) ReadMapsSeqFileData(ctx context.Context, handle seqfile start = *handle.(*usermem.Addr) } for vseg := mm.vmas.LowerBoundSegment(start); vseg.Ok(); vseg = vseg.NextSegment() { - // FIXME: If we use a usermem.Addr for the handle, we get + // FIXME(b/30793614): If we use a usermem.Addr for the handle, we get // "panic: autosave error: type usermem.Addr is not registered". vmaAddr := vseg.End() data = append(data, seqfile.SeqData{ @@ -88,7 +88,7 @@ func (mm *MemoryManager) ReadMapsSeqFileData(ctx context.Context, handle seqfile // // Artifically adjust the seqfile handle so we only output vsyscall entry once. if start != vsyscallEnd { - // FIXME: Can't get a pointer to constant vsyscallEnd. + // FIXME(b/30793614): Can't get a pointer to constant vsyscallEnd. vmaAddr := vsyscallEnd data = append(data, seqfile.SeqData{ Buf: []byte(vsyscallMapsEntry), @@ -134,7 +134,7 @@ func (mm *MemoryManager) appendVMAMapsEntryLocked(ctx context.Context, vseg vmaI if vma.hint != "" { s = vma.hint } else if vma.id != nil { - // FIXME: We are holding mm.mappingMu here, which is + // FIXME(jamieliu): We are holding mm.mappingMu here, which is // consistent with Linux's holding mmap_sem in // fs/proc/task_mmu.c:show_map_vma() => fs/seq_file.c:seq_file_path(). // However, it's not clear that fs.File.MappedName() is actually @@ -162,7 +162,7 @@ func (mm *MemoryManager) ReadSmapsSeqFileData(ctx context.Context, handle seqfil start = *handle.(*usermem.Addr) } for vseg := mm.vmas.LowerBoundSegment(start); vseg.Ok(); vseg = vseg.NextSegment() { - // FIXME: If we use a usermem.Addr for the handle, we get + // FIXME(b/30793614): If we use a usermem.Addr for the handle, we get // "panic: autosave error: type usermem.Addr is not registered". vmaAddr := vseg.End() data = append(data, seqfile.SeqData{ @@ -174,7 +174,7 @@ func (mm *MemoryManager) ReadSmapsSeqFileData(ctx context.Context, handle seqfil // We always emulate vsyscall, so advertise it here. See // ReadMapsSeqFileData for additional commentary. if start != vsyscallEnd { - // FIXME: Can't get a pointer to constant vsyscallEnd. + // FIXME(b/30793614): Can't get a pointer to constant vsyscallEnd. vmaAddr := vsyscallEnd data = append(data, seqfile.SeqData{ Buf: []byte(vsyscallSmapsEntry), diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go index cfbf7a104..3b5161998 100644 --- a/pkg/sentry/mm/special_mappable.go +++ b/pkg/sentry/mm/special_mappable.go @@ -136,7 +136,7 @@ func (m *SpecialMappable) Length() uint64 { // NewSharedAnonMappable returns a SpecialMappable that implements the // semantics of mmap(MAP_SHARED|MAP_ANONYMOUS) and mappings of /dev/zero. // -// TODO: The use of SpecialMappable is a lazy code reuse hack. Linux +// TODO(jamieliu): The use of SpecialMappable is a lazy code reuse hack. Linux // uses an ephemeral file created by mm/shmem.c:shmem_zero_setup(); we should // do the same to get non-zero device and inode IDs. func NewSharedAnonMappable(length uint64, mfp pgalloc.MemoryFileProvider) (*SpecialMappable, error) { diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index cc7eb76d2..7b675b9b5 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -137,7 +137,7 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme return 0, err } - // TODO: In Linux, VM_LOCKONFAULT (which may be set on the new + // TODO(jamieliu): In Linux, VM_LOCKONFAULT (which may be set on the new // vma by mlockall(MCL_FUTURE|MCL_ONFAULT) => mm_struct::def_flags) appears // to effectively disable MAP_POPULATE by unsetting FOLL_POPULATE in // mm/util.c:vm_mmap_pgoff() => mm/gup.c:__mm_populate() => @@ -148,7 +148,7 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme mm.populateVMAAndUnlock(ctx, vseg, ar, true) case opts.Mappable == nil && length <= privateAllocUnit: - // NOTE: Get pmas and map eagerly in the hope + // NOTE(b/63077076, b/63360184): Get pmas and map eagerly in the hope // that doing so will save on future page faults. We only do this for // anonymous mappings, since otherwise the cost of // memmap.Mappable.Translate is unknown; and only for small mappings, @@ -698,7 +698,7 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad return mm.brk.End, syserror.EINVAL } - // TODO: This enforces RLIMIT_DATA, but is + // TODO(gvisor.dev/issue/156): This enforces RLIMIT_DATA, but is // slightly more permissive than the usual data limit. In particular, // this only limits the size of the heap; a true RLIMIT_DATA limits the // size of heap + data + bss. The segment sizes need to be plumbed from diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index e9c9a80ea..931995254 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -274,7 +274,7 @@ func (mm *MemoryManager) getVMAsLocked(ctx context.Context, ar usermem.AddrRange // Loop invariants: vgap = vseg.PrevGap(); addr < vseg.End(). vma := vseg.ValuePtr() if addr < vseg.Start() { - // TODO: Implement vma.growsDown here. + // TODO(jamieliu): Implement vma.growsDown here. return vbegin, vgap, syserror.EFAULT } diff --git a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go index c0a0af92d..d0f6bb225 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go @@ -62,7 +62,7 @@ func updateSystemValues(fd int) error { // Calculate whether guestPCID is supported. // - // FIXME: These should go through the much more pleasant + // FIXME(ascannell): These should go through the much more pleasant // cpuid package interfaces, once a way to accept raw kvm CPUID entries // is plumbed (or some rough equivalent). for i := 0; i < int(cpuidSupported.nr); i++ { diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go index d1c9458ea..0e48417b9 100644 --- a/pkg/sentry/platform/platform.go +++ b/pkg/sentry/platform/platform.go @@ -181,7 +181,7 @@ var ( // this signal both to Contexts and to the sentry itself, under the assumption // that they originate from races with Context.Interrupt(). // -// NOTE: The Go runtime only guarantees that a small subset +// NOTE(b/23420492): The Go runtime only guarantees that a small subset // of signals will be always be unblocked on all threads, one of which // is SIGCHLD. const SignalInterrupt = linux.SIGCHLD diff --git a/pkg/sentry/platform/ptrace/subprocess.go b/pkg/sentry/platform/ptrace/subprocess.go index 82f125073..2a5d699ec 100644 --- a/pkg/sentry/platform/ptrace/subprocess.go +++ b/pkg/sentry/platform/ptrace/subprocess.go @@ -79,7 +79,7 @@ func (tp *threadPool) lookupOrCreate(currentTID int32, newThread func() *thread) // Before creating a new thread, see if we can find a thread // whose system tid has disappeared. // - // TODO: Other parts of this package depend on + // TODO(b/77216482): Other parts of this package depend on // threads never exiting. for origTID, t := range tp.threads { // Signal zero is an easy existence check. diff --git a/pkg/sentry/platform/ring0/x86.go b/pkg/sentry/platform/ring0/x86.go index 7c88010d8..4c6daec22 100644 --- a/pkg/sentry/platform/ring0/x86.go +++ b/pkg/sentry/platform/ring0/x86.go @@ -116,7 +116,7 @@ const ( // // Note that sign-extension semantics apply to the highest order bit. // -// FIXME: This should use the cpuid passed to Init. +// FIXME(b/69382326): This should use the cpuid passed to Init. func VirtualAddressBits() uint32 { ax, _, _, _ := cpuid.HostID(0x80000008, 0) return (ax >> 8) & 0xff @@ -124,7 +124,7 @@ func VirtualAddressBits() uint32 { // PhysicalAddressBits returns the number of bits available for physical addresses. // -// FIXME: This should use the cpuid passed to Init. +// FIXME(b/69382326): This should use the cpuid passed to Init. func PhysicalAddressBits() uint32 { ax, _, _, _ := cpuid.HostID(0x80000008, 0) return ax & 0xff diff --git a/pkg/sentry/sighandling/sighandling.go b/pkg/sentry/sighandling/sighandling.go index 6b5d5f993..571245ce5 100644 --- a/pkg/sentry/sighandling/sighandling.go +++ b/pkg/sentry/sighandling/sighandling.go @@ -86,7 +86,7 @@ func handleSignals(sigchans []chan os.Signal, handler func(linux.Signal), start, // // Otherwise ignore the signal. // - // TODO: Drop in Go 1.12, which uses tgkill + // TODO(b/114489875): Drop in Go 1.12, which uses tgkill // in runtime.raise. switch signal { case linux.SIGHUP, linux.SIGINT, linux.SIGTERM: diff --git a/pkg/sentry/sighandling/sighandling_unsafe.go b/pkg/sentry/sighandling/sighandling_unsafe.go index 5913d47a8..db6e71487 100644 --- a/pkg/sentry/sighandling/sighandling_unsafe.go +++ b/pkg/sentry/sighandling/sighandling_unsafe.go @@ -23,7 +23,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" ) -// TODO: Move to pkg/abi/linux along with definitions in +// TODO(b/34161764): Move to pkg/abi/linux along with definitions in // pkg/sentry/arch. type sigaction struct { handler uintptr diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 23138d874..768fa0dfa 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -608,7 +608,7 @@ func (s *SocketOperations) Shutdown(t *kernel.Task, how int) *syserr.Error { // GetSockOpt implements the linux syscall getsockopt(2) for sockets backed by // tcpip.Endpoint. func (s *SocketOperations) GetSockOpt(t *kernel.Task, level, name, outLen int) (interface{}, *syserr.Error) { - // TODO: Unlike other socket options, SO_TIMESTAMP is + // TODO(b/78348848): Unlike other socket options, SO_TIMESTAMP is // implemented specifically for epsocket.SocketOperations rather than // commonEndpoint. commonEndpoint should be extended to support socket // options where the implementation is not shared, as unix sockets need @@ -658,7 +658,7 @@ func GetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, // getSockOptSocket implements GetSockOpt when level is SOL_SOCKET. func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, skType transport.SockType, name, outLen int) (interface{}, *syserr.Error) { - // TODO: Stop rejecting short optLen values in getsockopt. + // TODO(b/124056281): Stop rejecting short optLen values in getsockopt. switch name { case linux.SO_TYPE: if outLen < sizeOfInt32 { @@ -789,7 +789,7 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family return linux.Linger{}, nil case linux.SO_SNDTIMEO: - // TODO: Linux allows shorter lengths for partial results. + // TODO(igudger): Linux allows shorter lengths for partial results. if outLen < linux.SizeOfTimeval { return nil, syserr.ErrInvalidArgument } @@ -797,7 +797,7 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family return linux.NsecToTimeval(s.SendTimeout()), nil case linux.SO_RCVTIMEO: - // TODO: Linux allows shorter lengths for partial results. + // TODO(igudger): Linux allows shorter lengths for partial results. if outLen < linux.SizeOfTimeval { return nil, syserr.ErrInvalidArgument } @@ -894,7 +894,7 @@ func getSockOptTCP(t *kernel.Task, ep commonEndpoint, name, outLen int) (interfa return nil, syserr.TranslateNetstackError(err) } - // TODO: Translate fields once they are added to + // TODO(b/64800844): Translate fields once they are added to // tcpip.TCPInfoOption. info := linux.TCPInfo{} @@ -995,7 +995,7 @@ func getSockOptIP(t *kernel.Task, ep commonEndpoint, name, outLen int) (interfac // SetSockOpt implements the linux syscall setsockopt(2) for sockets backed by // tcpip.Endpoint. func (s *SocketOperations) SetSockOpt(t *kernel.Task, level int, name int, optVal []byte) *syserr.Error { - // TODO: Unlike other socket options, SO_TIMESTAMP is + // TODO(b/78348848): Unlike other socket options, SO_TIMESTAMP is // implemented specifically for epsocket.SocketOperations rather than // commonEndpoint. commonEndpoint should be extended to support socket // options where the implementation is not shared, as unix sockets need @@ -1338,7 +1338,7 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.AddMembershipOption{ NIC: tcpip.NICID(req.InterfaceIndex), - // TODO: Change AddMembership to use the standard + // TODO(igudger): Change AddMembership to use the standard // any address representation. InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]), MulticastAddr: tcpip.Address(req.MulticastAddr[:]), @@ -1352,7 +1352,7 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.RemoveMembershipOption{ NIC: tcpip.NICID(req.InterfaceIndex), - // TODO: Change DropMembership to use the standard + // TODO(igudger): Change DropMembership to use the standard // any address representation. InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]), MulticastAddr: tcpip.Address(req.MulticastAddr[:]), @@ -1380,7 +1380,7 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s )) case linux.MCAST_JOIN_GROUP: - // FIXME: Implement MCAST_JOIN_GROUP. + // FIXME(b/124219304): Implement MCAST_JOIN_GROUP. t.Kernel().EmitUnimplementedEvent(t) return syserr.ErrInvalidArgument @@ -1695,7 +1695,7 @@ func (s *SocketOperations) coalescingRead(ctx context.Context, dst usermem.IOSeq // nonBlockingRead issues a non-blocking read. // -// TODO: Support timestamps for stream sockets. +// TODO(b/78348848): Support timestamps for stream sockets. func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSequence, peek, trunc, senderRequested bool) (int, int, interface{}, uint32, socket.ControlMessages, *syserr.Error) { isPacket := s.isPacketBased() @@ -1762,7 +1762,7 @@ func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSe dst = dst.DropFirst(n) num, err := dst.CopyOutFrom(ctx, safemem.FromVecReaderFunc{func(dsts [][]byte) (int64, error) { n, _, err := s.Endpoint.Peek(dsts) - // TODO: Handle peek timestamp. + // TODO(b/78348848): Handle peek timestamp. if err != nil { return int64(n), syserr.TranslateNetstackError(err).ToError() } @@ -1963,7 +1963,7 @@ func (s *SocketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to [] func (s *SocketOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { // SIOCGSTAMP is implemented by epsocket rather than all commonEndpoint // sockets. - // TODO: Add a commonEndpoint method to support SIOCGSTAMP. + // TODO(b/78348848): Add a commonEndpoint method to support SIOCGSTAMP. if int(args[1].Int()) == syscall.SIOCGSTAMP { s.readMu.Lock() defer s.readMu.Unlock() @@ -2153,19 +2153,19 @@ func interfaceIoctl(ctx context.Context, io usermem.IO, arg int, ifr *linux.IFRe case syscall.SIOCGIFMAP: // Gets the hardware parameters of the device. - // TODO: Implement. + // TODO(b/71872867): Implement. case syscall.SIOCGIFTXQLEN: // Gets the transmit queue length of the device. - // TODO: Implement. + // TODO(b/71872867): Implement. case syscall.SIOCGIFDSTADDR: // Gets the destination address of a point-to-point device. - // TODO: Implement. + // TODO(b/71872867): Implement. case syscall.SIOCGIFBRDADDR: // Gets the broadcast address of a device. - // TODO: Implement. + // TODO(b/71872867): Implement. case syscall.SIOCGIFNETMASK: // Gets the network mask of a device. diff --git a/pkg/sentry/socket/epsocket/save_restore.go b/pkg/sentry/socket/epsocket/save_restore.go index 34d9a7cf0..f19afb6c0 100644 --- a/pkg/sentry/socket/epsocket/save_restore.go +++ b/pkg/sentry/socket/epsocket/save_restore.go @@ -20,7 +20,7 @@ import ( // afterLoad is invoked by stateify. func (s *Stack) afterLoad() { - s.Stack = stack.StackFromEnv // FIXME + s.Stack = stack.StackFromEnv // FIXME(b/36201077) if s.Stack == nil { panic("can't restore without netstack/tcpip/stack.Stack") } diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index c0081c819..37c48f4bc 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -77,7 +77,7 @@ func (s *Stack) InterfaceAddrs() map[int32][]inet.InterfaceAddr { Family: family, PrefixLen: uint8(len(a.Address) * 8), Addr: []byte(a.Address), - // TODO: Other fields. + // TODO(b/68878065): Other fields. }) } nicAddrs[int32(id)] = addrs diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index c4848b313..49349074f 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -348,7 +348,7 @@ func (s *socketOperations) SetSockOpt(t *kernel.Task, level int, name int, opt [ func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (int, int, interface{}, uint32, socket.ControlMessages, *syserr.Error) { // Whitelist flags. // - // FIXME: We can't support MSG_ERRQUEUE because it uses ancillary + // FIXME(jamieliu): We can't support MSG_ERRQUEUE because it uses ancillary // messages that netstack/tcpip/transport/unix doesn't understand. Kill the // Socket interface's dependence on netstack. if flags&^(syscall.MSG_DONTWAIT|syscall.MSG_PEEK|syscall.MSG_TRUNC) != 0 { diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index 7e70b09b2..e414b829b 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -110,7 +110,7 @@ func (p *Protocol) dumpLinks(ctx context.Context, hdr linux.NetlinkMessageHeader m.PutAttr(linux.IFLA_ADDRESS, mac) m.PutAttr(linux.IFLA_BROADCAST, brd) - // TODO: There are many more attributes. + // TODO(b/68878065): There are many more attributes. } return nil @@ -122,7 +122,7 @@ func (p *Protocol) dumpAddrs(ctx context.Context, hdr linux.NetlinkMessageHeader // netlink header and 1 byte protocol family common to all // NETLINK_ROUTE requests. // - // TODO: Filter output by passed protocol family. + // TODO(b/68878065): Filter output by passed protocol family. // The RTM_GETADDR dump response is a set of RTM_NEWADDR messages each // containing an InterfaceAddrMessage followed by a set of netlink @@ -151,7 +151,7 @@ func (p *Protocol) dumpAddrs(ctx context.Context, hdr linux.NetlinkMessageHeader m.PutAttr(linux.IFA_ADDRESS, []byte(a.Addr)) - // TODO: There are many more attributes. + // TODO(b/68878065): There are many more attributes. } } @@ -175,7 +175,7 @@ func (p *Protocol) ProcessMessage(ctx context.Context, hdr linux.NetlinkMessageH } } - // TODO: Only the dump variant of the types below are + // TODO(b/68878065): Only the dump variant of the types below are // supported. if hdr.Flags&linux.NLM_F_DUMP != linux.NLM_F_DUMP { return syserr.ErrNotSupported diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index 0fe9b39b6..a34f9d3ca 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -168,7 +168,7 @@ func (s *Socket) EventUnregister(e *waiter.Entry) { // Ioctl implements fs.FileOperations.Ioctl. func (s *Socket) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { - // TODO: no ioctls supported. + // TODO(b/68878065): no ioctls supported. return 0, syserror.ENOTTY } @@ -319,7 +319,7 @@ func (s *Socket) GetSockOpt(t *kernel.Task, level int, name int, outLen int) (in t.Kernel().EmitUnimplementedEvent(t) } } - // TODO: other sockopts are not supported. + // TODO(b/68878065): other sockopts are not supported. return nil, syserr.ErrProtocolNotAvailable } @@ -369,7 +369,7 @@ func (s *Socket) SetSockOpt(t *kernel.Task, level int, name int, opt []byte) *sy } } - // TODO: other sockopts are not supported. + // TODO(b/68878065): other sockopts are not supported. return syserr.ErrProtocolNotAvailable } @@ -389,7 +389,7 @@ func (s *Socket) GetSockName(t *kernel.Task) (interface{}, uint32, *syserr.Error func (s *Socket) GetPeerName(t *kernel.Task) (interface{}, uint32, *syserr.Error) { sa := linux.SockAddrNetlink{ Family: linux.AF_NETLINK, - // TODO: Support non-kernel peers. For now the peer + // TODO(b/68878065): Support non-kernel peers. For now the peer // must be the kernel. PortID: 0, } @@ -540,7 +540,7 @@ func (s *Socket) processMessages(ctx context.Context, buf []byte) *syserr.Error continue } - // TODO: ACKs not supported yet. + // TODO(b/68877377): ACKs not supported yet. if hdr.Flags&linux.NLM_F_ACK == linux.NLM_F_ACK { return syserr.ErrNotSupported } diff --git a/pkg/sentry/socket/rpcinet/conn/conn.go b/pkg/sentry/socket/rpcinet/conn/conn.go index 9c749b888..64106c4b5 100644 --- a/pkg/sentry/socket/rpcinet/conn/conn.go +++ b/pkg/sentry/socket/rpcinet/conn/conn.go @@ -50,7 +50,7 @@ type RPCConnection struct { // NewRPCConnection initializes a RPC connection to a socket gofer. func NewRPCConnection(s *unet.Socket) *RPCConnection { conn := &RPCConnection{socket: s, requests: map[uint64]request{}} - go func() { // S/R-FIXME + go func() { // S/R-FIXME(b/77962828) var nums [16]byte for { for n := 0; n < len(nums); { diff --git a/pkg/sentry/socket/rpcinet/notifier/notifier.go b/pkg/sentry/socket/rpcinet/notifier/notifier.go index d9bda78b0..f06d12231 100644 --- a/pkg/sentry/socket/rpcinet/notifier/notifier.go +++ b/pkg/sentry/socket/rpcinet/notifier/notifier.go @@ -64,7 +64,7 @@ func NewRPCNotifier(cn *conn.RPCConnection) (*Notifier, error) { fdMap: make(map[uint32]*fdInfo), } - go w.waitAndNotify() // S/R-FIXME + go w.waitAndNotify() // S/R-FIXME(b/77962828) return w, nil } @@ -166,7 +166,7 @@ func (n *Notifier) waitAndNotify() error { res := n.rpcConn.Request(id).Result.(*pb.SyscallResponse_EpollWait).EpollWait.Result if e, ok := res.(*pb.EpollWaitResponse_ErrorNumber); ok { err := syscall.Errno(e.ErrorNumber) - // NOTE: I don't think epoll_wait can return EAGAIN but I'm being + // NOTE(magi): I don't think epoll_wait can return EAGAIN but I'm being // conseratively careful here since exiting the notification thread // would be really bad. if err == syscall.EINTR || err == syscall.EAGAIN { diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index 3418a6d75..cf8f69efb 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -288,7 +288,7 @@ func (s *socketOperations) Accept(t *kernel.Task, peerRequested bool, flags int, if blocking && se == syserr.ErrTryAgain { // Register for notifications. e, ch := waiter.NewChannelEntry(nil) - // FIXME: This waiter.EventHUp is a partial + // FIXME(b/119878986): This waiter.EventHUp is a partial // measure, need to figure out how to translate linux events to // internal events. s.EventRegister(&e, waiter.EventIn|waiter.EventHUp) @@ -370,7 +370,7 @@ func (s *socketOperations) Shutdown(t *kernel.Task, how int) *syserr.Error { // We save the shutdown state because of strange differences on linux // related to recvs on blocking vs. non-blocking sockets after a SHUT_RD. // We need to emulate that behavior on the blocking side. - // TODO: There is a possible race that can exist with loopback, + // TODO(b/120096741): There is a possible race that can exist with loopback, // where data could possibly be lost. s.setShutdownFlags(how) @@ -771,7 +771,7 @@ func (s *socketOperations) SendMsg(t *kernel.Task, src usermem.IOSequence, to [] return 0, syserr.FromError(err) } - // TODO: this needs to change to map directly to a SendMsg syscall + // TODO(bgeffon): this needs to change to map directly to a SendMsg syscall // in the RPC. totalWritten := 0 n, err := rpcSendMsg(t, &pb.SyscallRequest_Sendmsg{&pb.SendmsgRequest{ diff --git a/pkg/sentry/socket/rpcinet/syscall_rpc.proto b/pkg/sentry/socket/rpcinet/syscall_rpc.proto index c056e4c9d..9586f5923 100644 --- a/pkg/sentry/socket/rpcinet/syscall_rpc.proto +++ b/pkg/sentry/socket/rpcinet/syscall_rpc.proto @@ -3,7 +3,7 @@ syntax = "proto3"; // package syscall_rpc is a set of networking related system calls that can be // forwarded to a socket gofer. // -// TODO: Document individual RPCs. +// TODO(b/77963526): Document individual RPCs. package syscall_rpc; message SendmsgRequest { diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index a6d870b44..434a200d9 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -722,7 +722,7 @@ func (s SyscallMap) Name(sysno uintptr) string { // N.B. This is not in an init function because we can't be sure all syscall // tables are registered with the kernel when init runs. // -// TODO: remove kernel package dependencies from this +// TODO(gvisor.dev/issue/155): remove kernel package dependencies from this // package and have the kernel package self-initialize all syscall tables. func Initialize() { for _, table := range kernel.SyscallTables() { diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go index 8759e5e32..304a12dde 100644 --- a/pkg/sentry/syscalls/linux/error.go +++ b/pkg/sentry/syscalls/linux/error.go @@ -89,7 +89,7 @@ func handleIOError(t *kernel.Task, partialResult bool, err, intr error, op strin // side is gone. The partial write is returned. EPIPE will be // returned on the next call. // - // TODO: In some cases SIGPIPE should + // TODO(gvisor.dev/issue/161): In some cases SIGPIPE should // also be sent to the application. return nil case syserror.ErrWouldBlock: diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index be793ca11..b9b4ccbd1 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -143,10 +143,10 @@ var AMD64 = &kernel.SyscallTable{ 65: Semop, 66: Semctl, 67: Shmdt, - // 68: @Syscall(Msgget), TODO - // 69: @Syscall(Msgsnd), TODO - // 70: @Syscall(Msgrcv), TODO - // 71: @Syscall(Msgctl), TODO + // 68: @Syscall(Msgget), TODO(b/29354921) + // 69: @Syscall(Msgsnd), TODO(b/29354921) + // 70: @Syscall(Msgrcv), TODO(b/29354921) + // 71: @Syscall(Msgctl), TODO(b/29354921) 72: Fcntl, 73: Flock, 74: Fsync, @@ -197,8 +197,8 @@ var AMD64 = &kernel.SyscallTable{ 119: Setresgid, 120: Getresgid, 121: Getpgid, - // 122: @Syscall(Setfsuid), TODO - // 123: @Syscall(Setfsgid), TODO + // 122: @Syscall(Setfsuid), TODO(b/112851702) + // 123: @Syscall(Setfsgid), TODO(b/112851702) 124: Getsid, 125: Capget, 126: Capset, @@ -217,7 +217,7 @@ var AMD64 = &kernel.SyscallTable{ 136: syscalls.ErrorWithEvent(syscall.ENOSYS), 137: Statfs, 138: Fstatfs, - // 139: @Syscall(Sysfs), TODO + // 139: @Syscall(Sysfs), TODO(gvisor.dev/issue/165) 140: Getpriority, 141: Setpriority, // @Syscall(SchedSetparam, returns:EPERM or ENOSYS, note:Returns EPERM if the process does not have cap_sys_nice; ENOSYS otherwise) @@ -291,7 +291,7 @@ var AMD64 = &kernel.SyscallTable{ // @Syscall(Security, note:Not implemented in Linux) 185: syscalls.Error(syscall.ENOSYS), 186: Gettid, - 187: nil, // @Syscall(Readahead), TODO + 187: nil, // @Syscall(Readahead), TODO(b/29351341) // @Syscall(Setxattr, returns:ENOTSUP, note:Requires filesystem support) 188: syscalls.ErrorWithEvent(syscall.ENOTSUP), // @Syscall(Lsetxattr, returns:ENOTSUP, note:Requires filesystem support) @@ -342,7 +342,7 @@ var AMD64 = &kernel.SyscallTable{ 217: Getdents64, 218: SetTidAddress, 219: RestartSyscall, - // 220: @Syscall(Semtimedop), TODO + // 220: @Syscall(Semtimedop), TODO(b/29354920) 221: Fadvise64, 222: TimerCreate, 223: TimerSettime, @@ -360,16 +360,16 @@ var AMD64 = &kernel.SyscallTable{ 235: Utimes, // @Syscall(Vserver, note:Not implemented by Linux) 236: syscalls.Error(syscall.ENOSYS), // Vserver, not implemented by Linux - // @Syscall(Mbind, returns:EPERM or ENOSYS, note:Returns EPERM if the process does not have cap_sys_nice; ENOSYS otherwise), TODO + // @Syscall(Mbind, returns:EPERM or ENOSYS, note:Returns EPERM if the process does not have cap_sys_nice; ENOSYS otherwise), TODO(b/117792295) 237: syscalls.CapError(linux.CAP_SYS_NICE), // may require cap_sys_nice 238: SetMempolicy, 239: GetMempolicy, - // 240: @Syscall(MqOpen), TODO - // 241: @Syscall(MqUnlink), TODO - // 242: @Syscall(MqTimedsend), TODO - // 243: @Syscall(MqTimedreceive), TODO - // 244: @Syscall(MqNotify), TODO - // 245: @Syscall(MqGetsetattr), TODO + // 240: @Syscall(MqOpen), TODO(b/29354921) + // 241: @Syscall(MqUnlink), TODO(b/29354921) + // 242: @Syscall(MqTimedsend), TODO(b/29354921) + // 243: @Syscall(MqTimedreceive), TODO(b/29354921) + // 244: @Syscall(MqNotify), TODO(b/29354921) + // 245: @Syscall(MqGetsetattr), TODO(b/29354921) 246: syscalls.CapError(linux.CAP_SYS_BOOT), // kexec_load, requires cap_sys_boot 247: Waitid, // @Syscall(AddKey, returns:EACCES, note:Not available to user) @@ -407,22 +407,22 @@ var AMD64 = &kernel.SyscallTable{ 273: syscalls.Error(syscall.ENOSYS), // @Syscall(GetRobustList, note:Obsolete) 274: syscalls.Error(syscall.ENOSYS), - // 275: @Syscall(Splice), TODO - // 276: @Syscall(Tee), TODO + // 275: @Syscall(Splice), TODO(b/29354098) + // 276: @Syscall(Tee), TODO(b/29354098) 277: SyncFileRange, - // 278: @Syscall(Vmsplice), TODO + // 278: @Syscall(Vmsplice), TODO(b/29354098) // @Syscall(MovePages, returns:EPERM or ENOSYS, note:Returns EPERM if the process does not have cap_sys_nice; ENOSYS otherwise) 279: syscalls.CapError(linux.CAP_SYS_NICE), // requires cap_sys_nice (mostly) 280: Utimensat, 281: EpollPwait, - // 282: @Syscall(Signalfd), TODO + // 282: @Syscall(Signalfd), TODO(b/19846426) 283: TimerfdCreate, 284: Eventfd, 285: Fallocate, 286: TimerfdSettime, 287: TimerfdGettime, 288: Accept4, - // 289: @Syscall(Signalfd4), TODO + // 289: @Syscall(Signalfd4), TODO(b/19846426) 290: Eventfd2, 291: EpollCreate1, 292: Dup3, @@ -447,17 +447,17 @@ var AMD64 = &kernel.SyscallTable{ 305: syscalls.CapError(linux.CAP_SYS_TIME), // requires cap_sys_time 306: Syncfs, 307: SendMMsg, - // 308: @Syscall(Setns), TODO + // 308: @Syscall(Setns), TODO(b/29354995) 309: Getcpu, - // 310: @Syscall(ProcessVmReadv), TODO may require cap_sys_ptrace - // 311: @Syscall(ProcessVmWritev), TODO may require cap_sys_ptrace + // 310: @Syscall(ProcessVmReadv), TODO(gvisor.dev/issue/158) may require cap_sys_ptrace + // 311: @Syscall(ProcessVmWritev), TODO(gvisor.dev/issue/158) may require cap_sys_ptrace // @Syscall(Kcmp, returns:EPERM or ENOSYS, note:Requires cap_sys_ptrace) 312: syscalls.CapError(linux.CAP_SYS_PTRACE), // @Syscall(FinitModule, returns:EPERM or ENOSYS, note:Returns EPERM if the process does not have cap_sys_module; ENOSYS otherwise) 313: syscalls.CapError(linux.CAP_SYS_MODULE), - // 314: @Syscall(SchedSetattr), TODO, we have no scheduler - // 315: @Syscall(SchedGetattr), TODO, we have no scheduler - // 316: @Syscall(Renameat2), TODO + // 314: @Syscall(SchedSetattr), TODO(b/118902272), we have no scheduler + // 315: @Syscall(SchedGetattr), TODO(b/118902272), we have no scheduler + // 316: @Syscall(Renameat2), TODO(b/118902772) 317: Seccomp, 318: GetRandom, 319: MemfdCreate, @@ -465,9 +465,9 @@ var AMD64 = &kernel.SyscallTable{ 320: syscalls.CapError(linux.CAP_SYS_BOOT), // @Syscall(Bpf, returns:EPERM or ENOSYS, note:Returns EPERM if the process does not have cap_sys_boot; ENOSYS otherwise) 321: syscalls.CapError(linux.CAP_SYS_ADMIN), // requires cap_sys_admin for all commands - // 322: @Syscall(Execveat), TODO - // 323: @Syscall(Userfaultfd), TODO - // 324: @Syscall(Membarrier), TODO + // 322: @Syscall(Execveat), TODO(b/118901836) + // 323: @Syscall(Userfaultfd), TODO(b/118906345) + // 324: @Syscall(Membarrier), TODO(b/118904897) 325: Mlock2, // Syscalls after 325 are "backports" from versions of Linux after 4.4. // 326: @Syscall(CopyFileRange), diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go index 355071131..61c2647bf 100644 --- a/pkg/sentry/syscalls/linux/sys_aio.go +++ b/pkg/sentry/syscalls/linux/sys_aio.go @@ -120,7 +120,7 @@ func IoDestroy(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys // Does not exist. return 0, nil, syserror.EINVAL } - // FIXME: Linux blocks until all AIO to the destroyed context is + // FIXME(fvoznika): Linux blocks until all AIO to the destroyed context is // done. return 0, nil, nil } diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 50151f7b6..967464c85 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -259,7 +259,7 @@ func mknodAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, mode linux.FileM case linux.ModeCharacterDevice: fallthrough case linux.ModeBlockDevice: - // TODO: We don't support creating block or character + // TODO(b/72101894): We don't support creating block or character // devices at the moment. // // When we start supporting block and character devices, we'll @@ -1532,7 +1532,7 @@ func chown(t *kernel.Task, d *fs.Dirent, uid auth.UID, gid auth.GID) error { owner.GID = kgid } - // FIXME: This is racy; the inode's owner may have changed in + // FIXME(b/62949101): This is racy; the inode's owner may have changed in // the meantime. (Linux holds i_mutex while calling // fs/attr.c:notify_change() => inode_operations::setattr => // inode_change_ok().) diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 8732861e0..805b251b1 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -185,7 +185,7 @@ func Madvise(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysca case linux.MADV_MERGEABLE, linux.MADV_UNMERGEABLE: fallthrough case linux.MADV_DONTDUMP, linux.MADV_DODUMP: - // TODO: Core dumping isn't implemented, so these are + // TODO(b/72045799): Core dumping isn't implemented, so these are // no-ops. fallthrough case linux.MADV_NORMAL, linux.MADV_RANDOM, linux.MADV_SEQUENTIAL, linux.MADV_WILLNEED: @@ -223,7 +223,7 @@ func GetMempolicy(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel. nodeFlag := flags&linux.MPOL_F_NODE != 0 addrFlag := flags&linux.MPOL_F_ADDR != 0 - // TODO: Once sysfs is implemented, report a single numa node in + // TODO(rahat): Once sysfs is implemented, report a single numa node in // /sys/devices/system/node. if nodemask != 0 && maxnode < 1 { return 0, nil, syserror.EINVAL diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go index 8105e9b43..50c7d7a74 100644 --- a/pkg/sentry/syscalls/linux/sys_read.go +++ b/pkg/sentry/syscalls/linux/sys_read.go @@ -192,7 +192,7 @@ func Preadv(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal } // Preadv2 implements linux syscall preadv2(2). -// TODO: Implement RWF_HIPRI functionality. +// TODO(b/120162627): Implement RWF_HIPRI functionality. func Preadv2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { // While the syscall is // preadv2(int fd, struct iovec* iov, int iov_cnt, off_t offset, int flags) diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go index 30ccc3f66..c8748958a 100644 --- a/pkg/sentry/syscalls/linux/sys_socket.go +++ b/pkg/sentry/syscalls/linux/sys_socket.go @@ -317,7 +317,7 @@ func accept(t *kernel.Task, fd kdefs.FD, addr usermem.Addr, addrLen usermem.Addr return 0, syserror.ConvertIntr(e.ToError(), kernel.ERESTARTSYS) } if peerRequested { - // NOTE: Linux does not give you an error if it can't + // NOTE(magi): Linux does not give you an error if it can't // write the data back out so neither do we. if err := writeAddress(t, peer, peerLen, addr, addrLen); err == syscall.EINVAL { return 0, err @@ -735,7 +735,7 @@ func recvSingleMsg(t *kernel.Task, s socket.Socket, msgPtr usermem.Addr, flags i return 0, err } - // FIXME: Pretend we have an empty error queue. + // FIXME(b/63594852): Pretend we have an empty error queue. if flags&linux.MSG_ERRQUEUE != 0 { return 0, syscall.EAGAIN } diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go index 61cafefb9..ddcb5b789 100644 --- a/pkg/sentry/syscalls/linux/sys_thread.go +++ b/pkg/sentry/syscalls/linux/sys_thread.go @@ -350,7 +350,7 @@ func Waitid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal } si.SetPid(int32(wr.TID)) si.SetUid(int32(wr.UID)) - // TODO: convert kernel.ExitStatus to functions and make + // TODO(b/73541790): convert kernel.ExitStatus to functions and make // WaitResult.Status a linux.WaitStatus s := syscall.WaitStatus(wr.Status) switch { diff --git a/pkg/sentry/syscalls/linux/sys_write.go b/pkg/sentry/syscalls/linux/sys_write.go index a5ad7efb2..e405608c4 100644 --- a/pkg/sentry/syscalls/linux/sys_write.go +++ b/pkg/sentry/syscalls/linux/sys_write.go @@ -192,8 +192,8 @@ func Pwritev(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysca } // Pwritev2 implements linux syscall pwritev2(2). -// TODO: Implement RWF_HIPRI functionality. -// TODO: Implement O_SYNC and D_SYNC functionality. +// TODO(b/120162627): Implement RWF_HIPRI functionality. +// TODO(b/120161091): Implement O_SYNC and D_SYNC functionality. func Pwritev2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { // While the syscall is // pwritev2(int fd, struct iovec* iov, int iov_cnt, off_t offset, int flags) diff --git a/pkg/sentry/time/calibrated_clock.go b/pkg/sentry/time/calibrated_clock.go index c8cf4eca4..a98bcd7de 100644 --- a/pkg/sentry/time/calibrated_clock.go +++ b/pkg/sentry/time/calibrated_clock.go @@ -37,7 +37,7 @@ var fallbackMetric = metric.MustCreateNewUint64Metric("/time/fallback", false /* // clock. type CalibratedClock struct { // mu protects the fields below. - // TODO: consider a sequence counter for read locking. + // TODO(mpratt): consider a sequence counter for read locking. mu sync.RWMutex // ref sample the reference clock that this clock is calibrated @@ -140,7 +140,7 @@ func (c *CalibratedClock) updateParams(actual Parameters) { // N.B. logErrorAdjustment will have already logged the error // at warning level. // - // TODO: We could allow Realtime clock jumps here. + // TODO(mpratt): We could allow Realtime clock jumps here. c.resetLocked("Extreme clock error.") return } @@ -229,7 +229,7 @@ func (c *CalibratedClock) GetTime() (int64, error) { // CalibratedClocks contains calibrated monotonic and realtime clocks. // -// TODO: We know that Linux runs the monotonic and realtime clocks at +// TODO(mpratt): We know that Linux runs the monotonic and realtime clocks at // the same rate, so rather than tracking both individually, we could do one // calibration for both clocks. type CalibratedClocks struct { diff --git a/pkg/sentry/time/parameters.go b/pkg/sentry/time/parameters.go index f3ad58454..8568b1193 100644 --- a/pkg/sentry/time/parameters.go +++ b/pkg/sentry/time/parameters.go @@ -43,7 +43,7 @@ const ( // These statements assume that the host clock does not change. Actual // error will depend upon host clock changes. // - // TODO: make error correction more robust to delayed + // TODO(b/68779214): make error correction more robust to delayed // updates. ApproxUpdateInterval = 1 * time.Second diff --git a/pkg/sentry/usermem/usermem.go b/pkg/sentry/usermem/usermem.go index 99766a803..4c7d5014a 100644 --- a/pkg/sentry/usermem/usermem.go +++ b/pkg/sentry/usermem/usermem.go @@ -28,7 +28,7 @@ import ( // IO provides access to the contents of a virtual memory space. // -// FIXME: Implementations of IO cannot expect ctx to contain any +// FIXME(b/38173783): Implementations of IO cannot expect ctx to contain any // meaningful data. type IO interface { // CopyOut copies len(src) bytes from src to the memory mapped at addr. It @@ -85,7 +85,7 @@ type IO interface { // order. CopyInTo(ctx context.Context, ars AddrRangeSeq, dst safemem.Writer, opts IOOpts) (int64, error) - // TODO: The requirement that CopyOutFrom/CopyInTo call src/dst + // TODO(jamieliu): The requirement that CopyOutFrom/CopyInTo call src/dst // at most once, which is unnecessary in most cases, forces implementations // to gather safemem.Blocks into a single slice to pass to src/dst. Add // CopyOutFromIter/CopyInToIter, which relaxes this restriction, to avoid diff --git a/pkg/sentry/watchdog/watchdog.go b/pkg/sentry/watchdog/watchdog.go index c49b537a5..b4f1e3a4f 100644 --- a/pkg/sentry/watchdog/watchdog.go +++ b/pkg/sentry/watchdog/watchdog.go @@ -236,7 +236,7 @@ func (w *Watchdog) runTurn() { if !ok { // New stuck task detected. // - // TODO: Tasks blocked doing IO may be considered stuck in kernel. + // TODO(b/65849403): Tasks blocked doing IO may be considered stuck in kernel. tc = &offender{lastUpdateTime: lastUpdateTime} stuckTasks.Increment() newTaskFound = true diff --git a/pkg/syserr/syserr.go b/pkg/syserr/syserr.go index dad83e80c..232634dd4 100644 --- a/pkg/syserr/syserr.go +++ b/pkg/syserr/syserr.go @@ -49,7 +49,7 @@ func New(message string, linuxTranslation *linux.Errno) *Error { return err } - // TODO: Remove this. + // TODO(b/34162363): Remove this. errno := linuxTranslation.Number() if errno <= 0 || errno >= len(linuxBackwardsTranslations) { panic(fmt.Sprint("invalid errno: ", errno)) @@ -106,12 +106,12 @@ type linuxBackwardsTranslation struct { ok bool } -// TODO: Remove this. +// TODO(b/34162363): Remove this. var linuxBackwardsTranslations [maxErrno]linuxBackwardsTranslation // ToError translates an Error to a corresponding error value. // -// TODO: Remove this. +// TODO(b/34162363): Remove this. func (e *Error) ToError() error { if e == nil { return nil @@ -138,7 +138,7 @@ func (e *Error) ToLinux() *linux.Errno { return e.errno } -// TODO: Remove or replace most of these errors. +// TODO(b/34162363): Remove or replace most of these errors. // // Some of the errors should be replaced with package specific errors and // others should be removed entirely. @@ -278,7 +278,7 @@ var ( // FromError converts a generic error to an *Error. // -// TODO: Remove this function. +// TODO(b/34162363): Remove this function. func FromError(err error) *Error { if err == nil { return nil diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index ed9a4eee5..1c3acda4b 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -64,7 +64,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V } h := header.ICMPv4(v) - // TODO: Meaningfully handle all ICMP types. + // TODO(b/112892170): Meaningfully handle all ICMP types. switch h.Type() { case header.ICMPv4Echo: received.Echo.Increment() diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 3210e6fc7..be28be36d 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -73,7 +73,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V } h := header.ICMPv6(v) - // TODO: Meaningfully handle all ICMP types. + // TODO(b/112892170): Meaningfully handle all ICMP types. switch h.Type() { case header.ICMPv6PacketTooBig: received.PacketTooBig.Increment() @@ -247,7 +247,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. DstAddr: r.RemoteAddress, }) - // TODO: count this in ICMP stats. + // TODO(stijlist): count this in ICMP stats. return linkEP.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, ProtocolNumber) } diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 8b6c17a90..c18571b0f 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -176,7 +176,7 @@ func (n *NIC) primaryEndpoint(protocol tcpip.NetworkProtocolNumber) *referencedN for e := list.Front(); e != nil; e = e.Next() { r := e.(*referencedNetworkEndpoint) - // TODO: allow broadcast address when SO_BROADCAST is set. + // TODO(crawshaw): allow broadcast address when SO_BROADCAST is set. switch r.ep.ID().LocalAddress { case header.IPv4Broadcast, header.IPv4Any: continue @@ -476,7 +476,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr n.mu.RUnlock() if ok && ref.tryIncRef() { r.RemoteAddress = src - // TODO: Update the source NIC as well. + // TODO(b/123449044): Update the source NIC as well. ref.ep.HandlePacket(&r, vv) ref.decRef() } else { @@ -485,7 +485,7 @@ func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddr hdr := buffer.NewPrependableFromView(vv.First()) vv.RemoveFirst() - // TODO: use route.WritePacket. + // TODO(b/128629022): use route.WritePacket. if err := n.linkEP.WritePacket(&r, nil /* gso */, hdr, vv, protocol); err != nil { r.Stats().IP.OutgoingPacketErrors.Increment() } else { diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 8f7b6f781..cb9ffe9c2 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -476,7 +476,7 @@ func (s *Stack) Stats() tcpip.Stats { // SetForwarding enables or disables the packet forwarding between NICs. func (s *Stack) SetForwarding(enable bool) { - // TODO: Expose via /proc/sys/net/ipv4/ip_forward. + // TODO(igudger, bgeffon): Expose via /proc/sys/net/ipv4/ip_forward. s.mu.Lock() s.forwarding = enable s.mu.Unlock() @@ -484,7 +484,7 @@ func (s *Stack) SetForwarding(enable bool) { // Forwarding returns if the packet forwarding between NICs is enabled. func (s *Stack) Forwarding() bool { - // TODO: Expose via /proc/sys/net/ipv4/ip_forward. + // TODO(igudger, bgeffon): Expose via /proc/sys/net/ipv4/ip_forward. s.mu.RLock() defer s.mu.RUnlock() return s.forwarding diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index f2c6c9a8d..3d7e4b719 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -15,5 +15,5 @@ package stack // StackFromEnv is the global stack created in restore run. -// FIXME +// FIXME(b/36201077) var StackFromEnv *Stack diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 0c2589083..2df974bf2 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -453,7 +453,7 @@ func TestTransportForwarding(t *testing.T) { s := stack.New([]string{"fakeNet"}, []string{"fakeTrans"}, stack.Options{}) s.SetForwarding(true) - // TODO: Change this to a channel NIC. + // TODO(b/123449044): Change this to a channel NIC. id1 := loopback.New() if err := s.CreateNIC(1, id1); err != nil { t.Fatalf("CreateNIC #1 failed: %v", err) diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 80cd6b4e5..b09137f08 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -444,7 +444,7 @@ type PasscredOption int // TCPInfoOption is used by GetSockOpt to expose TCP statistics. // -// TODO: Add and populate stat fields. +// TODO(b/64800844): Add and populate stat fields. type TCPInfoOption struct { RTT time.Duration RTTVar time.Duration diff --git a/pkg/tcpip/transport/raw/raw.go b/pkg/tcpip/transport/raw/raw.go index 8dada2e4f..f0f60ce91 100644 --- a/pkg/tcpip/transport/raw/raw.go +++ b/pkg/tcpip/transport/raw/raw.go @@ -100,7 +100,7 @@ type endpoint struct { } // NewEndpoint returns a raw endpoint for the given protocols. -// TODO: IP_HDRINCL, IPPROTO_RAW, and AF_PACKET. +// TODO(b/129292371): IP_HDRINCL, IPPROTO_RAW, and AF_PACKET. func NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, transProto tcpip.TransportProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { if netProto != header.IPv4ProtocolNumber { return nil, tcpip.ErrUnknownProtocol diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index e5c05f8c0..d44d63e95 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -73,7 +73,7 @@ go_test( "tcp_test.go", "tcp_timestamp_test.go", ], - # FIXME + # FIXME(b/68809571) tags = ["flaky"], deps = [ ":tcp", diff --git a/pkg/unet/unet.go b/pkg/unet/unet.go index deeea078d..114fb8c5b 100644 --- a/pkg/unet/unet.go +++ b/pkg/unet/unet.go @@ -211,7 +211,7 @@ func SocketPair(packet bool) (*Socket, *Socket, error) { // variable between our two sockets. We only use SocketPair in tests // anyway. // - // NOTE: This is purely due to the fact that the raw + // NOTE(b/27107811): This is purely due to the fact that the raw // syscall does not serve as a boundary for the sanitizer. var race int32 a, err := NewSocket(fds[0]) diff --git a/pkg/unet/unet_test.go b/pkg/unet/unet_test.go index ecc670925..db5485539 100644 --- a/pkg/unet/unet_test.go +++ b/pkg/unet/unet_test.go @@ -40,7 +40,7 @@ func randomFilename() (string, error) { return "", err } - // NOTE: We try to use relative path if possible. This is + // NOTE(b/26918832): We try to use relative path if possible. This is // to help conforming to the unix path length limit. if rel, err := filepath.Rel(cwd, file); err == nil { return rel, nil diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index 2488981f9..712c50ee9 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -231,7 +231,7 @@ func (cm *containerManager) Start(args *StartArgs, _ *struct{}) error { } // Prevent CIDs containing ".." from confusing the sentry when creating // /containers/ directory. - // TODO: Once we have multiple independent roots, this + // TODO(b/129293409): Once we have multiple independent roots, this // check won't be necessary. if path.Clean(args.CID) != args.CID { return fmt.Errorf("container ID shouldn't contain directory traversals such as \"..\": %q", args.CID) @@ -352,7 +352,7 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error { return fmt.Errorf("creating network: %v", err) } if eps, ok := networkStack.(*epsocket.Stack); ok { - stack.StackFromEnv = eps.Stack // FIXME + stack.StackFromEnv = eps.Stack // FIXME(b/36201077) } info, err := o.FilePayload.Files[0].Stat() if err != nil { diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index 761142d98..07061b9b3 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -274,7 +274,7 @@ func getMountNameAndOptions(conf *Config, m specs.Mount, fds *fdDispenser) (stri useOverlay = conf.Overlay && !mountFlags(m.Options).ReadOnly default: - // TODO: Support all the mount types and make this a + // TODO(nlacasse): Support all the mount types and make this a // fatal error. Most applications will "just work" without // them, so this is a warning for now. // we do not support. @@ -425,7 +425,7 @@ func addRestoreMount(conf *Config, renv *fs.RestoreEnvironment, m specs.Mount, f if err != nil { return err } - // TODO: Fix this when we support all the mount types and + // TODO(nlacasse): Fix this when we support all the mount types and // make this a fatal error. if fsName == "" { return nil @@ -475,7 +475,7 @@ func createRestoreEnvironment(spec *specs.Spec, conf *Config, fds *fdDispenser) } } - // TODO: handle '/tmp' properly (see mountTmp()). + // TODO(b/67958150): handle '/tmp' properly (see mountTmp()). if !tmpMounted { tmpMount := specs.Mount{ Type: tmpfs, diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 48ecb2626..75ec19c32 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -577,7 +577,7 @@ func (l *Loader) startContainer(k *kernel.Kernel, spec *specs.Spec, conf *Config // sentry currently supports only 1 mount namespace, which is tied to a // single user namespace. Thus we must run in the same user namespace // to access mounts. - // TODO: Create a new mount namespace for the container. + // TODO(b/63601033): Create a new mount namespace for the container. creds := auth.NewUserCredentials( auth.KUID(spec.Process.User.UID), auth.KGID(spec.Process.User.GID), diff --git a/runsc/cmd/checkpoint.go b/runsc/cmd/checkpoint.go index d8f748aa0..f722df055 100644 --- a/runsc/cmd/checkpoint.go +++ b/runsc/cmd/checkpoint.go @@ -105,7 +105,7 @@ func (c *Checkpoint) Execute(_ context.Context, f *flag.FlagSet, args ...interfa return subcommands.ExitSuccess } - // TODO: Make it possible to restore into same container. + // TODO(b/110843694): Make it possible to restore into same container. // For now, we can fake it by destroying the container and making a // new container with the same ID. This hack does not work with docker // which uses the container pid to ensure that the restore-container is diff --git a/runsc/container/container.go b/runsc/container/container.go index 1bed1a97e..a30c217f7 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -529,7 +529,7 @@ func (c *Container) WaitPID(pid int32, clearStatus bool) (syscall.WaitStatus, er // SignalContainer sends the signal to the container. If all is true and signal // is SIGKILL, then waits for all processes to exit before returning. // SignalContainer returns an error if the container is already stopped. -// TODO: Distinguish different error types. +// TODO(b/113680494): Distinguish different error types. func (c *Container) SignalContainer(sig syscall.Signal, all bool) error { log.Debugf("Signal container %q: %v", c.ID, sig) // Signaling container in Stopped state is allowed. When all=false, diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index 9fe584aa3..603c4d929 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -242,10 +242,10 @@ func configs(opts ...configOption) []*boot.Config { case overlay: c.Overlay = true case kvm: - // TODO: KVM tests are flaky. Disable until fixed. + // TODO(b/112165693): KVM tests are flaky. Disable until fixed. continue - // TODO: KVM doesn't work with --race. + // TODO(b/68787993): KVM doesn't work with --race. if testutil.RaceEnabled { continue } diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 92495c69e..48a0dafe2 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -267,7 +267,7 @@ func (s *Sandbox) Event(cid string) (*boot.Event, error) { defer conn.Close() var e boot.Event - // TODO: Pass in the container id (cid) here. The sandbox + // TODO(b/129292330): Pass in the container id (cid) here. The sandbox // should return events only for that container. if err := conn.Call(boot.ContainerEvent, nil, &e); err != nil { return nil, fmt.Errorf("retrieving event data from sandbox: %v", err) @@ -457,7 +457,7 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund } if conf.Platform == boot.PlatformPtrace { - // TODO: Also set a new PID namespace so that we limit + // TODO(b/75837838): Also set a new PID namespace so that we limit // access to other host processes. log.Infof("Sandbox will be started in the current PID namespace") } else { @@ -520,7 +520,7 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund // root for itself, so it has to have the CAP_SYS_ADMIN // capability. // - // FIXME: The current implementations of + // FIXME(b/122554829): The current implementations of // os/exec doesn't allow to set ambient capabilities if // a process is started in a new user namespace. As a // workaround, we start the sandbox process with the 0 diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index 32f81b8d4..ac85bec71 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -90,7 +90,7 @@ func ValidateSpec(spec *specs.Spec) error { log.Warningf("AppArmor profile %q is being ignored", spec.Process.ApparmorProfile) } - // TODO: Apply seccomp to application inside sandbox. + // TODO(b/72226747): Apply seccomp to application inside sandbox. if spec.Linux != nil && spec.Linux.Seccomp != nil { log.Warningf("Seccomp spec is being ignored") } @@ -220,7 +220,7 @@ func Capabilities(enableRaw bool, specCaps *specs.LinuxCapabilities) (*auth.Task if caps.PermittedCaps, err = capsFromNames(specCaps.Permitted, skipSet); err != nil { return nil, err } - // TODO: Support ambient capabilities. + // TODO(nlacasse): Support ambient capabilities. } return &caps, nil } diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index 94e0f24e0..d35f59433 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -277,7 +277,7 @@ syscall_test(test = "//test/syscalls/linux:sendfile_test") syscall_test(test = "//test/syscalls/linux:sigaction_test") -# TODO: Enable once the test passes in runsc. +# TODO(b/119826902): Enable once the test passes in runsc. # syscall_test(test = "//test/syscalls/linux:sigaltstack_test") syscall_test(test = "//test/syscalls/linux:sigiret_test") @@ -414,7 +414,7 @@ syscall_test( ) syscall_test( - # NOTE: Large sendmsg may stall a long time. + # NOTE(b/116636318): Large sendmsg may stall a long time. size = "enormous", test = "//test/syscalls/linux:socket_unix_dgram_local_test", ) @@ -437,7 +437,7 @@ syscall_test( ) syscall_test( - # NOTE: Large sendmsg may stall a long time. + # NOTE(b/116636318): Large sendmsg may stall a long time. size = "enormous", test = "//test/syscalls/linux:socket_unix_seqpacket_local_test", ) diff --git a/test/syscalls/build_defs.bzl b/test/syscalls/build_defs.bzl index 610b030b2..cd74a769d 100644 --- a/test/syscalls/build_defs.bzl +++ b/test/syscalls/build_defs.bzl @@ -78,10 +78,10 @@ def _syscall_test( tags += [full_platform, "file_" + file_access] # Add tag to prevent the tests from running in a Bazel sandbox. - # TODO: Make the tests run without this tag. + # TODO(b/120560048): Make the tests run without this tag. tags.append("no-sandbox") - # TODO: KVM tests are tagged "manual" to until the platform is + # TODO(b/112165693): KVM tests are tagged "manual" to until the platform is # more stable. if platform == "kvm": tags += ["manual"] diff --git a/test/syscalls/linux/32bit.cc b/test/syscalls/linux/32bit.cc index 230648c9b..78baf548e 100644 --- a/test/syscalls/linux/32bit.cc +++ b/test/syscalls/linux/32bit.cc @@ -80,11 +80,11 @@ constexpr int kExitCode = 42; TEST(Syscall32Bit, Int80) { switch (GvisorPlatform()) { case Platform::kKVM: - // TODO: 32-bit segments are broken (but not explictly + // TODO(b/111805002): 32-bit segments are broken (but not explictly // disabled). return; case Platform::kPtrace: - // TODO: The ptrace platform does not have a + // TODO(gvisor.dev/issue/167): The ptrace platform does not have a // consistent story here. return; case Platform::kNative: @@ -99,10 +99,10 @@ TEST(Syscall32Bit, Int80) { TEST(Syscall32Bit, Sysenter) { switch (GvisorPlatform()) { case Platform::kKVM: - // TODO: See above. + // TODO(b/111805002): See above. return; case Platform::kPtrace: - // TODO: See above. + // TODO(gvisor.dev/issue/167): See above. return; case Platform::kNative: break; @@ -123,10 +123,10 @@ TEST(Syscall32Bit, Sysenter) { TEST(Syscall32Bit, Syscall) { switch (GvisorPlatform()) { case Platform::kKVM: - // TODO: See above. + // TODO(b/111805002): See above. return; case Platform::kPtrace: - // TODO: See above. + // TODO(gvisor.dev/issue/167): See above. return; case Platform::kNative: break; @@ -207,7 +207,7 @@ void FarCall32() { TEST(Call32Bit, Disallowed) { switch (GvisorPlatform()) { case Platform::kKVM: - // TODO: See above. + // TODO(b/111805002): See above. return; case Platform::kPtrace: // The ptrace platform cannot prevent switching to compatibility mode. diff --git a/test/syscalls/linux/aio.cc b/test/syscalls/linux/aio.cc index 06643ccb8..b96aab9b9 100644 --- a/test/syscalls/linux/aio.cc +++ b/test/syscalls/linux/aio.cc @@ -103,7 +103,7 @@ TEST_F(AIOTest, BasicWrite) { // aio implementation uses aio_ring. gVisor doesn't and returns all zeroes. // Linux implements aio_ring, so skip the zeroes check. // - // TODO: Remove when gVisor implements aio_ring. + // TODO(b/65486370): Remove when gVisor implements aio_ring. auto ring = reinterpret_cast(ctx_); auto magic = IsRunningOnGvisor() ? 0 : AIO_RING_MAGIC; EXPECT_EQ(ring->magic, magic); diff --git a/test/syscalls/linux/chmod.cc b/test/syscalls/linux/chmod.cc index 2f2ff3b7d..2f42fe326 100644 --- a/test/syscalls/linux/chmod.cc +++ b/test/syscalls/linux/chmod.cc @@ -235,7 +235,7 @@ TEST(ChmodTest, FchmodFileToNoPermissionsSucceeds_NoRandomSave) { // Verify that we can get a RW FD after chmod, even if a RO fd is left open. TEST(ChmodTest, ChmodWritableWithOpenFD) { - // FIXME: broken on hostfs. + // FIXME(b/72455313): broken on hostfs. if (IsRunningOnGvisor()) { return; } diff --git a/test/syscalls/linux/epoll.cc b/test/syscalls/linux/epoll.cc index 7b1d83ad8..b4a3bfcba 100644 --- a/test/syscalls/linux/epoll.cc +++ b/test/syscalls/linux/epoll.cc @@ -56,7 +56,7 @@ TEST(EpollTest, AllWritable) { struct epoll_event result[kFDsPerEpoll]; ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1), SyscallSucceedsWithValue(kFDsPerEpoll)); - // TODO: Why do some tests check epoll_event::data, and others + // TODO(edahlgren): Why do some tests check epoll_event::data, and others // don't? Does Linux actually guarantee that, in any of these test cases, // epoll_wait will necessarily write out the epoll_events in the order that // they were registered? diff --git a/test/syscalls/linux/exec_binary.cc b/test/syscalls/linux/exec_binary.cc index 187696ed9..c10d85398 100644 --- a/test/syscalls/linux/exec_binary.cc +++ b/test/syscalls/linux/exec_binary.cc @@ -285,7 +285,7 @@ ElfBinary<64> StandardElf() { elf.header.e_phoff = sizeof(elf.header); elf.header.e_phentsize = sizeof(decltype(elf)::ElfPhdr); - // TODO: Always include a PT_GNU_STACK segment to + // TODO(gvisor.dev/issue/153): Always include a PT_GNU_STACK segment to // disable executable stacks. With this omitted the stack (and all PROT_READ) // mappings should be executable, but gVisor doesn't support that. decltype(elf)::ElfPhdr phdr = {}; @@ -403,7 +403,7 @@ TEST(ElfTest, DataSegment) { // Linux will allow PT_LOAD segments to overlap. TEST(ElfTest, DirectlyOverlappingSegments) { - // NOTE: see PIEOutOfOrderSegments. + // NOTE(b/37289926): see PIEOutOfOrderSegments. SKIP_IF(IsRunningOnGvisor()); ElfBinary<64> elf = StandardElf(); @@ -439,7 +439,7 @@ TEST(ElfTest, DirectlyOverlappingSegments) { // Linux allows out-of-order PT_LOAD segments. TEST(ElfTest, OutOfOrderSegments) { - // NOTE: see PIEOutOfOrderSegments. + // NOTE(b/37289926): see PIEOutOfOrderSegments. SKIP_IF(IsRunningOnGvisor()); ElfBinary<64> elf = StandardElf(); @@ -670,7 +670,7 @@ TEST(ElfTest, PIENonZeroStart) { } TEST(ElfTest, PIEOutOfOrderSegments) { - // TODO: This triggers a bug in Linux where it computes the size + // TODO(b/37289926): This triggers a bug in Linux where it computes the size // of the binary as 0x20000 - 0x40000 = 0xfffffffffffe0000, which obviously // fails to map. // @@ -1005,7 +1005,7 @@ TEST(ElfTest, NoExecute) { // Execute, but no read permissions on the binary works just fine. TEST(ElfTest, NoRead) { - // TODO: gVisor's backing filesystem may prevent the + // TODO(gvisor.dev/issue/160): gVisor's backing filesystem may prevent the // sentry from reading the executable. SKIP_IF(IsRunningOnGvisor()); @@ -1024,7 +1024,7 @@ TEST(ElfTest, NoRead) { ASSERT_NO_ERRNO(WaitStopped(child)); - // TODO: A task with a non-readable executable is marked + // TODO(gvisor.dev/issue/160): A task with a non-readable executable is marked // non-dumpable, preventing access to proc files. gVisor does not implement // this behavior. } diff --git a/test/syscalls/linux/file_base.h b/test/syscalls/linux/file_base.h index 19c9a5053..43f568111 100644 --- a/test/syscalls/linux/file_base.h +++ b/test/syscalls/linux/file_base.h @@ -52,7 +52,7 @@ class FileTest : public ::testing::Test { test_file_fd_ = ASSERT_NO_ERRNO_AND_VALUE( Open(test_file_name_, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)); - // FIXME: enable when mknod syscall is supported. + // FIXME(edahlgren): enable when mknod syscall is supported. // test_fifo_name_ = NewTempAbsPath(); // ASSERT_THAT(mknod(test_fifo_name_.c_str()), S_IFIFO|0644, 0, // SyscallSucceeds()); @@ -97,7 +97,7 @@ class FileTest : public ::testing::Test { UnlinkFile(); ClosePipes(); - // FIXME: enable when mknod syscall is supported. + // FIXME(edahlgren): enable when mknod syscall is supported. // close(test_fifo_[0]); // close(test_fifo_[1]); // unlink(test_fifo_name_.c_str()); diff --git a/test/syscalls/linux/ioctl.cc b/test/syscalls/linux/ioctl.cc index de29047e0..c7741a177 100644 --- a/test/syscalls/linux/ioctl.cc +++ b/test/syscalls/linux/ioctl.cc @@ -158,7 +158,7 @@ TEST_F(IoctlTest, FIOASYNCNoTarget) { } TEST_F(IoctlTest, FIOASYNCSelfTarget) { - // FIXME: gVisor erroneously sends SIGIO on close(2), which would + // FIXME(b/120624367): gVisor erroneously sends SIGIO on close(2), which would // kill the test when pair goes out of scope. Temporarily ignore SIGIO so that // that the close signal is ignored. struct sigaction sa; @@ -195,7 +195,7 @@ TEST_F(IoctlTest, FIOASYNCSelfTarget) { // Equivalent to FIOASYNCSelfTarget except that FIOSETOWN is called before // FIOASYNC. TEST_F(IoctlTest, FIOASYNCSelfTarget2) { - // FIXME: gVisor erroneously sends SIGIO on close(2), which would + // FIXME(b/120624367): gVisor erroneously sends SIGIO on close(2), which would // kill the test when pair goes out of scope. Temporarily ignore SIGIO so that // that the close signal is ignored. struct sigaction sa; diff --git a/test/syscalls/linux/ip_socket_test_util.cc b/test/syscalls/linux/ip_socket_test_util.cc index 4ad787cc0..0a149c2e5 100644 --- a/test/syscalls/linux/ip_socket_test_util.cc +++ b/test/syscalls/linux/ip_socket_test_util.cc @@ -24,7 +24,7 @@ namespace gvisor { namespace testing { PosixErrorOr InterfaceIndex(std::string name) { - // TODO: Consider using netlink. + // TODO(igudger): Consider using netlink. ifreq req = {}; memcpy(req.ifr_name, name.c_str(), name.size()); ASSIGN_OR_RETURN_ERRNO(auto sock, Socket(AF_INET, SOCK_DGRAM, 0)); diff --git a/test/syscalls/linux/lseek.cc b/test/syscalls/linux/lseek.cc index fb6a1546e..6a4f1423c 100644 --- a/test/syscalls/linux/lseek.cc +++ b/test/syscalls/linux/lseek.cc @@ -194,7 +194,7 @@ TEST(LseekTest, EtcPasswdDup) { ASSERT_THAT(lseek(fd3.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(1000)); } -// TODO: Add tests where we have donated in sockets. +// TODO(magi): Add tests where we have donated in sockets. } // namespace diff --git a/test/syscalls/linux/mkdir.cc b/test/syscalls/linux/mkdir.cc index 84db45eb3..50807b68f 100644 --- a/test/syscalls/linux/mkdir.cc +++ b/test/syscalls/linux/mkdir.cc @@ -36,7 +36,7 @@ class MkdirTest : public ::testing::Test { // TearDown unlinks created files. void TearDown() override { - // FIXME: We don't currently implement rmdir. + // FIXME(edahlgren): We don't currently implement rmdir. // We do this unconditionally because there's no harm in trying. rmdir(dirname_.c_str()); } diff --git a/test/syscalls/linux/mmap.cc b/test/syscalls/linux/mmap.cc index b500e79a4..a4fb9d1e0 100644 --- a/test/syscalls/linux/mmap.cc +++ b/test/syscalls/linux/mmap.cc @@ -816,7 +816,7 @@ class MMapFileTest : public MMapTest { // MAP_POPULATE allowed. // There isn't a good way to verify it actually did anything. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, MapPopulate) { ASSERT_THAT( Map(0, kPageSize, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd_.get(), 0), @@ -825,7 +825,7 @@ TEST_F(MMapFileTest, MapPopulate) { // MAP_POPULATE on a short file. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, MapPopulateShort) { ASSERT_THAT(Map(0, 2 * kPageSize, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd_.get(), 0), @@ -923,7 +923,7 @@ TEST_F(MMapFileTest, WriteSharedOnReadOnlyFd) { // MAP_SHARED PROT_READ not allowed on write-only FDs. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, ReadSharedOnWriteOnlyFd) { const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(filename_, O_WRONLY)); @@ -936,7 +936,7 @@ TEST_F(MMapFileTest, ReadSharedOnWriteOnlyFd) { // MAP_SHARED PROT_WRITE not allowed on write-only FDs. // The FD must always be readable. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, WriteSharedOnWriteOnlyFd) { const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(filename_, O_WRONLY)); @@ -1371,7 +1371,7 @@ TEST_F(MMapFileTest, WritePrivate) { // SIGBUS raised when writing past end of file to a private mapping. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, SigBusDeathWritePrivate) { SetupGvisorDeathTest(); @@ -1390,7 +1390,7 @@ TEST_F(MMapFileTest, SigBusDeathWritePrivate) { // SIGBUS raised when reading past end of file on a shared mapping. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, SigBusDeathReadShared) { SetupGvisorDeathTest(); @@ -1410,7 +1410,7 @@ TEST_F(MMapFileTest, SigBusDeathReadShared) { // SIGBUS raised when reading past end of file on a shared mapping. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, SigBusDeathWriteShared) { SetupGvisorDeathTest(); @@ -1459,7 +1459,7 @@ TEST_F(MMapFileTest, NoSigBusOnPageContainingEOFWritePrivate) { // Tests that SIGBUS is not raised when reading from a file-mapped page // containing EOF, *after* the EOF for a shared mapping. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, NoSigBusOnPageContainingEOFReadShared) { uintptr_t addr; ASSERT_THAT(addr = Map(0, 2 * kPageSize, PROT_READ, MAP_SHARED, fd_.get(), 0), @@ -1476,7 +1476,7 @@ TEST_F(MMapFileTest, NoSigBusOnPageContainingEOFReadShared) { // Tests that SIGBUS is not raised when writing to a file-mapped page containing // EOF, *after* the EOF for a shared mapping. // -// FIXME: Parameterize. +// FIXME(b/37222275): Parameterize. TEST_F(MMapFileTest, NoSigBusOnPageContainingEOFWriteShared) { uintptr_t addr; ASSERT_THAT(addr = Map(0, 2 * kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, diff --git a/test/syscalls/linux/open.cc b/test/syscalls/linux/open.cc index cdc226300..22e4666c2 100644 --- a/test/syscalls/linux/open.cc +++ b/test/syscalls/linux/open.cc @@ -279,7 +279,7 @@ TEST_F(OpenTest, Null) { ASSERT_THAT(open(&c, O_RDONLY), SyscallFailsWithErrno(ENOENT)); } -// NOTE: While the man pages specify that this behavior should be +// NOTE(b/119785738): While the man pages specify that this behavior should be // undefined, Linux truncates the file on opening read only if we have write // permission, so we will too. TEST_F(OpenTest, CanTruncateReadOnly) { diff --git a/test/syscalls/linux/partial_bad_buffer.cc b/test/syscalls/linux/partial_bad_buffer.cc index 073a6b8c1..71288ebc4 100644 --- a/test/syscalls/linux/partial_bad_buffer.cc +++ b/test/syscalls/linux/partial_bad_buffer.cc @@ -158,7 +158,7 @@ TEST_F(PartialBadBufferTest, PreadvSmall) { } TEST_F(PartialBadBufferTest, WriteBig) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); @@ -168,7 +168,7 @@ TEST_F(PartialBadBufferTest, WriteBig) { } TEST_F(PartialBadBufferTest, WriteSmall) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); @@ -178,7 +178,7 @@ TEST_F(PartialBadBufferTest, WriteSmall) { } TEST_F(PartialBadBufferTest, PwriteBig) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); @@ -188,7 +188,7 @@ TEST_F(PartialBadBufferTest, PwriteBig) { } TEST_F(PartialBadBufferTest, PwriteSmall) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); @@ -198,7 +198,7 @@ TEST_F(PartialBadBufferTest, PwriteSmall) { } TEST_F(PartialBadBufferTest, WritevBig) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); @@ -211,7 +211,7 @@ TEST_F(PartialBadBufferTest, WritevBig) { } TEST_F(PartialBadBufferTest, WritevSmall) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); @@ -224,7 +224,7 @@ TEST_F(PartialBadBufferTest, WritevSmall) { } TEST_F(PartialBadBufferTest, PwritevBig) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); @@ -238,7 +238,7 @@ TEST_F(PartialBadBufferTest, PwritevBig) { } TEST_F(PartialBadBufferTest, PwritevSmall) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); @@ -279,7 +279,7 @@ TEST_F(PartialBadBufferTest, GetdentsOneEntry) { // Verify that when write returns EFAULT the kernel hasn't silently written // the initial valid bytes. TEST_F(PartialBadBufferTest, WriteEfaultIsntPartial) { - // FIXME: The sentry write syscalls will return immediately + // FIXME(b/24788078): The sentry write syscalls will return immediately // if Access returns an error, but Access may not return an error // and the sentry will instead perform a partial write. SKIP_IF(IsRunningOnGvisor()); diff --git a/test/syscalls/linux/pipe.cc b/test/syscalls/linux/pipe.cc index c49ec9f09..abd10b11b 100644 --- a/test/syscalls/linux/pipe.cc +++ b/test/syscalls/linux/pipe.cc @@ -36,7 +36,7 @@ namespace { // Buffer size of a pipe. // -// TODO: Get this from F_GETPIPE_SZ. +// TODO(b/35762278): Get this from F_GETPIPE_SZ. constexpr int kPipeSize = 65536; class PipeTest : public ::testing::Test { @@ -316,7 +316,7 @@ TEST_F(PipeTest, BlockWriteClosed) { // Blocking write returns EPIPE when read end is closed even if something has // been written. // -// FIXME: Pipe writes blocking early allows S/R to interrupt the +// FIXME(b/35924046): Pipe writes blocking early allows S/R to interrupt the // write(2) call before the buffer is full. Then the next call will will return // non-zero instead of EPIPE. TEST_F(PipeTest, BlockPartialWriteClosed_NoRandomSave) { @@ -329,7 +329,7 @@ TEST_F(PipeTest, BlockPartialWriteClosed_NoRandomSave) { // Write more than fits in the buffer. Blocks then returns partial write // when the other end is closed. The next call returns EPIPE. if (IsRunningOnGvisor()) { - // FIXME: Pipe writes block early on gVisor, resulting in a + // FIXME(b/35924046): Pipe writes block early on gVisor, resulting in a // shorter than expected partial write. ASSERT_THAT(write(wfd, buf.data(), buf.size()), SyscallSucceedsWithValue(::testing::Gt(0))); diff --git a/test/syscalls/linux/proc.cc b/test/syscalls/linux/proc.cc index 3ec31ae8b..7ba274226 100644 --- a/test/syscalls/linux/proc.cc +++ b/test/syscalls/linux/proc.cc @@ -61,7 +61,7 @@ #include "test/util/thread_util.h" #include "test/util/timer_util.h" -// NOTE: No, this isn't really a syscall but this is a really simple +// NOTE(magi): No, this isn't really a syscall but this is a really simple // way to get it tested on both gVisor, PTrace and Linux. using ::testing::AllOf; @@ -489,7 +489,7 @@ TEST(ProcSelfMaps, Map1) { } TEST(ProcSelfMaps, Map2) { - // NOTE: The permissions must be different or the pages will get merged. + // NOTE(magi): The permissions must be different or the pages will get merged. Mapping map1 = ASSERT_NO_ERRNO_AND_VALUE( MmapAnon(kPageSize, PROT_READ | PROT_EXEC, MAP_PRIVATE)); Mapping map2 = @@ -564,7 +564,7 @@ TEST(ProcSelfMaps, MapUnmap) { } TEST(ProcSelfMaps, Mprotect) { - // FIXME: Linux's mprotect() sometimes fails to merge VMAs in this + // FIXME(jamieliu): Linux's mprotect() sometimes fails to merge VMAs in this // case. SKIP_IF(!IsRunningOnGvisor()); @@ -977,7 +977,7 @@ void MapPopulateRSS(int prot, uint64_t* before, uint64_t* after) { *after = ASSERT_NO_ERRNO_AND_VALUE(CurrentRSS()); } -// TODO: Test for PROT_READ + MAP_POPULATE anonymous mappings. Their +// TODO(b/73896574): Test for PROT_READ + MAP_POPULATE anonymous mappings. Their // semantics are more subtle: // // Small pages -> Zero page mapped, not counted in RSS @@ -1140,7 +1140,7 @@ TEST(ProcPidStatusTest, ValuesAreTabDelimited) { // Threads properly counts running threads. // -// TODO: Test zombied threads while the thread group leader is still +// TODO(mpratt): Test zombied threads while the thread group leader is still // running with generalized fork and clone children from the wait test. TEST(ProcPidStatusTest, Threads) { char buf[4096] = {}; @@ -1274,7 +1274,7 @@ TEST(ProcPidSymlink, SubprocessRunning) { SyscallSucceedsWithValue(sizeof(buf))); } -// FIXME: Inconsistent behavior between gVisor and linux +// FIXME(gvisor.dev/issue/164): Inconsistent behavior between gVisor and linux // on proc files. TEST(ProcPidSymlink, SubprocessZombied) { ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false)); @@ -1298,13 +1298,13 @@ TEST(ProcPidSymlink, SubprocessZombied) { SyscallFailsWithErrno(want)); } - // FIXME: Inconsistent behavior between gVisor and linux + // FIXME(gvisor.dev/issue/164): Inconsistent behavior between gVisor and linux // on proc files. // 4.17 & gVisor: Syscall succeeds and returns 1 // EXPECT_THAT(ReadlinkWhileZombied("ns/pid", buf, sizeof(buf)), // SyscallFailsWithErrno(EACCES)); - // FIXME: Inconsistent behavior between gVisor and linux + // FIXME(gvisor.dev/issue/164): Inconsistent behavior between gVisor and linux // on proc files. // 4.17 & gVisor: Syscall succeeds and returns 1. // EXPECT_THAT(ReadlinkWhileZombied("ns/user", buf, sizeof(buf)), @@ -1313,7 +1313,7 @@ TEST(ProcPidSymlink, SubprocessZombied) { // Test whether /proc/PID/ symlinks can be read for an exited process. TEST(ProcPidSymlink, SubprocessExited) { - // FIXME: These all succeed on gVisor. + // FIXME(gvisor.dev/issue/164): These all succeed on gVisor. SKIP_IF(IsRunningOnGvisor()); char buf[1]; @@ -1404,7 +1404,7 @@ TEST(ProcPidFile, SubprocessZombie) { EXPECT_THAT(ReadWhileZombied("uid_map", buf, sizeof(buf)), SyscallSucceedsWithValue(sizeof(buf))); - // FIXME: Inconsistent behavior between gVisor and linux + // FIXME(gvisor.dev/issue/164): Inconsistent behavior between gVisor and linux // on proc files. // gVisor & 4.17: Succeeds and returns 1. // EXPECT_THAT(ReadWhileZombied("io", buf, sizeof(buf)), @@ -1415,7 +1415,7 @@ TEST(ProcPidFile, SubprocessZombie) { TEST(ProcPidFile, SubprocessExited) { char buf[1]; - // FIXME: Inconsistent behavior between kernels + // FIXME(gvisor.dev/issue/164): Inconsistent behavior between kernels // gVisor: Fails with ESRCH. // 4.17: Succeeds and returns 1. // EXPECT_THAT(ReadWhileExited("auxv", buf, sizeof(buf)), @@ -1425,7 +1425,7 @@ TEST(ProcPidFile, SubprocessExited) { SyscallFailsWithErrno(ESRCH)); if (!IsRunningOnGvisor()) { - // FIXME: Succeeds on gVisor. + // FIXME(gvisor.dev/issue/164): Succeeds on gVisor. EXPECT_THAT(ReadWhileExited("comm", buf, sizeof(buf)), SyscallFailsWithErrno(ESRCH)); } @@ -1434,25 +1434,25 @@ TEST(ProcPidFile, SubprocessExited) { SyscallSucceedsWithValue(sizeof(buf))); if (!IsRunningOnGvisor()) { - // FIXME: Succeeds on gVisor. + // FIXME(gvisor.dev/issue/164): Succeeds on gVisor. EXPECT_THAT(ReadWhileExited("io", buf, sizeof(buf)), SyscallFailsWithErrno(ESRCH)); } if (!IsRunningOnGvisor()) { - // FIXME: Returns EOF on gVisor. + // FIXME(gvisor.dev/issue/164): Returns EOF on gVisor. EXPECT_THAT(ReadWhileExited("maps", buf, sizeof(buf)), SyscallFailsWithErrno(ESRCH)); } if (!IsRunningOnGvisor()) { - // FIXME: Succeeds on gVisor. + // FIXME(gvisor.dev/issue/164): Succeeds on gVisor. EXPECT_THAT(ReadWhileExited("stat", buf, sizeof(buf)), SyscallFailsWithErrno(ESRCH)); } if (!IsRunningOnGvisor()) { - // FIXME: Succeeds on gVisor. + // FIXME(gvisor.dev/issue/164): Succeeds on gVisor. EXPECT_THAT(ReadWhileExited("status", buf, sizeof(buf)), SyscallFailsWithErrno(ESRCH)); } diff --git a/test/syscalls/linux/proc_pid_smaps.cc b/test/syscalls/linux/proc_pid_smaps.cc index 5f9c42ce5..cf5c462f3 100644 --- a/test/syscalls/linux/proc_pid_smaps.cc +++ b/test/syscalls/linux/proc_pid_smaps.cc @@ -82,7 +82,7 @@ struct ProcPidSmapsEntry { // Given the value part of a /proc/[pid]/smaps field containing a value in kB // (for example, " 4 kB", returns the value in kB (in this example, 4). PosixErrorOr SmapsValueKb(absl::string_view value) { - // TODO: let us use RE2 or + // TODO(jamieliu): let us use RE2 or std::pair parts = absl::StrSplit(value, ' ', absl::SkipEmpty()); if (parts.second != "kB") { diff --git a/test/syscalls/linux/ptrace.cc b/test/syscalls/linux/ptrace.cc index 1c9d7d4f4..e0c56f1fc 100644 --- a/test/syscalls/linux/ptrace.cc +++ b/test/syscalls/linux/ptrace.cc @@ -823,7 +823,7 @@ TEST(PtraceTest, TEST(PtraceTest, Int3) { switch (GvisorPlatform()) { case Platform::kKVM: - // TODO: int3 isn't handled properly. + // TODO(b/124248694): int3 isn't handled properly. return; default: break; diff --git a/test/syscalls/linux/pwrite64.cc b/test/syscalls/linux/pwrite64.cc index 60ae6de1f..485b1e48d 100644 --- a/test/syscalls/linux/pwrite64.cc +++ b/test/syscalls/linux/pwrite64.cc @@ -30,7 +30,7 @@ namespace { // This test is currently very rudimentary. // -// TODO: +// TODO(edahlgren): // * bad buffer states (EFAULT). // * bad fds (wrong permission, wrong type of file, EBADF). // * check offset is not incremented. diff --git a/test/syscalls/linux/readv_socket.cc b/test/syscalls/linux/readv_socket.cc index 2c129b7e8..cf22c395e 100644 --- a/test/syscalls/linux/readv_socket.cc +++ b/test/syscalls/linux/readv_socket.cc @@ -41,7 +41,7 @@ class ReadvSocketTest : public SocketTest { ASSERT_THAT(write(test_unix_seqpacket_socket_[1], kReadvTestData, kReadvTestDataSize), SyscallSucceedsWithValue(kReadvTestDataSize)); - // FIXME: Enable when possible. + // FIXME(b/69821513): Enable when possible. // ASSERT_THAT(write(test_tcp_socket_[1], kReadvTestData, // kReadvTestDataSize), // SyscallSucceedsWithValue(kReadvTestDataSize)); diff --git a/test/syscalls/linux/rtsignal.cc b/test/syscalls/linux/rtsignal.cc index 1f2fed7cc..ff948f9d5 100644 --- a/test/syscalls/linux/rtsignal.cc +++ b/test/syscalls/linux/rtsignal.cc @@ -75,7 +75,7 @@ class RtSignalTest : public ::testing::Test { static int rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t* uinfo) { int ret; do { - // NOTE: rt_sigqueueinfo(2) could return EAGAIN for RT signals. + // NOTE(b/25434735): rt_sigqueueinfo(2) could return EAGAIN for RT signals. ret = syscall(SYS_rt_sigqueueinfo, tgid, sig, uinfo); } while (ret == -1 && errno == EAGAIN); return ret; diff --git a/test/syscalls/linux/socket_inet_loopback.cc b/test/syscalls/linux/socket_inet_loopback.cc index cdc5c0ce8..14d7827c2 100644 --- a/test/syscalls/linux/socket_inet_loopback.cc +++ b/test/syscalls/linux/socket_inet_loopback.cc @@ -221,7 +221,7 @@ TEST_P(SocketInetReusePortTest, TcpPortReuseMultiThread) { std::atomic connects_received = ATOMIC_VAR_INIT(0); std::unique_ptr listen_thread[kThreadCount]; int accept_counts[kThreadCount] = {}; - // TODO: figure how to not disable S/R for the whole test. + // TODO(avagin): figure how to not disable S/R for the whole test. // We need to take into account that this test executes a lot of system // calls from many threads. DisableSave ds; @@ -325,7 +325,7 @@ TEST_P(SocketInetReusePortTest, UdpPortReuseMultiThread) { std::atomic packets_received = ATOMIC_VAR_INIT(0); std::unique_ptr receiver_thread[kThreadCount]; int packets_per_socket[kThreadCount] = {}; - // TODO: figure how to not disable S/R for the whole test. + // TODO(avagin): figure how to not disable S/R for the whole test. DisableSave ds; // Too expensive. for (int i = 0; i < kThreadCount; i++) { @@ -642,7 +642,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6OnlyV6AnyReservesV6) { TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReserved) { auto const& param = GetParam(); - // FIXME + // FIXME(b/114268588) SKIP_IF(IsRunningOnGvisor() && param.type == SOCK_STREAM); for (int i = 0; true; i++) { @@ -743,7 +743,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V6EphemeralPortReserved) { TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { auto const& param = GetParam(); - // FIXME + // FIXME(b/114268588) SKIP_IF(IsRunningOnGvisor() && param.type == SOCK_STREAM); for (int i = 0; true; i++) { @@ -867,7 +867,7 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, V4MappedEphemeralPortReserved) { TEST_P(SocketMultiProtocolInetLoopbackTest, V4EphemeralPortReserved) { auto const& param = GetParam(); - // FIXME + // FIXME(b/114268588) SKIP_IF(IsRunningOnGvisor() && param.type == SOCK_STREAM); for (int i = 0; true; i++) { diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc index 8b4fc57b6..9dd9e1bd6 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc @@ -244,7 +244,7 @@ TestAddress V4Multicast() { // set interface or group membership. TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastSelfNoGroup) { - // FIXME: A group membership is not required for external + // FIXME(b/125485338): A group membership is not required for external // multicast on gVisor. SKIP_IF(IsRunningOnGvisor()); @@ -371,7 +371,7 @@ TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, // Check that multicast packets won't be delivered to another socket with no // set interface or group membership. TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastNoGroup) { - // FIXME: A group membership is not required for external + // FIXME(b/125485338): A group membership is not required for external // multicast on gVisor. SKIP_IF(IsRunningOnGvisor()); diff --git a/test/syscalls/linux/socket_netlink_route.cc b/test/syscalls/linux/socket_netlink_route.cc index 8d2e7d333..ed4ae1c71 100644 --- a/test/syscalls/linux/socket_netlink_route.cc +++ b/test/syscalls/linux/socket_netlink_route.cc @@ -180,7 +180,7 @@ void CheckGetLinkResponse(const struct nlmsghdr* hdr, int seq, int port) { // RTM_NEWLINK contains at least the header and ifinfomsg. EXPECT_GE(hdr->nlmsg_len, NLMSG_SPACE(sizeof(struct ifinfomsg))); - // TODO: Check ifinfomsg contents and following attrs. + // TODO(mpratt): Check ifinfomsg contents and following attrs. } TEST(NetlinkRouteTest, GetLinkDump) { @@ -370,7 +370,7 @@ TEST(NetlinkRouteTest, GetAddrDump) { // RTM_NEWADDR contains at least the header and ifaddrmsg. EXPECT_GE(hdr->nlmsg_len, sizeof(*hdr) + sizeof(struct ifaddrmsg)); - // TODO: Check ifaddrmsg contents and following attrs. + // TODO(mpratt): Check ifaddrmsg contents and following attrs. })); } diff --git a/test/syscalls/linux/socket_stream_blocking.cc b/test/syscalls/linux/socket_stream_blocking.cc index 8b3f6a647..f0f86c01c 100644 --- a/test/syscalls/linux/socket_stream_blocking.cc +++ b/test/syscalls/linux/socket_stream_blocking.cc @@ -33,7 +33,7 @@ namespace gvisor { namespace testing { TEST_P(BlockingStreamSocketPairTest, BlockPartialWriteClosed) { - // FIXME: gVisor doesn't support SO_SNDBUF on UDS, nor does it + // FIXME(b/35921550): gVisor doesn't support SO_SNDBUF on UDS, nor does it // enforce any limit; it will write arbitrary amounts of data without // blocking. SKIP_IF(IsRunningOnGvisor()); diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc index 035087566..0be23e541 100644 --- a/test/syscalls/linux/socket_test_util.cc +++ b/test/syscalls/linux/socket_test_util.cc @@ -353,7 +353,7 @@ PosixErrorOr> CreateTCPAcceptBindSocketPair( } MaybeSave(); // Successful accept. - // FIXME + // FIXME(b/110484944) if (connect_result == -1) { absl::SleepFor(absl::Seconds(1)); } diff --git a/test/syscalls/linux/socket_unix.cc b/test/syscalls/linux/socket_unix.cc index 7332b768e..fafb23ad1 100644 --- a/test/syscalls/linux/socket_unix.cc +++ b/test/syscalls/linux/socket_unix.cc @@ -186,7 +186,7 @@ TEST_P(UnixSocketPairTest, BasicFDPassNoSpace) { // BasicFDPassNoSpaceMsgCtrunc sends an FD, but does not provide any space to // receive it. It then verifies that the MSG_CTRUNC flag is set in the msghdr. TEST_P(UnixSocketPairTest, BasicFDPassNoSpaceMsgCtrunc) { - // FIXME: Support MSG_CTRUNC. + // FIXME(gvisor.dev/issue/206): Support MSG_CTRUNC. SKIP_IF(IsRunningOnGvisor()); auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -224,7 +224,7 @@ TEST_P(UnixSocketPairTest, BasicFDPassNoSpaceMsgCtrunc) { // accomidate the FD, but msg_control is set to NULL. In this case, msg_control // should override msg_controllen. TEST_P(UnixSocketPairTest, BasicFDPassNullControlMsgCtrunc) { - // FIXME: Fix handling of NULL msg_control. + // FIXME(gvisor.dev/issue/207): Fix handling of NULL msg_control. SKIP_IF(IsRunningOnGvisor()); auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -259,7 +259,7 @@ TEST_P(UnixSocketPairTest, BasicFDPassNullControlMsgCtrunc) { // space to receive it. It then verifies that the MSG_CTRUNC flag is set in the // msghdr. TEST_P(UnixSocketPairTest, BasicFDPassNotEnoughSpaceMsgCtrunc) { - // FIXME: Support MSG_CTRUNC. + // FIXME(gvisor.dev/issue/206): Support MSG_CTRUNC. SKIP_IF(IsRunningOnGvisor()); auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -296,7 +296,7 @@ TEST_P(UnixSocketPairTest, BasicFDPassNotEnoughSpaceMsgCtrunc) { // space to receive two of them. It then verifies that the MSG_CTRUNC flag is // set in the msghdr. TEST_P(UnixSocketPairTest, BasicThreeFDPassTruncationMsgCtrunc) { - // FIXME: Support MSG_CTRUNC. + // FIXME(gvisor.dev/issue/206): Support MSG_CTRUNC. SKIP_IF(IsRunningOnGvisor()); auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -408,7 +408,7 @@ TEST_P(UnixSocketPairTest, BasicFDPassUnalignedRecvNoMsgTrunc) { // provides enough space to receive one of them. It then verifies that the // MSG_CTRUNC flag is set in the msghdr. TEST_P(UnixSocketPairTest, BasicTwoFDPassUnalignedRecvTruncationMsgTrunc) { - // FIXME: Support MSG_CTRUNC. + // FIXME(gvisor.dev/issue/206): Support MSG_CTRUNC. SKIP_IF(IsRunningOnGvisor()); auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -1010,7 +1010,7 @@ TEST_P(UnixSocketPairTest, CredPassNoMsgCtrunc) { // the data without providing space for any credentials and verifies that // MSG_CTRUNC is set in the msghdr. TEST_P(UnixSocketPairTest, CredPassNoSpaceMsgCtrunc) { - // FIXME: Support MSG_CTRUNC. + // FIXME(gvisor.dev/issue/206): Support MSG_CTRUNC. SKIP_IF(IsRunningOnGvisor()); auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -1061,7 +1061,7 @@ TEST_P(UnixSocketPairTest, CredPassNoSpaceMsgCtrunc) { // the data while providing enough space for only the first field of the // credentials and verifies that MSG_CTRUNC is set in the msghdr. TEST_P(UnixSocketPairTest, CredPassTruncatedMsgCtrunc) { - // FIXME: Support MSG_CTRUNC. + // FIXME(gvisor.dev/issue/206): Support MSG_CTRUNC. SKIP_IF(IsRunningOnGvisor()); auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); @@ -1615,7 +1615,7 @@ TEST_P(UnixSocketPairTest, SocketShutdown) { } TEST_P(UnixSocketPairTest, SocketReopenFromProcfs) { - // TODO: We should be returning ENXIO and NOT EIO. + // TODO(b/122310852): We should be returning ENXIO and NOT EIO. SKIP_IF(IsRunningOnGvisor()); auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); diff --git a/test/syscalls/linux/socket_unix_dgram.cc b/test/syscalls/linux/socket_unix_dgram.cc index c17d3990f..5dd5e6d77 100644 --- a/test/syscalls/linux/socket_unix_dgram.cc +++ b/test/syscalls/linux/socket_unix_dgram.cc @@ -28,7 +28,7 @@ namespace testing { namespace { TEST_P(DgramUnixSocketPairTest, WriteOneSideClosed) { - // FIXME: gVisor datagram sockets return EPIPE instead of + // FIXME(b/35925052): gVisor datagram sockets return EPIPE instead of // ECONNREFUSED. SKIP_IF(IsRunningOnGvisor()); diff --git a/test/syscalls/linux/socket_unix_dgram_non_blocking.cc b/test/syscalls/linux/socket_unix_dgram_non_blocking.cc index 460eb8320..3becb513d 100644 --- a/test/syscalls/linux/socket_unix_dgram_non_blocking.cc +++ b/test/syscalls/linux/socket_unix_dgram_non_blocking.cc @@ -31,7 +31,7 @@ using NonBlockingDgramUnixSocketPairTest = SocketPairTest; TEST_P(NonBlockingDgramUnixSocketPairTest, ReadOneSideClosed) { if (IsRunningOnGvisor()) { - // FIXME: gVisor datagram sockets return 0 instead of + // FIXME(b/70803293): gVisor datagram sockets return 0 instead of // EAGAIN. return; } diff --git a/test/syscalls/linux/socket_unix_non_stream.cc b/test/syscalls/linux/socket_unix_non_stream.cc index 8e0cbee4c..a565978f9 100644 --- a/test/syscalls/linux/socket_unix_non_stream.cc +++ b/test/syscalls/linux/socket_unix_non_stream.cc @@ -47,7 +47,7 @@ TEST_P(UnixNonStreamSocketPairTest, RecvMsgTooLarge) { const int ret = RetryEINTR(write)(sockets->second_fd(), write_buf.data(), write_buf.size()); if (ret < 0 && errno == ENOBUFS) { - // NOTE: Linux may stall the write for a long time and + // NOTE(b/116636318): Linux may stall the write for a long time and // ultimately return ENOBUFS. Allow this error, since a retry will likely // result in the same error. return; @@ -136,7 +136,7 @@ TEST_P(UnixNonStreamSocketPairTest, FragmentedSendMsg) { // N.B. At minimum, the socketpair gofer should provide a socket that is // already the correct size. // - // TODO: When internal UDS support SO_SNDBUF, we can assert that + // TODO(b/35921550): When internal UDS support SO_SNDBUF, we can assert that // we always get the right SO_SNDBUF on gVisor. GTEST_SKIP() << "SO_SNDBUF = " << actual_sndbuf << ", want " << sndbuf; } @@ -156,7 +156,7 @@ TEST_P(UnixNonStreamSocketPairTest, FragmentedSendMsg) { msg.msg_iov = &iov; msg.msg_iovlen = 1; - // NOTE: Linux has poor behavior in the presence of + // NOTE(b/116636318,b/115833655): Linux has poor behavior in the presence of // physical memory fragmentation. As a result, this may stall for a long time // and ultimately return ENOBUFS. Allow this error, since it means that we // made it to the host kernel and started the sendmsg. @@ -192,7 +192,7 @@ TEST_P(UnixNonStreamSocketPairTest, FragmentedRecvMsg) { // N.B. At minimum, the socketpair gofer should provide a socket that is // already the correct size. // - // TODO: When internal UDS support SO_SNDBUF, we can assert that + // TODO(b/35921550): When internal UDS support SO_SNDBUF, we can assert that // we always get the right SO_SNDBUF on gVisor. GTEST_SKIP() << "SO_SNDBUF = " << actual_sndbuf << ", want " << sndbuf; } @@ -201,7 +201,7 @@ TEST_P(UnixNonStreamSocketPairTest, FragmentedRecvMsg) { const int ret = RetryEINTR(write)(sockets->first_fd(), write_buf.data(), write_buf.size()); if (ret < 0 && errno == ENOBUFS) { - // NOTE: Linux may stall the write for a long time and + // NOTE(b/116636318): Linux may stall the write for a long time and // ultimately return ENOBUFS. Allow this error, since a retry will likely // result in the same error. return; diff --git a/test/syscalls/linux/socket_unix_unbound_seqpacket.cc b/test/syscalls/linux/socket_unix_unbound_seqpacket.cc index 270d7203f..21209b244 100644 --- a/test/syscalls/linux/socket_unix_unbound_seqpacket.cc +++ b/test/syscalls/linux/socket_unix_unbound_seqpacket.cc @@ -42,7 +42,7 @@ TEST_P(UnboundUnixSeqpacketSocketPairTest, SendtoWithoutConnect) { } TEST_P(UnboundUnixSeqpacketSocketPairTest, SendtoWithoutConnectIgnoresAddr) { - // FIXME: gVisor tries to find /foo/bar and thus returns ENOENT. + // FIXME(b/68223466): gVisor tries to find /foo/bar and thus returns ENOENT. if (IsRunningOnGvisor()) { return; } diff --git a/test/syscalls/linux/socket_unix_unbound_stream.cc b/test/syscalls/linux/socket_unix_unbound_stream.cc index 4db5b4be1..b95f9569e 100644 --- a/test/syscalls/linux/socket_unix_unbound_stream.cc +++ b/test/syscalls/linux/socket_unix_unbound_stream.cc @@ -269,7 +269,7 @@ TEST_P(UnixStreamSocketPairTest, SinglePeek) { // 9f389e35674f5b086edd70ed524ca0f287259725 which changes this behavior. We // used to target 3.11 compatibility, so disable this test on newer kernels. // - // NOTE: Bring this up to Linux 4.4 compatibility. + // NOTE(b/118902768): Bring this up to Linux 4.4 compatibility. auto version = ASSERT_NO_ERRNO_AND_VALUE(GetKernelVersion()); SKIP_IF(version.major > 4 || (version.major == 4 && version.minor >= 3)); } @@ -686,7 +686,7 @@ TEST_P(UnboundUnixStreamSocketPairTest, SendtoWithoutConnect) { } TEST_P(UnboundUnixStreamSocketPairTest, SendtoWithoutConnectIgnoresAddr) { - // FIXME: gVisor tries to find /foo/bar and thus returns ENOENT. + // FIXME(b/68223466): gVisor tries to find /foo/bar and thus returns ENOENT. if (IsRunningOnGvisor()) { return; } diff --git a/test/syscalls/linux/stat.cc b/test/syscalls/linux/stat.cc index 48a2059de..746318d09 100644 --- a/test/syscalls/linux/stat.cc +++ b/test/syscalls/linux/stat.cc @@ -416,7 +416,7 @@ TEST_F(StatTest, ZeroLinksOpenFdRegularFileChild_NoRandomSave) { EXPECT_EQ(st_child_before.st_gid, st_child_fd.st_gid); EXPECT_EQ(st_child_before.st_size, st_child_fd.st_size); - // TODO: This isn't ideal but since fstatfs(2) will always return + // TODO(b/34861058): This isn't ideal but since fstatfs(2) will always return // OVERLAYFS_SUPER_MAGIC we have no way to know if this fs is backed by a // gofer which doesn't support links. EXPECT_TRUE(st_child_fd.st_nlink == 0 || st_child_fd.st_nlink == 1); diff --git a/test/syscalls/linux/stat_times.cc b/test/syscalls/linux/stat_times.cc index 442957c65..8346e9a8e 100644 --- a/test/syscalls/linux/stat_times.cc +++ b/test/syscalls/linux/stat_times.cc @@ -68,7 +68,7 @@ TEST_F(StatTimesTest, FileCreationTimes) { TEST_F(StatTimesTest, FileCtimeChanges) { auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); - MaybeSave(); // FIXME: ctime is inconsistent. + MaybeSave(); // FIXME(b/69865927): ctime is inconsistent. absl::Time atime, mtime, ctime; std::tie(atime, mtime, ctime) = GetTime(file); @@ -150,7 +150,7 @@ TEST_F(StatTimesTest, FileAtimeChanges) { const auto file = ASSERT_NO_ERRNO_AND_VALUE( TempPath::CreateFileWith(GetAbsoluteTestTmpdir(), contents, 0666)); - MaybeSave(); // FIXME: ctime is inconsistent. + MaybeSave(); // FIXME(b/69865927): ctime is inconsistent. absl::Time atime, mtime, ctime; std::tie(atime, mtime, ctime) = GetTime(file); @@ -184,7 +184,7 @@ TEST_F(StatTimesTest, DirAtimeChanges) { const auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileIn(dir.path())); - MaybeSave(); // FIXME: ctime is inconsistent. + MaybeSave(); // FIXME(b/69865927): ctime is inconsistent. absl::Time atime, mtime, ctime; std::tie(atime, mtime, ctime) = GetTime(dir); @@ -193,7 +193,7 @@ TEST_F(StatTimesTest, DirAtimeChanges) { const absl::Time before = absl::Now() - absl::Seconds(1); - // NOTE: Keep an fd open. This ensures that the inode backing the + // NOTE(b/37756234): Keep an fd open. This ensures that the inode backing the // directory won't be destroyed before the final GetTime to avoid writing out // timestamps and causing side effects. const auto fd = ASSERT_NO_ERRNO_AND_VALUE(Open(dir.path(), O_RDONLY, 0)); diff --git a/test/syscalls/linux/tcp_socket.cc b/test/syscalls/linux/tcp_socket.cc index 1057f5892..33620a874 100644 --- a/test/syscalls/linux/tcp_socket.cc +++ b/test/syscalls/linux/tcp_socket.cc @@ -191,7 +191,7 @@ TEST_P(TcpSocketTest, SenderAddressIgnoredOnPeek) { TEST_P(TcpSocketTest, SendtoAddressIgnored) { struct sockaddr_storage addr; memset(&addr, 0, sizeof(addr)); - addr.ss_family = GetParam(); // FIXME + addr.ss_family = GetParam(); // FIXME(b/63803955) char data = '\0'; EXPECT_THAT( diff --git a/test/syscalls/linux/tkill.cc b/test/syscalls/linux/tkill.cc index 9842ccc9b..3e8ce5327 100644 --- a/test/syscalls/linux/tkill.cc +++ b/test/syscalls/linux/tkill.cc @@ -32,7 +32,7 @@ namespace { static int tkill(pid_t tid, int sig) { int ret; do { - // NOTE: tkill(2) could return EAGAIN for RT signals. + // NOTE(b/25434735): tkill(2) could return EAGAIN for RT signals. ret = syscall(SYS_tkill, tid, sig); } while (ret == -1 && errno == EAGAIN); return ret; diff --git a/test/syscalls/linux/udp_bind.cc b/test/syscalls/linux/udp_bind.cc index 902be47d3..547eb2a6c 100644 --- a/test/syscalls/linux/udp_bind.cc +++ b/test/syscalls/linux/udp_bind.cc @@ -286,7 +286,7 @@ INSTANTIATE_TEST_SUITE_P( []() { SendtoTestParam param = {}; param.description = "connected IPv6 sendto IPv4 mapped IPv6"; - // TODO: Determine if this inconsistent behavior is worth + // TODO(igudger): Determine if this inconsistent behavior is worth // implementing. param.skip_on_gvisor = true; param.send_domain = AF_INET6; @@ -299,7 +299,7 @@ INSTANTIATE_TEST_SUITE_P( []() { SendtoTestParam param = {}; param.description = "connected IPv6 sendto IPv4"; - // TODO: Determine if this inconsistent behavior is worth + // TODO(igudger): Determine if this inconsistent behavior is worth // implementing. param.skip_on_gvisor = true; param.send_domain = AF_INET6; diff --git a/test/syscalls/linux/uidgid.cc b/test/syscalls/linux/uidgid.cc index c0c1f2960..d78a09b1e 100644 --- a/test/syscalls/linux/uidgid.cc +++ b/test/syscalls/linux/uidgid.cc @@ -169,7 +169,7 @@ TEST(UidGidRootTest, SetgidNotFromThreadGroupLeader) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(IsRoot())); const gid_t gid = FLAGS_scratch_gid1; - // NOTE: Do setgid in a separate thread so that we can test if + // NOTE(b/64676707): Do setgid in a separate thread so that we can test if // info.si_pid is set correctly. ScopedThread([gid] { ASSERT_THAT(setgid(gid), SyscallSucceeds()); }); EXPECT_NO_ERRNO(CheckGIDs(gid, gid, gid)); diff --git a/test/syscalls/linux/utimes.cc b/test/syscalls/linux/utimes.cc index d95ee74ec..bf776cd93 100644 --- a/test/syscalls/linux/utimes.cc +++ b/test/syscalls/linux/utimes.cc @@ -33,7 +33,7 @@ namespace testing { namespace { -// TODO: utimes(nullptr) does not pick the "now" time in the +// TODO(b/36516566): utimes(nullptr) does not pick the "now" time in the // application's time domain, so when asserting that times are within a window, // we expand the window to allow for differences between the time domains. constexpr absl::Duration kClockSlack = absl::Milliseconds(100); @@ -235,7 +235,7 @@ void TestUtimensat(int dirFd, std::string const& path) { EXPECT_LE(mtime3, after); if (!IsRunningOnGvisor()) { - // FIXME: Gofers set atime and mtime to different "now" times. + // FIXME(b/36516566): Gofers set atime and mtime to different "now" times. EXPECT_EQ(atime3, mtime3); } } diff --git a/test/syscalls/linux/wait.cc b/test/syscalls/linux/wait.cc index cfab8a976..fcd606bec 100644 --- a/test/syscalls/linux/wait.cc +++ b/test/syscalls/linux/wait.cc @@ -40,7 +40,7 @@ using ::testing::UnorderedElementsAre; // These unit tests focus on the wait4(2) system call, but include a basic // checks for the i386 waitpid(2) syscall, which is a subset of wait4(2). // -// NOTE: Some functionality is not tested as +// NOTE(b/22640830,b/27680907,b/29049891): Some functionality is not tested as // it is not currently supported by gVisor: // * UID in waitid(2) siginfo. // * Process groups. diff --git a/test/syscalls/linux/write.cc b/test/syscalls/linux/write.cc index 432bd6066..7f80b2fa8 100644 --- a/test/syscalls/linux/write.cc +++ b/test/syscalls/linux/write.cc @@ -33,7 +33,7 @@ namespace testing { namespace { // This test is currently very rudimentary. // -// TODO: +// TODO(edahlgren): // * bad buffer states (EFAULT). // * bad fds (wrong permission, wrong type of file, EBADF). // * check offset is incremented. diff --git a/third_party/gvsync/downgradable_rwmutex_unsafe.go b/third_party/gvsync/downgradable_rwmutex_unsafe.go index a63a0d084..131f0a2ba 100644 --- a/third_party/gvsync/downgradable_rwmutex_unsafe.go +++ b/third_party/gvsync/downgradable_rwmutex_unsafe.go @@ -49,7 +49,7 @@ func (rw *DowngradableRWMutex) RLock() { // RUnlock undoes a single RLock call. func (rw *DowngradableRWMutex) RUnlock() { if RaceEnabled { - // TODO: Why does this need to be ReleaseMerge instead of + // TODO(jamieliu): Why does this need to be ReleaseMerge instead of // Release? IIUC this establishes Unlock happens-before RUnlock, which // seems unnecessary. RaceReleaseMerge(unsafe.Pointer(&rw.writerSem)) diff --git a/vdso/cycle_clock.h b/vdso/cycle_clock.h index 26d6690c0..309e07a3f 100644 --- a/vdso/cycle_clock.h +++ b/vdso/cycle_clock.h @@ -23,7 +23,7 @@ namespace vdso { #if __x86_64__ -// TODO: The appropriate barrier instruction to use with rdtsc on +// TODO(b/74613497): The appropriate barrier instruction to use with rdtsc on // x86_64 depends on the vendor. Intel processors can use lfence but AMD may // need mfence, depending on MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT. diff --git a/vdso/vdso_amd64.lds b/vdso/vdso_amd64.lds index 166779931..e2615ae9e 100644 --- a/vdso/vdso_amd64.lds +++ b/vdso/vdso_amd64.lds @@ -56,7 +56,7 @@ SECTIONS { .altinstr_replacement : { *(.altinstr_replacement) } /* - * TODO: Remove this alignment? Then the VDSO would fit + * TODO(gvisor.dev/issue/157): Remove this alignment? Then the VDSO would fit * in a single page. */ . = ALIGN(0x1000); diff --git a/vdso/vdso_arm64.lds b/vdso/vdso_arm64.lds index 19f8efa01..469185468 100644 --- a/vdso/vdso_arm64.lds +++ b/vdso/vdso_arm64.lds @@ -59,7 +59,7 @@ SECTIONS { .altinstr_replacement : { *(.altinstr_replacement) } /* - * TODO: Remove this alignment? Then the VDSO would fit + * TODO(gvisor.dev/issue/157): Remove this alignment? Then the VDSO would fit * in a single page. */ . = ALIGN(0x1000); -- cgit v1.2.3 From 4d52a5520101a88424fb63dd99412a1db33fbd06 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 29 Apr 2019 14:25:05 -0700 Subject: Change copyright notice to "The gVisor Authors" Based on the guidelines at https://opensource.google.com/docs/releasing/authors/. 1. $ rg -l "Google LLC" | xargs sed -i 's/Google LLC.*/The gVisor Authors./' 2. Manual fixup of "Google Inc" references. 3. Add AUTHORS file. Authors may request to be added to this file. 4. Point netstack AUTHORS to gVisor AUTHORS. Drop CONTRIBUTORS. Fixes #209 PiperOrigin-RevId: 245823212 Change-Id: I64530b24ad021a7d683137459cafc510f5ee1de9 --- AUTHORS | 8 ++++++++ kokoro/run_build.sh | 2 +- kokoro/run_tests.sh | 2 +- pkg/abi/abi.go | 2 +- pkg/abi/abi_linux.go | 2 +- pkg/abi/flag.go | 2 +- pkg/abi/linux/aio.go | 2 +- pkg/abi/linux/ashmem.go | 2 +- pkg/abi/linux/audit.go | 2 +- pkg/abi/linux/binder.go | 2 +- pkg/abi/linux/bpf.go | 2 +- pkg/abi/linux/capability.go | 2 +- pkg/abi/linux/dev.go | 2 +- pkg/abi/linux/elf.go | 2 +- pkg/abi/linux/errors.go | 2 +- pkg/abi/linux/eventfd.go | 2 +- pkg/abi/linux/exec.go | 2 +- pkg/abi/linux/fcntl.go | 2 +- pkg/abi/linux/file.go | 2 +- pkg/abi/linux/fs.go | 2 +- pkg/abi/linux/futex.go | 2 +- pkg/abi/linux/inotify.go | 2 +- pkg/abi/linux/ioctl.go | 2 +- pkg/abi/linux/ip.go | 2 +- pkg/abi/linux/ipc.go | 2 +- pkg/abi/linux/limits.go | 2 +- pkg/abi/linux/linux.go | 2 +- pkg/abi/linux/mm.go | 2 +- pkg/abi/linux/netdevice.go | 2 +- pkg/abi/linux/netlink.go | 2 +- pkg/abi/linux/netlink_route.go | 2 +- pkg/abi/linux/poll.go | 2 +- pkg/abi/linux/prctl.go | 2 +- pkg/abi/linux/ptrace.go | 2 +- pkg/abi/linux/rusage.go | 2 +- pkg/abi/linux/sched.go | 2 +- pkg/abi/linux/seccomp.go | 2 +- pkg/abi/linux/sem.go | 2 +- pkg/abi/linux/shm.go | 2 +- pkg/abi/linux/signal.go | 2 +- pkg/abi/linux/socket.go | 2 +- pkg/abi/linux/tcp.go | 2 +- pkg/abi/linux/time.go | 2 +- pkg/abi/linux/timer.go | 2 +- pkg/abi/linux/tty.go | 2 +- pkg/abi/linux/uio.go | 2 +- pkg/abi/linux/utsname.go | 2 +- pkg/amutex/amutex.go | 2 +- pkg/amutex/amutex_test.go | 2 +- pkg/atomicbitops/atomic_bitops.go | 2 +- pkg/atomicbitops/atomic_bitops_amd64.s | 2 +- pkg/atomicbitops/atomic_bitops_common.go | 2 +- pkg/atomicbitops/atomic_bitops_test.go | 2 +- pkg/binary/binary.go | 2 +- pkg/binary/binary_test.go | 2 +- pkg/bits/bits.go | 2 +- pkg/bits/bits_template.go | 2 +- pkg/bits/uint64_arch_amd64.go | 2 +- pkg/bits/uint64_arch_amd64_asm.s | 2 +- pkg/bits/uint64_arch_generic.go | 2 +- pkg/bits/uint64_test.go | 2 +- pkg/bpf/bpf.go | 2 +- pkg/bpf/decoder.go | 2 +- pkg/bpf/decoder_test.go | 2 +- pkg/bpf/input_bytes.go | 2 +- pkg/bpf/interpreter.go | 2 +- pkg/bpf/interpreter_test.go | 2 +- pkg/bpf/program_builder.go | 2 +- pkg/bpf/program_builder_test.go | 2 +- pkg/compressio/compressio.go | 2 +- pkg/compressio/compressio_test.go | 2 +- pkg/control/client/client.go | 2 +- pkg/control/server/server.go | 2 +- pkg/cpuid/cpu_amd64.s | 2 +- pkg/cpuid/cpuid.go | 2 +- pkg/cpuid/cpuid_parse_test.go | 2 +- pkg/cpuid/cpuid_test.go | 2 +- pkg/dhcp/client.go | 2 +- pkg/dhcp/dhcp.go | 2 +- pkg/dhcp/dhcp_string.go | 2 +- pkg/dhcp/dhcp_test.go | 2 +- pkg/dhcp/server.go | 2 +- pkg/eventchannel/event.go | 2 +- pkg/eventchannel/event.proto | 2 +- pkg/fd/fd.go | 2 +- pkg/fd/fd_test.go | 2 +- pkg/fdnotifier/fdnotifier.go | 2 +- pkg/fdnotifier/poll_unsafe.go | 2 +- pkg/gate/gate.go | 2 +- pkg/gate/gate_test.go | 2 +- pkg/ilist/list.go | 2 +- pkg/ilist/list_test.go | 2 +- pkg/linewriter/linewriter.go | 2 +- pkg/linewriter/linewriter_test.go | 2 +- pkg/log/glog.go | 2 +- pkg/log/glog_unsafe.go | 2 +- pkg/log/json.go | 2 +- pkg/log/json_k8s.go | 2 +- pkg/log/json_test.go | 2 +- pkg/log/log.go | 2 +- pkg/log/log_test.go | 2 +- pkg/metric/metric.go | 2 +- pkg/metric/metric.proto | 2 +- pkg/metric/metric_test.go | 2 +- pkg/p9/buffer.go | 2 +- pkg/p9/buffer_test.go | 2 +- pkg/p9/client.go | 2 +- pkg/p9/client_file.go | 2 +- pkg/p9/client_test.go | 2 +- pkg/p9/file.go | 2 +- pkg/p9/handlers.go | 2 +- pkg/p9/local_server/local_server.go | 2 +- pkg/p9/messages.go | 2 +- pkg/p9/messages_test.go | 2 +- pkg/p9/p9.go | 2 +- pkg/p9/p9_test.go | 2 +- pkg/p9/p9test/client_test.go | 2 +- pkg/p9/p9test/p9test.go | 2 +- pkg/p9/path_tree.go | 2 +- pkg/p9/pool.go | 2 +- pkg/p9/pool_test.go | 2 +- pkg/p9/server.go | 2 +- pkg/p9/transport.go | 2 +- pkg/p9/transport_test.go | 2 +- pkg/p9/version.go | 2 +- pkg/p9/version_test.go | 2 +- pkg/rand/rand.go | 2 +- pkg/rand/rand_linux.go | 2 +- pkg/refs/refcounter.go | 2 +- pkg/refs/refcounter_state.go | 2 +- pkg/refs/refcounter_test.go | 2 +- pkg/seccomp/seccomp.go | 2 +- pkg/seccomp/seccomp_rules.go | 2 +- pkg/seccomp/seccomp_test.go | 2 +- pkg/seccomp/seccomp_test_victim.go | 2 +- pkg/seccomp/seccomp_unsafe.go | 2 +- pkg/secio/full_reader.go | 2 +- pkg/secio/secio.go | 2 +- pkg/secio/secio_test.go | 2 +- pkg/segment/range.go | 2 +- pkg/segment/set.go | 2 +- pkg/segment/set_state.go | 2 +- pkg/segment/test/segment_test.go | 2 +- pkg/segment/test/set_functions.go | 2 +- pkg/sentry/arch/aligned.go | 2 +- pkg/sentry/arch/arch.go | 2 +- pkg/sentry/arch/arch_amd64.go | 2 +- pkg/sentry/arch/arch_amd64.s | 2 +- pkg/sentry/arch/arch_state_x86.go | 2 +- pkg/sentry/arch/arch_x86.go | 2 +- pkg/sentry/arch/auxv.go | 2 +- pkg/sentry/arch/registers.proto | 2 +- pkg/sentry/arch/signal_act.go | 2 +- pkg/sentry/arch/signal_amd64.go | 2 +- pkg/sentry/arch/signal_info.go | 2 +- pkg/sentry/arch/signal_stack.go | 2 +- pkg/sentry/arch/stack.go | 2 +- pkg/sentry/arch/syscalls_amd64.go | 2 +- pkg/sentry/context/context.go | 2 +- pkg/sentry/context/contexttest/contexttest.go | 2 +- pkg/sentry/control/control.go | 2 +- pkg/sentry/control/pprof.go | 2 +- pkg/sentry/control/proc.go | 2 +- pkg/sentry/control/proc_test.go | 2 +- pkg/sentry/control/state.go | 2 +- pkg/sentry/device/device.go | 2 +- pkg/sentry/device/device_test.go | 2 +- pkg/sentry/fs/anon/anon.go | 2 +- pkg/sentry/fs/anon/device.go | 2 +- pkg/sentry/fs/ashmem/area.go | 2 +- pkg/sentry/fs/ashmem/device.go | 2 +- pkg/sentry/fs/ashmem/pin_board.go | 2 +- pkg/sentry/fs/ashmem/pin_board_test.go | 2 +- pkg/sentry/fs/attr.go | 2 +- pkg/sentry/fs/binder/binder.go | 2 +- pkg/sentry/fs/context.go | 2 +- pkg/sentry/fs/copy_up.go | 2 +- pkg/sentry/fs/copy_up_test.go | 2 +- pkg/sentry/fs/dentry.go | 2 +- pkg/sentry/fs/dev/dev.go | 2 +- pkg/sentry/fs/dev/device.go | 2 +- pkg/sentry/fs/dev/fs.go | 2 +- pkg/sentry/fs/dev/full.go | 2 +- pkg/sentry/fs/dev/null.go | 2 +- pkg/sentry/fs/dev/random.go | 2 +- pkg/sentry/fs/dirent.go | 2 +- pkg/sentry/fs/dirent_cache.go | 2 +- pkg/sentry/fs/dirent_cache_limiter.go | 2 +- pkg/sentry/fs/dirent_cache_test.go | 2 +- pkg/sentry/fs/dirent_refs_test.go | 2 +- pkg/sentry/fs/dirent_state.go | 2 +- pkg/sentry/fs/fdpipe/pipe.go | 2 +- pkg/sentry/fs/fdpipe/pipe_opener.go | 2 +- pkg/sentry/fs/fdpipe/pipe_opener_test.go | 2 +- pkg/sentry/fs/fdpipe/pipe_state.go | 2 +- pkg/sentry/fs/fdpipe/pipe_test.go | 2 +- pkg/sentry/fs/file.go | 2 +- pkg/sentry/fs/file_operations.go | 2 +- pkg/sentry/fs/file_overlay.go | 2 +- pkg/sentry/fs/file_overlay_test.go | 2 +- pkg/sentry/fs/file_state.go | 2 +- pkg/sentry/fs/file_test.go | 2 +- pkg/sentry/fs/filesystems.go | 2 +- pkg/sentry/fs/filetest/filetest.go | 2 +- pkg/sentry/fs/flags.go | 2 +- pkg/sentry/fs/fs.go | 2 +- pkg/sentry/fs/fsutil/dirty_set.go | 2 +- pkg/sentry/fs/fsutil/dirty_set_test.go | 2 +- pkg/sentry/fs/fsutil/file.go | 2 +- pkg/sentry/fs/fsutil/file_range_set.go | 2 +- pkg/sentry/fs/fsutil/frame_ref_set.go | 2 +- pkg/sentry/fs/fsutil/fsutil.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper_state.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go | 2 +- pkg/sentry/fs/fsutil/host_mappable.go | 2 +- pkg/sentry/fs/fsutil/inode.go | 2 +- pkg/sentry/fs/fsutil/inode_cached.go | 2 +- pkg/sentry/fs/fsutil/inode_cached_test.go | 2 +- pkg/sentry/fs/gofer/attr.go | 2 +- pkg/sentry/fs/gofer/cache_policy.go | 2 +- pkg/sentry/fs/gofer/context_file.go | 2 +- pkg/sentry/fs/gofer/device.go | 2 +- pkg/sentry/fs/gofer/file.go | 2 +- pkg/sentry/fs/gofer/file_state.go | 2 +- pkg/sentry/fs/gofer/fs.go | 2 +- pkg/sentry/fs/gofer/gofer_test.go | 2 +- pkg/sentry/fs/gofer/handles.go | 2 +- pkg/sentry/fs/gofer/inode.go | 2 +- pkg/sentry/fs/gofer/inode_state.go | 2 +- pkg/sentry/fs/gofer/path.go | 2 +- pkg/sentry/fs/gofer/session.go | 2 +- pkg/sentry/fs/gofer/session_state.go | 2 +- pkg/sentry/fs/gofer/socket.go | 2 +- pkg/sentry/fs/gofer/util.go | 2 +- pkg/sentry/fs/host/control.go | 2 +- pkg/sentry/fs/host/descriptor.go | 2 +- pkg/sentry/fs/host/descriptor_state.go | 2 +- pkg/sentry/fs/host/descriptor_test.go | 2 +- pkg/sentry/fs/host/device.go | 2 +- pkg/sentry/fs/host/file.go | 2 +- pkg/sentry/fs/host/fs.go | 2 +- pkg/sentry/fs/host/fs_test.go | 2 +- pkg/sentry/fs/host/inode.go | 2 +- pkg/sentry/fs/host/inode_state.go | 2 +- pkg/sentry/fs/host/inode_test.go | 2 +- pkg/sentry/fs/host/ioctl_unsafe.go | 2 +- pkg/sentry/fs/host/socket.go | 2 +- pkg/sentry/fs/host/socket_iovec.go | 2 +- pkg/sentry/fs/host/socket_state.go | 2 +- pkg/sentry/fs/host/socket_test.go | 2 +- pkg/sentry/fs/host/socket_unsafe.go | 2 +- pkg/sentry/fs/host/tty.go | 2 +- pkg/sentry/fs/host/util.go | 2 +- pkg/sentry/fs/host/util_unsafe.go | 2 +- pkg/sentry/fs/host/wait_test.go | 2 +- pkg/sentry/fs/inode.go | 2 +- pkg/sentry/fs/inode_inotify.go | 2 +- pkg/sentry/fs/inode_operations.go | 2 +- pkg/sentry/fs/inode_overlay.go | 2 +- pkg/sentry/fs/inode_overlay_test.go | 2 +- pkg/sentry/fs/inotify.go | 2 +- pkg/sentry/fs/inotify_event.go | 2 +- pkg/sentry/fs/inotify_watch.go | 2 +- pkg/sentry/fs/lock/lock.go | 2 +- pkg/sentry/fs/lock/lock_range_test.go | 2 +- pkg/sentry/fs/lock/lock_set_functions.go | 2 +- pkg/sentry/fs/lock/lock_test.go | 2 +- pkg/sentry/fs/mock.go | 2 +- pkg/sentry/fs/mount.go | 2 +- pkg/sentry/fs/mount_overlay.go | 2 +- pkg/sentry/fs/mount_test.go | 2 +- pkg/sentry/fs/mounts.go | 2 +- pkg/sentry/fs/mounts_test.go | 2 +- pkg/sentry/fs/offset.go | 2 +- pkg/sentry/fs/overlay.go | 2 +- pkg/sentry/fs/path.go | 2 +- pkg/sentry/fs/path_test.go | 2 +- pkg/sentry/fs/proc/cpuinfo.go | 2 +- pkg/sentry/fs/proc/device/device.go | 2 +- pkg/sentry/fs/proc/exec_args.go | 2 +- pkg/sentry/fs/proc/fds.go | 2 +- pkg/sentry/fs/proc/filesystems.go | 2 +- pkg/sentry/fs/proc/fs.go | 2 +- pkg/sentry/fs/proc/inode.go | 2 +- pkg/sentry/fs/proc/loadavg.go | 2 +- pkg/sentry/fs/proc/meminfo.go | 2 +- pkg/sentry/fs/proc/mounts.go | 2 +- pkg/sentry/fs/proc/net.go | 2 +- pkg/sentry/fs/proc/net_test.go | 2 +- pkg/sentry/fs/proc/proc.go | 2 +- pkg/sentry/fs/proc/rpcinet_proc.go | 2 +- pkg/sentry/fs/proc/seqfile/seqfile.go | 2 +- pkg/sentry/fs/proc/seqfile/seqfile_test.go | 2 +- pkg/sentry/fs/proc/stat.go | 2 +- pkg/sentry/fs/proc/sys.go | 2 +- pkg/sentry/fs/proc/sys_net.go | 2 +- pkg/sentry/fs/proc/sys_net_state.go | 2 +- pkg/sentry/fs/proc/sys_net_test.go | 2 +- pkg/sentry/fs/proc/task.go | 2 +- pkg/sentry/fs/proc/uid_gid_map.go | 2 +- pkg/sentry/fs/proc/uptime.go | 2 +- pkg/sentry/fs/proc/version.go | 2 +- pkg/sentry/fs/ramfs/dir.go | 2 +- pkg/sentry/fs/ramfs/socket.go | 2 +- pkg/sentry/fs/ramfs/symlink.go | 2 +- pkg/sentry/fs/ramfs/tree.go | 2 +- pkg/sentry/fs/ramfs/tree_test.go | 2 +- pkg/sentry/fs/restore.go | 2 +- pkg/sentry/fs/save.go | 2 +- pkg/sentry/fs/seek.go | 2 +- pkg/sentry/fs/sync.go | 2 +- pkg/sentry/fs/sys/device.go | 2 +- pkg/sentry/fs/sys/devices.go | 2 +- pkg/sentry/fs/sys/fs.go | 2 +- pkg/sentry/fs/sys/sys.go | 2 +- pkg/sentry/fs/timerfd/timerfd.go | 2 +- pkg/sentry/fs/tmpfs/device.go | 2 +- pkg/sentry/fs/tmpfs/file_regular.go | 2 +- pkg/sentry/fs/tmpfs/file_test.go | 2 +- pkg/sentry/fs/tmpfs/fs.go | 2 +- pkg/sentry/fs/tmpfs/inode_file.go | 2 +- pkg/sentry/fs/tmpfs/tmpfs.go | 2 +- pkg/sentry/fs/tty/dir.go | 2 +- pkg/sentry/fs/tty/fs.go | 2 +- pkg/sentry/fs/tty/line_discipline.go | 2 +- pkg/sentry/fs/tty/master.go | 2 +- pkg/sentry/fs/tty/queue.go | 2 +- pkg/sentry/fs/tty/slave.go | 2 +- pkg/sentry/fs/tty/terminal.go | 2 +- pkg/sentry/fs/tty/tty_test.go | 2 +- pkg/sentry/hostcpu/getcpu_amd64.s | 2 +- pkg/sentry/hostcpu/hostcpu.go | 2 +- pkg/sentry/hostcpu/hostcpu_test.go | 2 +- pkg/sentry/inet/context.go | 2 +- pkg/sentry/inet/inet.go | 2 +- pkg/sentry/inet/test_stack.go | 2 +- pkg/sentry/kernel/abstract_socket_namespace.go | 2 +- pkg/sentry/kernel/auth/auth.go | 2 +- pkg/sentry/kernel/auth/capability_set.go | 2 +- pkg/sentry/kernel/auth/context.go | 2 +- pkg/sentry/kernel/auth/credentials.go | 2 +- pkg/sentry/kernel/auth/id.go | 2 +- pkg/sentry/kernel/auth/id_map.go | 2 +- pkg/sentry/kernel/auth/id_map_functions.go | 2 +- pkg/sentry/kernel/auth/user_namespace.go | 2 +- pkg/sentry/kernel/context.go | 2 +- pkg/sentry/kernel/contexttest/contexttest.go | 2 +- pkg/sentry/kernel/epoll/epoll.go | 2 +- pkg/sentry/kernel/epoll/epoll_state.go | 2 +- pkg/sentry/kernel/epoll/epoll_test.go | 2 +- pkg/sentry/kernel/eventfd/eventfd.go | 2 +- pkg/sentry/kernel/eventfd/eventfd_test.go | 2 +- pkg/sentry/kernel/fasync/fasync.go | 2 +- pkg/sentry/kernel/fd_map.go | 2 +- pkg/sentry/kernel/fd_map_test.go | 2 +- pkg/sentry/kernel/fs_context.go | 2 +- pkg/sentry/kernel/futex/futex.go | 2 +- pkg/sentry/kernel/futex/futex_test.go | 2 +- pkg/sentry/kernel/ipc_namespace.go | 2 +- pkg/sentry/kernel/kdefs/kdefs.go | 2 +- pkg/sentry/kernel/kernel.go | 2 +- pkg/sentry/kernel/kernel_state.go | 2 +- pkg/sentry/kernel/memevent/memory_events.go | 2 +- pkg/sentry/kernel/memevent/memory_events.proto | 2 +- pkg/sentry/kernel/pending_signals.go | 2 +- pkg/sentry/kernel/pending_signals_state.go | 2 +- pkg/sentry/kernel/pipe/buffers.go | 2 +- pkg/sentry/kernel/pipe/device.go | 2 +- pkg/sentry/kernel/pipe/node.go | 2 +- pkg/sentry/kernel/pipe/node_test.go | 2 +- pkg/sentry/kernel/pipe/pipe.go | 2 +- pkg/sentry/kernel/pipe/pipe_test.go | 2 +- pkg/sentry/kernel/pipe/reader.go | 2 +- pkg/sentry/kernel/pipe/reader_writer.go | 2 +- pkg/sentry/kernel/pipe/writer.go | 2 +- pkg/sentry/kernel/posixtimer.go | 2 +- pkg/sentry/kernel/ptrace.go | 2 +- pkg/sentry/kernel/ptrace_amd64.go | 2 +- pkg/sentry/kernel/ptrace_arm64.go | 2 +- pkg/sentry/kernel/rseq.go | 2 +- pkg/sentry/kernel/sched/cpuset.go | 2 +- pkg/sentry/kernel/sched/cpuset_test.go | 2 +- pkg/sentry/kernel/sched/sched.go | 2 +- pkg/sentry/kernel/seccomp.go | 2 +- pkg/sentry/kernel/semaphore/semaphore.go | 2 +- pkg/sentry/kernel/semaphore/semaphore_test.go | 2 +- pkg/sentry/kernel/sessions.go | 2 +- pkg/sentry/kernel/shm/device.go | 2 +- pkg/sentry/kernel/shm/shm.go | 2 +- pkg/sentry/kernel/signal.go | 2 +- pkg/sentry/kernel/signal_handlers.go | 2 +- pkg/sentry/kernel/syscalls.go | 2 +- pkg/sentry/kernel/syscalls_state.go | 2 +- pkg/sentry/kernel/syslog.go | 2 +- pkg/sentry/kernel/table_test.go | 2 +- pkg/sentry/kernel/task.go | 2 +- pkg/sentry/kernel/task_acct.go | 2 +- pkg/sentry/kernel/task_block.go | 2 +- pkg/sentry/kernel/task_clone.go | 2 +- pkg/sentry/kernel/task_context.go | 2 +- pkg/sentry/kernel/task_exec.go | 2 +- pkg/sentry/kernel/task_exit.go | 2 +- pkg/sentry/kernel/task_futex.go | 2 +- pkg/sentry/kernel/task_identity.go | 2 +- pkg/sentry/kernel/task_log.go | 2 +- pkg/sentry/kernel/task_net.go | 2 +- pkg/sentry/kernel/task_run.go | 2 +- pkg/sentry/kernel/task_sched.go | 2 +- pkg/sentry/kernel/task_signals.go | 2 +- pkg/sentry/kernel/task_start.go | 2 +- pkg/sentry/kernel/task_stop.go | 2 +- pkg/sentry/kernel/task_syscall.go | 2 +- pkg/sentry/kernel/task_test.go | 2 +- pkg/sentry/kernel/task_usermem.go | 2 +- pkg/sentry/kernel/thread_group.go | 2 +- pkg/sentry/kernel/threads.go | 2 +- pkg/sentry/kernel/time/context.go | 2 +- pkg/sentry/kernel/time/time.go | 2 +- pkg/sentry/kernel/timekeeper.go | 2 +- pkg/sentry/kernel/timekeeper_state.go | 2 +- pkg/sentry/kernel/timekeeper_test.go | 2 +- pkg/sentry/kernel/uncaught_signal.proto | 2 +- pkg/sentry/kernel/uts_namespace.go | 2 +- pkg/sentry/kernel/vdso.go | 2 +- pkg/sentry/kernel/version.go | 2 +- pkg/sentry/limits/context.go | 2 +- pkg/sentry/limits/limits.go | 2 +- pkg/sentry/limits/limits_test.go | 2 +- pkg/sentry/limits/linux.go | 2 +- pkg/sentry/loader/elf.go | 2 +- pkg/sentry/loader/interpreter.go | 2 +- pkg/sentry/loader/loader.go | 2 +- pkg/sentry/loader/vdso.go | 2 +- pkg/sentry/loader/vdso_state.go | 2 +- pkg/sentry/memmap/mapping_set.go | 2 +- pkg/sentry/memmap/mapping_set_test.go | 2 +- pkg/sentry/memmap/memmap.go | 2 +- pkg/sentry/memutil/memutil.go | 2 +- pkg/sentry/memutil/memutil_unsafe.go | 2 +- pkg/sentry/mm/address_space.go | 2 +- pkg/sentry/mm/aio_context.go | 2 +- pkg/sentry/mm/aio_context_state.go | 2 +- pkg/sentry/mm/debug.go | 2 +- pkg/sentry/mm/io.go | 2 +- pkg/sentry/mm/lifecycle.go | 2 +- pkg/sentry/mm/metadata.go | 2 +- pkg/sentry/mm/mm.go | 2 +- pkg/sentry/mm/mm_test.go | 2 +- pkg/sentry/mm/pma.go | 2 +- pkg/sentry/mm/procfs.go | 2 +- pkg/sentry/mm/save_restore.go | 2 +- pkg/sentry/mm/shm.go | 2 +- pkg/sentry/mm/special_mappable.go | 2 +- pkg/sentry/mm/syscalls.go | 2 +- pkg/sentry/mm/vma.go | 2 +- pkg/sentry/pgalloc/context.go | 2 +- pkg/sentry/pgalloc/pgalloc.go | 2 +- pkg/sentry/pgalloc/pgalloc_test.go | 2 +- pkg/sentry/pgalloc/pgalloc_unsafe.go | 2 +- pkg/sentry/pgalloc/save_restore.go | 2 +- pkg/sentry/platform/context.go | 2 +- pkg/sentry/platform/interrupt/interrupt.go | 2 +- pkg/sentry/platform/interrupt/interrupt_test.go | 2 +- pkg/sentry/platform/kvm/address_space.go | 2 +- pkg/sentry/platform/kvm/allocator.go | 2 +- pkg/sentry/platform/kvm/bluepill.go | 2 +- pkg/sentry/platform/kvm/bluepill_amd64.go | 2 +- pkg/sentry/platform/kvm/bluepill_amd64.s | 2 +- pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/bluepill_fault.go | 2 +- pkg/sentry/platform/kvm/bluepill_unsafe.go | 2 +- pkg/sentry/platform/kvm/context.go | 2 +- pkg/sentry/platform/kvm/kvm.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/kvm_const.go | 2 +- pkg/sentry/platform/kvm/kvm_test.go | 2 +- pkg/sentry/platform/kvm/machine.go | 2 +- pkg/sentry/platform/kvm/machine_amd64.go | 2 +- pkg/sentry/platform/kvm/machine_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/machine_unsafe.go | 2 +- pkg/sentry/platform/kvm/physical_map.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil_amd64.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil_amd64.s | 2 +- pkg/sentry/platform/kvm/virtual_map.go | 2 +- pkg/sentry/platform/kvm/virtual_map_test.go | 2 +- pkg/sentry/platform/mmap_min_addr.go | 2 +- pkg/sentry/platform/platform.go | 2 +- pkg/sentry/platform/procid/procid.go | 2 +- pkg/sentry/platform/procid/procid_amd64.s | 2 +- pkg/sentry/platform/procid/procid_arm64.s | 2 +- pkg/sentry/platform/procid/procid_net_test.go | 2 +- pkg/sentry/platform/procid/procid_test.go | 2 +- pkg/sentry/platform/ptrace/ptrace.go | 2 +- pkg/sentry/platform/ptrace/ptrace_unsafe.go | 2 +- pkg/sentry/platform/ptrace/stub_amd64.s | 2 +- pkg/sentry/platform/ptrace/stub_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess.go | 2 +- pkg/sentry/platform/ptrace/subprocess_amd64.go | 2 +- pkg/sentry/platform/ptrace/subprocess_linux.go | 2 +- pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess_unsafe.go | 2 +- pkg/sentry/platform/ring0/defs.go | 2 +- pkg/sentry/platform/ring0/defs_amd64.go | 2 +- pkg/sentry/platform/ring0/entry_amd64.go | 2 +- pkg/sentry/platform/ring0/entry_amd64.s | 2 +- pkg/sentry/platform/ring0/gen_offsets/main.go | 2 +- pkg/sentry/platform/ring0/kernel.go | 2 +- pkg/sentry/platform/ring0/kernel_amd64.go | 2 +- pkg/sentry/platform/ring0/kernel_unsafe.go | 2 +- pkg/sentry/platform/ring0/lib_amd64.go | 2 +- pkg/sentry/platform/ring0/lib_amd64.s | 2 +- pkg/sentry/platform/ring0/offsets_amd64.go | 2 +- pkg/sentry/platform/ring0/pagetables/allocator.go | 2 +- pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_test.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_x86.go | 2 +- pkg/sentry/platform/ring0/pagetables/pcids_x86.go | 2 +- pkg/sentry/platform/ring0/pagetables/walker_amd64.go | 2 +- pkg/sentry/platform/ring0/ring0.go | 2 +- pkg/sentry/platform/ring0/x86.go | 2 +- pkg/sentry/platform/safecopy/atomic_amd64.s | 2 +- pkg/sentry/platform/safecopy/safecopy.go | 2 +- pkg/sentry/platform/safecopy/safecopy_test.go | 2 +- pkg/sentry/platform/safecopy/safecopy_unsafe.go | 2 +- pkg/sentry/platform/safecopy/sighandler_amd64.s | 2 +- pkg/sentry/platform/safecopy/sighandler_arm64.s | 2 +- pkg/sentry/safemem/block_unsafe.go | 2 +- pkg/sentry/safemem/io.go | 2 +- pkg/sentry/safemem/io_test.go | 2 +- pkg/sentry/safemem/safemem.go | 2 +- pkg/sentry/safemem/seq_test.go | 2 +- pkg/sentry/safemem/seq_unsafe.go | 2 +- pkg/sentry/sighandling/sighandling.go | 2 +- pkg/sentry/sighandling/sighandling_unsafe.go | 2 +- pkg/sentry/socket/control/control.go | 2 +- pkg/sentry/socket/epsocket/device.go | 2 +- pkg/sentry/socket/epsocket/epsocket.go | 2 +- pkg/sentry/socket/epsocket/provider.go | 2 +- pkg/sentry/socket/epsocket/save_restore.go | 2 +- pkg/sentry/socket/epsocket/stack.go | 2 +- pkg/sentry/socket/hostinet/device.go | 2 +- pkg/sentry/socket/hostinet/hostinet.go | 2 +- pkg/sentry/socket/hostinet/save_restore.go | 2 +- pkg/sentry/socket/hostinet/socket.go | 2 +- pkg/sentry/socket/hostinet/socket_unsafe.go | 2 +- pkg/sentry/socket/hostinet/stack.go | 2 +- pkg/sentry/socket/netlink/message.go | 2 +- pkg/sentry/socket/netlink/port/port.go | 2 +- pkg/sentry/socket/netlink/port/port_test.go | 2 +- pkg/sentry/socket/netlink/provider.go | 2 +- pkg/sentry/socket/netlink/route/protocol.go | 2 +- pkg/sentry/socket/netlink/socket.go | 2 +- pkg/sentry/socket/rpcinet/conn/conn.go | 2 +- pkg/sentry/socket/rpcinet/device.go | 2 +- pkg/sentry/socket/rpcinet/notifier/notifier.go | 2 +- pkg/sentry/socket/rpcinet/rpcinet.go | 2 +- pkg/sentry/socket/rpcinet/socket.go | 2 +- pkg/sentry/socket/rpcinet/stack.go | 2 +- pkg/sentry/socket/rpcinet/stack_unsafe.go | 2 +- pkg/sentry/socket/socket.go | 2 +- pkg/sentry/socket/unix/device.go | 2 +- pkg/sentry/socket/unix/io.go | 2 +- pkg/sentry/socket/unix/transport/connectioned.go | 2 +- pkg/sentry/socket/unix/transport/connectioned_state.go | 2 +- pkg/sentry/socket/unix/transport/connectionless.go | 2 +- pkg/sentry/socket/unix/transport/queue.go | 2 +- pkg/sentry/socket/unix/transport/unix.go | 2 +- pkg/sentry/socket/unix/unix.go | 2 +- pkg/sentry/state/state.go | 2 +- pkg/sentry/state/state_metadata.go | 2 +- pkg/sentry/state/state_unsafe.go | 2 +- pkg/sentry/strace/capability.go | 2 +- pkg/sentry/strace/clone.go | 2 +- pkg/sentry/strace/futex.go | 2 +- pkg/sentry/strace/linux64.go | 2 +- pkg/sentry/strace/open.go | 2 +- pkg/sentry/strace/poll.go | 2 +- pkg/sentry/strace/ptrace.go | 2 +- pkg/sentry/strace/signal.go | 2 +- pkg/sentry/strace/socket.go | 2 +- pkg/sentry/strace/strace.go | 2 +- pkg/sentry/strace/strace.proto | 2 +- pkg/sentry/strace/syscalls.go | 2 +- pkg/sentry/syscalls/epoll.go | 2 +- pkg/sentry/syscalls/linux/error.go | 2 +- pkg/sentry/syscalls/linux/flags.go | 2 +- pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sigset.go | 2 +- pkg/sentry/syscalls/linux/sys_aio.go | 2 +- pkg/sentry/syscalls/linux/sys_capability.go | 2 +- pkg/sentry/syscalls/linux/sys_epoll.go | 2 +- pkg/sentry/syscalls/linux/sys_eventfd.go | 2 +- pkg/sentry/syscalls/linux/sys_file.go | 2 +- pkg/sentry/syscalls/linux/sys_futex.go | 2 +- pkg/sentry/syscalls/linux/sys_getdents.go | 2 +- pkg/sentry/syscalls/linux/sys_identity.go | 2 +- pkg/sentry/syscalls/linux/sys_inotify.go | 2 +- pkg/sentry/syscalls/linux/sys_lseek.go | 2 +- pkg/sentry/syscalls/linux/sys_mmap.go | 2 +- pkg/sentry/syscalls/linux/sys_mount.go | 2 +- pkg/sentry/syscalls/linux/sys_pipe.go | 2 +- pkg/sentry/syscalls/linux/sys_poll.go | 2 +- pkg/sentry/syscalls/linux/sys_prctl.go | 2 +- pkg/sentry/syscalls/linux/sys_random.go | 2 +- pkg/sentry/syscalls/linux/sys_read.go | 2 +- pkg/sentry/syscalls/linux/sys_rlimit.go | 2 +- pkg/sentry/syscalls/linux/sys_rusage.go | 2 +- pkg/sentry/syscalls/linux/sys_sched.go | 2 +- pkg/sentry/syscalls/linux/sys_seccomp.go | 2 +- pkg/sentry/syscalls/linux/sys_sem.go | 2 +- pkg/sentry/syscalls/linux/sys_shm.go | 2 +- pkg/sentry/syscalls/linux/sys_signal.go | 2 +- pkg/sentry/syscalls/linux/sys_socket.go | 2 +- pkg/sentry/syscalls/linux/sys_stat.go | 2 +- pkg/sentry/syscalls/linux/sys_sync.go | 2 +- pkg/sentry/syscalls/linux/sys_sysinfo.go | 2 +- pkg/sentry/syscalls/linux/sys_syslog.go | 2 +- pkg/sentry/syscalls/linux/sys_thread.go | 2 +- pkg/sentry/syscalls/linux/sys_time.go | 2 +- pkg/sentry/syscalls/linux/sys_timer.go | 2 +- pkg/sentry/syscalls/linux/sys_timerfd.go | 2 +- pkg/sentry/syscalls/linux/sys_tls.go | 2 +- pkg/sentry/syscalls/linux/sys_utsname.go | 2 +- pkg/sentry/syscalls/linux/sys_write.go | 2 +- pkg/sentry/syscalls/linux/timespec.go | 2 +- pkg/sentry/syscalls/syscalls.go | 2 +- pkg/sentry/time/calibrated_clock.go | 2 +- pkg/sentry/time/calibrated_clock_test.go | 2 +- pkg/sentry/time/clock_id.go | 2 +- pkg/sentry/time/clocks.go | 2 +- pkg/sentry/time/muldiv_amd64.s | 2 +- pkg/sentry/time/muldiv_arm64.s | 2 +- pkg/sentry/time/parameters.go | 2 +- pkg/sentry/time/parameters_test.go | 2 +- pkg/sentry/time/sampler.go | 2 +- pkg/sentry/time/sampler_test.go | 2 +- pkg/sentry/time/sampler_unsafe.go | 2 +- pkg/sentry/time/tsc_amd64.s | 2 +- pkg/sentry/time/tsc_arm64.s | 2 +- pkg/sentry/unimpl/events.go | 2 +- pkg/sentry/unimpl/unimplemented_syscall.proto | 2 +- pkg/sentry/uniqueid/context.go | 2 +- pkg/sentry/usage/cpu.go | 2 +- pkg/sentry/usage/io.go | 2 +- pkg/sentry/usage/memory.go | 2 +- pkg/sentry/usage/memory_unsafe.go | 2 +- pkg/sentry/usage/usage.go | 2 +- pkg/sentry/usermem/access_type.go | 2 +- pkg/sentry/usermem/addr.go | 2 +- pkg/sentry/usermem/addr_range_seq_test.go | 2 +- pkg/sentry/usermem/addr_range_seq_unsafe.go | 2 +- pkg/sentry/usermem/bytes_io.go | 2 +- pkg/sentry/usermem/bytes_io_unsafe.go | 2 +- pkg/sentry/usermem/usermem.go | 2 +- pkg/sentry/usermem/usermem_arm64.go | 2 +- pkg/sentry/usermem/usermem_test.go | 2 +- pkg/sentry/usermem/usermem_unsafe.go | 2 +- pkg/sentry/usermem/usermem_x86.go | 2 +- pkg/sentry/watchdog/watchdog.go | 2 +- pkg/sleep/commit_amd64.s | 2 +- pkg/sleep/commit_asm.go | 2 +- pkg/sleep/commit_noasm.go | 2 +- pkg/sleep/empty.s | 2 +- pkg/sleep/sleep_test.go | 2 +- pkg/sleep/sleep_unsafe.go | 2 +- pkg/state/decode.go | 2 +- pkg/state/encode.go | 2 +- pkg/state/encode_unsafe.go | 2 +- pkg/state/map.go | 2 +- pkg/state/object.proto | 2 +- pkg/state/printer.go | 2 +- pkg/state/state.go | 2 +- pkg/state/state_test.go | 2 +- pkg/state/statefile/statefile.go | 2 +- pkg/state/statefile/statefile_test.go | 2 +- pkg/state/stats.go | 2 +- pkg/syserr/host_linux.go | 2 +- pkg/syserr/netstack.go | 2 +- pkg/syserr/syserr.go | 2 +- pkg/syserror/syserror.go | 2 +- pkg/syserror/syserror_test.go | 2 +- pkg/tcpip/adapters/gonet/gonet.go | 2 +- pkg/tcpip/adapters/gonet/gonet_test.go | 2 +- pkg/tcpip/buffer/prependable.go | 2 +- pkg/tcpip/buffer/view.go | 2 +- pkg/tcpip/buffer/view_test.go | 2 +- pkg/tcpip/checker/checker.go | 2 +- pkg/tcpip/hash/jenkins/jenkins.go | 2 +- pkg/tcpip/hash/jenkins/jenkins_test.go | 2 +- pkg/tcpip/header/arp.go | 2 +- pkg/tcpip/header/checksum.go | 2 +- pkg/tcpip/header/eth.go | 2 +- pkg/tcpip/header/gue.go | 2 +- pkg/tcpip/header/icmpv4.go | 2 +- pkg/tcpip/header/icmpv6.go | 2 +- pkg/tcpip/header/interfaces.go | 2 +- pkg/tcpip/header/ipv4.go | 2 +- pkg/tcpip/header/ipv6.go | 2 +- pkg/tcpip/header/ipv6_fragment.go | 2 +- pkg/tcpip/header/ipversion_test.go | 2 +- pkg/tcpip/header/tcp.go | 2 +- pkg/tcpip/header/tcp_test.go | 2 +- pkg/tcpip/header/udp.go | 2 +- pkg/tcpip/link/channel/channel.go | 2 +- pkg/tcpip/link/fdbased/endpoint.go | 2 +- pkg/tcpip/link/fdbased/endpoint_test.go | 2 +- pkg/tcpip/link/fdbased/endpoint_unsafe.go | 2 +- pkg/tcpip/link/fdbased/mmap.go | 2 +- pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go | 2 +- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/muxed/injectable.go | 2 +- pkg/tcpip/link/muxed/injectable_test.go | 2 +- pkg/tcpip/link/rawfile/blockingpoll_amd64.s | 2 +- pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go | 2 +- pkg/tcpip/link/rawfile/blockingpoll_unsafe.go | 2 +- pkg/tcpip/link/rawfile/errors.go | 2 +- pkg/tcpip/link/rawfile/rawfile_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe_test.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/rx.go | 2 +- pkg/tcpip/link/sharedmem/pipe/tx.go | 2 +- pkg/tcpip/link/sharedmem/queue/queue_test.go | 2 +- pkg/tcpip/link/sharedmem/queue/rx.go | 2 +- pkg/tcpip/link/sharedmem/queue/tx.go | 2 +- pkg/tcpip/link/sharedmem/rx.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_test.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/tx.go | 2 +- pkg/tcpip/link/sniffer/pcap.go | 2 +- pkg/tcpip/link/sniffer/sniffer.go | 2 +- pkg/tcpip/link/tun/tun_unsafe.go | 2 +- pkg/tcpip/link/waitable/waitable.go | 2 +- pkg/tcpip/link/waitable/waitable_test.go | 2 +- pkg/tcpip/network/arp/arp.go | 2 +- pkg/tcpip/network/arp/arp_test.go | 2 +- pkg/tcpip/network/fragmentation/frag_heap.go | 2 +- pkg/tcpip/network/fragmentation/frag_heap_test.go | 2 +- pkg/tcpip/network/fragmentation/fragmentation.go | 2 +- pkg/tcpip/network/fragmentation/fragmentation_test.go | 2 +- pkg/tcpip/network/fragmentation/reassembler.go | 2 +- pkg/tcpip/network/fragmentation/reassembler_test.go | 2 +- pkg/tcpip/network/hash/hash.go | 2 +- pkg/tcpip/network/ip_test.go | 2 +- pkg/tcpip/network/ipv4/icmp.go | 2 +- pkg/tcpip/network/ipv4/ipv4.go | 2 +- pkg/tcpip/network/ipv4/ipv4_test.go | 2 +- pkg/tcpip/network/ipv6/icmp.go | 2 +- pkg/tcpip/network/ipv6/icmp_test.go | 2 +- pkg/tcpip/network/ipv6/ipv6.go | 2 +- pkg/tcpip/ports/ports.go | 2 +- pkg/tcpip/ports/ports_test.go | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 2 +- pkg/tcpip/seqnum/seqnum.go | 2 +- pkg/tcpip/stack/linkaddrcache.go | 2 +- pkg/tcpip/stack/linkaddrcache_test.go | 2 +- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/stack/registration.go | 2 +- pkg/tcpip/stack/route.go | 2 +- pkg/tcpip/stack/stack.go | 2 +- pkg/tcpip/stack/stack_global_state.go | 2 +- pkg/tcpip/stack/stack_test.go | 2 +- pkg/tcpip/stack/transport_demuxer.go | 2 +- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/tcpip.go | 2 +- pkg/tcpip/tcpip_test.go | 2 +- pkg/tcpip/time.s | 2 +- pkg/tcpip/time_unsafe.go | 2 +- pkg/tcpip/transport/icmp/endpoint.go | 2 +- pkg/tcpip/transport/icmp/endpoint_state.go | 2 +- pkg/tcpip/transport/icmp/protocol.go | 2 +- pkg/tcpip/transport/raw/raw.go | 2 +- pkg/tcpip/transport/raw/state.go | 2 +- pkg/tcpip/transport/tcp/accept.go | 2 +- pkg/tcpip/transport/tcp/connect.go | 2 +- pkg/tcpip/transport/tcp/cubic.go | 2 +- pkg/tcpip/transport/tcp/dual_stack_test.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 2 +- pkg/tcpip/transport/tcp/endpoint_state.go | 2 +- pkg/tcpip/transport/tcp/forwarder.go | 2 +- pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/tcp/rcv.go | 2 +- pkg/tcpip/transport/tcp/reno.go | 2 +- pkg/tcpip/transport/tcp/sack.go | 2 +- pkg/tcpip/transport/tcp/sack_scoreboard.go | 2 +- pkg/tcpip/transport/tcp/sack_scoreboard_test.go | 2 +- pkg/tcpip/transport/tcp/segment.go | 2 +- pkg/tcpip/transport/tcp/segment_heap.go | 2 +- pkg/tcpip/transport/tcp/segment_queue.go | 2 +- pkg/tcpip/transport/tcp/segment_state.go | 2 +- pkg/tcpip/transport/tcp/snd.go | 2 +- pkg/tcpip/transport/tcp/snd_state.go | 2 +- pkg/tcpip/transport/tcp/tcp_sack_test.go | 2 +- pkg/tcpip/transport/tcp/tcp_test.go | 2 +- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 2 +- pkg/tcpip/transport/tcp/testing/context/context.go | 2 +- pkg/tcpip/transport/tcp/timer.go | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 2 +- pkg/tcpip/transport/udp/endpoint_state.go | 2 +- pkg/tcpip/transport/udp/forwarder.go | 2 +- pkg/tcpip/transport/udp/protocol.go | 2 +- pkg/tcpip/transport/udp/udp_test.go | 2 +- pkg/tmutex/tmutex.go | 2 +- pkg/tmutex/tmutex_test.go | 2 +- pkg/unet/unet.go | 2 +- pkg/unet/unet_test.go | 2 +- pkg/unet/unet_unsafe.go | 2 +- pkg/urpc/urpc.go | 2 +- pkg/urpc/urpc_test.go | 2 +- pkg/waiter/waiter.go | 2 +- pkg/waiter/waiter_test.go | 2 +- runsc/boot/compat.go | 2 +- runsc/boot/compat_amd64.go | 2 +- runsc/boot/compat_test.go | 2 +- runsc/boot/config.go | 2 +- runsc/boot/controller.go | 2 +- runsc/boot/debug.go | 2 +- runsc/boot/events.go | 2 +- runsc/boot/fds.go | 2 +- runsc/boot/filter/config.go | 2 +- runsc/boot/filter/extra_filters.go | 2 +- runsc/boot/filter/extra_filters_msan.go | 2 +- runsc/boot/filter/extra_filters_race.go | 2 +- runsc/boot/filter/filter.go | 2 +- runsc/boot/fs.go | 2 +- runsc/boot/limits.go | 2 +- runsc/boot/loader.go | 2 +- runsc/boot/loader_test.go | 2 +- runsc/boot/network.go | 2 +- runsc/boot/strace.go | 2 +- runsc/cgroup/cgroup.go | 2 +- runsc/cgroup/cgroup_test.go | 2 +- runsc/cmd/boot.go | 2 +- runsc/cmd/capability.go | 2 +- runsc/cmd/capability_test.go | 2 +- runsc/cmd/checkpoint.go | 2 +- runsc/cmd/chroot.go | 2 +- runsc/cmd/cmd.go | 2 +- runsc/cmd/create.go | 2 +- runsc/cmd/debug.go | 2 +- runsc/cmd/delete.go | 2 +- runsc/cmd/delete_test.go | 2 +- runsc/cmd/do.go | 2 +- runsc/cmd/events.go | 2 +- runsc/cmd/exec.go | 2 +- runsc/cmd/exec_test.go | 2 +- runsc/cmd/gofer.go | 2 +- runsc/cmd/gofer_test.go | 2 +- runsc/cmd/kill.go | 2 +- runsc/cmd/list.go | 2 +- runsc/cmd/path.go | 2 +- runsc/cmd/pause.go | 2 +- runsc/cmd/ps.go | 2 +- runsc/cmd/restore.go | 2 +- runsc/cmd/resume.go | 2 +- runsc/cmd/run.go | 2 +- runsc/cmd/spec.go | 2 +- runsc/cmd/start.go | 2 +- runsc/cmd/state.go | 2 +- runsc/cmd/wait.go | 2 +- runsc/console/console.go | 2 +- runsc/container/console_test.go | 2 +- runsc/container/container.go | 2 +- runsc/container/container_test.go | 2 +- runsc/container/hook.go | 2 +- runsc/container/multi_container_test.go | 2 +- runsc/container/shared_volume_test.go | 2 +- runsc/container/status.go | 2 +- runsc/container/test_app.go | 2 +- runsc/fsgofer/filter/config.go | 2 +- runsc/fsgofer/filter/extra_filters.go | 2 +- runsc/fsgofer/filter/extra_filters_msan.go | 2 +- runsc/fsgofer/filter/extra_filters_race.go | 2 +- runsc/fsgofer/filter/filter.go | 2 +- runsc/fsgofer/fsgofer.go | 2 +- runsc/fsgofer/fsgofer_test.go | 2 +- runsc/fsgofer/fsgofer_unsafe.go | 2 +- runsc/main.go | 2 +- runsc/sandbox/network.go | 2 +- runsc/sandbox/network_unsafe.go | 2 +- runsc/sandbox/sandbox.go | 2 +- runsc/specutils/fs.go | 2 +- runsc/specutils/namespace.go | 2 +- runsc/specutils/specutils.go | 2 +- runsc/specutils/specutils_test.go | 2 +- runsc/test/image/image.go | 2 +- runsc/test/image/image_test.go | 2 +- runsc/test/image/mysql.sql | 2 +- runsc/test/image/ruby.rb | 2 +- runsc/test/image/ruby.sh | 2 +- runsc/test/install.sh | 2 +- runsc/test/integration/exec_test.go | 2 +- runsc/test/integration/integration.go | 2 +- runsc/test/integration/integration_test.go | 2 +- runsc/test/root/cgroup_test.go | 2 +- runsc/test/root/chroot_test.go | 2 +- runsc/test/root/crictl_test.go | 2 +- runsc/test/root/root.go | 2 +- runsc/test/root/testdata/busybox.go | 2 +- runsc/test/root/testdata/containerd_config.go | 2 +- runsc/test/root/testdata/httpd.go | 2 +- runsc/test/root/testdata/httpd_mount_paths.go | 2 +- runsc/test/root/testdata/sandbox.go | 2 +- runsc/test/testutil/crictl.go | 2 +- runsc/test/testutil/docker.go | 2 +- runsc/test/testutil/testutil.go | 2 +- runsc/test/testutil/testutil_race.go | 2 +- runsc/tools/dockercfg/dockercfg.go | 2 +- runsc/version.go | 2 +- test/syscalls/gtest/gtest.go | 2 +- test/syscalls/linux/32bit.cc | 2 +- test/syscalls/linux/accept_bind.cc | 2 +- test/syscalls/linux/accept_bind_stream.cc | 2 +- test/syscalls/linux/access.cc | 2 +- test/syscalls/linux/affinity.cc | 2 +- test/syscalls/linux/aio.cc | 2 +- test/syscalls/linux/alarm.cc | 2 +- test/syscalls/linux/arch_prctl.cc | 2 +- test/syscalls/linux/bad.cc | 2 +- test/syscalls/linux/base_poll_test.cc | 2 +- test/syscalls/linux/base_poll_test.h | 2 +- test/syscalls/linux/bind.cc | 2 +- test/syscalls/linux/brk.cc | 2 +- test/syscalls/linux/chdir.cc | 2 +- test/syscalls/linux/chmod.cc | 2 +- test/syscalls/linux/chown.cc | 2 +- test/syscalls/linux/chroot.cc | 2 +- test/syscalls/linux/clock_getres.cc | 2 +- test/syscalls/linux/clock_gettime.cc | 2 +- test/syscalls/linux/clock_nanosleep.cc | 2 +- test/syscalls/linux/concurrency.cc | 2 +- test/syscalls/linux/creat.cc | 2 +- test/syscalls/linux/dev.cc | 2 +- test/syscalls/linux/dup.cc | 2 +- test/syscalls/linux/epoll.cc | 2 +- test/syscalls/linux/eventfd.cc | 2 +- test/syscalls/linux/exceptions.cc | 2 +- test/syscalls/linux/exec.cc | 2 +- test/syscalls/linux/exec.h | 2 +- test/syscalls/linux/exec_assert_closed_workload.cc | 2 +- test/syscalls/linux/exec_basic_workload.cc | 2 +- test/syscalls/linux/exec_binary.cc | 2 +- test/syscalls/linux/exec_proc_exe_workload.cc | 2 +- test/syscalls/linux/exec_state_workload.cc | 2 +- test/syscalls/linux/exit.cc | 2 +- test/syscalls/linux/exit_script.sh | 2 +- test/syscalls/linux/fadvise64.cc | 2 +- test/syscalls/linux/fallocate.cc | 2 +- test/syscalls/linux/fault.cc | 2 +- test/syscalls/linux/fchdir.cc | 2 +- test/syscalls/linux/fcntl.cc | 2 +- test/syscalls/linux/file_base.h | 2 +- test/syscalls/linux/flock.cc | 2 +- test/syscalls/linux/fork.cc | 2 +- test/syscalls/linux/fpsig_fork.cc | 2 +- test/syscalls/linux/fpsig_nested.cc | 2 +- test/syscalls/linux/fsync.cc | 2 +- test/syscalls/linux/futex.cc | 2 +- test/syscalls/linux/getcpu.cc | 2 +- test/syscalls/linux/getdents.cc | 2 +- test/syscalls/linux/getrandom.cc | 2 +- test/syscalls/linux/getrusage.cc | 2 +- test/syscalls/linux/inotify.cc | 2 +- test/syscalls/linux/ioctl.cc | 2 +- test/syscalls/linux/ip_socket_test_util.cc | 2 +- test/syscalls/linux/ip_socket_test_util.h | 2 +- test/syscalls/linux/itimer.cc | 2 +- test/syscalls/linux/kill.cc | 2 +- test/syscalls/linux/link.cc | 2 +- test/syscalls/linux/lseek.cc | 2 +- test/syscalls/linux/madvise.cc | 2 +- test/syscalls/linux/memfd.cc | 2 +- test/syscalls/linux/memory_accounting.cc | 2 +- test/syscalls/linux/mempolicy.cc | 2 +- test/syscalls/linux/mincore.cc | 2 +- test/syscalls/linux/mkdir.cc | 2 +- test/syscalls/linux/mknod.cc | 2 +- test/syscalls/linux/mlock.cc | 2 +- test/syscalls/linux/mmap.cc | 2 +- test/syscalls/linux/mount.cc | 2 +- test/syscalls/linux/mremap.cc | 2 +- test/syscalls/linux/msync.cc | 2 +- test/syscalls/linux/munmap.cc | 2 +- test/syscalls/linux/open.cc | 2 +- test/syscalls/linux/open_create.cc | 2 +- test/syscalls/linux/partial_bad_buffer.cc | 2 +- test/syscalls/linux/pause.cc | 2 +- test/syscalls/linux/pipe.cc | 2 +- test/syscalls/linux/poll.cc | 2 +- test/syscalls/linux/ppoll.cc | 2 +- test/syscalls/linux/prctl.cc | 2 +- test/syscalls/linux/prctl_setuid.cc | 2 +- test/syscalls/linux/pread64.cc | 2 +- test/syscalls/linux/preadv.cc | 2 +- test/syscalls/linux/preadv2.cc | 2 +- test/syscalls/linux/priority.cc | 2 +- test/syscalls/linux/priority_execve.cc | 2 +- test/syscalls/linux/proc.cc | 2 +- test/syscalls/linux/proc_net.cc | 2 +- test/syscalls/linux/proc_net_unix.cc | 2 +- test/syscalls/linux/proc_pid_smaps.cc | 2 +- test/syscalls/linux/proc_pid_uid_gid_map.cc | 2 +- test/syscalls/linux/pselect.cc | 2 +- test/syscalls/linux/ptrace.cc | 2 +- test/syscalls/linux/pty.cc | 2 +- test/syscalls/linux/pwrite64.cc | 2 +- test/syscalls/linux/pwritev2.cc | 2 +- test/syscalls/linux/raw_socket_ipv4.cc | 2 +- test/syscalls/linux/read.cc | 2 +- test/syscalls/linux/readv.cc | 2 +- test/syscalls/linux/readv_common.cc | 2 +- test/syscalls/linux/readv_common.h | 2 +- test/syscalls/linux/readv_socket.cc | 2 +- test/syscalls/linux/rename.cc | 2 +- test/syscalls/linux/rlimits.cc | 2 +- test/syscalls/linux/rtsignal.cc | 2 +- test/syscalls/linux/sched.cc | 2 +- test/syscalls/linux/sched_yield.cc | 2 +- test/syscalls/linux/seccomp.cc | 2 +- test/syscalls/linux/select.cc | 2 +- test/syscalls/linux/semaphore.cc | 2 +- test/syscalls/linux/sendfile.cc | 2 +- test/syscalls/linux/sendfile_socket.cc | 2 +- test/syscalls/linux/shm.cc | 2 +- test/syscalls/linux/sigaction.cc | 2 +- test/syscalls/linux/sigaltstack.cc | 2 +- test/syscalls/linux/sigaltstack_check.cc | 2 +- test/syscalls/linux/sigiret.cc | 2 +- test/syscalls/linux/sigprocmask.cc | 2 +- test/syscalls/linux/sigstop.cc | 2 +- test/syscalls/linux/sigtimedwait.cc | 2 +- test/syscalls/linux/socket_abstract.cc | 2 +- test/syscalls/linux/socket_blocking.cc | 2 +- test/syscalls/linux/socket_blocking.h | 2 +- test/syscalls/linux/socket_filesystem.cc | 2 +- test/syscalls/linux/socket_generic.cc | 2 +- test/syscalls/linux/socket_generic.h | 2 +- test/syscalls/linux/socket_inet_loopback.cc | 2 +- test/syscalls/linux/socket_ip_loopback_blocking.cc | 2 +- test/syscalls/linux/socket_ip_tcp_generic.cc | 2 +- test/syscalls/linux/socket_ip_tcp_generic.h | 2 +- test/syscalls/linux/socket_ip_tcp_generic_loopback.cc | 2 +- test/syscalls/linux/socket_ip_tcp_loopback.cc | 2 +- test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc | 2 +- test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc | 2 +- test/syscalls/linux/socket_ip_tcp_udp_generic.cc | 2 +- test/syscalls/linux/socket_ip_udp_generic.cc | 2 +- test/syscalls/linux/socket_ip_udp_generic.h | 2 +- test/syscalls/linux/socket_ip_udp_loopback.cc | 2 +- test/syscalls/linux/socket_ip_udp_loopback_blocking.cc | 2 +- test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc | 2 +- .../syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc | 2 +- test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h | 2 +- .../linux/socket_ipv4_tcp_unbound_external_networking_test.cc | 2 +- test/syscalls/linux/socket_ipv4_udp_unbound.cc | 2 +- test/syscalls/linux/socket_ipv4_udp_unbound.h | 2 +- .../syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc | 2 +- test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h | 2 +- .../linux/socket_ipv4_udp_unbound_external_networking_test.cc | 2 +- test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc | 2 +- test/syscalls/linux/socket_netdevice.cc | 2 +- test/syscalls/linux/socket_netlink_route.cc | 2 +- test/syscalls/linux/socket_netlink_util.cc | 2 +- test/syscalls/linux/socket_netlink_util.h | 2 +- test/syscalls/linux/socket_non_blocking.cc | 2 +- test/syscalls/linux/socket_non_blocking.h | 2 +- test/syscalls/linux/socket_non_stream.cc | 2 +- test/syscalls/linux/socket_non_stream.h | 2 +- test/syscalls/linux/socket_non_stream_blocking.cc | 2 +- test/syscalls/linux/socket_non_stream_blocking.h | 2 +- test/syscalls/linux/socket_stream.cc | 2 +- test/syscalls/linux/socket_stream.h | 2 +- test/syscalls/linux/socket_stream_blocking.cc | 2 +- test/syscalls/linux/socket_stream_blocking.h | 2 +- test/syscalls/linux/socket_stream_nonblock.cc | 2 +- test/syscalls/linux/socket_stream_nonblock.h | 2 +- test/syscalls/linux/socket_test_util.cc | 2 +- test/syscalls/linux/socket_test_util.h | 2 +- test/syscalls/linux/socket_unix.cc | 2 +- test/syscalls/linux/socket_unix.h | 2 +- test/syscalls/linux/socket_unix_abstract.cc | 2 +- test/syscalls/linux/socket_unix_abstract_nonblock.cc | 2 +- test/syscalls/linux/socket_unix_blocking_local.cc | 2 +- test/syscalls/linux/socket_unix_dgram.cc | 2 +- test/syscalls/linux/socket_unix_dgram.h | 2 +- test/syscalls/linux/socket_unix_dgram_local.cc | 2 +- test/syscalls/linux/socket_unix_dgram_non_blocking.cc | 2 +- test/syscalls/linux/socket_unix_domain.cc | 2 +- test/syscalls/linux/socket_unix_filesystem.cc | 2 +- test/syscalls/linux/socket_unix_filesystem_nonblock.cc | 2 +- test/syscalls/linux/socket_unix_non_stream.cc | 2 +- test/syscalls/linux/socket_unix_non_stream.h | 2 +- test/syscalls/linux/socket_unix_non_stream_blocking_local.cc | 2 +- test/syscalls/linux/socket_unix_pair.cc | 2 +- test/syscalls/linux/socket_unix_pair_nonblock.cc | 2 +- test/syscalls/linux/socket_unix_seqpacket.cc | 2 +- test/syscalls/linux/socket_unix_seqpacket.h | 2 +- test/syscalls/linux/socket_unix_seqpacket_local.cc | 2 +- test/syscalls/linux/socket_unix_stream.cc | 2 +- test/syscalls/linux/socket_unix_stream_blocking_local.cc | 2 +- test/syscalls/linux/socket_unix_stream_local.cc | 2 +- test/syscalls/linux/socket_unix_stream_nonblock_local.cc | 2 +- test/syscalls/linux/socket_unix_unbound_abstract.cc | 2 +- test/syscalls/linux/socket_unix_unbound_dgram.cc | 2 +- test/syscalls/linux/socket_unix_unbound_filesystem.cc | 2 +- test/syscalls/linux/socket_unix_unbound_seqpacket.cc | 2 +- test/syscalls/linux/socket_unix_unbound_stream.cc | 2 +- test/syscalls/linux/stat.cc | 2 +- test/syscalls/linux/stat_times.cc | 2 +- test/syscalls/linux/statfs.cc | 2 +- test/syscalls/linux/sticky.cc | 2 +- test/syscalls/linux/symlink.cc | 2 +- test/syscalls/linux/sync.cc | 2 +- test/syscalls/linux/sync_file_range.cc | 2 +- test/syscalls/linux/sysinfo.cc | 2 +- test/syscalls/linux/syslog.cc | 2 +- test/syscalls/linux/sysret.cc | 2 +- test/syscalls/linux/tcp_socket.cc | 2 +- test/syscalls/linux/temp_umask.h | 2 +- test/syscalls/linux/tgkill.cc | 2 +- test/syscalls/linux/time.cc | 2 +- test/syscalls/linux/timerfd.cc | 2 +- test/syscalls/linux/timers.cc | 2 +- test/syscalls/linux/tkill.cc | 2 +- test/syscalls/linux/truncate.cc | 2 +- test/syscalls/linux/udp_bind.cc | 2 +- test/syscalls/linux/udp_socket.cc | 2 +- test/syscalls/linux/uidgid.cc | 2 +- test/syscalls/linux/uname.cc | 2 +- test/syscalls/linux/unix_domain_socket_test_util.cc | 2 +- test/syscalls/linux/unix_domain_socket_test_util.h | 2 +- test/syscalls/linux/unlink.cc | 2 +- test/syscalls/linux/unshare.cc | 2 +- test/syscalls/linux/utimes.cc | 2 +- test/syscalls/linux/vdso.cc | 2 +- test/syscalls/linux/vdso_clock_gettime.cc | 2 +- test/syscalls/linux/vfork.cc | 2 +- test/syscalls/linux/vsyscall.cc | 2 +- test/syscalls/linux/wait.cc | 2 +- test/syscalls/linux/write.cc | 2 +- test/syscalls/syscall_test_runner.go | 2 +- test/syscalls/syscall_test_runner.sh | 2 +- test/util/capability_util.cc | 2 +- test/util/capability_util.h | 2 +- test/util/cleanup.h | 2 +- test/util/epoll_util.cc | 2 +- test/util/epoll_util.h | 2 +- test/util/eventfd_util.h | 2 +- test/util/file_descriptor.h | 2 +- test/util/fs_util.cc | 2 +- test/util/fs_util.h | 2 +- test/util/fs_util_test.cc | 2 +- test/util/logging.cc | 2 +- test/util/logging.h | 2 +- test/util/memory_util.h | 2 +- test/util/mount_util.h | 2 +- test/util/multiprocess_util.cc | 2 +- test/util/multiprocess_util.h | 2 +- test/util/posix_error.cc | 2 +- test/util/posix_error.h | 2 +- test/util/posix_error_test.cc | 2 +- test/util/proc_util.cc | 2 +- test/util/proc_util.h | 2 +- test/util/proc_util_test.cc | 2 +- test/util/rlimit_util.cc | 2 +- test/util/rlimit_util.h | 2 +- test/util/save_util.cc | 2 +- test/util/save_util.h | 2 +- test/util/signal_util.cc | 2 +- test/util/signal_util.h | 2 +- test/util/temp_path.cc | 2 +- test/util/temp_path.h | 2 +- test/util/test_main.cc | 2 +- test/util/test_util.cc | 2 +- test/util/test_util.h | 2 +- test/util/test_util_test.cc | 2 +- test/util/thread_util.h | 2 +- test/util/timer_util.cc | 2 +- test/util/timer_util.h | 2 +- third_party/gvsync/atomicptr_unsafe.go | 2 +- third_party/gvsync/atomicptrtest/atomicptr_test.go | 2 +- third_party/gvsync/downgradable_rwmutex_test.go | 2 +- third_party/gvsync/downgradable_rwmutex_unsafe.go | 2 +- third_party/gvsync/gvsync.go | 2 +- third_party/gvsync/memmove_unsafe.go | 2 +- third_party/gvsync/norace_unsafe.go | 2 +- third_party/gvsync/race_unsafe.go | 2 +- third_party/gvsync/seqatomic_unsafe.go | 2 +- third_party/gvsync/seqatomictest/seqatomic_test.go | 2 +- third_party/gvsync/seqcount.go | 2 +- third_party/gvsync/seqcount_test.go | 2 +- tools/go_generics/generics.go | 2 +- tools/go_generics/generics_tests/all_stmts/input.go | 2 +- tools/go_generics/generics_tests/all_stmts/output/output.go | 2 +- tools/go_generics/generics_tests/all_types/input.go | 2 +- tools/go_generics/generics_tests/all_types/lib/lib.go | 2 +- tools/go_generics/generics_tests/all_types/output/output.go | 2 +- tools/go_generics/generics_tests/consts/input.go | 2 +- tools/go_generics/generics_tests/consts/output/output.go | 2 +- tools/go_generics/generics_tests/imports/input.go | 2 +- tools/go_generics/generics_tests/imports/output/output.go | 2 +- tools/go_generics/generics_tests/remove_typedef/input.go | 2 +- tools/go_generics/generics_tests/remove_typedef/output/output.go | 2 +- tools/go_generics/generics_tests/simple/input.go | 2 +- tools/go_generics/generics_tests/simple/output/output.go | 2 +- tools/go_generics/globals/globals_visitor.go | 2 +- tools/go_generics/globals/scope.go | 2 +- tools/go_generics/go_generics_unittest.sh | 2 +- tools/go_generics/go_merge/main.go | 2 +- tools/go_generics/imports.go | 2 +- tools/go_generics/remove.go | 2 +- tools/go_generics/rules_tests/template.go | 2 +- tools/go_generics/rules_tests/template_test.go | 2 +- tools/go_stateify/main.go | 2 +- tools/tag_release.sh | 2 +- tools/workspace_status.sh | 2 +- vdso/barrier.h | 2 +- vdso/check_vdso.py | 2 +- vdso/compiler.h | 2 +- vdso/cycle_clock.h | 2 +- vdso/seqlock.h | 2 +- vdso/syscalls.h | 2 +- vdso/vdso.cc | 2 +- vdso/vdso_time.cc | 2 +- vdso/vdso_time.h | 2 +- 1235 files changed, 1242 insertions(+), 1234 deletions(-) create mode 100644 AUTHORS (limited to 'pkg/tcpip/stack') diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..01ba46567 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,8 @@ +# This is the list of gVisor authors for copyright purposes. +# +# This does not necessarily list everyone who has contributed code, since in +# some cases, their employer may be the copyright holder. To see the full list +# of contributors, see the revision history in source control. +# +# Please send a patch if you would like to be included in this list. +Google LLC diff --git a/kokoro/run_build.sh b/kokoro/run_build.sh index 89e24b037..63fffda48 100755 --- a/kokoro/run_build.sh +++ b/kokoro/run_build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/kokoro/run_tests.sh b/kokoro/run_tests.sh index 8a3ce7402..08f678e39 100755 --- a/kokoro/run_tests.sh +++ b/kokoro/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/pkg/abi/abi.go b/pkg/abi/abi.go index 7770f0405..d56c481c9 100644 --- a/pkg/abi/abi.go +++ b/pkg/abi/abi.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/abi_linux.go b/pkg/abi/abi_linux.go index 9d9f361a4..3059479bd 100644 --- a/pkg/abi/abi_linux.go +++ b/pkg/abi/abi_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/flag.go b/pkg/abi/flag.go index b48757da8..dcdd66d4e 100644 --- a/pkg/abi/flag.go +++ b/pkg/abi/flag.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/aio.go b/pkg/abi/linux/aio.go index 1b7ca714a..3c6e0079d 100644 --- a/pkg/abi/linux/aio.go +++ b/pkg/abi/linux/aio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ashmem.go b/pkg/abi/linux/ashmem.go index ced1e44d4..2a722abe0 100644 --- a/pkg/abi/linux/ashmem.go +++ b/pkg/abi/linux/ashmem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/audit.go b/pkg/abi/linux/audit.go index b39ba4515..6cca69af9 100644 --- a/pkg/abi/linux/audit.go +++ b/pkg/abi/linux/audit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/binder.go b/pkg/abi/linux/binder.go index 522dc6f53..63b08324a 100644 --- a/pkg/abi/linux/binder.go +++ b/pkg/abi/linux/binder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go index d9cd09948..aa3d3ce70 100644 --- a/pkg/abi/linux/bpf.go +++ b/pkg/abi/linux/bpf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/capability.go b/pkg/abi/linux/capability.go index 7d96f013e..c120cac64 100644 --- a/pkg/abi/linux/capability.go +++ b/pkg/abi/linux/capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/dev.go b/pkg/abi/linux/dev.go index 5b1199aac..421e11256 100644 --- a/pkg/abi/linux/dev.go +++ b/pkg/abi/linux/dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/elf.go b/pkg/abi/linux/elf.go index 928067c04..fb1c679d2 100644 --- a/pkg/abi/linux/elf.go +++ b/pkg/abi/linux/elf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errors.go index e5f6f3f07..93f85a864 100644 --- a/pkg/abi/linux/errors.go +++ b/pkg/abi/linux/errors.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/eventfd.go b/pkg/abi/linux/eventfd.go index 5614f5cf1..9c479fc8f 100644 --- a/pkg/abi/linux/eventfd.go +++ b/pkg/abi/linux/eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/exec.go b/pkg/abi/linux/exec.go index a07c29243..579d46c41 100644 --- a/pkg/abi/linux/exec.go +++ b/pkg/abi/linux/exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/fcntl.go b/pkg/abi/linux/fcntl.go index c8558933a..cc8f2702d 100644 --- a/pkg/abi/linux/fcntl.go +++ b/pkg/abi/linux/fcntl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 46b10ca97..753fec3ed 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go index a9f2ba132..c82ab9b5b 100644 --- a/pkg/abi/linux/fs.go +++ b/pkg/abi/linux/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/futex.go b/pkg/abi/linux/futex.go index afdf4123b..08bfde3b5 100644 --- a/pkg/abi/linux/futex.go +++ b/pkg/abi/linux/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/inotify.go b/pkg/abi/linux/inotify.go index 79c5d3593..2d08194ba 100644 --- a/pkg/abi/linux/inotify.go +++ b/pkg/abi/linux/inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index 191b26e4d..04bb767dc 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ip.go b/pkg/abi/linux/ip.go index 77ac1062c..31e56ffa6 100644 --- a/pkg/abi/linux/ip.go +++ b/pkg/abi/linux/ip.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ipc.go b/pkg/abi/linux/ipc.go index 10681768b..2ef8d6cbb 100644 --- a/pkg/abi/linux/ipc.go +++ b/pkg/abi/linux/ipc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go index e0aa5b31d..c74dfcd53 100644 --- a/pkg/abi/linux/limits.go +++ b/pkg/abi/linux/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/linux.go b/pkg/abi/linux/linux.go index d365f693d..8a8f831cd 100644 --- a/pkg/abi/linux/linux.go +++ b/pkg/abi/linux/linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go index eda8d9788..0b02f938a 100644 --- a/pkg/abi/linux/mm.go +++ b/pkg/abi/linux/mm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/netdevice.go b/pkg/abi/linux/netdevice.go index e3b6b1e40..aef1acf75 100644 --- a/pkg/abi/linux/netdevice.go +++ b/pkg/abi/linux/netdevice.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/netlink.go b/pkg/abi/linux/netlink.go index 25c5e17fd..5e718c363 100644 --- a/pkg/abi/linux/netlink.go +++ b/pkg/abi/linux/netlink.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/netlink_route.go b/pkg/abi/linux/netlink_route.go index 4200b6506..630dc339a 100644 --- a/pkg/abi/linux/netlink_route.go +++ b/pkg/abi/linux/netlink_route.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/poll.go b/pkg/abi/linux/poll.go index 9f0b15d1c..c04d26e4c 100644 --- a/pkg/abi/linux/poll.go +++ b/pkg/abi/linux/poll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go index db3206f36..dae2de290 100644 --- a/pkg/abi/linux/prctl.go +++ b/pkg/abi/linux/prctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ptrace.go b/pkg/abi/linux/ptrace.go index 7db4f5464..23e605ab2 100644 --- a/pkg/abi/linux/ptrace.go +++ b/pkg/abi/linux/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/rusage.go b/pkg/abi/linux/rusage.go index 7fea4b589..d8302dc85 100644 --- a/pkg/abi/linux/rusage.go +++ b/pkg/abi/linux/rusage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/sched.go b/pkg/abi/linux/sched.go index ef96a3801..193d9a242 100644 --- a/pkg/abi/linux/sched.go +++ b/pkg/abi/linux/sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go index 8673a27bf..4eeb5cd7a 100644 --- a/pkg/abi/linux/seccomp.go +++ b/pkg/abi/linux/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/sem.go b/pkg/abi/linux/sem.go index b80c93daf..de422c519 100644 --- a/pkg/abi/linux/sem.go +++ b/pkg/abi/linux/sem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/shm.go b/pkg/abi/linux/shm.go index 82a80e609..e45aadb10 100644 --- a/pkg/abi/linux/shm.go +++ b/pkg/abi/linux/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go index 395f9f31e..9cbd77dda 100644 --- a/pkg/abi/linux/signal.go +++ b/pkg/abi/linux/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index 6fa4e7c3e..417840731 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/tcp.go b/pkg/abi/linux/tcp.go index 67908deb9..174d470e2 100644 --- a/pkg/abi/linux/tcp.go +++ b/pkg/abi/linux/tcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/time.go b/pkg/abi/linux/time.go index bbd21e726..fa9ee27e1 100644 --- a/pkg/abi/linux/time.go +++ b/pkg/abi/linux/time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/timer.go b/pkg/abi/linux/timer.go index a6f420bdb..e32d09e10 100644 --- a/pkg/abi/linux/timer.go +++ b/pkg/abi/linux/timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index bff882d89..8ac02aee8 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/uio.go b/pkg/abi/linux/uio.go index 7e00d9959..1fd1e9802 100644 --- a/pkg/abi/linux/uio.go +++ b/pkg/abi/linux/uio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/utsname.go b/pkg/abi/linux/utsname.go index f80ed7d4a..60f220a67 100644 --- a/pkg/abi/linux/utsname.go +++ b/pkg/abi/linux/utsname.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/amutex/amutex.go b/pkg/amutex/amutex.go index 26b674435..85e819304 100644 --- a/pkg/amutex/amutex.go +++ b/pkg/amutex/amutex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/amutex/amutex_test.go b/pkg/amutex/amutex_test.go index 104e0dab1..6a0af006e 100644 --- a/pkg/amutex/amutex_test.go +++ b/pkg/amutex/amutex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/atomicbitops/atomic_bitops.go b/pkg/atomicbitops/atomic_bitops.go index 9a57f9599..63aa2b7f1 100644 --- a/pkg/atomicbitops/atomic_bitops.go +++ b/pkg/atomicbitops/atomic_bitops.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/atomicbitops/atomic_bitops_amd64.s b/pkg/atomicbitops/atomic_bitops_amd64.s index b37e3aad3..db0972001 100644 --- a/pkg/atomicbitops/atomic_bitops_amd64.s +++ b/pkg/atomicbitops/atomic_bitops_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/atomicbitops/atomic_bitops_common.go b/pkg/atomicbitops/atomic_bitops_common.go index b03242baa..b2a943dcb 100644 --- a/pkg/atomicbitops/atomic_bitops_common.go +++ b/pkg/atomicbitops/atomic_bitops_common.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/atomicbitops/atomic_bitops_test.go b/pkg/atomicbitops/atomic_bitops_test.go index ee6207cb3..965e9be79 100644 --- a/pkg/atomicbitops/atomic_bitops_test.go +++ b/pkg/atomicbitops/atomic_bitops_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/binary/binary.go b/pkg/binary/binary.go index 02f7e9fb8..631785f7b 100644 --- a/pkg/binary/binary.go +++ b/pkg/binary/binary.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/binary/binary_test.go b/pkg/binary/binary_test.go index 200961c70..4d609a438 100644 --- a/pkg/binary/binary_test.go +++ b/pkg/binary/binary_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/bits.go b/pkg/bits/bits.go index eb3c80f49..a26433ad6 100644 --- a/pkg/bits/bits.go +++ b/pkg/bits/bits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/bits_template.go b/pkg/bits/bits_template.go index 8c578cca2..93a435b80 100644 --- a/pkg/bits/bits_template.go +++ b/pkg/bits/bits_template.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/uint64_arch_amd64.go b/pkg/bits/uint64_arch_amd64.go index 1fef89394..faccaa61a 100644 --- a/pkg/bits/uint64_arch_amd64.go +++ b/pkg/bits/uint64_arch_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/uint64_arch_amd64_asm.s b/pkg/bits/uint64_arch_amd64_asm.s index 8c7322f0f..8ff364181 100644 --- a/pkg/bits/uint64_arch_amd64_asm.s +++ b/pkg/bits/uint64_arch_amd64_asm.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/uint64_arch_generic.go b/pkg/bits/uint64_arch_generic.go index cfb47400b..7dd2d1480 100644 --- a/pkg/bits/uint64_arch_generic.go +++ b/pkg/bits/uint64_arch_generic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/uint64_test.go b/pkg/bits/uint64_test.go index d6dbaf602..1b018d808 100644 --- a/pkg/bits/uint64_test.go +++ b/pkg/bits/uint64_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/bpf.go b/pkg/bpf/bpf.go index 98d44d911..eb546f48f 100644 --- a/pkg/bpf/bpf.go +++ b/pkg/bpf/bpf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/decoder.go b/pkg/bpf/decoder.go index ae6b8839a..45c192215 100644 --- a/pkg/bpf/decoder.go +++ b/pkg/bpf/decoder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/decoder_test.go b/pkg/bpf/decoder_test.go index f093e1e41..8c4bdad21 100644 --- a/pkg/bpf/decoder_test.go +++ b/pkg/bpf/decoder_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/input_bytes.go b/pkg/bpf/input_bytes.go index 745c0749b..86b216cfc 100644 --- a/pkg/bpf/input_bytes.go +++ b/pkg/bpf/input_bytes.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/interpreter.go b/pkg/bpf/interpreter.go index 86c7add4d..86de523a2 100644 --- a/pkg/bpf/interpreter.go +++ b/pkg/bpf/interpreter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/interpreter_test.go b/pkg/bpf/interpreter_test.go index c46a43991..67b00ffe3 100644 --- a/pkg/bpf/interpreter_test.go +++ b/pkg/bpf/interpreter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/program_builder.go b/pkg/bpf/program_builder.go index b4ce228e1..fc9d27203 100644 --- a/pkg/bpf/program_builder.go +++ b/pkg/bpf/program_builder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/program_builder_test.go b/pkg/bpf/program_builder_test.go index 0e0b79d88..5b2ad67de 100644 --- a/pkg/bpf/program_builder_test.go +++ b/pkg/bpf/program_builder_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/compressio/compressio.go b/pkg/compressio/compressio.go index 4daaa82b6..8c14ccbfa 100644 --- a/pkg/compressio/compressio.go +++ b/pkg/compressio/compressio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/compressio/compressio_test.go b/pkg/compressio/compressio_test.go index 1bbabee79..86dc47e44 100644 --- a/pkg/compressio/compressio_test.go +++ b/pkg/compressio/compressio_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/control/client/client.go b/pkg/control/client/client.go index 0d0c9f148..3fec27846 100644 --- a/pkg/control/client/client.go +++ b/pkg/control/client/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/control/server/server.go b/pkg/control/server/server.go index c46b5d70b..1a15da1a8 100644 --- a/pkg/control/server/server.go +++ b/pkg/control/server/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/cpuid/cpu_amd64.s b/pkg/cpuid/cpu_amd64.s index 905c1d12e..ac80d3c8a 100644 --- a/pkg/cpuid/cpu_amd64.s +++ b/pkg/cpuid/cpu_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go index 61441150e..3eb2bcd2b 100644 --- a/pkg/cpuid/cpuid.go +++ b/pkg/cpuid/cpuid.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/cpuid/cpuid_parse_test.go b/pkg/cpuid/cpuid_parse_test.go index e8f87a10e..dd9969db4 100644 --- a/pkg/cpuid/cpuid_parse_test.go +++ b/pkg/cpuid/cpuid_parse_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/cpuid/cpuid_test.go b/pkg/cpuid/cpuid_test.go index 64ade1cbe..6ae14d2da 100644 --- a/pkg/cpuid/cpuid_test.go +++ b/pkg/cpuid/cpuid_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 2ba79be32..b7cde3819 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/dhcp.go b/pkg/dhcp/dhcp.go index 6945bcd35..f96ffd891 100644 --- a/pkg/dhcp/dhcp.go +++ b/pkg/dhcp/dhcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/dhcp_string.go b/pkg/dhcp/dhcp_string.go index 8533895bd..29ce98593 100644 --- a/pkg/dhcp/dhcp_string.go +++ b/pkg/dhcp/dhcp_string.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index e1d8ef603..751626bb0 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index 9549ff705..6a1972860 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/eventchannel/event.go b/pkg/eventchannel/event.go index 41a7b5ed3..4c8ae573b 100644 --- a/pkg/eventchannel/event.go +++ b/pkg/eventchannel/event.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/eventchannel/event.proto b/pkg/eventchannel/event.proto index c1679c7e7..34468f072 100644 --- a/pkg/eventchannel/event.proto +++ b/pkg/eventchannel/event.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/fd/fd.go b/pkg/fd/fd.go index d40758c22..2785243a2 100644 --- a/pkg/fd/fd.go +++ b/pkg/fd/fd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/fd/fd_test.go b/pkg/fd/fd_test.go index 42bb3ef6c..5fb0ad47d 100644 --- a/pkg/fd/fd_test.go +++ b/pkg/fd/fd_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/fdnotifier/fdnotifier.go b/pkg/fdnotifier/fdnotifier.go index aa4906ca0..f0b028b0b 100644 --- a/pkg/fdnotifier/fdnotifier.go +++ b/pkg/fdnotifier/fdnotifier.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/fdnotifier/poll_unsafe.go b/pkg/fdnotifier/poll_unsafe.go index 05be9aeb5..bc5e0ac44 100644 --- a/pkg/fdnotifier/poll_unsafe.go +++ b/pkg/fdnotifier/poll_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/gate/gate.go b/pkg/gate/gate.go index 48122bf5a..bda6aae09 100644 --- a/pkg/gate/gate.go +++ b/pkg/gate/gate.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/gate/gate_test.go b/pkg/gate/gate_test.go index 95620fa8e..7467e7d07 100644 --- a/pkg/gate/gate_test.go +++ b/pkg/gate/gate_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/ilist/list.go b/pkg/ilist/list.go index 51c9b6df3..019caadca 100644 --- a/pkg/ilist/list.go +++ b/pkg/ilist/list.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/ilist/list_test.go b/pkg/ilist/list_test.go index f37946dc2..3f9abfb56 100644 --- a/pkg/ilist/list_test.go +++ b/pkg/ilist/list_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/linewriter/linewriter.go b/pkg/linewriter/linewriter.go index 5fbd4e779..cd6e4e2ce 100644 --- a/pkg/linewriter/linewriter.go +++ b/pkg/linewriter/linewriter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/linewriter/linewriter_test.go b/pkg/linewriter/linewriter_test.go index 9140ee6af..96dc7e6e0 100644 --- a/pkg/linewriter/linewriter_test.go +++ b/pkg/linewriter/linewriter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/glog.go b/pkg/log/glog.go index 24d5390d7..5732785b4 100644 --- a/pkg/log/glog.go +++ b/pkg/log/glog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/glog_unsafe.go b/pkg/log/glog_unsafe.go index bb06aa7d3..ea17ae349 100644 --- a/pkg/log/glog_unsafe.go +++ b/pkg/log/glog_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/json.go b/pkg/log/json.go index 96bd13d87..a278c8fc8 100644 --- a/pkg/log/json.go +++ b/pkg/log/json.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/json_k8s.go b/pkg/log/json_k8s.go index 9c2f8d2b7..c2c019915 100644 --- a/pkg/log/json_k8s.go +++ b/pkg/log/json_k8s.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/json_test.go b/pkg/log/json_test.go index b8c7a795e..f25224fe1 100644 --- a/pkg/log/json_test.go +++ b/pkg/log/json_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/log.go b/pkg/log/log.go index b8d456aae..7d563241e 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/log_test.go b/pkg/log/log_test.go index a59d457dd..0634e7c1f 100644 --- a/pkg/log/log_test.go +++ b/pkg/log/log_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/metric/metric.go b/pkg/metric/metric.go index e5eb95f89..803709cc4 100644 --- a/pkg/metric/metric.go +++ b/pkg/metric/metric.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/metric/metric.proto b/pkg/metric/metric.proto index 917fda1ac..a2c2bd1ba 100644 --- a/pkg/metric/metric.proto +++ b/pkg/metric/metric.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/metric/metric_test.go b/pkg/metric/metric_test.go index 40034a589..b8b124c83 100644 --- a/pkg/metric/metric_test.go +++ b/pkg/metric/metric_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/buffer.go b/pkg/p9/buffer.go index b7bb14ef9..4c8c6555d 100644 --- a/pkg/p9/buffer.go +++ b/pkg/p9/buffer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/buffer_test.go b/pkg/p9/buffer_test.go index 18d55e5c0..a9c75f86b 100644 --- a/pkg/p9/buffer_test.go +++ b/pkg/p9/buffer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/client.go b/pkg/p9/client.go index 67887874a..2f9c716d0 100644 --- a/pkg/p9/client.go +++ b/pkg/p9/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/client_file.go b/pkg/p9/client_file.go index 992d1daf7..63c65129a 100644 --- a/pkg/p9/client_file.go +++ b/pkg/p9/client_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/client_test.go b/pkg/p9/client_test.go index f7145452d..fc49729d8 100644 --- a/pkg/p9/client_test.go +++ b/pkg/p9/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/file.go b/pkg/p9/file.go index 55ceb52e1..a52a0f3e7 100644 --- a/pkg/p9/file.go +++ b/pkg/p9/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index c1d1ac1e8..6da2ce4e3 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/local_server/local_server.go b/pkg/p9/local_server/local_server.go index 69b90c6cd..f4077a9d4 100644 --- a/pkg/p9/local_server/local_server.go +++ b/pkg/p9/local_server/local_server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/messages.go b/pkg/p9/messages.go index 97decd3cc..833defbd6 100644 --- a/pkg/p9/messages.go +++ b/pkg/p9/messages.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/messages_test.go b/pkg/p9/messages_test.go index 68395a396..10a0587cf 100644 --- a/pkg/p9/messages_test.go +++ b/pkg/p9/messages_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/p9.go b/pkg/p9/p9.go index 4ea9f2f9a..78c7d3f86 100644 --- a/pkg/p9/p9.go +++ b/pkg/p9/p9.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/p9_test.go b/pkg/p9/p9_test.go index 02498346c..8dda6cc64 100644 --- a/pkg/p9/p9_test.go +++ b/pkg/p9/p9_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/p9test/client_test.go b/pkg/p9/p9test/client_test.go index 242d81b95..e00dd03ab 100644 --- a/pkg/p9/p9test/client_test.go +++ b/pkg/p9/p9test/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/p9test/p9test.go b/pkg/p9/p9test/p9test.go index f9bacbf84..1c8eff200 100644 --- a/pkg/p9/p9test/p9test.go +++ b/pkg/p9/p9test/p9test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/path_tree.go b/pkg/p9/path_tree.go index 60b20578e..f37ad4ab2 100644 --- a/pkg/p9/path_tree.go +++ b/pkg/p9/path_tree.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/pool.go b/pkg/p9/pool.go index 34ed898e8..52de889e1 100644 --- a/pkg/p9/pool.go +++ b/pkg/p9/pool.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/pool_test.go b/pkg/p9/pool_test.go index 71052d8c4..e4746b8da 100644 --- a/pkg/p9/pool_test.go +++ b/pkg/p9/pool_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/server.go b/pkg/p9/server.go index 3ef151595..b2a86d8fa 100644 --- a/pkg/p9/server.go +++ b/pkg/p9/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/transport.go b/pkg/p9/transport.go index bafb377de..ef59077ff 100644 --- a/pkg/p9/transport.go +++ b/pkg/p9/transport.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/transport_test.go b/pkg/p9/transport_test.go index b7b7825bd..c833d1c9c 100644 --- a/pkg/p9/transport_test.go +++ b/pkg/p9/transport_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/version.go b/pkg/p9/version.go index ceb6fabbf..a36a499a1 100644 --- a/pkg/p9/version.go +++ b/pkg/p9/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/version_test.go b/pkg/p9/version_test.go index c053614c9..291e8580e 100644 --- a/pkg/p9/version_test.go +++ b/pkg/p9/version_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/rand/rand.go b/pkg/rand/rand.go index 593a14380..a2714784d 100644 --- a/pkg/rand/rand.go +++ b/pkg/rand/rand.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/rand/rand_linux.go b/pkg/rand/rand_linux.go index 7ebe8f3b0..2b92db3e6 100644 --- a/pkg/rand/rand_linux.go +++ b/pkg/rand/rand_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/refs/refcounter.go b/pkg/refs/refcounter.go index 8f08c74c7..20f515391 100644 --- a/pkg/refs/refcounter.go +++ b/pkg/refs/refcounter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/refs/refcounter_state.go b/pkg/refs/refcounter_state.go index 136f06fbf..7c99fd2b5 100644 --- a/pkg/refs/refcounter_state.go +++ b/pkg/refs/refcounter_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/refs/refcounter_test.go b/pkg/refs/refcounter_test.go index abaa87453..ffd3d3f07 100644 --- a/pkg/refs/refcounter_test.go +++ b/pkg/refs/refcounter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index e113f3574..50c9409e4 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp_rules.go b/pkg/seccomp/seccomp_rules.go index a9278c64b..29eec8db1 100644 --- a/pkg/seccomp/seccomp_rules.go +++ b/pkg/seccomp/seccomp_rules.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp_test.go b/pkg/seccomp/seccomp_test.go index 11ed90eb4..47ecac6f7 100644 --- a/pkg/seccomp/seccomp_test.go +++ b/pkg/seccomp/seccomp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp_test_victim.go b/pkg/seccomp/seccomp_test_victim.go index dd5ed0041..afc2f755f 100644 --- a/pkg/seccomp/seccomp_test_victim.go +++ b/pkg/seccomp/seccomp_test_victim.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp_unsafe.go b/pkg/seccomp/seccomp_unsafe.go index a31c6471d..ccd40d9db 100644 --- a/pkg/seccomp/seccomp_unsafe.go +++ b/pkg/seccomp/seccomp_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/secio/full_reader.go b/pkg/secio/full_reader.go index 90b1772a7..aed2564bd 100644 --- a/pkg/secio/full_reader.go +++ b/pkg/secio/full_reader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/secio/secio.go b/pkg/secio/secio.go index e5f74a497..b43226035 100644 --- a/pkg/secio/secio.go +++ b/pkg/secio/secio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/secio/secio_test.go b/pkg/secio/secio_test.go index 8304c4f74..d1d905187 100644 --- a/pkg/secio/secio_test.go +++ b/pkg/secio/secio_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/range.go b/pkg/segment/range.go index 057bcd7ff..4d4aeffef 100644 --- a/pkg/segment/range.go +++ b/pkg/segment/range.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/set.go b/pkg/segment/set.go index 74a916ea3..982eb3fdd 100644 --- a/pkg/segment/set.go +++ b/pkg/segment/set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/set_state.go b/pkg/segment/set_state.go index b86e1b75f..76de92591 100644 --- a/pkg/segment/set_state.go +++ b/pkg/segment/set_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/test/segment_test.go b/pkg/segment/test/segment_test.go index 0825105db..f19a005f3 100644 --- a/pkg/segment/test/segment_test.go +++ b/pkg/segment/test/segment_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/test/set_functions.go b/pkg/segment/test/set_functions.go index 41f649011..bcddb39bb 100644 --- a/pkg/segment/test/set_functions.go +++ b/pkg/segment/test/set_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/aligned.go b/pkg/sentry/arch/aligned.go index c88c034f6..df01a903d 100644 --- a/pkg/sentry/arch/aligned.go +++ b/pkg/sentry/arch/aligned.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index 16d8eb2b2..53f0c9018 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index 7ec2f2c84..135c2ee1f 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch_amd64.s b/pkg/sentry/arch/arch_amd64.s index fa9857df7..bd61402cf 100644 --- a/pkg/sentry/arch/arch_amd64.s +++ b/pkg/sentry/arch/arch_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch_state_x86.go b/pkg/sentry/arch/arch_state_x86.go index 01949049d..bb52d8db0 100644 --- a/pkg/sentry/arch/arch_state_x86.go +++ b/pkg/sentry/arch/arch_state_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index 4305fe2cb..4d167ce98 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/auxv.go b/pkg/sentry/arch/auxv.go index 5df65a691..80c923103 100644 --- a/pkg/sentry/arch/auxv.go +++ b/pkg/sentry/arch/auxv.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/registers.proto b/pkg/sentry/arch/registers.proto index f4c2f7043..9dc83e241 100644 --- a/pkg/sentry/arch/registers.proto +++ b/pkg/sentry/arch/registers.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/signal_act.go b/pkg/sentry/arch/signal_act.go index ad098c746..f9ca2e74e 100644 --- a/pkg/sentry/arch/signal_act.go +++ b/pkg/sentry/arch/signal_act.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index 7f76eba27..aa030fd70 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/signal_info.go b/pkg/sentry/arch/signal_info.go index fa0ecbec5..f93ee8b46 100644 --- a/pkg/sentry/arch/signal_info.go +++ b/pkg/sentry/arch/signal_info.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/signal_stack.go b/pkg/sentry/arch/signal_stack.go index c02ae3b7c..a442f9fdc 100644 --- a/pkg/sentry/arch/signal_stack.go +++ b/pkg/sentry/arch/signal_stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/stack.go b/pkg/sentry/arch/stack.go index 2e33ccdf5..7e6324e82 100644 --- a/pkg/sentry/arch/stack.go +++ b/pkg/sentry/arch/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/syscalls_amd64.go b/pkg/sentry/arch/syscalls_amd64.go index 47c31d4b9..8b4f23007 100644 --- a/pkg/sentry/arch/syscalls_amd64.go +++ b/pkg/sentry/arch/syscalls_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/context/context.go b/pkg/sentry/context/context.go index eefc3e1b4..d70f3a5c3 100644 --- a/pkg/sentry/context/context.go +++ b/pkg/sentry/context/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/context/contexttest/contexttest.go b/pkg/sentry/context/contexttest/contexttest.go index a29087775..a42038711 100644 --- a/pkg/sentry/context/contexttest/contexttest.go +++ b/pkg/sentry/context/contexttest/contexttest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/control/control.go b/pkg/sentry/control/control.go index 32d30b6ea..6060b9b4f 100644 --- a/pkg/sentry/control/control.go +++ b/pkg/sentry/control/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/control/pprof.go b/pkg/sentry/control/pprof.go index 1af092af3..94ed149f2 100644 --- a/pkg/sentry/control/pprof.go +++ b/pkg/sentry/control/pprof.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/control/proc.go b/pkg/sentry/control/proc.go index aca2267a7..f7f02a3e1 100644 --- a/pkg/sentry/control/proc.go +++ b/pkg/sentry/control/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/control/proc_test.go b/pkg/sentry/control/proc_test.go index 5d52cd829..b7895d03c 100644 --- a/pkg/sentry/control/proc_test.go +++ b/pkg/sentry/control/proc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/control/state.go b/pkg/sentry/control/state.go index b6bbf69fa..11efcaba1 100644 --- a/pkg/sentry/control/state.go +++ b/pkg/sentry/control/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/device/device.go b/pkg/sentry/device/device.go index ae4fa1d93..458d03b30 100644 --- a/pkg/sentry/device/device.go +++ b/pkg/sentry/device/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/device/device_test.go b/pkg/sentry/device/device_test.go index 5d8805c2f..e3f51ce4f 100644 --- a/pkg/sentry/device/device_test.go +++ b/pkg/sentry/device/device_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/anon/anon.go b/pkg/sentry/fs/anon/anon.go index a5e8c4f0d..a6ea8b9e7 100644 --- a/pkg/sentry/fs/anon/anon.go +++ b/pkg/sentry/fs/anon/anon.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/anon/device.go b/pkg/sentry/fs/anon/device.go index 2d1249299..5927bd11e 100644 --- a/pkg/sentry/fs/anon/device.go +++ b/pkg/sentry/fs/anon/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index 1f61c5711..b53746519 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index 5369d1b0d..5e005bc2e 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ashmem/pin_board.go b/pkg/sentry/fs/ashmem/pin_board.go index 7c997f533..bdf23b371 100644 --- a/pkg/sentry/fs/ashmem/pin_board.go +++ b/pkg/sentry/fs/ashmem/pin_board.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ashmem/pin_board_test.go b/pkg/sentry/fs/ashmem/pin_board_test.go index 736e628dc..24f5d86d6 100644 --- a/pkg/sentry/fs/ashmem/pin_board_test.go +++ b/pkg/sentry/fs/ashmem/pin_board_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index 3523b068a..591e35e6a 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index d9f1559de..acbbd5466 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/context.go b/pkg/sentry/fs/context.go index 4869428a8..c80ea0175 100644 --- a/pkg/sentry/fs/context.go +++ b/pkg/sentry/fs/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/copy_up.go b/pkg/sentry/fs/copy_up.go index ba69e718d..ee2d3d115 100644 --- a/pkg/sentry/fs/copy_up.go +++ b/pkg/sentry/fs/copy_up.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/copy_up_test.go b/pkg/sentry/fs/copy_up_test.go index 98a0b7638..54810afca 100644 --- a/pkg/sentry/fs/copy_up_test.go +++ b/pkg/sentry/fs/copy_up_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dentry.go b/pkg/sentry/fs/dentry.go index 29fb155a4..fe656cc24 100644 --- a/pkg/sentry/fs/dentry.go +++ b/pkg/sentry/fs/dentry.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index fbc750a71..34ac01173 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/device.go b/pkg/sentry/fs/dev/device.go index 3cecdf6e2..9f4e41fc9 100644 --- a/pkg/sentry/fs/dev/device.go +++ b/pkg/sentry/fs/dev/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go index cf4e7d00f..6096a40f8 100644 --- a/pkg/sentry/fs/dev/fs.go +++ b/pkg/sentry/fs/dev/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index 82da9aae9..6b11afa44 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 5d306d352..069212b6d 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index ffd5cf6c3..de0f3e5e5 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index 54fc11fe1..c0bc261a2 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_cache.go b/pkg/sentry/fs/dirent_cache.go index d26a06971..71f2d11de 100644 --- a/pkg/sentry/fs/dirent_cache.go +++ b/pkg/sentry/fs/dirent_cache.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_cache_limiter.go b/pkg/sentry/fs/dirent_cache_limiter.go index 024c7b2d5..ebb80bd50 100644 --- a/pkg/sentry/fs/dirent_cache_limiter.go +++ b/pkg/sentry/fs/dirent_cache_limiter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_cache_test.go b/pkg/sentry/fs/dirent_cache_test.go index 93e8d415f..395c879f5 100644 --- a/pkg/sentry/fs/dirent_cache_test.go +++ b/pkg/sentry/fs/dirent_cache_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_refs_test.go b/pkg/sentry/fs/dirent_refs_test.go index 325404e27..db88d850e 100644 --- a/pkg/sentry/fs/dirent_refs_test.go +++ b/pkg/sentry/fs/dirent_refs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_state.go b/pkg/sentry/fs/dirent_state.go index 5cf151dab..18652b809 100644 --- a/pkg/sentry/fs/dirent_state.go +++ b/pkg/sentry/fs/dirent_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 98483ab68..95e66ea8d 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener.go b/pkg/sentry/fs/fdpipe/pipe_opener.go index 92ab6ff0e..0cabe2e18 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener_test.go b/pkg/sentry/fs/fdpipe/pipe_opener_test.go index 69516e048..8c8b1b40c 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe_state.go b/pkg/sentry/fs/fdpipe/pipe_state.go index 4395666ad..8b347aa11 100644 --- a/pkg/sentry/fs/fdpipe/pipe_state.go +++ b/pkg/sentry/fs/fdpipe/pipe_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe_test.go b/pkg/sentry/fs/fdpipe/pipe_test.go index 7e3ee5257..b59a6aa0e 100644 --- a/pkg/sentry/fs/fdpipe/pipe_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 5d5026661..62b35dabc 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_operations.go b/pkg/sentry/fs/file_operations.go index e0fa5135f..ab0acb6eb 100644 --- a/pkg/sentry/fs/file_operations.go +++ b/pkg/sentry/fs/file_operations.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index 6e680f0a4..948ce9c6f 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_overlay_test.go b/pkg/sentry/fs/file_overlay_test.go index a4ac58763..6a2b8007c 100644 --- a/pkg/sentry/fs/file_overlay_test.go +++ b/pkg/sentry/fs/file_overlay_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_state.go b/pkg/sentry/fs/file_state.go index 1c3bae3e8..523182d59 100644 --- a/pkg/sentry/fs/file_state.go +++ b/pkg/sentry/fs/file_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_test.go b/pkg/sentry/fs/file_test.go index f3ed9a70b..d867a0257 100644 --- a/pkg/sentry/fs/file_test.go +++ b/pkg/sentry/fs/file_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/filesystems.go b/pkg/sentry/fs/filesystems.go index a6b27c402..acd84dfcc 100644 --- a/pkg/sentry/fs/filesystems.go +++ b/pkg/sentry/fs/filesystems.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/filetest/filetest.go b/pkg/sentry/fs/filetest/filetest.go index 388a1ce36..f6b827800 100644 --- a/pkg/sentry/fs/filetest/filetest.go +++ b/pkg/sentry/fs/filetest/filetest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index bf2a20b33..5c8cb773f 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fs.go b/pkg/sentry/fs/fs.go index 119689776..632055cce 100644 --- a/pkg/sentry/fs/fs.go +++ b/pkg/sentry/fs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/dirty_set.go b/pkg/sentry/fs/fsutil/dirty_set.go index 5add16ac4..9cd196d7d 100644 --- a/pkg/sentry/fs/fsutil/dirty_set.go +++ b/pkg/sentry/fs/fsutil/dirty_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/dirty_set_test.go b/pkg/sentry/fs/fsutil/dirty_set_test.go index f5c9d9215..d9c68baa3 100644 --- a/pkg/sentry/fs/fsutil/dirty_set_test.go +++ b/pkg/sentry/fs/fsutil/dirty_set_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go index 42afdd11c..e355d8594 100644 --- a/pkg/sentry/fs/fsutil/file.go +++ b/pkg/sentry/fs/fsutil/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/file_range_set.go b/pkg/sentry/fs/fsutil/file_range_set.go index 32ebf64ff..b5ac6c71c 100644 --- a/pkg/sentry/fs/fsutil/file_range_set.go +++ b/pkg/sentry/fs/fsutil/file_range_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/frame_ref_set.go b/pkg/sentry/fs/fsutil/frame_ref_set.go index b6e783614..6565c28c8 100644 --- a/pkg/sentry/fs/fsutil/frame_ref_set.go +++ b/pkg/sentry/fs/fsutil/frame_ref_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/fsutil.go b/pkg/sentry/fs/fsutil/fsutil.go index 319c4841b..c9587b1d9 100644 --- a/pkg/sentry/fs/fsutil/fsutil.go +++ b/pkg/sentry/fs/fsutil/fsutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go index 9599665f0..2bdfc0db6 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_state.go b/pkg/sentry/fs/fsutil/host_file_mapper_state.go index bbd15b30b..576d2a3df 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper_state.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go index 86df76822..7167be263 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/host_mappable.go b/pkg/sentry/fs/fsutil/host_mappable.go index 4a182baa1..28686f3b3 100644 --- a/pkg/sentry/fs/fsutil/host_mappable.go +++ b/pkg/sentry/fs/fsutil/host_mappable.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index 468171a9b..b6366d906 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index ba33b9912..919d2534c 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/inode_cached_test.go b/pkg/sentry/fs/fsutil/inode_cached_test.go index 2a8a1639c..661ec41f6 100644 --- a/pkg/sentry/fs/fsutil/inode_cached_test.go +++ b/pkg/sentry/fs/fsutil/inode_cached_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/attr.go b/pkg/sentry/fs/gofer/attr.go index 98700d014..c572f3396 100644 --- a/pkg/sentry/fs/gofer/attr.go +++ b/pkg/sentry/fs/gofer/attr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/cache_policy.go b/pkg/sentry/fs/gofer/cache_policy.go index 51c573aef..35cd0c1d6 100644 --- a/pkg/sentry/fs/gofer/cache_policy.go +++ b/pkg/sentry/fs/gofer/cache_policy.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/context_file.go b/pkg/sentry/fs/gofer/context_file.go index 455953237..d512afefc 100644 --- a/pkg/sentry/fs/gofer/context_file.go +++ b/pkg/sentry/fs/gofer/context_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/device.go b/pkg/sentry/fs/gofer/device.go index 52c5acf48..1de6c247c 100644 --- a/pkg/sentry/fs/gofer/device.go +++ b/pkg/sentry/fs/gofer/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 35caa42cd..bc2be546e 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/file_state.go b/pkg/sentry/fs/gofer/file_state.go index d0c64003c..31264e065 100644 --- a/pkg/sentry/fs/gofer/file_state.go +++ b/pkg/sentry/fs/gofer/file_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go index adff0abac..6ab89fcc2 100644 --- a/pkg/sentry/fs/gofer/fs.go +++ b/pkg/sentry/fs/gofer/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/gofer_test.go b/pkg/sentry/fs/gofer/gofer_test.go index 36201f017..29d34da7e 100644 --- a/pkg/sentry/fs/gofer/gofer_test.go +++ b/pkg/sentry/fs/gofer/gofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/handles.go b/pkg/sentry/fs/gofer/handles.go index 0b33e80c3..c7098cd36 100644 --- a/pkg/sentry/fs/gofer/handles.go +++ b/pkg/sentry/fs/gofer/handles.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index 1181a24cc..f6f20844d 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/inode_state.go b/pkg/sentry/fs/gofer/inode_state.go index 44d76ba9f..ac22ee4b1 100644 --- a/pkg/sentry/fs/gofer/inode_state.go +++ b/pkg/sentry/fs/gofer/inode_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/path.go b/pkg/sentry/fs/gofer/path.go index 8ae33d286..4cbf9e9d9 100644 --- a/pkg/sentry/fs/gofer/path.go +++ b/pkg/sentry/fs/gofer/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go index 4ed688ce5..4cb65e7c6 100644 --- a/pkg/sentry/fs/gofer/session.go +++ b/pkg/sentry/fs/gofer/session.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/session_state.go b/pkg/sentry/fs/gofer/session_state.go index b1f299be5..68fbf3417 100644 --- a/pkg/sentry/fs/gofer/session_state.go +++ b/pkg/sentry/fs/gofer/session_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/socket.go b/pkg/sentry/fs/gofer/socket.go index ce6d3d5c3..cbd5b9a84 100644 --- a/pkg/sentry/fs/gofer/socket.go +++ b/pkg/sentry/fs/gofer/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/util.go b/pkg/sentry/fs/gofer/util.go index 1a759370d..d0e1096ce 100644 --- a/pkg/sentry/fs/gofer/util.go +++ b/pkg/sentry/fs/gofer/util.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/control.go b/pkg/sentry/fs/host/control.go index 0753640a2..480f0c8f4 100644 --- a/pkg/sentry/fs/host/control.go +++ b/pkg/sentry/fs/host/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/descriptor.go b/pkg/sentry/fs/host/descriptor.go index 554e1693a..ffcd57a94 100644 --- a/pkg/sentry/fs/host/descriptor.go +++ b/pkg/sentry/fs/host/descriptor.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/descriptor_state.go b/pkg/sentry/fs/host/descriptor_state.go index 530c0109f..8167390a9 100644 --- a/pkg/sentry/fs/host/descriptor_state.go +++ b/pkg/sentry/fs/host/descriptor_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/descriptor_test.go b/pkg/sentry/fs/host/descriptor_test.go index 5dec84ab2..ff08e43af 100644 --- a/pkg/sentry/fs/host/descriptor_test.go +++ b/pkg/sentry/fs/host/descriptor_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/device.go b/pkg/sentry/fs/host/device.go index b5adedf44..055024c44 100644 --- a/pkg/sentry/fs/host/device.go +++ b/pkg/sentry/fs/host/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index 2a8f285ff..82e2ae3b9 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index de349a41a..b1b8dc0b6 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/fs_test.go b/pkg/sentry/fs/host/fs_test.go index c83b29a16..16c89ddf1 100644 --- a/pkg/sentry/fs/host/fs_test.go +++ b/pkg/sentry/fs/host/fs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index 69c648f67..20e077f77 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/inode_state.go b/pkg/sentry/fs/host/inode_state.go index b7c1a9581..26cc755bc 100644 --- a/pkg/sentry/fs/host/inode_state.go +++ b/pkg/sentry/fs/host/inode_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/inode_test.go b/pkg/sentry/fs/host/inode_test.go index 9f1561bd5..ad1878b5a 100644 --- a/pkg/sentry/fs/host/inode_test.go +++ b/pkg/sentry/fs/host/inode_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/ioctl_unsafe.go b/pkg/sentry/fs/host/ioctl_unsafe.go index 175dca613..b5a85c4d9 100644 --- a/pkg/sentry/fs/host/ioctl_unsafe.go +++ b/pkg/sentry/fs/host/ioctl_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket.go b/pkg/sentry/fs/host/socket.go index be2c3581f..3034e9441 100644 --- a/pkg/sentry/fs/host/socket.go +++ b/pkg/sentry/fs/host/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket_iovec.go b/pkg/sentry/fs/host/socket_iovec.go index d4ce4a8c1..5efbb3ae8 100644 --- a/pkg/sentry/fs/host/socket_iovec.go +++ b/pkg/sentry/fs/host/socket_iovec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket_state.go b/pkg/sentry/fs/host/socket_state.go index 2932c1f16..5676c451a 100644 --- a/pkg/sentry/fs/host/socket_state.go +++ b/pkg/sentry/fs/host/socket_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket_test.go b/pkg/sentry/fs/host/socket_test.go index 83e8e1b3c..cc760a7e1 100644 --- a/pkg/sentry/fs/host/socket_test.go +++ b/pkg/sentry/fs/host/socket_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket_unsafe.go b/pkg/sentry/fs/host/socket_unsafe.go index f35e2492d..8873705c0 100644 --- a/pkg/sentry/fs/host/socket_unsafe.go +++ b/pkg/sentry/fs/host/socket_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/tty.go b/pkg/sentry/fs/host/tty.go index c5cb75df7..e45b339f5 100644 --- a/pkg/sentry/fs/host/tty.go +++ b/pkg/sentry/fs/host/tty.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/util.go b/pkg/sentry/fs/host/util.go index 40c450660..94ff7708e 100644 --- a/pkg/sentry/fs/host/util.go +++ b/pkg/sentry/fs/host/util.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/util_unsafe.go b/pkg/sentry/fs/host/util_unsafe.go index a8721d197..b95a57c3f 100644 --- a/pkg/sentry/fs/host/util_unsafe.go +++ b/pkg/sentry/fs/host/util_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/wait_test.go b/pkg/sentry/fs/host/wait_test.go index 9ca8c399f..afcb74724 100644 --- a/pkg/sentry/fs/host/wait_test.go +++ b/pkg/sentry/fs/host/wait_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index fe411a766..d764ef93d 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode_inotify.go b/pkg/sentry/fs/inode_inotify.go index d2b653bc7..0f2a66a79 100644 --- a/pkg/sentry/fs/inode_inotify.go +++ b/pkg/sentry/fs/inode_inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode_operations.go b/pkg/sentry/fs/inode_operations.go index ff8b75f31..ac287e1e4 100644 --- a/pkg/sentry/fs/inode_operations.go +++ b/pkg/sentry/fs/inode_operations.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go index bda3e1861..3d015328e 100644 --- a/pkg/sentry/fs/inode_overlay.go +++ b/pkg/sentry/fs/inode_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode_overlay_test.go b/pkg/sentry/fs/inode_overlay_test.go index fa8accf6c..66b3da2d0 100644 --- a/pkg/sentry/fs/inode_overlay_test.go +++ b/pkg/sentry/fs/inode_overlay_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 59fa662f3..2652582c3 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go index f09928b68..d52f956e4 100644 --- a/pkg/sentry/fs/inotify_event.go +++ b/pkg/sentry/fs/inotify_event.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inotify_watch.go b/pkg/sentry/fs/inotify_watch.go index d33e7e498..a0b488467 100644 --- a/pkg/sentry/fs/inotify_watch.go +++ b/pkg/sentry/fs/inotify_watch.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go index 5ff800d2d..f2aee4512 100644 --- a/pkg/sentry/fs/lock/lock.go +++ b/pkg/sentry/fs/lock/lock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/lock/lock_range_test.go b/pkg/sentry/fs/lock/lock_range_test.go index b0ab882b9..6221199d1 100644 --- a/pkg/sentry/fs/lock/lock_range_test.go +++ b/pkg/sentry/fs/lock/lock_range_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/lock/lock_set_functions.go b/pkg/sentry/fs/lock/lock_set_functions.go index 395592a4b..8a3ace0c1 100644 --- a/pkg/sentry/fs/lock/lock_set_functions.go +++ b/pkg/sentry/fs/lock/lock_set_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/lock/lock_test.go b/pkg/sentry/fs/lock/lock_test.go index 67fa4b1dd..ba002aeb7 100644 --- a/pkg/sentry/fs/lock/lock_test.go +++ b/pkg/sentry/fs/lock/lock_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mock.go b/pkg/sentry/fs/mock.go index 118e30f63..cf359a1f1 100644 --- a/pkg/sentry/fs/mock.go +++ b/pkg/sentry/fs/mock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index 4d1693204..a169ea4c9 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go index fb60a1aec..535f812c8 100644 --- a/pkg/sentry/fs/mount_overlay.go +++ b/pkg/sentry/fs/mount_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mount_test.go b/pkg/sentry/fs/mount_test.go index d7605b2c9..9f7fbeff2 100644 --- a/pkg/sentry/fs/mount_test.go +++ b/pkg/sentry/fs/mount_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go index f6f7be0aa..01eb4607e 100644 --- a/pkg/sentry/fs/mounts.go +++ b/pkg/sentry/fs/mounts.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mounts_test.go b/pkg/sentry/fs/mounts_test.go index 54000614f..56d726dd1 100644 --- a/pkg/sentry/fs/mounts_test.go +++ b/pkg/sentry/fs/mounts_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/offset.go b/pkg/sentry/fs/offset.go index 38aee765a..3f68da149 100644 --- a/pkg/sentry/fs/offset.go +++ b/pkg/sentry/fs/offset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go index f3e2d5cbe..db89a5f70 100644 --- a/pkg/sentry/fs/overlay.go +++ b/pkg/sentry/fs/overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/path.go b/pkg/sentry/fs/path.go index 52139b648..e4dc02dbb 100644 --- a/pkg/sentry/fs/path.go +++ b/pkg/sentry/fs/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/path_test.go b/pkg/sentry/fs/path_test.go index 4ba1498f6..e6f57ebba 100644 --- a/pkg/sentry/fs/path_test.go +++ b/pkg/sentry/fs/path_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go index f756c45bf..15031234e 100644 --- a/pkg/sentry/fs/proc/cpuinfo.go +++ b/pkg/sentry/fs/proc/cpuinfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/device/device.go b/pkg/sentry/fs/proc/device/device.go index 04b687bcf..0de466c73 100644 --- a/pkg/sentry/fs/proc/device/device.go +++ b/pkg/sentry/fs/proc/device/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index fc21dfbbd..d49dad685 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index f2329e623..744b31c74 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/filesystems.go b/pkg/sentry/fs/proc/filesystems.go index c050a00be..7bb081d0e 100644 --- a/pkg/sentry/fs/proc/filesystems.go +++ b/pkg/sentry/fs/proc/filesystems.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/fs.go b/pkg/sentry/fs/proc/fs.go index 666a2d054..7c5f8484a 100644 --- a/pkg/sentry/fs/proc/fs.go +++ b/pkg/sentry/fs/proc/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/inode.go b/pkg/sentry/fs/proc/inode.go index 8dde2ea46..b03807043 100644 --- a/pkg/sentry/fs/proc/inode.go +++ b/pkg/sentry/fs/proc/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go index 3ee0e570a..2dfe7089a 100644 --- a/pkg/sentry/fs/proc/loadavg.go +++ b/pkg/sentry/fs/proc/loadavg.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go index 75cbf3e77..d2b9b92c7 100644 --- a/pkg/sentry/fs/proc/meminfo.go +++ b/pkg/sentry/fs/proc/meminfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index fe62b167b..37ed30724 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go index d24b2d370..4a107c739 100644 --- a/pkg/sentry/fs/proc/net.go +++ b/pkg/sentry/fs/proc/net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/net_test.go b/pkg/sentry/fs/proc/net_test.go index 94677cc1d..9aed5fdca 100644 --- a/pkg/sentry/fs/proc/net_test.go +++ b/pkg/sentry/fs/proc/net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index 64e1e1998..196fa5128 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/rpcinet_proc.go b/pkg/sentry/fs/proc/rpcinet_proc.go index 81f64a28b..db53686f6 100644 --- a/pkg/sentry/fs/proc/rpcinet_proc.go +++ b/pkg/sentry/fs/proc/rpcinet_proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index 0a0eb45e2..10ea1f55d 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/seqfile/seqfile_test.go b/pkg/sentry/fs/proc/seqfile/seqfile_test.go index 35403ab7f..c4de565eb 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile_test.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go index 18bd8e9b6..397f9ec6b 100644 --- a/pkg/sentry/fs/proc/stat.go +++ b/pkg/sentry/fs/proc/stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index a7bc9198e..b889ed625 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index 0ce77f04f..e49794a48 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/sys_net_state.go b/pkg/sentry/fs/proc/sys_net_state.go index 5f481a1cf..6eba709c6 100644 --- a/pkg/sentry/fs/proc/sys_net_state.go +++ b/pkg/sentry/fs/proc/sys_net_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/sys_net_test.go b/pkg/sentry/fs/proc/sys_net_test.go index ea0d94fce..78135ba13 100644 --- a/pkg/sentry/fs/proc/sys_net_test.go +++ b/pkg/sentry/fs/proc/sys_net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 9f65a8337..0f400e80f 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index d433632cf..d649da0f1 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index d7ae26fcf..1ddf9fafa 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go index 58e0c793c..a5479990c 100644 --- a/pkg/sentry/fs/proc/version.go +++ b/pkg/sentry/fs/proc/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index c0400b67d..a6b6a5c33 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index 5bcb6c364..9406a07ca 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index 35dabdad2..f7835fe05 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/tree.go b/pkg/sentry/fs/ramfs/tree.go index c1ac8a78b..8c6b31f70 100644 --- a/pkg/sentry/fs/ramfs/tree.go +++ b/pkg/sentry/fs/ramfs/tree.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/tree_test.go b/pkg/sentry/fs/ramfs/tree_test.go index 8bee9cfc1..27abeb6ba 100644 --- a/pkg/sentry/fs/ramfs/tree_test.go +++ b/pkg/sentry/fs/ramfs/tree_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/restore.go b/pkg/sentry/fs/restore.go index a6645b41e..f10168125 100644 --- a/pkg/sentry/fs/restore.go +++ b/pkg/sentry/fs/restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/save.go b/pkg/sentry/fs/save.go index 90988d385..2eaf6ab69 100644 --- a/pkg/sentry/fs/save.go +++ b/pkg/sentry/fs/save.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/seek.go b/pkg/sentry/fs/seek.go index 72f3fb632..0f43918ad 100644 --- a/pkg/sentry/fs/seek.go +++ b/pkg/sentry/fs/seek.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sync.go b/pkg/sentry/fs/sync.go index 6dcc2fe8d..1fff8059c 100644 --- a/pkg/sentry/fs/sync.go +++ b/pkg/sentry/fs/sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sys/device.go b/pkg/sentry/fs/sys/device.go index 38ecd0c18..128d3a9d9 100644 --- a/pkg/sentry/fs/sys/device.go +++ b/pkg/sentry/fs/sys/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sys/devices.go b/pkg/sentry/fs/sys/devices.go index 8b728a4e4..db91de435 100644 --- a/pkg/sentry/fs/sys/devices.go +++ b/pkg/sentry/fs/sys/devices.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go index 44ae43754..f0c2322e0 100644 --- a/pkg/sentry/fs/sys/fs.go +++ b/pkg/sentry/fs/sys/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go index c5b56fe69..d20ef91fa 100644 --- a/pkg/sentry/fs/sys/sys.go +++ b/pkg/sentry/fs/sys/sys.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index ef9a08854..749961f51 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/device.go b/pkg/sentry/fs/tmpfs/device.go index aade93c26..179c3a46f 100644 --- a/pkg/sentry/fs/tmpfs/device.go +++ b/pkg/sentry/fs/tmpfs/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index d0c9b8bea..1ef256511 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/file_test.go b/pkg/sentry/fs/tmpfs/file_test.go index 743061190..b44c06556 100644 --- a/pkg/sentry/fs/tmpfs/file_test.go +++ b/pkg/sentry/fs/tmpfs/file_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index 8e44421b6..b7c29a4d1 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 4450e1363..f89d86c83 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 5bb4922cb..832914453 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index f8713471a..0fc777e67 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go index a53448c47..701b2f7d9 100644 --- a/pkg/sentry/fs/tty/fs.go +++ b/pkg/sentry/fs/tty/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index c4a364edb..20d29d130 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index e2686a074..45e167e5f 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/queue.go b/pkg/sentry/fs/tty/queue.go index 5e88d84d9..11fb92be3 100644 --- a/pkg/sentry/fs/tty/queue.go +++ b/pkg/sentry/fs/tty/queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index ed080ca0f..0ae57a02c 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/terminal.go b/pkg/sentry/fs/tty/terminal.go index 79f9d76d7..2b4160ba5 100644 --- a/pkg/sentry/fs/tty/terminal.go +++ b/pkg/sentry/fs/tty/terminal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/tty_test.go b/pkg/sentry/fs/tty/tty_test.go index ad535838f..d2e75a511 100644 --- a/pkg/sentry/fs/tty/tty_test.go +++ b/pkg/sentry/fs/tty/tty_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/hostcpu/getcpu_amd64.s b/pkg/sentry/hostcpu/getcpu_amd64.s index 409db1450..aa00316da 100644 --- a/pkg/sentry/hostcpu/getcpu_amd64.s +++ b/pkg/sentry/hostcpu/getcpu_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/hostcpu/hostcpu.go b/pkg/sentry/hostcpu/hostcpu.go index 3adc847bb..d78f78402 100644 --- a/pkg/sentry/hostcpu/hostcpu.go +++ b/pkg/sentry/hostcpu/hostcpu.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/hostcpu/hostcpu_test.go b/pkg/sentry/hostcpu/hostcpu_test.go index 38de0e1f6..7d6885c9e 100644 --- a/pkg/sentry/hostcpu/hostcpu_test.go +++ b/pkg/sentry/hostcpu/hostcpu_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/inet/context.go b/pkg/sentry/inet/context.go index d05e96f15..8550c4793 100644 --- a/pkg/sentry/inet/context.go +++ b/pkg/sentry/inet/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index 8206377cc..7c104fd47 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/inet/test_stack.go b/pkg/sentry/inet/test_stack.go index 05c1a1792..624371eb6 100644 --- a/pkg/sentry/inet/test_stack.go +++ b/pkg/sentry/inet/test_stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go index 1ea2cee36..5ce52e66c 100644 --- a/pkg/sentry/kernel/abstract_socket_namespace.go +++ b/pkg/sentry/kernel/abstract_socket_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/auth.go b/pkg/sentry/kernel/auth/auth.go index 19f15fd36..847d121aa 100644 --- a/pkg/sentry/kernel/auth/auth.go +++ b/pkg/sentry/kernel/auth/auth.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/capability_set.go b/pkg/sentry/kernel/auth/capability_set.go index 88d6243aa..7a0c967cd 100644 --- a/pkg/sentry/kernel/auth/capability_set.go +++ b/pkg/sentry/kernel/auth/capability_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/context.go b/pkg/sentry/kernel/auth/context.go index f7e945599..16d110610 100644 --- a/pkg/sentry/kernel/auth/context.go +++ b/pkg/sentry/kernel/auth/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index 2055da196..1511a0324 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/id.go b/pkg/sentry/kernel/auth/id.go index e5bed44d7..0a58ba17c 100644 --- a/pkg/sentry/kernel/auth/id.go +++ b/pkg/sentry/kernel/auth/id.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index 43f439825..e5d6028d6 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/id_map_functions.go b/pkg/sentry/kernel/auth/id_map_functions.go index 8f1a189ec..432dbfb6d 100644 --- a/pkg/sentry/kernel/auth/id_map_functions.go +++ b/pkg/sentry/kernel/auth/id_map_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index 159940a69..a40dd668f 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/context.go b/pkg/sentry/kernel/context.go index b629521eb..a1a084eab 100644 --- a/pkg/sentry/kernel/context.go +++ b/pkg/sentry/kernel/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/contexttest/contexttest.go b/pkg/sentry/kernel/contexttest/contexttest.go index eb56a6a07..ae67e2a25 100644 --- a/pkg/sentry/kernel/contexttest/contexttest.go +++ b/pkg/sentry/kernel/contexttest/contexttest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index befefb11c..2399ae6f2 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/epoll/epoll_state.go b/pkg/sentry/kernel/epoll/epoll_state.go index f6e3e4825..4c3c38f9e 100644 --- a/pkg/sentry/kernel/epoll/epoll_state.go +++ b/pkg/sentry/kernel/epoll/epoll_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/epoll/epoll_test.go b/pkg/sentry/kernel/epoll/epoll_test.go index d89c1b745..49b781b69 100644 --- a/pkg/sentry/kernel/epoll/epoll_test.go +++ b/pkg/sentry/kernel/epoll/epoll_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index b448ad813..5d3139eef 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/eventfd/eventfd_test.go b/pkg/sentry/kernel/eventfd/eventfd_test.go index 14e8996d9..1159638e5 100644 --- a/pkg/sentry/kernel/eventfd/eventfd_test.go +++ b/pkg/sentry/kernel/eventfd/eventfd_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/fasync/fasync.go b/pkg/sentry/kernel/fasync/fasync.go index 298d988ea..84cd08501 100644 --- a/pkg/sentry/kernel/fasync/fasync.go +++ b/pkg/sentry/kernel/fasync/fasync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index 715f4714d..c5636d233 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/fd_map_test.go b/pkg/sentry/kernel/fd_map_test.go index 9e76f0a2d..22db4c7cf 100644 --- a/pkg/sentry/kernel/fd_map_test.go +++ b/pkg/sentry/kernel/fd_map_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index 3cf0db280..d8115f59a 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index cd7d51621..bb38eb81e 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/futex/futex_test.go b/pkg/sentry/kernel/futex/futex_test.go index 9d44ee8e5..2de5239bf 100644 --- a/pkg/sentry/kernel/futex/futex_test.go +++ b/pkg/sentry/kernel/futex/futex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index 9ceb9bd92..ebe12812c 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/kdefs/kdefs.go b/pkg/sentry/kernel/kdefs/kdefs.go index 8eafe810b..304da2032 100644 --- a/pkg/sentry/kernel/kdefs/kdefs.go +++ b/pkg/sentry/kernel/kdefs/kdefs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index a1b2d7161..0468dd678 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/kernel_state.go b/pkg/sentry/kernel/kernel_state.go index aae6f9ad2..48c3ff5a9 100644 --- a/pkg/sentry/kernel/kernel_state.go +++ b/pkg/sentry/kernel/kernel_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/memevent/memory_events.go b/pkg/sentry/kernel/memevent/memory_events.go index d09d6debf..0e2cee807 100644 --- a/pkg/sentry/kernel/memevent/memory_events.go +++ b/pkg/sentry/kernel/memevent/memory_events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/memevent/memory_events.proto b/pkg/sentry/kernel/memevent/memory_events.proto index 43b8deb76..bf8029ff5 100644 --- a/pkg/sentry/kernel/memevent/memory_events.proto +++ b/pkg/sentry/kernel/memevent/memory_events.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index deff6def9..c93f6598a 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pending_signals_state.go b/pkg/sentry/kernel/pending_signals_state.go index 72be6702f..2c902c7e3 100644 --- a/pkg/sentry/kernel/pending_signals_state.go +++ b/pkg/sentry/kernel/pending_signals_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index 54e059f8b..ba53fd482 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/device.go b/pkg/sentry/kernel/pipe/device.go index eec5c5de8..eb59e15a1 100644 --- a/pkg/sentry/kernel/pipe/device.go +++ b/pkg/sentry/kernel/pipe/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index 1336b6293..99188dddf 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/node_test.go b/pkg/sentry/kernel/pipe/node_test.go index ad103b195..7ddecdad8 100644 --- a/pkg/sentry/kernel/pipe/node_test.go +++ b/pkg/sentry/kernel/pipe/node_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index 357d1162e..bd7649d2f 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/pipe_test.go b/pkg/sentry/kernel/pipe/pipe_test.go index 3b9895927..de340c40c 100644 --- a/pkg/sentry/kernel/pipe/pipe_test.go +++ b/pkg/sentry/kernel/pipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index f27379969..48fab45d1 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index 1090432d7..ddcc5e09a 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index 6fea9769c..0f29fbc43 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/posixtimer.go b/pkg/sentry/kernel/posixtimer.go index 40b5acca3..a016b4087 100644 --- a/pkg/sentry/kernel/posixtimer.go +++ b/pkg/sentry/kernel/posixtimer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index 15f2e2964..4423e7efd 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/ptrace_amd64.go b/pkg/sentry/kernel/ptrace_amd64.go index 1f88efca3..048eeaa3f 100644 --- a/pkg/sentry/kernel/ptrace_amd64.go +++ b/pkg/sentry/kernel/ptrace_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google Inc. +// Copyright 2019 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. diff --git a/pkg/sentry/kernel/ptrace_arm64.go b/pkg/sentry/kernel/ptrace_arm64.go index 4636405e6..4899c813f 100644 --- a/pkg/sentry/kernel/ptrace_arm64.go +++ b/pkg/sentry/kernel/ptrace_arm64.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google Inc. +// Copyright 2019 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. diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 6d3314e81..c4fb2c56c 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/sched/cpuset.go b/pkg/sentry/kernel/sched/cpuset.go index 41ac1067d..c6c436690 100644 --- a/pkg/sentry/kernel/sched/cpuset.go +++ b/pkg/sentry/kernel/sched/cpuset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/sched/cpuset_test.go b/pkg/sentry/kernel/sched/cpuset_test.go index a036ed513..3af9f1197 100644 --- a/pkg/sentry/kernel/sched/cpuset_test.go +++ b/pkg/sentry/kernel/sched/cpuset_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/sched/sched.go b/pkg/sentry/kernel/sched/sched.go index e59909baf..de18c9d02 100644 --- a/pkg/sentry/kernel/sched/sched.go +++ b/pkg/sentry/kernel/sched/sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go index 4bed4d373..cc75eb08a 100644 --- a/pkg/sentry/kernel/seccomp.go +++ b/pkg/sentry/kernel/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index 2b7c1a9bc..9d0620e02 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/semaphore/semaphore_test.go b/pkg/sentry/kernel/semaphore/semaphore_test.go index 2e51e6ee5..abfcd0fb4 100644 --- a/pkg/sentry/kernel/semaphore/semaphore_test.go +++ b/pkg/sentry/kernel/semaphore/semaphore_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index 070c2f930..610e199da 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/shm/device.go b/pkg/sentry/kernel/shm/device.go index bbc653ed8..3cb759072 100644 --- a/pkg/sentry/kernel/shm/device.go +++ b/pkg/sentry/kernel/shm/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index d4812a065..00393b5f0 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/signal.go b/pkg/sentry/kernel/signal.go index 22a56c6fc..b528ec0dc 100644 --- a/pkg/sentry/kernel/signal.go +++ b/pkg/sentry/kernel/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 60cbe85b8..ce8bcb5e5 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index 293b21249..0572053db 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/syscalls_state.go b/pkg/sentry/kernel/syscalls_state.go index 981455d46..00358326b 100644 --- a/pkg/sentry/kernel/syscalls_state.go +++ b/pkg/sentry/kernel/syscalls_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go index 2aecf3eea..175d1b247 100644 --- a/pkg/sentry/kernel/syslog.go +++ b/pkg/sentry/kernel/syslog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/table_test.go b/pkg/sentry/kernel/table_test.go index 3b29d3c6a..8f7cdb9f3 100644 --- a/pkg/sentry/kernel/table_test.go +++ b/pkg/sentry/kernel/table_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index ed2175c37..f9378c2de 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_acct.go b/pkg/sentry/kernel/task_acct.go index 24230af89..1ca2a82eb 100644 --- a/pkg/sentry/kernel/task_acct.go +++ b/pkg/sentry/kernel/task_acct.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_block.go b/pkg/sentry/kernel/task_block.go index e5027e551..30a7f6b1e 100644 --- a/pkg/sentry/kernel/task_block.go +++ b/pkg/sentry/kernel/task_block.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index daf974920..bba8ddd39 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index ac38dd157..bbd294141 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index b49f902a5..5d1425d5c 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index a07956208..6e9701b01 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_futex.go b/pkg/sentry/kernel/task_futex.go index 351cf47d7..f98097c2c 100644 --- a/pkg/sentry/kernel/task_futex.go +++ b/pkg/sentry/kernel/task_futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_identity.go b/pkg/sentry/kernel/task_identity.go index 6c9608f8d..17f08729a 100644 --- a/pkg/sentry/kernel/task_identity.go +++ b/pkg/sentry/kernel/task_identity.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_log.go b/pkg/sentry/kernel/task_log.go index f4c881c2d..e0e57e8bd 100644 --- a/pkg/sentry/kernel/task_log.go +++ b/pkg/sentry/kernel/task_log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_net.go b/pkg/sentry/kernel/task_net.go index fc7cefc1f..04c684c1a 100644 --- a/pkg/sentry/kernel/task_net.go +++ b/pkg/sentry/kernel/task_net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 7115aa967..4549b437e 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index 3d654bf93..5455f6ea9 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 7f2e0df72..654cf7525 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_start.go b/pkg/sentry/kernel/task_start.go index b7534c0a2..b42531e57 100644 --- a/pkg/sentry/kernel/task_start.go +++ b/pkg/sentry/kernel/task_start.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_stop.go b/pkg/sentry/kernel/task_stop.go index 1302cadc1..e735a5dd0 100644 --- a/pkg/sentry/kernel/task_stop.go +++ b/pkg/sentry/kernel/task_stop.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 52f5fde8d..a9283d0df 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_test.go b/pkg/sentry/kernel/task_test.go index 3f37f505d..b895361d0 100644 --- a/pkg/sentry/kernel/task_test.go +++ b/pkg/sentry/kernel/task_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_usermem.go b/pkg/sentry/kernel/task_usermem.go index cb68799d3..461bd7316 100644 --- a/pkg/sentry/kernel/task_usermem.go +++ b/pkg/sentry/kernel/task_usermem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index 58f3a7ec9..8bd53928e 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 4fd6cf4e2..656bbd46c 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/time/context.go b/pkg/sentry/kernel/time/context.go index 3675ea20d..c0660d362 100644 --- a/pkg/sentry/kernel/time/context.go +++ b/pkg/sentry/kernel/time/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index ca0f4ba2e..3846cf1ea 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index d7bd85e78..505a4fa4f 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/timekeeper_state.go b/pkg/sentry/kernel/timekeeper_state.go index f3a3ed543..6ce358a05 100644 --- a/pkg/sentry/kernel/timekeeper_state.go +++ b/pkg/sentry/kernel/timekeeper_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/timekeeper_test.go b/pkg/sentry/kernel/timekeeper_test.go index 6084bcb18..a92ad689e 100644 --- a/pkg/sentry/kernel/timekeeper_test.go +++ b/pkg/sentry/kernel/timekeeper_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/uncaught_signal.proto b/pkg/sentry/kernel/uncaught_signal.proto index c7f6a1978..0bdb062cb 100644 --- a/pkg/sentry/kernel/uncaught_signal.proto +++ b/pkg/sentry/kernel/uncaught_signal.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go index ed5f0c031..96fe3cbb9 100644 --- a/pkg/sentry/kernel/uts_namespace.go +++ b/pkg/sentry/kernel/uts_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go index 3a35f1d00..d40ad74f4 100644 --- a/pkg/sentry/kernel/vdso.go +++ b/pkg/sentry/kernel/vdso.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/version.go b/pkg/sentry/kernel/version.go index 8d2f14209..5640dd71d 100644 --- a/pkg/sentry/kernel/version.go +++ b/pkg/sentry/kernel/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/limits/context.go b/pkg/sentry/limits/context.go index bf413eb7d..9200edb52 100644 --- a/pkg/sentry/limits/context.go +++ b/pkg/sentry/limits/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index b0571739f..b6c22656b 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/limits/limits_test.go b/pkg/sentry/limits/limits_test.go index 945428163..658a20f56 100644 --- a/pkg/sentry/limits/limits_test.go +++ b/pkg/sentry/limits/limits_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/limits/linux.go b/pkg/sentry/limits/linux.go index e09d0d2fb..a2b401e3d 100644 --- a/pkg/sentry/limits/linux.go +++ b/pkg/sentry/limits/linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/elf.go b/pkg/sentry/loader/elf.go index 385ad0102..97e32c8ba 100644 --- a/pkg/sentry/loader/elf.go +++ b/pkg/sentry/loader/elf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/interpreter.go b/pkg/sentry/loader/interpreter.go index 35b83654d..b88062ae5 100644 --- a/pkg/sentry/loader/interpreter.go +++ b/pkg/sentry/loader/interpreter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go index 79051befa..dc1a52398 100644 --- a/pkg/sentry/loader/loader.go +++ b/pkg/sentry/loader/loader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index 8c196df84..207d8ed3d 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/vdso_state.go b/pkg/sentry/loader/vdso_state.go index b327f0e1e..db378e90a 100644 --- a/pkg/sentry/loader/vdso_state.go +++ b/pkg/sentry/loader/vdso_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memmap/mapping_set.go b/pkg/sentry/memmap/mapping_set.go index bd07e9aac..3cf2b338f 100644 --- a/pkg/sentry/memmap/mapping_set.go +++ b/pkg/sentry/memmap/mapping_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memmap/mapping_set_test.go b/pkg/sentry/memmap/mapping_set_test.go index 45d1d4688..c702555ce 100644 --- a/pkg/sentry/memmap/mapping_set_test.go +++ b/pkg/sentry/memmap/mapping_set_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index 3f6f7ebd0..0106c857d 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memutil/memutil.go b/pkg/sentry/memutil/memutil.go index 286d50ca4..a4154c42a 100644 --- a/pkg/sentry/memutil/memutil.go +++ b/pkg/sentry/memutil/memutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memutil/memutil_unsafe.go b/pkg/sentry/memutil/memutil_unsafe.go index bc2c72f55..92eab8a26 100644 --- a/pkg/sentry/memutil/memutil_unsafe.go +++ b/pkg/sentry/memutil/memutil_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/address_space.go b/pkg/sentry/mm/address_space.go index 4dddcf7b5..06f587fde 100644 --- a/pkg/sentry/mm/address_space.go +++ b/pkg/sentry/mm/address_space.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go index 7075792e0..5c61acf36 100644 --- a/pkg/sentry/mm/aio_context.go +++ b/pkg/sentry/mm/aio_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/aio_context_state.go b/pkg/sentry/mm/aio_context_state.go index 192a6f744..c37fc9f7b 100644 --- a/pkg/sentry/mm/aio_context_state.go +++ b/pkg/sentry/mm/aio_context_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/debug.go b/pkg/sentry/mm/debug.go index d075ee1ca..fe58cfc4c 100644 --- a/pkg/sentry/mm/debug.go +++ b/pkg/sentry/mm/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/io.go b/pkg/sentry/mm/io.go index 81787a6fd..e4c057d28 100644 --- a/pkg/sentry/mm/io.go +++ b/pkg/sentry/mm/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/lifecycle.go b/pkg/sentry/mm/lifecycle.go index 2fe03172c..e6aa6f9ef 100644 --- a/pkg/sentry/mm/lifecycle.go +++ b/pkg/sentry/mm/lifecycle.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/metadata.go b/pkg/sentry/mm/metadata.go index 5ef1ba0b1..9768e51f1 100644 --- a/pkg/sentry/mm/metadata.go +++ b/pkg/sentry/mm/metadata.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index a3417a46e..d25aa5136 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/mm_test.go b/pkg/sentry/mm/mm_test.go index ae4fba478..f4917419f 100644 --- a/pkg/sentry/mm/mm_test.go +++ b/pkg/sentry/mm/mm_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/pma.go b/pkg/sentry/mm/pma.go index 0cca743ef..ece561ff0 100644 --- a/pkg/sentry/mm/pma.go +++ b/pkg/sentry/mm/pma.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/procfs.go b/pkg/sentry/mm/procfs.go index 7cdbf6e25..c8302a553 100644 --- a/pkg/sentry/mm/procfs.go +++ b/pkg/sentry/mm/procfs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/save_restore.go b/pkg/sentry/mm/save_restore.go index 46e0e0754..0385957bd 100644 --- a/pkg/sentry/mm/save_restore.go +++ b/pkg/sentry/mm/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/shm.go b/pkg/sentry/mm/shm.go index 3bc48c7e7..12913007b 100644 --- a/pkg/sentry/mm/shm.go +++ b/pkg/sentry/mm/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go index 3b5161998..687959005 100644 --- a/pkg/sentry/mm/special_mappable.go +++ b/pkg/sentry/mm/special_mappable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index 7b675b9b5..a25318abb 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index 931995254..ad901344b 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/pgalloc/context.go b/pkg/sentry/pgalloc/context.go index adc97e78f..cb9809b1f 100644 --- a/pkg/sentry/pgalloc/context.go +++ b/pkg/sentry/pgalloc/context.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google Inc. +// Copyright 2019 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. diff --git a/pkg/sentry/pgalloc/pgalloc.go b/pkg/sentry/pgalloc/pgalloc.go index 0754e608f..411dafa07 100644 --- a/pkg/sentry/pgalloc/pgalloc.go +++ b/pkg/sentry/pgalloc/pgalloc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/pgalloc/pgalloc_test.go b/pkg/sentry/pgalloc/pgalloc_test.go index 726623c1a..14a39bb9e 100644 --- a/pkg/sentry/pgalloc/pgalloc_test.go +++ b/pkg/sentry/pgalloc/pgalloc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/pgalloc/pgalloc_unsafe.go b/pkg/sentry/pgalloc/pgalloc_unsafe.go index 33b0a68a8..a4b5d581c 100644 --- a/pkg/sentry/pgalloc/pgalloc_unsafe.go +++ b/pkg/sentry/pgalloc/pgalloc_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/pgalloc/save_restore.go b/pkg/sentry/pgalloc/save_restore.go index 21024e656..cf169af55 100644 --- a/pkg/sentry/pgalloc/save_restore.go +++ b/pkg/sentry/pgalloc/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/context.go b/pkg/sentry/platform/context.go index cca21a23e..793f57fd7 100644 --- a/pkg/sentry/platform/context.go +++ b/pkg/sentry/platform/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/interrupt/interrupt.go b/pkg/sentry/platform/interrupt/interrupt.go index 9c83f41eb..a4651f500 100644 --- a/pkg/sentry/platform/interrupt/interrupt.go +++ b/pkg/sentry/platform/interrupt/interrupt.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/interrupt/interrupt_test.go b/pkg/sentry/platform/interrupt/interrupt_test.go index fb3284395..0ecdf6e7a 100644 --- a/pkg/sentry/platform/interrupt/interrupt_test.go +++ b/pkg/sentry/platform/interrupt/interrupt_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/address_space.go b/pkg/sentry/platform/kvm/address_space.go index f2f7ab1e8..689122175 100644 --- a/pkg/sentry/platform/kvm/address_space.go +++ b/pkg/sentry/platform/kvm/address_space.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/allocator.go b/pkg/sentry/platform/kvm/allocator.go index b25cad155..42bcc9733 100644 --- a/pkg/sentry/platform/kvm/allocator.go +++ b/pkg/sentry/platform/kvm/allocator.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill.go b/pkg/sentry/platform/kvm/bluepill.go index f24f1c662..a926e6f8b 100644 --- a/pkg/sentry/platform/kvm/bluepill.go +++ b/pkg/sentry/platform/kvm/bluepill.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.go b/pkg/sentry/platform/kvm/bluepill_amd64.go index 6520682d7..c258408f9 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.s b/pkg/sentry/platform/kvm/bluepill_amd64.s index 65b01f358..2bc34a435 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.s +++ b/pkg/sentry/platform/kvm/bluepill_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go index 21de2488e..92fde7ee0 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_fault.go b/pkg/sentry/platform/kvm/bluepill_fault.go index e79a30ef2..3c452f5ba 100644 --- a/pkg/sentry/platform/kvm/bluepill_fault.go +++ b/pkg/sentry/platform/kvm/bluepill_fault.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_unsafe.go b/pkg/sentry/platform/kvm/bluepill_unsafe.go index 2605f8c93..4184939e5 100644 --- a/pkg/sentry/platform/kvm/bluepill_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/context.go b/pkg/sentry/platform/kvm/context.go index c75a4b415..0eb0020f7 100644 --- a/pkg/sentry/platform/kvm/context.go +++ b/pkg/sentry/platform/kvm/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm.go b/pkg/sentry/platform/kvm/kvm.go index c5a4435b1..ed0521c3f 100644 --- a/pkg/sentry/platform/kvm/kvm.go +++ b/pkg/sentry/platform/kvm/kvm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm_amd64.go b/pkg/sentry/platform/kvm/kvm_amd64.go index 70d0ac63b..61493ccaf 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64.go +++ b/pkg/sentry/platform/kvm/kvm_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go index d0f6bb225..46c4b9113 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm_const.go b/pkg/sentry/platform/kvm/kvm_const.go index cac8d9937..d05f05c29 100644 --- a/pkg/sentry/platform/kvm/kvm_const.go +++ b/pkg/sentry/platform/kvm/kvm_const.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm_test.go b/pkg/sentry/platform/kvm/kvm_test.go index 361200622..e83db71e9 100644 --- a/pkg/sentry/platform/kvm/kvm_test.go +++ b/pkg/sentry/platform/kvm/kvm_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index b8b3c9a4a..f5953b96e 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go index ccfe837b5..b6821122a 100644 --- a/pkg/sentry/platform/kvm/machine_amd64.go +++ b/pkg/sentry/platform/kvm/machine_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go index 69ba67ced..06a2e3b0c 100644 --- a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/machine_unsafe.go b/pkg/sentry/platform/kvm/machine_unsafe.go index 22ae60b63..452d88d7f 100644 --- a/pkg/sentry/platform/kvm/machine_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/physical_map.go b/pkg/sentry/platform/kvm/physical_map.go index 9d7dca5b3..450eb8201 100644 --- a/pkg/sentry/platform/kvm/physical_map.go +++ b/pkg/sentry/platform/kvm/physical_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/testutil/testutil.go b/pkg/sentry/platform/kvm/testutil/testutil.go index 0d496561d..6cf2359a3 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil.go +++ b/pkg/sentry/platform/kvm/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/testutil/testutil_amd64.go b/pkg/sentry/platform/kvm/testutil/testutil_amd64.go index fcba33813..203d71528 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_amd64.go +++ b/pkg/sentry/platform/kvm/testutil/testutil_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/testutil/testutil_amd64.s b/pkg/sentry/platform/kvm/testutil/testutil_amd64.s index f1da41a44..491ec0c2a 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_amd64.s +++ b/pkg/sentry/platform/kvm/testutil/testutil_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/virtual_map.go b/pkg/sentry/platform/kvm/virtual_map.go index 0343e9267..28a1b4414 100644 --- a/pkg/sentry/platform/kvm/virtual_map.go +++ b/pkg/sentry/platform/kvm/virtual_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/virtual_map_test.go b/pkg/sentry/platform/kvm/virtual_map_test.go index 935e0eb93..d03ec654a 100644 --- a/pkg/sentry/platform/kvm/virtual_map_test.go +++ b/pkg/sentry/platform/kvm/virtual_map_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/mmap_min_addr.go b/pkg/sentry/platform/mmap_min_addr.go index 1bcc1f8e9..90976735b 100644 --- a/pkg/sentry/platform/mmap_min_addr.go +++ b/pkg/sentry/platform/mmap_min_addr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go index 0e48417b9..ae37276ad 100644 --- a/pkg/sentry/platform/platform.go +++ b/pkg/sentry/platform/platform.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid.go b/pkg/sentry/platform/procid/procid.go index 3f49ab093..78b92422c 100644 --- a/pkg/sentry/platform/procid/procid.go +++ b/pkg/sentry/platform/procid/procid.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid_amd64.s b/pkg/sentry/platform/procid/procid_amd64.s index ef3439c03..272c9fc14 100644 --- a/pkg/sentry/platform/procid/procid_amd64.s +++ b/pkg/sentry/platform/procid/procid_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid_arm64.s b/pkg/sentry/platform/procid/procid_arm64.s index 02e907b6b..7a1684a18 100644 --- a/pkg/sentry/platform/procid/procid_arm64.s +++ b/pkg/sentry/platform/procid/procid_arm64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid_net_test.go b/pkg/sentry/platform/procid/procid_net_test.go index e8dcc479d..b628e2285 100644 --- a/pkg/sentry/platform/procid/procid_net_test.go +++ b/pkg/sentry/platform/procid/procid_net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid_test.go b/pkg/sentry/platform/procid/procid_test.go index 7a57c7cdc..88dd0b3ae 100644 --- a/pkg/sentry/platform/procid/procid_test.go +++ b/pkg/sentry/platform/procid/procid_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/ptrace.go b/pkg/sentry/platform/ptrace/ptrace.go index 3c0713e95..6a890dd81 100644 --- a/pkg/sentry/platform/ptrace/ptrace.go +++ b/pkg/sentry/platform/ptrace/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/ptrace_unsafe.go b/pkg/sentry/platform/ptrace/ptrace_unsafe.go index 223b23199..585f6c1fb 100644 --- a/pkg/sentry/platform/ptrace/ptrace_unsafe.go +++ b/pkg/sentry/platform/ptrace/ptrace_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/stub_amd64.s b/pkg/sentry/platform/ptrace/stub_amd64.s index 63f98e40d..64c718d21 100644 --- a/pkg/sentry/platform/ptrace/stub_amd64.s +++ b/pkg/sentry/platform/ptrace/stub_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/stub_unsafe.go b/pkg/sentry/platform/ptrace/stub_unsafe.go index 48c16c4a1..54d5021a9 100644 --- a/pkg/sentry/platform/ptrace/stub_unsafe.go +++ b/pkg/sentry/platform/ptrace/stub_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess.go b/pkg/sentry/platform/ptrace/subprocess.go index 2a5d699ec..83b43057f 100644 --- a/pkg/sentry/platform/ptrace/subprocess.go +++ b/pkg/sentry/platform/ptrace/subprocess.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess_amd64.go b/pkg/sentry/platform/ptrace/subprocess_amd64.go index d23a1133e..77a0e908f 100644 --- a/pkg/sentry/platform/ptrace/subprocess_amd64.go +++ b/pkg/sentry/platform/ptrace/subprocess_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index e2aab8135..2c07b4ac3 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go b/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go index 0c9263060..1bf7eab28 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess_unsafe.go b/pkg/sentry/platform/ptrace/subprocess_unsafe.go index ca6c4ac97..17736b05b 100644 --- a/pkg/sentry/platform/ptrace/subprocess_unsafe.go +++ b/pkg/sentry/platform/ptrace/subprocess_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/defs.go b/pkg/sentry/platform/ring0/defs.go index 98d0a6de0..5bbd4612d 100644 --- a/pkg/sentry/platform/ring0/defs.go +++ b/pkg/sentry/platform/ring0/defs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/defs_amd64.go b/pkg/sentry/platform/ring0/defs_amd64.go index 67242b92b..413c3dbc4 100644 --- a/pkg/sentry/platform/ring0/defs_amd64.go +++ b/pkg/sentry/platform/ring0/defs_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/entry_amd64.go b/pkg/sentry/platform/ring0/entry_amd64.go index 4a9affe64..a5ce67885 100644 --- a/pkg/sentry/platform/ring0/entry_amd64.go +++ b/pkg/sentry/platform/ring0/entry_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/entry_amd64.s b/pkg/sentry/platform/ring0/entry_amd64.s index afb040a6f..8cb8c4996 100644 --- a/pkg/sentry/platform/ring0/entry_amd64.s +++ b/pkg/sentry/platform/ring0/entry_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/gen_offsets/main.go b/pkg/sentry/platform/ring0/gen_offsets/main.go index 11c49855f..a4927da2f 100644 --- a/pkg/sentry/platform/ring0/gen_offsets/main.go +++ b/pkg/sentry/platform/ring0/gen_offsets/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/kernel.go b/pkg/sentry/platform/ring0/kernel.go index 19ac6eb7c..900c0bba7 100644 --- a/pkg/sentry/platform/ring0/kernel.go +++ b/pkg/sentry/platform/ring0/kernel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/kernel_amd64.go b/pkg/sentry/platform/ring0/kernel_amd64.go index 5ed4342dd..3577b5127 100644 --- a/pkg/sentry/platform/ring0/kernel_amd64.go +++ b/pkg/sentry/platform/ring0/kernel_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/kernel_unsafe.go b/pkg/sentry/platform/ring0/kernel_unsafe.go index faf4240e5..16955ad91 100644 --- a/pkg/sentry/platform/ring0/kernel_unsafe.go +++ b/pkg/sentry/platform/ring0/kernel_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/lib_amd64.go b/pkg/sentry/platform/ring0/lib_amd64.go index 2b95a0141..9c5f26962 100644 --- a/pkg/sentry/platform/ring0/lib_amd64.go +++ b/pkg/sentry/platform/ring0/lib_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/lib_amd64.s b/pkg/sentry/platform/ring0/lib_amd64.s index 98a130525..75d742750 100644 --- a/pkg/sentry/platform/ring0/lib_amd64.s +++ b/pkg/sentry/platform/ring0/lib_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/offsets_amd64.go b/pkg/sentry/platform/ring0/offsets_amd64.go index 806e07ec0..85cc3fdad 100644 --- a/pkg/sentry/platform/ring0/offsets_amd64.go +++ b/pkg/sentry/platform/ring0/offsets_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/allocator.go b/pkg/sentry/platform/ring0/pagetables/allocator.go index ee6e90a11..23fd5c352 100644 --- a/pkg/sentry/platform/ring0/pagetables/allocator.go +++ b/pkg/sentry/platform/ring0/pagetables/allocator.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go index f48647b3a..1b996b4e2 100644 --- a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go +++ b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables.go b/pkg/sentry/platform/ring0/pagetables/pagetables.go index c7207ec18..e5dcaada7 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go index 746f614e5..7aa6c524e 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go index 2f82c4353..a1ec4b109 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go index 3e5dc7dc7..36e424495 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go index 6bd8c3584..ff427fbe9 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pcids_x86.go b/pkg/sentry/platform/ring0/pagetables/pcids_x86.go index 0d9a51aa5..0f029f25d 100644 --- a/pkg/sentry/platform/ring0/pagetables/pcids_x86.go +++ b/pkg/sentry/platform/ring0/pagetables/pcids_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/walker_amd64.go b/pkg/sentry/platform/ring0/pagetables/walker_amd64.go index c4c71d23e..8f9dacd93 100644 --- a/pkg/sentry/platform/ring0/pagetables/walker_amd64.go +++ b/pkg/sentry/platform/ring0/pagetables/walker_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/ring0.go b/pkg/sentry/platform/ring0/ring0.go index 10c51e88d..cdeb1b43a 100644 --- a/pkg/sentry/platform/ring0/ring0.go +++ b/pkg/sentry/platform/ring0/ring0.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/x86.go b/pkg/sentry/platform/ring0/x86.go index 4c6daec22..7e5ceafdb 100644 --- a/pkg/sentry/platform/ring0/x86.go +++ b/pkg/sentry/platform/ring0/x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/atomic_amd64.s b/pkg/sentry/platform/safecopy/atomic_amd64.s index f90b4bfd1..a0cd78f33 100644 --- a/pkg/sentry/platform/safecopy/atomic_amd64.s +++ b/pkg/sentry/platform/safecopy/atomic_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/safecopy.go b/pkg/sentry/platform/safecopy/safecopy.go index 69c66a3b7..5126871eb 100644 --- a/pkg/sentry/platform/safecopy/safecopy.go +++ b/pkg/sentry/platform/safecopy/safecopy.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/safecopy_test.go b/pkg/sentry/platform/safecopy/safecopy_test.go index 1a682d28a..5818f7f9b 100644 --- a/pkg/sentry/platform/safecopy/safecopy_test.go +++ b/pkg/sentry/platform/safecopy/safecopy_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/safecopy_unsafe.go b/pkg/sentry/platform/safecopy/safecopy_unsafe.go index f84527484..eef028e68 100644 --- a/pkg/sentry/platform/safecopy/safecopy_unsafe.go +++ b/pkg/sentry/platform/safecopy/safecopy_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/sighandler_amd64.s b/pkg/sentry/platform/safecopy/sighandler_amd64.s index db7701a29..475ae48e9 100644 --- a/pkg/sentry/platform/safecopy/sighandler_amd64.s +++ b/pkg/sentry/platform/safecopy/sighandler_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/sighandler_arm64.s b/pkg/sentry/platform/safecopy/sighandler_arm64.s index cdfca8207..53e4ac2c1 100644 --- a/pkg/sentry/platform/safecopy/sighandler_arm64.s +++ b/pkg/sentry/platform/safecopy/sighandler_arm64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/block_unsafe.go b/pkg/sentry/safemem/block_unsafe.go index c3a9780d2..1f72deb61 100644 --- a/pkg/sentry/safemem/block_unsafe.go +++ b/pkg/sentry/safemem/block_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/io.go b/pkg/sentry/safemem/io.go index 6cb52439f..5c3d73eb7 100644 --- a/pkg/sentry/safemem/io.go +++ b/pkg/sentry/safemem/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/io_test.go b/pkg/sentry/safemem/io_test.go index 2eda8c3bb..629741bee 100644 --- a/pkg/sentry/safemem/io_test.go +++ b/pkg/sentry/safemem/io_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/safemem.go b/pkg/sentry/safemem/safemem.go index 090932d3e..3e70d33a2 100644 --- a/pkg/sentry/safemem/safemem.go +++ b/pkg/sentry/safemem/safemem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/seq_test.go b/pkg/sentry/safemem/seq_test.go index fddcaf714..eba4bb535 100644 --- a/pkg/sentry/safemem/seq_test.go +++ b/pkg/sentry/safemem/seq_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/seq_unsafe.go b/pkg/sentry/safemem/seq_unsafe.go index 83a6b7183..354a95dde 100644 --- a/pkg/sentry/safemem/seq_unsafe.go +++ b/pkg/sentry/safemem/seq_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/sighandling/sighandling.go b/pkg/sentry/sighandling/sighandling.go index 571245ce5..659b43363 100644 --- a/pkg/sentry/sighandling/sighandling.go +++ b/pkg/sentry/sighandling/sighandling.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/sighandling/sighandling_unsafe.go b/pkg/sentry/sighandling/sighandling_unsafe.go index db6e71487..aca77888a 100644 --- a/pkg/sentry/sighandling/sighandling_unsafe.go +++ b/pkg/sentry/sighandling/sighandling_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index d44f5e88a..abda364c9 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/device.go b/pkg/sentry/socket/epsocket/device.go index 3cc138eb0..ab4083efe 100644 --- a/pkg/sentry/socket/epsocket/device.go +++ b/pkg/sentry/socket/epsocket/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 768fa0dfa..520d82f68 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/provider.go b/pkg/sentry/socket/epsocket/provider.go index 0d9c2df24..5a89a63fb 100644 --- a/pkg/sentry/socket/epsocket/provider.go +++ b/pkg/sentry/socket/epsocket/provider.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/save_restore.go b/pkg/sentry/socket/epsocket/save_restore.go index f19afb6c0..feaafb7cc 100644 --- a/pkg/sentry/socket/epsocket/save_restore.go +++ b/pkg/sentry/socket/epsocket/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index 37c48f4bc..edefa225b 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/device.go b/pkg/sentry/socket/hostinet/device.go index c5133f3bb..4267e3691 100644 --- a/pkg/sentry/socket/hostinet/device.go +++ b/pkg/sentry/socket/hostinet/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/hostinet.go b/pkg/sentry/socket/hostinet/hostinet.go index 7858892ab..0d6f51d2b 100644 --- a/pkg/sentry/socket/hostinet/hostinet.go +++ b/pkg/sentry/socket/hostinet/hostinet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/save_restore.go b/pkg/sentry/socket/hostinet/save_restore.go index 3827f082a..1dec33897 100644 --- a/pkg/sentry/socket/hostinet/save_restore.go +++ b/pkg/sentry/socket/hostinet/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index 49349074f..71884d3db 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/socket_unsafe.go b/pkg/sentry/socket/hostinet/socket_unsafe.go index 59c8910ca..eed0c7837 100644 --- a/pkg/sentry/socket/hostinet/socket_unsafe.go +++ b/pkg/sentry/socket/hostinet/socket_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/stack.go b/pkg/sentry/socket/hostinet/stack.go index 4ce73c1f1..9c45991ba 100644 --- a/pkg/sentry/socket/hostinet/stack.go +++ b/pkg/sentry/socket/hostinet/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/message.go b/pkg/sentry/socket/netlink/message.go index a95172cba..5bd3b49ce 100644 --- a/pkg/sentry/socket/netlink/message.go +++ b/pkg/sentry/socket/netlink/message.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/port/port.go b/pkg/sentry/socket/netlink/port/port.go index 20b9a6e37..e9d3275b1 100644 --- a/pkg/sentry/socket/netlink/port/port.go +++ b/pkg/sentry/socket/netlink/port/port.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/port/port_test.go b/pkg/sentry/socket/netlink/port/port_test.go index 49b3b48ab..516f6cd6c 100644 --- a/pkg/sentry/socket/netlink/port/port_test.go +++ b/pkg/sentry/socket/netlink/port/port_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/provider.go b/pkg/sentry/socket/netlink/provider.go index 06786bd50..76cf12fd4 100644 --- a/pkg/sentry/socket/netlink/provider.go +++ b/pkg/sentry/socket/netlink/provider.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index e414b829b..9f0a81403 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index a34f9d3ca..dc688eb00 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/conn/conn.go b/pkg/sentry/socket/rpcinet/conn/conn.go index 64106c4b5..f537c7f63 100644 --- a/pkg/sentry/socket/rpcinet/conn/conn.go +++ b/pkg/sentry/socket/rpcinet/conn/conn.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/device.go b/pkg/sentry/socket/rpcinet/device.go index d2b9f9222..44c0a39b7 100644 --- a/pkg/sentry/socket/rpcinet/device.go +++ b/pkg/sentry/socket/rpcinet/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/notifier/notifier.go b/pkg/sentry/socket/rpcinet/notifier/notifier.go index f06d12231..601e05994 100644 --- a/pkg/sentry/socket/rpcinet/notifier/notifier.go +++ b/pkg/sentry/socket/rpcinet/notifier/notifier.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/rpcinet.go b/pkg/sentry/socket/rpcinet/rpcinet.go index 6c98e6acb..5d4fd4dac 100644 --- a/pkg/sentry/socket/rpcinet/rpcinet.go +++ b/pkg/sentry/socket/rpcinet/rpcinet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index cf8f69efb..c028ed4dd 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/stack.go b/pkg/sentry/socket/rpcinet/stack.go index cb8344ec6..a1be711df 100644 --- a/pkg/sentry/socket/rpcinet/stack.go +++ b/pkg/sentry/socket/rpcinet/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/stack_unsafe.go b/pkg/sentry/socket/rpcinet/stack_unsafe.go index d04fb2069..e53f578ba 100644 --- a/pkg/sentry/socket/rpcinet/stack_unsafe.go +++ b/pkg/sentry/socket/rpcinet/stack_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index 62ba13782..7e840b452 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/device.go b/pkg/sentry/socket/unix/device.go index 41820dbb3..734d39ee6 100644 --- a/pkg/sentry/socket/unix/device.go +++ b/pkg/sentry/socket/unix/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/io.go b/pkg/sentry/socket/unix/io.go index 7d80e4393..382911d51 100644 --- a/pkg/sentry/socket/unix/io.go +++ b/pkg/sentry/socket/unix/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/connectioned.go b/pkg/sentry/socket/unix/transport/connectioned.go index 62641bb34..18e492862 100644 --- a/pkg/sentry/socket/unix/transport/connectioned.go +++ b/pkg/sentry/socket/unix/transport/connectioned.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/connectioned_state.go b/pkg/sentry/socket/unix/transport/connectioned_state.go index 608a6a97a..7e02a5db8 100644 --- a/pkg/sentry/socket/unix/transport/connectioned_state.go +++ b/pkg/sentry/socket/unix/transport/connectioned_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/connectionless.go b/pkg/sentry/socket/unix/transport/connectionless.go index 728863f3f..43ff875e4 100644 --- a/pkg/sentry/socket/unix/transport/connectionless.go +++ b/pkg/sentry/socket/unix/transport/connectionless.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/queue.go b/pkg/sentry/socket/unix/transport/queue.go index 45a58c600..b650caae7 100644 --- a/pkg/sentry/socket/unix/transport/queue.go +++ b/pkg/sentry/socket/unix/transport/queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/unix.go b/pkg/sentry/socket/unix/transport/unix.go index 12b1576bd..d5f7f7aa8 100644 --- a/pkg/sentry/socket/unix/transport/unix.go +++ b/pkg/sentry/socket/unix/transport/unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 01efd24d3..e9607aa01 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/state/state.go b/pkg/sentry/state/state.go index 224f8b709..27fde505b 100644 --- a/pkg/sentry/state/state.go +++ b/pkg/sentry/state/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/state/state_metadata.go b/pkg/sentry/state/state_metadata.go index 7f047b808..b8e128c40 100644 --- a/pkg/sentry/state/state_metadata.go +++ b/pkg/sentry/state/state_metadata.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/state/state_unsafe.go b/pkg/sentry/state/state_unsafe.go index f02e12b2a..7745b6ac6 100644 --- a/pkg/sentry/state/state_unsafe.go +++ b/pkg/sentry/state/state_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/capability.go b/pkg/sentry/strace/capability.go index 9001181e7..f85d6636e 100644 --- a/pkg/sentry/strace/capability.go +++ b/pkg/sentry/strace/capability.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/strace/clone.go b/pkg/sentry/strace/clone.go index e18ce84dc..ff6a432c6 100644 --- a/pkg/sentry/strace/clone.go +++ b/pkg/sentry/strace/clone.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/futex.go b/pkg/sentry/strace/futex.go index f4aa7fcad..24301bda6 100644 --- a/pkg/sentry/strace/futex.go +++ b/pkg/sentry/strace/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/linux64.go b/pkg/sentry/strace/linux64.go index 6043b8cb1..3650fd6e1 100644 --- a/pkg/sentry/strace/linux64.go +++ b/pkg/sentry/strace/linux64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/open.go b/pkg/sentry/strace/open.go index 3bf348d7a..140727b02 100644 --- a/pkg/sentry/strace/open.go +++ b/pkg/sentry/strace/open.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/poll.go b/pkg/sentry/strace/poll.go index b6b05423c..15605187d 100644 --- a/pkg/sentry/strace/poll.go +++ b/pkg/sentry/strace/poll.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/strace/ptrace.go b/pkg/sentry/strace/ptrace.go index 8c4b79227..485aacb8a 100644 --- a/pkg/sentry/strace/ptrace.go +++ b/pkg/sentry/strace/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/signal.go b/pkg/sentry/strace/signal.go index 524be0e15..f82460e1c 100644 --- a/pkg/sentry/strace/signal.go +++ b/pkg/sentry/strace/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/socket.go b/pkg/sentry/strace/socket.go index 4c1a9d469..dbe53b9a2 100644 --- a/pkg/sentry/strace/socket.go +++ b/pkg/sentry/strace/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index 434a200d9..f4c1be4ce 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/strace.proto b/pkg/sentry/strace/strace.proto index f1fc539d6..4b2f73a5f 100644 --- a/pkg/sentry/strace/strace.proto +++ b/pkg/sentry/strace/strace.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/syscalls.go b/pkg/sentry/strace/syscalls.go index 8c897fcbe..eae2d6c12 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/epoll.go b/pkg/sentry/syscalls/epoll.go index b90d191b7..ec1eab331 100644 --- a/pkg/sentry/syscalls/epoll.go +++ b/pkg/sentry/syscalls/epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go index 304a12dde..1ba3695fb 100644 --- a/pkg/sentry/syscalls/linux/error.go +++ b/pkg/sentry/syscalls/linux/error.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go index d2aec963a..d83e12971 100644 --- a/pkg/sentry/syscalls/linux/flags.go +++ b/pkg/sentry/syscalls/linux/flags.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index b9b4ccbd1..9a460ebdf 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sigset.go b/pkg/sentry/syscalls/linux/sigset.go index a033b7c70..5438b664b 100644 --- a/pkg/sentry/syscalls/linux/sigset.go +++ b/pkg/sentry/syscalls/linux/sigset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go index 61c2647bf..1b27b2415 100644 --- a/pkg/sentry/syscalls/linux/sys_aio.go +++ b/pkg/sentry/syscalls/linux/sys_aio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_capability.go b/pkg/sentry/syscalls/linux/sys_capability.go index cf972dc28..622cb8d0d 100644 --- a/pkg/sentry/syscalls/linux/sys_capability.go +++ b/pkg/sentry/syscalls/linux/sys_capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_epoll.go b/pkg/sentry/syscalls/linux/sys_epoll.go index 200c46355..1467feb4e 100644 --- a/pkg/sentry/syscalls/linux/sys_epoll.go +++ b/pkg/sentry/syscalls/linux/sys_epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_eventfd.go b/pkg/sentry/syscalls/linux/sys_eventfd.go index 903172890..ca4ead488 100644 --- a/pkg/sentry/syscalls/linux/sys_eventfd.go +++ b/pkg/sentry/syscalls/linux/sys_eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 967464c85..893322647 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go index f0c89cba4..7cef4b50c 100644 --- a/pkg/sentry/syscalls/linux/sys_futex.go +++ b/pkg/sentry/syscalls/linux/sys_futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_getdents.go b/pkg/sentry/syscalls/linux/sys_getdents.go index 4b441b31b..1b597d5bc 100644 --- a/pkg/sentry/syscalls/linux/sys_getdents.go +++ b/pkg/sentry/syscalls/linux/sys_getdents.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_identity.go b/pkg/sentry/syscalls/linux/sys_identity.go index 8d594aa83..27e765a2d 100644 --- a/pkg/sentry/syscalls/linux/sys_identity.go +++ b/pkg/sentry/syscalls/linux/sys_identity.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_inotify.go b/pkg/sentry/syscalls/linux/sys_inotify.go index 26a505782..20269a769 100644 --- a/pkg/sentry/syscalls/linux/sys_inotify.go +++ b/pkg/sentry/syscalls/linux/sys_inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_lseek.go b/pkg/sentry/syscalls/linux/sys_lseek.go index ad3bfd761..8aadc6d8c 100644 --- a/pkg/sentry/syscalls/linux/sys_lseek.go +++ b/pkg/sentry/syscalls/linux/sys_lseek.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 805b251b1..64a6e639c 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_mount.go b/pkg/sentry/syscalls/linux/sys_mount.go index e110a553f..cf613bad0 100644 --- a/pkg/sentry/syscalls/linux/sys_mount.go +++ b/pkg/sentry/syscalls/linux/sys_mount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_pipe.go b/pkg/sentry/syscalls/linux/sys_pipe.go index 3652c429e..036845c13 100644 --- a/pkg/sentry/syscalls/linux/sys_pipe.go +++ b/pkg/sentry/syscalls/linux/sys_pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_poll.go b/pkg/sentry/syscalls/linux/sys_poll.go index 17b6768e5..e32099dd4 100644 --- a/pkg/sentry/syscalls/linux/sys_poll.go +++ b/pkg/sentry/syscalls/linux/sys_poll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_prctl.go b/pkg/sentry/syscalls/linux/sys_prctl.go index 7a29bd9b7..117ae1a0e 100644 --- a/pkg/sentry/syscalls/linux/sys_prctl.go +++ b/pkg/sentry/syscalls/linux/sys_prctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_random.go b/pkg/sentry/syscalls/linux/sys_random.go index 452dff058..fc3959a7e 100644 --- a/pkg/sentry/syscalls/linux/sys_random.go +++ b/pkg/sentry/syscalls/linux/sys_random.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go index 50c7d7a74..48b0fd49d 100644 --- a/pkg/sentry/syscalls/linux/sys_read.go +++ b/pkg/sentry/syscalls/linux/sys_read.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_rlimit.go b/pkg/sentry/syscalls/linux/sys_rlimit.go index 443334693..8b0379779 100644 --- a/pkg/sentry/syscalls/linux/sys_rlimit.go +++ b/pkg/sentry/syscalls/linux/sys_rlimit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_rusage.go b/pkg/sentry/syscalls/linux/sys_rusage.go index ab07c77f9..003d718da 100644 --- a/pkg/sentry/syscalls/linux/sys_rusage.go +++ b/pkg/sentry/syscalls/linux/sys_rusage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_sched.go b/pkg/sentry/syscalls/linux/sys_sched.go index e679a6694..8aea03abe 100644 --- a/pkg/sentry/syscalls/linux/sys_sched.go +++ b/pkg/sentry/syscalls/linux/sys_sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_seccomp.go b/pkg/sentry/syscalls/linux/sys_seccomp.go index f08fdf5cb..b4262162a 100644 --- a/pkg/sentry/syscalls/linux/sys_seccomp.go +++ b/pkg/sentry/syscalls/linux/sys_seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_sem.go b/pkg/sentry/syscalls/linux/sys_sem.go index 86f850ef1..5bd61ab87 100644 --- a/pkg/sentry/syscalls/linux/sys_sem.go +++ b/pkg/sentry/syscalls/linux/sys_sem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_shm.go b/pkg/sentry/syscalls/linux/sys_shm.go index a0d3a73c5..d0eceac7c 100644 --- a/pkg/sentry/syscalls/linux/sys_shm.go +++ b/pkg/sentry/syscalls/linux/sys_shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_signal.go b/pkg/sentry/syscalls/linux/sys_signal.go index a539354c5..7fbeb4fcd 100644 --- a/pkg/sentry/syscalls/linux/sys_signal.go +++ b/pkg/sentry/syscalls/linux/sys_signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go index c8748958a..69862f110 100644 --- a/pkg/sentry/syscalls/linux/sys_socket.go +++ b/pkg/sentry/syscalls/linux/sys_socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_stat.go b/pkg/sentry/syscalls/linux/sys_stat.go index 49c225011..10fc201ef 100644 --- a/pkg/sentry/syscalls/linux/sys_stat.go +++ b/pkg/sentry/syscalls/linux/sys_stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_sync.go b/pkg/sentry/syscalls/linux/sys_sync.go index 68488330f..4352482fb 100644 --- a/pkg/sentry/syscalls/linux/sys_sync.go +++ b/pkg/sentry/syscalls/linux/sys_sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_sysinfo.go b/pkg/sentry/syscalls/linux/sys_sysinfo.go index 6f7acf98f..ecf88edc1 100644 --- a/pkg/sentry/syscalls/linux/sys_sysinfo.go +++ b/pkg/sentry/syscalls/linux/sys_sysinfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_syslog.go b/pkg/sentry/syscalls/linux/sys_syslog.go index 7193b7aed..9efc58d34 100644 --- a/pkg/sentry/syscalls/linux/sys_syslog.go +++ b/pkg/sentry/syscalls/linux/sys_syslog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go index ddcb5b789..23c2f7035 100644 --- a/pkg/sentry/syscalls/linux/sys_thread.go +++ b/pkg/sentry/syscalls/linux/sys_thread.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_time.go b/pkg/sentry/syscalls/linux/sys_time.go index 063fbb106..b4f2609c0 100644 --- a/pkg/sentry/syscalls/linux/sys_time.go +++ b/pkg/sentry/syscalls/linux/sys_time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_timer.go b/pkg/sentry/syscalls/linux/sys_timer.go index 6baf4599b..04ea7a4e9 100644 --- a/pkg/sentry/syscalls/linux/sys_timer.go +++ b/pkg/sentry/syscalls/linux/sys_timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_timerfd.go b/pkg/sentry/syscalls/linux/sys_timerfd.go index f70d13682..ec0155cbb 100644 --- a/pkg/sentry/syscalls/linux/sys_timerfd.go +++ b/pkg/sentry/syscalls/linux/sys_timerfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_tls.go b/pkg/sentry/syscalls/linux/sys_tls.go index 8ea78093b..1e8312e00 100644 --- a/pkg/sentry/syscalls/linux/sys_tls.go +++ b/pkg/sentry/syscalls/linux/sys_tls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_utsname.go b/pkg/sentry/syscalls/linux/sys_utsname.go index f7545b965..fa81fe10e 100644 --- a/pkg/sentry/syscalls/linux/sys_utsname.go +++ b/pkg/sentry/syscalls/linux/sys_utsname.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_write.go b/pkg/sentry/syscalls/linux/sys_write.go index e405608c4..1da72d606 100644 --- a/pkg/sentry/syscalls/linux/sys_write.go +++ b/pkg/sentry/syscalls/linux/sys_write.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/timespec.go b/pkg/sentry/syscalls/linux/timespec.go index 752ec326d..fa6fcdc0b 100644 --- a/pkg/sentry/syscalls/linux/timespec.go +++ b/pkg/sentry/syscalls/linux/timespec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/syscalls.go b/pkg/sentry/syscalls/syscalls.go index 425ce900c..5d10b3824 100644 --- a/pkg/sentry/syscalls/syscalls.go +++ b/pkg/sentry/syscalls/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/calibrated_clock.go b/pkg/sentry/time/calibrated_clock.go index a98bcd7de..c27e391c9 100644 --- a/pkg/sentry/time/calibrated_clock.go +++ b/pkg/sentry/time/calibrated_clock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/calibrated_clock_test.go b/pkg/sentry/time/calibrated_clock_test.go index a9237630e..d6622bfe2 100644 --- a/pkg/sentry/time/calibrated_clock_test.go +++ b/pkg/sentry/time/calibrated_clock_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/clock_id.go b/pkg/sentry/time/clock_id.go index 1317a5dad..724f59dd9 100644 --- a/pkg/sentry/time/clock_id.go +++ b/pkg/sentry/time/clock_id.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/clocks.go b/pkg/sentry/time/clocks.go index e26386520..837e86094 100644 --- a/pkg/sentry/time/clocks.go +++ b/pkg/sentry/time/clocks.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/muldiv_amd64.s b/pkg/sentry/time/muldiv_amd64.s index bfcb8c724..028c6684e 100644 --- a/pkg/sentry/time/muldiv_amd64.s +++ b/pkg/sentry/time/muldiv_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/muldiv_arm64.s b/pkg/sentry/time/muldiv_arm64.s index 5fa82a136..5ad57a8a3 100644 --- a/pkg/sentry/time/muldiv_arm64.s +++ b/pkg/sentry/time/muldiv_arm64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/parameters.go b/pkg/sentry/time/parameters.go index 8568b1193..63cf7c4a3 100644 --- a/pkg/sentry/time/parameters.go +++ b/pkg/sentry/time/parameters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/parameters_test.go b/pkg/sentry/time/parameters_test.go index 4a0c4e880..e1b9084ac 100644 --- a/pkg/sentry/time/parameters_test.go +++ b/pkg/sentry/time/parameters_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/sampler.go b/pkg/sentry/time/sampler.go index 445690d49..2140a99b7 100644 --- a/pkg/sentry/time/sampler.go +++ b/pkg/sentry/time/sampler.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/sampler_test.go b/pkg/sentry/time/sampler_test.go index ec0e442b6..3e70a1134 100644 --- a/pkg/sentry/time/sampler_test.go +++ b/pkg/sentry/time/sampler_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/sampler_unsafe.go b/pkg/sentry/time/sampler_unsafe.go index 0f8eb4fc8..e76180217 100644 --- a/pkg/sentry/time/sampler_unsafe.go +++ b/pkg/sentry/time/sampler_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/tsc_amd64.s b/pkg/sentry/time/tsc_amd64.s index e53d477f7..6a8eed664 100644 --- a/pkg/sentry/time/tsc_amd64.s +++ b/pkg/sentry/time/tsc_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/tsc_arm64.s b/pkg/sentry/time/tsc_arm64.s index c1c9760ef..da9fa4112 100644 --- a/pkg/sentry/time/tsc_arm64.s +++ b/pkg/sentry/time/tsc_arm64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/unimpl/events.go b/pkg/sentry/unimpl/events.go index f78f8c981..d92766e2d 100644 --- a/pkg/sentry/unimpl/events.go +++ b/pkg/sentry/unimpl/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/unimpl/unimplemented_syscall.proto b/pkg/sentry/unimpl/unimplemented_syscall.proto index 41579b016..0d7a94be7 100644 --- a/pkg/sentry/unimpl/unimplemented_syscall.proto +++ b/pkg/sentry/unimpl/unimplemented_syscall.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/uniqueid/context.go b/pkg/sentry/uniqueid/context.go index 399d98c29..e55b89689 100644 --- a/pkg/sentry/uniqueid/context.go +++ b/pkg/sentry/uniqueid/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/cpu.go b/pkg/sentry/usage/cpu.go index cbd7cfe19..bfc282d69 100644 --- a/pkg/sentry/usage/cpu.go +++ b/pkg/sentry/usage/cpu.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/io.go b/pkg/sentry/usage/io.go index 8e27a0a88..dfcd3a49d 100644 --- a/pkg/sentry/usage/io.go +++ b/pkg/sentry/usage/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/memory.go b/pkg/sentry/usage/memory.go index 5be9ed9c6..c316f1597 100644 --- a/pkg/sentry/usage/memory.go +++ b/pkg/sentry/usage/memory.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/memory_unsafe.go b/pkg/sentry/usage/memory_unsafe.go index a3ae668a5..9e0014ca0 100644 --- a/pkg/sentry/usage/memory_unsafe.go +++ b/pkg/sentry/usage/memory_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/usage.go b/pkg/sentry/usage/usage.go index ab327f8e2..e3d33a965 100644 --- a/pkg/sentry/usage/usage.go +++ b/pkg/sentry/usage/usage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/access_type.go b/pkg/sentry/usermem/access_type.go index 9e6a27bcf..9c1742a59 100644 --- a/pkg/sentry/usermem/access_type.go +++ b/pkg/sentry/usermem/access_type.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/addr.go b/pkg/sentry/usermem/addr.go index 2a75aa60c..e79210804 100644 --- a/pkg/sentry/usermem/addr.go +++ b/pkg/sentry/usermem/addr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/addr_range_seq_test.go b/pkg/sentry/usermem/addr_range_seq_test.go index bd6a1ec8a..82f735026 100644 --- a/pkg/sentry/usermem/addr_range_seq_test.go +++ b/pkg/sentry/usermem/addr_range_seq_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/addr_range_seq_unsafe.go b/pkg/sentry/usermem/addr_range_seq_unsafe.go index f5fd446fa..c09337c15 100644 --- a/pkg/sentry/usermem/addr_range_seq_unsafe.go +++ b/pkg/sentry/usermem/addr_range_seq_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/bytes_io.go b/pkg/sentry/usermem/bytes_io.go index 274f568d0..f98d82168 100644 --- a/pkg/sentry/usermem/bytes_io.go +++ b/pkg/sentry/usermem/bytes_io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/bytes_io_unsafe.go b/pkg/sentry/usermem/bytes_io_unsafe.go index 7add8bc82..bb49d2ff3 100644 --- a/pkg/sentry/usermem/bytes_io_unsafe.go +++ b/pkg/sentry/usermem/bytes_io_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/usermem.go b/pkg/sentry/usermem/usermem.go index 4c7d5014a..31e4d6ada 100644 --- a/pkg/sentry/usermem/usermem.go +++ b/pkg/sentry/usermem/usermem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/usermem_arm64.go b/pkg/sentry/usermem/usermem_arm64.go index 7fd4ce963..fdfc30a66 100644 --- a/pkg/sentry/usermem/usermem_arm64.go +++ b/pkg/sentry/usermem/usermem_arm64.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/usermem/usermem_test.go b/pkg/sentry/usermem/usermem_test.go index 1991a9641..4a07118b7 100644 --- a/pkg/sentry/usermem/usermem_test.go +++ b/pkg/sentry/usermem/usermem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/usermem_unsafe.go b/pkg/sentry/usermem/usermem_unsafe.go index 3895e7871..876783e78 100644 --- a/pkg/sentry/usermem/usermem_unsafe.go +++ b/pkg/sentry/usermem/usermem_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/usermem/usermem_x86.go b/pkg/sentry/usermem/usermem_x86.go index 9ec90f9ff..8059b72d2 100644 --- a/pkg/sentry/usermem/usermem_x86.go +++ b/pkg/sentry/usermem/usermem_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/watchdog/watchdog.go b/pkg/sentry/watchdog/watchdog.go index b4f1e3a4f..2fc4472dd 100644 --- a/pkg/sentry/watchdog/watchdog.go +++ b/pkg/sentry/watchdog/watchdog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/commit_amd64.s b/pkg/sleep/commit_amd64.s index d08df7f37..bc4ac2c3c 100644 --- a/pkg/sleep/commit_amd64.s +++ b/pkg/sleep/commit_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/commit_asm.go b/pkg/sleep/commit_asm.go index 90eef4cbc..35e2cc337 100644 --- a/pkg/sleep/commit_asm.go +++ b/pkg/sleep/commit_asm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/commit_noasm.go b/pkg/sleep/commit_noasm.go index 967d22e24..686b1da3d 100644 --- a/pkg/sleep/commit_noasm.go +++ b/pkg/sleep/commit_noasm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/empty.s b/pkg/sleep/empty.s index 85d52cd9c..fb37360ac 100644 --- a/pkg/sleep/empty.s +++ b/pkg/sleep/empty.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/sleep_test.go b/pkg/sleep/sleep_test.go index 8feb9ffc2..130806c86 100644 --- a/pkg/sleep/sleep_test.go +++ b/pkg/sleep/sleep_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/sleep_unsafe.go b/pkg/sleep/sleep_unsafe.go index 45fb6f0ea..62e0abc34 100644 --- a/pkg/sleep/sleep_unsafe.go +++ b/pkg/sleep/sleep_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/decode.go b/pkg/state/decode.go index 54b5ad8b8..73a59f871 100644 --- a/pkg/state/decode.go +++ b/pkg/state/decode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/encode.go b/pkg/state/encode.go index fe8512bbf..b0714170b 100644 --- a/pkg/state/encode.go +++ b/pkg/state/encode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/encode_unsafe.go b/pkg/state/encode_unsafe.go index be94742a8..457e6dbb7 100644 --- a/pkg/state/encode_unsafe.go +++ b/pkg/state/encode_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/map.go b/pkg/state/map.go index 0035d7250..1fb9b47b8 100644 --- a/pkg/state/map.go +++ b/pkg/state/map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/object.proto b/pkg/state/object.proto index d3b46ea97..952289069 100644 --- a/pkg/state/object.proto +++ b/pkg/state/object.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/printer.go b/pkg/state/printer.go index aee4b69fb..5174c3ba3 100644 --- a/pkg/state/printer.go +++ b/pkg/state/printer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/state.go b/pkg/state/state.go index 4486f83a7..cf7df803a 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index 22bcad9e1..7c24bbcda 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/statefile/statefile.go b/pkg/state/statefile/statefile.go index c21e3bb0e..ad4e3b43e 100644 --- a/pkg/state/statefile/statefile.go +++ b/pkg/state/statefile/statefile.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/statefile/statefile_test.go b/pkg/state/statefile/statefile_test.go index b4f400e01..60b769895 100644 --- a/pkg/state/statefile/statefile_test.go +++ b/pkg/state/statefile/statefile_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/stats.go b/pkg/state/stats.go index 17ca258fc..eb51cda47 100644 --- a/pkg/state/stats.go +++ b/pkg/state/stats.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserr/host_linux.go b/pkg/syserr/host_linux.go index 74bbe9f5b..fc6ef60a1 100644 --- a/pkg/syserr/host_linux.go +++ b/pkg/syserr/host_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go index 1a23919ef..bd489b424 100644 --- a/pkg/syserr/netstack.go +++ b/pkg/syserr/netstack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserr/syserr.go b/pkg/syserr/syserr.go index 232634dd4..4ddbd3322 100644 --- a/pkg/syserr/syserr.go +++ b/pkg/syserr/syserr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserror/syserror.go b/pkg/syserror/syserror.go index 5558cccff..345653544 100644 --- a/pkg/syserror/syserror.go +++ b/pkg/syserror/syserror.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserror/syserror_test.go b/pkg/syserror/syserror_test.go index 0f0da5781..f2a10ee7b 100644 --- a/pkg/syserror/syserror_test.go +++ b/pkg/syserror/syserror_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index 628e28f57..df8bf435d 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/adapters/gonet/gonet_test.go b/pkg/tcpip/adapters/gonet/gonet_test.go index e84f73feb..2c81c5697 100644 --- a/pkg/tcpip/adapters/gonet/gonet_test.go +++ b/pkg/tcpip/adapters/gonet/gonet_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/buffer/prependable.go b/pkg/tcpip/buffer/prependable.go index d3a9a0f88..43cbbc74c 100644 --- a/pkg/tcpip/buffer/prependable.go +++ b/pkg/tcpip/buffer/prependable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index 43cbb9461..1a9d40778 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/buffer/view_test.go b/pkg/tcpip/buffer/view_test.go index 74a0a96fc..ebc3a17b7 100644 --- a/pkg/tcpip/buffer/view_test.go +++ b/pkg/tcpip/buffer/view_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go index 5dfb3ca1d..6e7edf3ab 100644 --- a/pkg/tcpip/checker/checker.go +++ b/pkg/tcpip/checker/checker.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/hash/jenkins/jenkins.go b/pkg/tcpip/hash/jenkins/jenkins.go index e66d5f12b..52c22230e 100644 --- a/pkg/tcpip/hash/jenkins/jenkins.go +++ b/pkg/tcpip/hash/jenkins/jenkins.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/hash/jenkins/jenkins_test.go b/pkg/tcpip/hash/jenkins/jenkins_test.go index 9d86174aa..4c78b5808 100644 --- a/pkg/tcpip/hash/jenkins/jenkins_test.go +++ b/pkg/tcpip/hash/jenkins/jenkins_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/arp.go b/pkg/tcpip/header/arp.go index 22b259ccb..55fe7292c 100644 --- a/pkg/tcpip/header/arp.go +++ b/pkg/tcpip/header/arp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/checksum.go b/pkg/tcpip/header/checksum.go index 2e8c65fac..2eaa7938a 100644 --- a/pkg/tcpip/header/checksum.go +++ b/pkg/tcpip/header/checksum.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/eth.go b/pkg/tcpip/header/eth.go index 77365bc41..76143f454 100644 --- a/pkg/tcpip/header/eth.go +++ b/pkg/tcpip/header/eth.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/gue.go b/pkg/tcpip/header/gue.go index 2ad13955a..10d358c0e 100644 --- a/pkg/tcpip/header/gue.go +++ b/pkg/tcpip/header/gue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/icmpv4.go b/pkg/tcpip/header/icmpv4.go index 3ac89cdae..782e1053c 100644 --- a/pkg/tcpip/header/icmpv4.go +++ b/pkg/tcpip/header/icmpv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/icmpv6.go b/pkg/tcpip/header/icmpv6.go index e317975e8..d0b10d849 100644 --- a/pkg/tcpip/header/icmpv6.go +++ b/pkg/tcpip/header/icmpv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/interfaces.go b/pkg/tcpip/header/interfaces.go index ac327d8a5..fb250ea30 100644 --- a/pkg/tcpip/header/interfaces.go +++ b/pkg/tcpip/header/interfaces.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/ipv4.go b/pkg/tcpip/header/ipv4.go index c3b8fb00e..96e461491 100644 --- a/pkg/tcpip/header/ipv4.go +++ b/pkg/tcpip/header/ipv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go index 3d24736c7..66820a466 100644 --- a/pkg/tcpip/header/ipv6.go +++ b/pkg/tcpip/header/ipv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/ipv6_fragment.go b/pkg/tcpip/header/ipv6_fragment.go index e36d5177b..6d896355a 100644 --- a/pkg/tcpip/header/ipv6_fragment.go +++ b/pkg/tcpip/header/ipv6_fragment.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/ipversion_test.go b/pkg/tcpip/header/ipversion_test.go index 8301ba5cf..0c830180e 100644 --- a/pkg/tcpip/header/ipversion_test.go +++ b/pkg/tcpip/header/ipversion_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index e656ebb15..0cd89b992 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/tcp_test.go b/pkg/tcpip/header/tcp_test.go index 7cd98df3b..9a2b99489 100644 --- a/pkg/tcpip/header/tcp_test.go +++ b/pkg/tcpip/header/tcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/udp.go b/pkg/tcpip/header/udp.go index e8c860436..2205fec18 100644 --- a/pkg/tcpip/header/udp.go +++ b/pkg/tcpip/header/udp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index f7501a1bc..ee9dd8700 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 8f4d67074..4da376774 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index c8b037d57..31138e4ac 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/fdbased/endpoint_unsafe.go b/pkg/tcpip/link/fdbased/endpoint_unsafe.go index 36e7fe5a9..97a477b61 100644 --- a/pkg/tcpip/link/fdbased/endpoint_unsafe.go +++ b/pkg/tcpip/link/fdbased/endpoint_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/fdbased/mmap.go b/pkg/tcpip/link/fdbased/mmap.go index f1e71c233..430c85a42 100644 --- a/pkg/tcpip/link/fdbased/mmap.go +++ b/pkg/tcpip/link/fdbased/mmap.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go b/pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go index e5ac7996d..135da2498 100644 --- a/pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go +++ b/pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 2dc4bcfda..2c1148123 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/muxed/injectable.go b/pkg/tcpip/link/muxed/injectable.go index b3e71c7fc..be07b7c29 100644 --- a/pkg/tcpip/link/muxed/injectable.go +++ b/pkg/tcpip/link/muxed/injectable.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/muxed/injectable_test.go b/pkg/tcpip/link/muxed/injectable_test.go index 031449a05..5d40dfacc 100644 --- a/pkg/tcpip/link/muxed/injectable_test.go +++ b/pkg/tcpip/link/muxed/injectable_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s index 9dade5421..b54131573 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s +++ b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go index 3ba96a123..0b51982c6 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go index 94ddad8ea..4eab77c74 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/rawfile/errors.go b/pkg/tcpip/link/rawfile/errors.go index 7359849b1..8bde41637 100644 --- a/pkg/tcpip/link/rawfile/errors.go +++ b/pkg/tcpip/link/rawfile/errors.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go index fe2779125..86db7a487 100644 --- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go +++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe.go b/pkg/tcpip/link/sharedmem/pipe/pipe.go index e014324cc..74c9f0311 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go index 30742ccb1..59ef69a8b 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go index f491d74a2..62d17029e 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/rx.go b/pkg/tcpip/link/sharedmem/pipe/rx.go index 8d641c76f..f22e533ac 100644 --- a/pkg/tcpip/link/sharedmem/pipe/rx.go +++ b/pkg/tcpip/link/sharedmem/pipe/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/tx.go b/pkg/tcpip/link/sharedmem/pipe/tx.go index e75175d98..9841eb231 100644 --- a/pkg/tcpip/link/sharedmem/pipe/tx.go +++ b/pkg/tcpip/link/sharedmem/pipe/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/queue/queue_test.go b/pkg/tcpip/link/sharedmem/queue/queue_test.go index 391165bc3..d3f8f4b8b 100644 --- a/pkg/tcpip/link/sharedmem/queue/queue_test.go +++ b/pkg/tcpip/link/sharedmem/queue/queue_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/queue/rx.go b/pkg/tcpip/link/sharedmem/queue/rx.go index d3a5da08a..d9aecf2d9 100644 --- a/pkg/tcpip/link/sharedmem/queue/rx.go +++ b/pkg/tcpip/link/sharedmem/queue/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/queue/tx.go b/pkg/tcpip/link/sharedmem/queue/tx.go index 845108db1..a24dccd11 100644 --- a/pkg/tcpip/link/sharedmem/queue/tx.go +++ b/pkg/tcpip/link/sharedmem/queue/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/rx.go b/pkg/tcpip/link/sharedmem/rx.go index 3eeab769e..215cb607f 100644 --- a/pkg/tcpip/link/sharedmem/rx.go +++ b/pkg/tcpip/link/sharedmem/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 6e6aa5a13..e34b780f8 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 1f44e224c..65b9d7085 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go index b91adbaf7..f7e816a41 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/tx.go b/pkg/tcpip/link/sharedmem/tx.go index 37da34831..ac3577aa6 100644 --- a/pkg/tcpip/link/sharedmem/tx.go +++ b/pkg/tcpip/link/sharedmem/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sniffer/pcap.go b/pkg/tcpip/link/sniffer/pcap.go index 3d0d8d852..c16c19647 100644 --- a/pkg/tcpip/link/sniffer/pcap.go +++ b/pkg/tcpip/link/sniffer/pcap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 462a6e3a3..e87ae07d7 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/tun/tun_unsafe.go b/pkg/tcpip/link/tun/tun_unsafe.go index e4c589dda..09ca9b527 100644 --- a/pkg/tcpip/link/tun/tun_unsafe.go +++ b/pkg/tcpip/link/tun/tun_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index bd9f9845b..21690a226 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index a2df6be95..62054fb7f 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 975919e80..a3f2bce3e 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index 14b9cb8b6..1b971b1a3 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/frag_heap.go b/pkg/tcpip/network/fragmentation/frag_heap.go index 55615c8e6..9ad3e5a8a 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap.go +++ b/pkg/tcpip/network/fragmentation/frag_heap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/frag_heap_test.go b/pkg/tcpip/network/fragmentation/frag_heap_test.go index 1b1b72e88..3a2486ba8 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap_test.go +++ b/pkg/tcpip/network/fragmentation/frag_heap_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/fragmentation.go b/pkg/tcpip/network/fragmentation/fragmentation.go index a5dda0398..e90edb375 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation.go +++ b/pkg/tcpip/network/fragmentation/fragmentation.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/fragmentation_test.go b/pkg/tcpip/network/fragmentation/fragmentation_test.go index 5bf3463a9..99ded68a3 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation_test.go +++ b/pkg/tcpip/network/fragmentation/fragmentation_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/reassembler.go b/pkg/tcpip/network/fragmentation/reassembler.go index c9ad2bef6..04f9ab964 100644 --- a/pkg/tcpip/network/fragmentation/reassembler.go +++ b/pkg/tcpip/network/fragmentation/reassembler.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/reassembler_test.go b/pkg/tcpip/network/fragmentation/reassembler_test.go index a2bc9707a..7eee0710d 100644 --- a/pkg/tcpip/network/fragmentation/reassembler_test.go +++ b/pkg/tcpip/network/fragmentation/reassembler_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/hash/hash.go b/pkg/tcpip/network/hash/hash.go index 07960ddf0..0c91905dc 100644 --- a/pkg/tcpip/network/hash/hash.go +++ b/pkg/tcpip/network/hash/hash.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 522009fac..4b822e2c6 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index 1c3acda4b..9cb81245a 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index cbdca98a5..c6af0db79 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go index 42e85564e..146143ab3 100644 --- a/pkg/tcpip/network/ipv4/ipv4_test.go +++ b/pkg/tcpip/network/ipv4/ipv4_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index be28be36d..9c011e107 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index 8b57a0641..d8737a616 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 9a743ea80..4b8cd496b 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/ports/ports.go b/pkg/tcpip/ports/ports.go index d212a5792..a1712b590 100644 --- a/pkg/tcpip/ports/ports.go +++ b/pkg/tcpip/ports/ports.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/ports/ports_test.go b/pkg/tcpip/ports/ports_test.go index 01e7320b4..8466c661b 100644 --- a/pkg/tcpip/ports/ports_test.go +++ b/pkg/tcpip/ports/ports_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index cf8900c4d..1681de56e 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index da6202f97..642607f83 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/seqnum/seqnum.go b/pkg/tcpip/seqnum/seqnum.go index f2b988839..b40a3c212 100644 --- a/pkg/tcpip/seqnum/seqnum.go +++ b/pkg/tcpip/seqnum/seqnum.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index 40e4bdb4a..42b9768ae 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go index 77a09ca86..91b2ffea8 100644 --- a/pkg/tcpip/stack/linkaddrcache_test.go +++ b/pkg/tcpip/stack/linkaddrcache_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index c18571b0f..8008d9870 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 6e1660051..c70533a35 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 8ae562dcd..3d4c282a9 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index cb9ffe9c2..f204ca790 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index 3d7e4b719..dfec4258a 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index b5375df3c..351f63221 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index a8ac18e72..e8b562ad9 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 2df974bf2..8d74f1543 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index b09137f08..9367c8c02 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/tcpip_test.go b/pkg/tcpip/tcpip_test.go index 1f7b04398..ebb1c1b56 100644 --- a/pkg/tcpip/tcpip_test.go +++ b/pkg/tcpip/tcpip_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/time.s b/pkg/tcpip/time.s index 85d52cd9c..fb37360ac 100644 --- a/pkg/tcpip/time.s +++ b/pkg/tcpip/time.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/time_unsafe.go b/pkg/tcpip/time_unsafe.go index 7ec5741af..1a307483b 100644 --- a/pkg/tcpip/time_unsafe.go +++ b/pkg/tcpip/time_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index 8f2e3aa20..00840cfcf 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/icmp/endpoint_state.go b/pkg/tcpip/transport/icmp/endpoint_state.go index 8a7909246..332b3cd33 100644 --- a/pkg/tcpip/transport/icmp/endpoint_state.go +++ b/pkg/tcpip/transport/icmp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/icmp/protocol.go b/pkg/tcpip/transport/icmp/protocol.go index 09ee2f892..954fde9d8 100644 --- a/pkg/tcpip/transport/icmp/protocol.go +++ b/pkg/tcpip/transport/icmp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/raw/raw.go b/pkg/tcpip/transport/raw/raw.go index f0f60ce91..7004c7ff4 100644 --- a/pkg/tcpip/transport/raw/raw.go +++ b/pkg/tcpip/transport/raw/raw.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/transport/raw/state.go b/pkg/tcpip/transport/raw/state.go index e3891a8b8..e8907ebb1 100644 --- a/pkg/tcpip/transport/raw/state.go +++ b/pkg/tcpip/transport/raw/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index a3894ed8f..e506d7133 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 6c4a4d95e..eaa67aeb7 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/cubic.go b/pkg/tcpip/transport/tcp/cubic.go index 003525d86..e618cd2b9 100644 --- a/pkg/tcpip/transport/tcp/cubic.go +++ b/pkg/tcpip/transport/tcp/cubic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/dual_stack_test.go b/pkg/tcpip/transport/tcp/dual_stack_test.go index 2886cc707..43bcfa070 100644 --- a/pkg/tcpip/transport/tcp/dual_stack_test.go +++ b/pkg/tcpip/transport/tcp/dual_stack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 09eff5be1..982f491cc 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index 7f9dabb4d..27b0be046 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index 6a7efaf1d..e088e24cb 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index b5fb160bc..b86473891 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index fa6bdddba..b08a0e356 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/reno.go b/pkg/tcpip/transport/tcp/reno.go index e4f8b7d5a..f83ebc717 100644 --- a/pkg/tcpip/transport/tcp/reno.go +++ b/pkg/tcpip/transport/tcp/reno.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/sack.go b/pkg/tcpip/transport/tcp/sack.go index 24e48fe7b..6a013d99b 100644 --- a/pkg/tcpip/transport/tcp/sack.go +++ b/pkg/tcpip/transport/tcp/sack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard.go b/pkg/tcpip/transport/tcp/sack_scoreboard.go index 21878ad82..99560d5b4 100644 --- a/pkg/tcpip/transport/tcp/sack_scoreboard.go +++ b/pkg/tcpip/transport/tcp/sack_scoreboard.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go index 3cf2ff451..8f6890cdf 100644 --- a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go +++ b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index c603fe713..187effb6b 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/segment_heap.go b/pkg/tcpip/transport/tcp/segment_heap.go index 98422fadf..9fd061d7d 100644 --- a/pkg/tcpip/transport/tcp/segment_heap.go +++ b/pkg/tcpip/transport/tcp/segment_heap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 0c637d7ad..3b020e580 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/segment_state.go b/pkg/tcpip/transport/tcp/segment_state.go index 68b049f06..dd7e14aa6 100644 --- a/pkg/tcpip/transport/tcp/segment_state.go +++ b/pkg/tcpip/transport/tcp/segment_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index 6317748cf..50743670e 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go index 86bbd643f..12eff8afc 100644 --- a/pkg/tcpip/transport/tcp/snd_state.go +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/tcp_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go index 06b0702c5..dbfbd5c4f 100644 --- a/pkg/tcpip/transport/tcp/tcp_sack_test.go +++ b/pkg/tcpip/transport/tcp/tcp_sack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index c5732ad1c..a8b290dae 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index 87c640967..039bbcfba 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 6e2fed880..fa721a7f8 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/timer.go b/pkg/tcpip/transport/tcp/timer.go index 38240d2d5..fc1c7cbd2 100644 --- a/pkg/tcpip/transport/tcp/timer.go +++ b/pkg/tcpip/transport/tcp/timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go index b94568fb1..f1dcd36d5 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go index aaeae9b18..435e136de 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 1f9251de3..db65a4e88 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index b2daaf751..163dcbc13 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/udp/forwarder.go b/pkg/tcpip/transport/udp/forwarder.go index d80c47e34..25bdd2929 100644 --- a/pkg/tcpip/transport/udp/forwarder.go +++ b/pkg/tcpip/transport/udp/forwarder.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index 616a9f388..8b47cce17 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 2f4e94c58..86a8fa19b 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tmutex/tmutex.go b/pkg/tmutex/tmutex.go index df61d89f5..c4685020d 100644 --- a/pkg/tmutex/tmutex.go +++ b/pkg/tmutex/tmutex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tmutex/tmutex_test.go b/pkg/tmutex/tmutex_test.go index a4537cb3b..ce34c7962 100644 --- a/pkg/tmutex/tmutex_test.go +++ b/pkg/tmutex/tmutex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/unet/unet.go b/pkg/unet/unet.go index 114fb8c5b..2aa1af4ff 100644 --- a/pkg/unet/unet.go +++ b/pkg/unet/unet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/unet/unet_test.go b/pkg/unet/unet_test.go index db5485539..763b23c7c 100644 --- a/pkg/unet/unet_test.go +++ b/pkg/unet/unet_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/unet/unet_unsafe.go b/pkg/unet/unet_unsafe.go index 1d6ec286c..fa0916439 100644 --- a/pkg/unet/unet_unsafe.go +++ b/pkg/unet/unet_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/urpc/urpc.go b/pkg/urpc/urpc.go index 719f0e92f..0f155ec74 100644 --- a/pkg/urpc/urpc.go +++ b/pkg/urpc/urpc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/urpc/urpc_test.go b/pkg/urpc/urpc_test.go index f1b9a85ca..5bf2c5ed2 100644 --- a/pkg/urpc/urpc_test.go +++ b/pkg/urpc/urpc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index a6c9dff3c..8a65ed164 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/waiter/waiter_test.go b/pkg/waiter/waiter_test.go index 60853f9c1..c1b94a4f3 100644 --- a/pkg/waiter/waiter_test.go +++ b/pkg/waiter/waiter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index b3499bcde..c1b33c551 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/compat_amd64.go b/runsc/boot/compat_amd64.go index 0c9472f18..99df5e614 100644 --- a/runsc/boot/compat_amd64.go +++ b/runsc/boot/compat_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/compat_test.go b/runsc/boot/compat_test.go index f1940dd72..ccec3d20c 100644 --- a/runsc/boot/compat_test.go +++ b/runsc/boot/compat_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/config.go b/runsc/boot/config.go index ba47effc1..b6771de30 100644 --- a/runsc/boot/config.go +++ b/runsc/boot/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index 712c50ee9..ab7c58838 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/debug.go b/runsc/boot/debug.go index d224d08b7..79f7387ac 100644 --- a/runsc/boot/debug.go +++ b/runsc/boot/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/events.go b/runsc/boot/events.go index 717adfedd..ffd99f5e9 100644 --- a/runsc/boot/events.go +++ b/runsc/boot/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/fds.go b/runsc/boot/fds.go index a3d21d963..4e428b49c 100644 --- a/runsc/boot/fds.go +++ b/runsc/boot/fds.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/config.go b/runsc/boot/filter/config.go index 9c72e3b1a..652da1cef 100644 --- a/runsc/boot/filter/config.go +++ b/runsc/boot/filter/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/extra_filters.go b/runsc/boot/filter/extra_filters.go index 67f3101fe..5c5ec4e06 100644 --- a/runsc/boot/filter/extra_filters.go +++ b/runsc/boot/filter/extra_filters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/extra_filters_msan.go b/runsc/boot/filter/extra_filters_msan.go index fb95283ab..ac5a0f1aa 100644 --- a/runsc/boot/filter/extra_filters_msan.go +++ b/runsc/boot/filter/extra_filters_msan.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/extra_filters_race.go b/runsc/boot/filter/extra_filters_race.go index 02a122c95..ba3c1ce87 100644 --- a/runsc/boot/filter/extra_filters_race.go +++ b/runsc/boot/filter/extra_filters_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/filter.go b/runsc/boot/filter/filter.go index fb197f9b1..17479e0dd 100644 --- a/runsc/boot/filter/filter.go +++ b/runsc/boot/filter/filter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index 07061b9b3..aeb1c52cc 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/limits.go b/runsc/boot/limits.go index 32e62cdf7..3364aa5e6 100644 --- a/runsc/boot/limits.go +++ b/runsc/boot/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 75ec19c32..0b5be0a42 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/loader_test.go b/runsc/boot/loader_test.go index 01578cfc5..9a864ad3f 100644 --- a/runsc/boot/loader_test.go +++ b/runsc/boot/loader_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 35baa36ad..598ec969e 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/strace.go b/runsc/boot/strace.go index 028bcc1f4..19c7f8fbd 100644 --- a/runsc/boot/strace.go +++ b/runsc/boot/strace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cgroup/cgroup.go b/runsc/cgroup/cgroup.go index 2b338b6c6..7431b17d6 100644 --- a/runsc/cgroup/cgroup.go +++ b/runsc/cgroup/cgroup.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cgroup/cgroup_test.go b/runsc/cgroup/cgroup_test.go index ecc184f74..548c80e9a 100644 --- a/runsc/cgroup/cgroup_test.go +++ b/runsc/cgroup/cgroup_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go index ff2fa2fb9..ac937f7bc 100644 --- a/runsc/cmd/boot.go +++ b/runsc/cmd/boot.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/capability.go b/runsc/cmd/capability.go index e5da021e5..312e5b471 100644 --- a/runsc/cmd/capability.go +++ b/runsc/cmd/capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/capability_test.go b/runsc/cmd/capability_test.go index dd278b32d..ee74d33d8 100644 --- a/runsc/cmd/capability_test.go +++ b/runsc/cmd/capability_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/checkpoint.go b/runsc/cmd/checkpoint.go index f722df055..96d3c3378 100644 --- a/runsc/cmd/checkpoint.go +++ b/runsc/cmd/checkpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/chroot.go b/runsc/cmd/chroot.go index ed1dafef1..1a774db04 100644 --- a/runsc/cmd/chroot.go +++ b/runsc/cmd/chroot.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/runsc/cmd/cmd.go b/runsc/cmd/cmd.go index 208cf5304..aa7b1a636 100644 --- a/runsc/cmd/cmd.go +++ b/runsc/cmd/cmd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/create.go b/runsc/cmd/create.go index 30c8fa283..629c198fd 100644 --- a/runsc/cmd/create.go +++ b/runsc/cmd/create.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/debug.go b/runsc/cmd/debug.go index 3ee9a9b49..000f694c7 100644 --- a/runsc/cmd/debug.go +++ b/runsc/cmd/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/delete.go b/runsc/cmd/delete.go index 3206b267a..9039723e9 100644 --- a/runsc/cmd/delete.go +++ b/runsc/cmd/delete.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/delete_test.go b/runsc/cmd/delete_test.go index 4a5b4774a..45fc91016 100644 --- a/runsc/cmd/delete_test.go +++ b/runsc/cmd/delete_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/do.go b/runsc/cmd/do.go index 343461130..67d415733 100644 --- a/runsc/cmd/do.go +++ b/runsc/cmd/do.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go index 208d2f74b..c6bc8fc3a 100644 --- a/runsc/cmd/events.go +++ b/runsc/cmd/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 718d01067..ad2508405 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/exec_test.go b/runsc/cmd/exec_test.go index 686c5e150..6f0f258c0 100644 --- a/runsc/cmd/exec_test.go +++ b/runsc/cmd/exec_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index 82487887c..bccb29397 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/gofer_test.go b/runsc/cmd/gofer_test.go index 8e692feb9..cbea7f127 100644 --- a/runsc/cmd/gofer_test.go +++ b/runsc/cmd/gofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/kill.go b/runsc/cmd/kill.go index e67f82473..aed5f3291 100644 --- a/runsc/cmd/kill.go +++ b/runsc/cmd/kill.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go index 1dcea2af0..1f5ca2473 100644 --- a/runsc/cmd/list.go +++ b/runsc/cmd/list.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/path.go b/runsc/cmd/path.go index 1276f0dbd..0e9ef7fa5 100644 --- a/runsc/cmd/path.go +++ b/runsc/cmd/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/pause.go b/runsc/cmd/pause.go index 2c93e5f3e..11b36aa10 100644 --- a/runsc/cmd/pause.go +++ b/runsc/cmd/pause.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/ps.go b/runsc/cmd/ps.go index 060d796f2..3a3e6f17a 100644 --- a/runsc/cmd/ps.go +++ b/runsc/cmd/ps.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/restore.go b/runsc/cmd/restore.go index 66b23c38e..27b06713a 100644 --- a/runsc/cmd/restore.go +++ b/runsc/cmd/restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/resume.go b/runsc/cmd/resume.go index 5551d1450..9a2ade41e 100644 --- a/runsc/cmd/resume.go +++ b/runsc/cmd/resume.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/run.go b/runsc/cmd/run.go index be1c1b678..4d5f5c139 100644 --- a/runsc/cmd/run.go +++ b/runsc/cmd/run.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/spec.go b/runsc/cmd/spec.go index 063bd39c5..344da13ba 100644 --- a/runsc/cmd/spec.go +++ b/runsc/cmd/spec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go index 9e2e0c11d..657726251 100644 --- a/runsc/cmd/start.go +++ b/runsc/cmd/start.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go index c3ef65ab5..f0d449b19 100644 --- a/runsc/cmd/state.go +++ b/runsc/cmd/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/wait.go b/runsc/cmd/wait.go index 6498dd15c..a55a682f3 100644 --- a/runsc/cmd/wait.go +++ b/runsc/cmd/wait.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/console/console.go b/runsc/console/console.go index 2eb9a8807..64b23639a 100644 --- a/runsc/console/console.go +++ b/runsc/console/console.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/console_test.go b/runsc/container/console_test.go index 0b0dfb4cb..b8af27c15 100644 --- a/runsc/container/console_test.go +++ b/runsc/container/console_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/container.go b/runsc/container/container.go index a30c217f7..884bbc0fb 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index 603c4d929..9458dbb90 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/hook.go b/runsc/container/hook.go index 6b9e5550a..acae6781e 100644 --- a/runsc/container/hook.go +++ b/runsc/container/hook.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/multi_container_test.go b/runsc/container/multi_container_test.go index 8922e6dbe..e554237cf 100644 --- a/runsc/container/multi_container_test.go +++ b/runsc/container/multi_container_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/shared_volume_test.go b/runsc/container/shared_volume_test.go index 8f81ed630..9d5a592a5 100644 --- a/runsc/container/shared_volume_test.go +++ b/runsc/container/shared_volume_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/runsc/container/status.go b/runsc/container/status.go index 234ffb0dd..91d9112f1 100644 --- a/runsc/container/status.go +++ b/runsc/container/status.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/test_app.go b/runsc/container/test_app.go index b5071ada6..62923f1ef 100644 --- a/runsc/container/test_app.go +++ b/runsc/container/test_app.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go index 75a087848..a1ad49fb2 100644 --- a/runsc/fsgofer/filter/config.go +++ b/runsc/fsgofer/filter/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/extra_filters.go b/runsc/fsgofer/filter/extra_filters.go index 67f3101fe..5c5ec4e06 100644 --- a/runsc/fsgofer/filter/extra_filters.go +++ b/runsc/fsgofer/filter/extra_filters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/extra_filters_msan.go b/runsc/fsgofer/filter/extra_filters_msan.go index 7e142b790..553060bc3 100644 --- a/runsc/fsgofer/filter/extra_filters_msan.go +++ b/runsc/fsgofer/filter/extra_filters_msan.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/extra_filters_race.go b/runsc/fsgofer/filter/extra_filters_race.go index 3cd29472a..28555f898 100644 --- a/runsc/fsgofer/filter/extra_filters_race.go +++ b/runsc/fsgofer/filter/extra_filters_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/filter.go b/runsc/fsgofer/filter/filter.go index c120d57a6..ff8154369 100644 --- a/runsc/fsgofer/filter/filter.go +++ b/runsc/fsgofer/filter/filter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index c964a2a3b..158f22ddc 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/fsgofer_test.go b/runsc/fsgofer/fsgofer_test.go index e74df7ede..695836927 100644 --- a/runsc/fsgofer/fsgofer_test.go +++ b/runsc/fsgofer/fsgofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/fsgofer_unsafe.go b/runsc/fsgofer/fsgofer_unsafe.go index 94413db86..58af5e44d 100644 --- a/runsc/fsgofer/fsgofer_unsafe.go +++ b/runsc/fsgofer/fsgofer_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/main.go b/runsc/main.go index b35726a74..11bc73f75 100644 --- a/runsc/main.go +++ b/runsc/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index 6c6b665a0..2a68d7043 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/sandbox/network_unsafe.go b/runsc/sandbox/network_unsafe.go index f7447f002..2a2a0fb7e 100644 --- a/runsc/sandbox/network_unsafe.go +++ b/runsc/sandbox/network_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 48a0dafe2..dac35ca0b 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/specutils/fs.go b/runsc/specutils/fs.go index 98c3b19c0..1f3afb4e4 100644 --- a/runsc/specutils/fs.go +++ b/runsc/specutils/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/specutils/namespace.go b/runsc/specutils/namespace.go index 35da789f4..7d194335c 100644 --- a/runsc/specutils/namespace.go +++ b/runsc/specutils/namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index ac85bec71..c72207fb4 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/specutils/specutils_test.go b/runsc/specutils/specutils_test.go index 02af6e6ad..2c86fffe8 100644 --- a/runsc/specutils/specutils_test.go +++ b/runsc/specutils/specutils_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/image/image.go b/runsc/test/image/image.go index bcb6f876f..297f1ab92 100644 --- a/runsc/test/image/image.go +++ b/runsc/test/image/image.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/image/image_test.go b/runsc/test/image/image_test.go index f7e750d71..0c45602f9 100644 --- a/runsc/test/image/image_test.go +++ b/runsc/test/image/image_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/image/mysql.sql b/runsc/test/image/mysql.sql index c1271e719..51554b98d 100644 --- a/runsc/test/image/mysql.sql +++ b/runsc/test/image/mysql.sql @@ -1,4 +1,4 @@ -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/runsc/test/image/ruby.rb b/runsc/test/image/ruby.rb index 25d1ac129..aced49c6d 100644 --- a/runsc/test/image/ruby.rb +++ b/runsc/test/image/ruby.rb @@ -1,4 +1,4 @@ -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/runsc/test/image/ruby.sh b/runsc/test/image/ruby.sh index d3a9b5656..ebe8d5b0e 100644 --- a/runsc/test/image/ruby.sh +++ b/runsc/test/image/ruby.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/runsc/test/install.sh b/runsc/test/install.sh index 32e1e884e..457df2d26 100755 --- a/runsc/test/install.sh +++ b/runsc/test/install.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/runsc/test/integration/exec_test.go b/runsc/test/integration/exec_test.go index d87957e2d..7af064d79 100644 --- a/runsc/test/integration/exec_test.go +++ b/runsc/test/integration/exec_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/integration/integration.go b/runsc/test/integration/integration.go index e15321c87..4cd5f6c24 100644 --- a/runsc/test/integration/integration.go +++ b/runsc/test/integration/integration.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/integration/integration_test.go b/runsc/test/integration/integration_test.go index 4a2770d48..b2e86aacc 100644 --- a/runsc/test/integration/integration_test.go +++ b/runsc/test/integration/integration_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/cgroup_test.go b/runsc/test/root/cgroup_test.go index 91839048c..edb6dee1d 100644 --- a/runsc/test/root/cgroup_test.go +++ b/runsc/test/root/cgroup_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/chroot_test.go b/runsc/test/root/chroot_test.go index 0deca0532..da2f473b9 100644 --- a/runsc/test/root/chroot_test.go +++ b/runsc/test/root/chroot_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/crictl_test.go b/runsc/test/root/crictl_test.go index 37fe53ba3..3cc176104 100644 --- a/runsc/test/root/crictl_test.go +++ b/runsc/test/root/crictl_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/root.go b/runsc/test/root/root.go index 586ea0fe3..349c752cc 100644 --- a/runsc/test/root/root.go +++ b/runsc/test/root/root.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/busybox.go b/runsc/test/root/testdata/busybox.go index 544571c63..e4dbd2843 100644 --- a/runsc/test/root/testdata/busybox.go +++ b/runsc/test/root/testdata/busybox.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/containerd_config.go b/runsc/test/root/testdata/containerd_config.go index 949354987..e12f1ec88 100644 --- a/runsc/test/root/testdata/containerd_config.go +++ b/runsc/test/root/testdata/containerd_config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/httpd.go b/runsc/test/root/testdata/httpd.go index f65b1da5d..45d5e33d4 100644 --- a/runsc/test/root/testdata/httpd.go +++ b/runsc/test/root/testdata/httpd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/httpd_mount_paths.go b/runsc/test/root/testdata/httpd_mount_paths.go index 5ca14340e..ac3f4446a 100644 --- a/runsc/test/root/testdata/httpd_mount_paths.go +++ b/runsc/test/root/testdata/httpd_mount_paths.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/sandbox.go b/runsc/test/root/testdata/sandbox.go index 194242a27..0db210370 100644 --- a/runsc/test/root/testdata/sandbox.go +++ b/runsc/test/root/testdata/sandbox.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/testutil/crictl.go b/runsc/test/testutil/crictl.go index 84bb4475a..4f9ee0c05 100644 --- a/runsc/test/testutil/crictl.go +++ b/runsc/test/testutil/crictl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/testutil/docker.go b/runsc/test/testutil/docker.go index b651319ed..29ef505b4 100644 --- a/runsc/test/testutil/docker.go +++ b/runsc/test/testutil/docker.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/testutil/testutil.go b/runsc/test/testutil/testutil.go index 79f0a8b6b..6a4c045a8 100644 --- a/runsc/test/testutil/testutil.go +++ b/runsc/test/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/testutil/testutil_race.go b/runsc/test/testutil/testutil_race.go index 9267af150..86db6ffa1 100644 --- a/runsc/test/testutil/testutil_race.go +++ b/runsc/test/testutil/testutil_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/tools/dockercfg/dockercfg.go b/runsc/tools/dockercfg/dockercfg.go index cc7a67816..6fb134558 100644 --- a/runsc/tools/dockercfg/dockercfg.go +++ b/runsc/tools/dockercfg/dockercfg.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/version.go b/runsc/version.go index 4894f2de6..ce0573a9b 100644 --- a/runsc/version.go +++ b/runsc/version.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/gtest/gtest.go b/test/syscalls/gtest/gtest.go index dfe5037cd..bdec8eb07 100644 --- a/test/syscalls/gtest/gtest.go +++ b/test/syscalls/gtest/gtest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/32bit.cc b/test/syscalls/linux/32bit.cc index 78baf548e..a7cbee06b 100644 --- a/test/syscalls/linux/32bit.cc +++ b/test/syscalls/linux/32bit.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/accept_bind.cc b/test/syscalls/linux/accept_bind.cc index c2bb4a7ce..56377feab 100644 --- a/test/syscalls/linux/accept_bind.cc +++ b/test/syscalls/linux/accept_bind.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/accept_bind_stream.cc b/test/syscalls/linux/accept_bind_stream.cc index 1501e526e..b6cdb3f4f 100644 --- a/test/syscalls/linux/accept_bind_stream.cc +++ b/test/syscalls/linux/accept_bind_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/access.cc b/test/syscalls/linux/access.cc index 6ea070a5d..bcc25cef4 100644 --- a/test/syscalls/linux/access.cc +++ b/test/syscalls/linux/access.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/affinity.cc b/test/syscalls/linux/affinity.cc index 81bd9bcb5..f2d8375b6 100644 --- a/test/syscalls/linux/affinity.cc +++ b/test/syscalls/linux/affinity.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/aio.cc b/test/syscalls/linux/aio.cc index b96aab9b9..68dc05417 100644 --- a/test/syscalls/linux/aio.cc +++ b/test/syscalls/linux/aio.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/alarm.cc b/test/syscalls/linux/alarm.cc index e0ddbb415..d89269985 100644 --- a/test/syscalls/linux/alarm.cc +++ b/test/syscalls/linux/alarm.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/arch_prctl.cc b/test/syscalls/linux/arch_prctl.cc index 5687ceb86..81bf5a775 100644 --- a/test/syscalls/linux/arch_prctl.cc +++ b/test/syscalls/linux/arch_prctl.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/bad.cc b/test/syscalls/linux/bad.cc index a2634a8bf..f246a799e 100644 --- a/test/syscalls/linux/bad.cc +++ b/test/syscalls/linux/bad.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/base_poll_test.cc b/test/syscalls/linux/base_poll_test.cc index bba0108ea..ab7a19dd0 100644 --- a/test/syscalls/linux/base_poll_test.cc +++ b/test/syscalls/linux/base_poll_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/base_poll_test.h b/test/syscalls/linux/base_poll_test.h index 9b9b81933..088831f9f 100644 --- a/test/syscalls/linux/base_poll_test.h +++ b/test/syscalls/linux/base_poll_test.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/bind.cc b/test/syscalls/linux/bind.cc index f5aa9c500..de8cca53b 100644 --- a/test/syscalls/linux/bind.cc +++ b/test/syscalls/linux/bind.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/brk.cc b/test/syscalls/linux/brk.cc index 33d353959..a03a44465 100644 --- a/test/syscalls/linux/brk.cc +++ b/test/syscalls/linux/brk.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/chdir.cc b/test/syscalls/linux/chdir.cc index a4b54f0ee..3182c228b 100644 --- a/test/syscalls/linux/chdir.cc +++ b/test/syscalls/linux/chdir.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/chmod.cc b/test/syscalls/linux/chmod.cc index 2f42fe326..79e98597f 100644 --- a/test/syscalls/linux/chmod.cc +++ b/test/syscalls/linux/chmod.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/chown.cc b/test/syscalls/linux/chown.cc index ad892cf6a..eb1762ddf 100644 --- a/test/syscalls/linux/chown.cc +++ b/test/syscalls/linux/chown.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/chroot.cc b/test/syscalls/linux/chroot.cc index 6c200f63e..a4354ff62 100644 --- a/test/syscalls/linux/chroot.cc +++ b/test/syscalls/linux/chroot.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/clock_getres.cc b/test/syscalls/linux/clock_getres.cc index 8f8842299..c408b936c 100644 --- a/test/syscalls/linux/clock_getres.cc +++ b/test/syscalls/linux/clock_getres.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/clock_gettime.cc b/test/syscalls/linux/clock_gettime.cc index 4ecb5f5b1..082ae1c39 100644 --- a/test/syscalls/linux/clock_gettime.cc +++ b/test/syscalls/linux/clock_gettime.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/clock_nanosleep.cc b/test/syscalls/linux/clock_nanosleep.cc index 61c67a5ff..52a69d230 100644 --- a/test/syscalls/linux/clock_nanosleep.cc +++ b/test/syscalls/linux/clock_nanosleep.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/concurrency.cc b/test/syscalls/linux/concurrency.cc index 7978845c1..4e0a13f8b 100644 --- a/test/syscalls/linux/concurrency.cc +++ b/test/syscalls/linux/concurrency.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/creat.cc b/test/syscalls/linux/creat.cc index df2cc0d5c..3c270d6da 100644 --- a/test/syscalls/linux/creat.cc +++ b/test/syscalls/linux/creat.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/dev.cc b/test/syscalls/linux/dev.cc index a140d3b30..b86ebe233 100644 --- a/test/syscalls/linux/dev.cc +++ b/test/syscalls/linux/dev.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/dup.cc b/test/syscalls/linux/dup.cc index e8de2f4c4..4f773bc75 100644 --- a/test/syscalls/linux/dup.cc +++ b/test/syscalls/linux/dup.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/epoll.cc b/test/syscalls/linux/epoll.cc index b4a3bfcba..a4f8f3cec 100644 --- a/test/syscalls/linux/epoll.cc +++ b/test/syscalls/linux/epoll.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/eventfd.cc b/test/syscalls/linux/eventfd.cc index 8111da30e..5e5c39d44 100644 --- a/test/syscalls/linux/eventfd.cc +++ b/test/syscalls/linux/eventfd.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exceptions.cc b/test/syscalls/linux/exceptions.cc index 3f0aa8bf1..0da4c817d 100644 --- a/test/syscalls/linux/exceptions.cc +++ b/test/syscalls/linux/exceptions.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec.cc b/test/syscalls/linux/exec.cc index 30bc4b608..06c322a99 100644 --- a/test/syscalls/linux/exec.cc +++ b/test/syscalls/linux/exec.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec.h b/test/syscalls/linux/exec.h index b82bfffd1..5c0f7e654 100644 --- a/test/syscalls/linux/exec.h +++ b/test/syscalls/linux/exec.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_assert_closed_workload.cc b/test/syscalls/linux/exec_assert_closed_workload.cc index 4448431e1..95643618d 100644 --- a/test/syscalls/linux/exec_assert_closed_workload.cc +++ b/test/syscalls/linux/exec_assert_closed_workload.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_basic_workload.cc b/test/syscalls/linux/exec_basic_workload.cc index d4bdf511f..1bbd6437e 100644 --- a/test/syscalls/linux/exec_basic_workload.cc +++ b/test/syscalls/linux/exec_basic_workload.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_binary.cc b/test/syscalls/linux/exec_binary.cc index c10d85398..bdd6eb10b 100644 --- a/test/syscalls/linux/exec_binary.cc +++ b/test/syscalls/linux/exec_binary.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_proc_exe_workload.cc b/test/syscalls/linux/exec_proc_exe_workload.cc index b9a4ac749..b3fbd5042 100644 --- a/test/syscalls/linux/exec_proc_exe_workload.cc +++ b/test/syscalls/linux/exec_proc_exe_workload.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_state_workload.cc b/test/syscalls/linux/exec_state_workload.cc index b66e22565..725c2977f 100644 --- a/test/syscalls/linux/exec_state_workload.cc +++ b/test/syscalls/linux/exec_state_workload.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exit.cc b/test/syscalls/linux/exit.cc index 7246a7b3b..99de2b376 100644 --- a/test/syscalls/linux/exit.cc +++ b/test/syscalls/linux/exit.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exit_script.sh b/test/syscalls/linux/exit_script.sh index f014fcf99..527518e06 100755 --- a/test/syscalls/linux/exit_script.sh +++ b/test/syscalls/linux/exit_script.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/test/syscalls/linux/fadvise64.cc b/test/syscalls/linux/fadvise64.cc index 041e8b7b6..2af7aa6d9 100644 --- a/test/syscalls/linux/fadvise64.cc +++ b/test/syscalls/linux/fadvise64.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fallocate.cc b/test/syscalls/linux/fallocate.cc index e51538734..61b8acc7a 100644 --- a/test/syscalls/linux/fallocate.cc +++ b/test/syscalls/linux/fallocate.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fault.cc b/test/syscalls/linux/fault.cc index cfa7d0d1f..f6e19026f 100644 --- a/test/syscalls/linux/fault.cc +++ b/test/syscalls/linux/fault.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fchdir.cc b/test/syscalls/linux/fchdir.cc index 2b13e36c3..08bcae1e8 100644 --- a/test/syscalls/linux/fchdir.cc +++ b/test/syscalls/linux/fchdir.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fcntl.cc b/test/syscalls/linux/fcntl.cc index 32a90a163..2f8e7c9dd 100644 --- a/test/syscalls/linux/fcntl.cc +++ b/test/syscalls/linux/fcntl.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/file_base.h b/test/syscalls/linux/file_base.h index 43f568111..b5b972c07 100644 --- a/test/syscalls/linux/file_base.h +++ b/test/syscalls/linux/file_base.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/flock.cc b/test/syscalls/linux/flock.cc index 1388d3839..d89cfcbd7 100644 --- a/test/syscalls/linux/flock.cc +++ b/test/syscalls/linux/flock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fork.cc b/test/syscalls/linux/fork.cc index 73ac885b5..dd6e1a422 100644 --- a/test/syscalls/linux/fork.cc +++ b/test/syscalls/linux/fork.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fpsig_fork.cc b/test/syscalls/linux/fpsig_fork.cc index e8f1dfa8a..e7e9f06a1 100644 --- a/test/syscalls/linux/fpsig_fork.cc +++ b/test/syscalls/linux/fpsig_fork.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fpsig_nested.cc b/test/syscalls/linux/fpsig_nested.cc index 2fa40b42d..395463aed 100644 --- a/test/syscalls/linux/fpsig_nested.cc +++ b/test/syscalls/linux/fpsig_nested.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fsync.cc b/test/syscalls/linux/fsync.cc index b34229248..e7e057f06 100644 --- a/test/syscalls/linux/fsync.cc +++ b/test/syscalls/linux/fsync.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/futex.cc b/test/syscalls/linux/futex.cc index c7a709a0a..bfec95466 100644 --- a/test/syscalls/linux/futex.cc +++ b/test/syscalls/linux/futex.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/getcpu.cc b/test/syscalls/linux/getcpu.cc index 3a52b25fa..f4d94bd6a 100644 --- a/test/syscalls/linux/getcpu.cc +++ b/test/syscalls/linux/getcpu.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/getdents.cc b/test/syscalls/linux/getdents.cc index e8a7bcd43..d146c8db7 100644 --- a/test/syscalls/linux/getdents.cc +++ b/test/syscalls/linux/getdents.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/getrandom.cc b/test/syscalls/linux/getrandom.cc index be5325497..f97f60029 100644 --- a/test/syscalls/linux/getrandom.cc +++ b/test/syscalls/linux/getrandom.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/getrusage.cc b/test/syscalls/linux/getrusage.cc index 1ae603858..9bdb1e4cd 100644 --- a/test/syscalls/linux/getrusage.cc +++ b/test/syscalls/linux/getrusage.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/inotify.cc b/test/syscalls/linux/inotify.cc index b99d339e5..6a3539e22 100644 --- a/test/syscalls/linux/inotify.cc +++ b/test/syscalls/linux/inotify.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ioctl.cc b/test/syscalls/linux/ioctl.cc index c7741a177..c525d41d2 100644 --- a/test/syscalls/linux/ioctl.cc +++ b/test/syscalls/linux/ioctl.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ip_socket_test_util.cc b/test/syscalls/linux/ip_socket_test_util.cc index 0a149c2e5..7612919d4 100644 --- a/test/syscalls/linux/ip_socket_test_util.cc +++ b/test/syscalls/linux/ip_socket_test_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ip_socket_test_util.h b/test/syscalls/linux/ip_socket_test_util.h index cac790e64..6898effb8 100644 --- a/test/syscalls/linux/ip_socket_test_util.h +++ b/test/syscalls/linux/ip_socket_test_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/itimer.cc b/test/syscalls/linux/itimer.cc index ddfbc28fc..57ffd1595 100644 --- a/test/syscalls/linux/itimer.cc +++ b/test/syscalls/linux/itimer.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/kill.cc b/test/syscalls/linux/kill.cc index cd98de41f..18ad923b8 100644 --- a/test/syscalls/linux/kill.cc +++ b/test/syscalls/linux/kill.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/link.cc b/test/syscalls/linux/link.cc index ed74437bc..a91703070 100644 --- a/test/syscalls/linux/link.cc +++ b/test/syscalls/linux/link.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/lseek.cc b/test/syscalls/linux/lseek.cc index 6a4f1423c..a8af8e545 100644 --- a/test/syscalls/linux/lseek.cc +++ b/test/syscalls/linux/lseek.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/madvise.cc b/test/syscalls/linux/madvise.cc index a79c8c75d..f6ad4d18b 100644 --- a/test/syscalls/linux/madvise.cc +++ b/test/syscalls/linux/madvise.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/memfd.cc b/test/syscalls/linux/memfd.cc index c2513682d..7e103124b 100644 --- a/test/syscalls/linux/memfd.cc +++ b/test/syscalls/linux/memfd.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/memory_accounting.cc b/test/syscalls/linux/memory_accounting.cc index b4b680c34..a6e20f9c3 100644 --- a/test/syscalls/linux/memory_accounting.cc +++ b/test/syscalls/linux/memory_accounting.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mempolicy.cc b/test/syscalls/linux/mempolicy.cc index 9f8033bdf..4ac4cb88f 100644 --- a/test/syscalls/linux/mempolicy.cc +++ b/test/syscalls/linux/mempolicy.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mincore.cc b/test/syscalls/linux/mincore.cc index c572bf5ec..5c1240c89 100644 --- a/test/syscalls/linux/mincore.cc +++ b/test/syscalls/linux/mincore.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mkdir.cc b/test/syscalls/linux/mkdir.cc index 50807b68f..cf138d328 100644 --- a/test/syscalls/linux/mkdir.cc +++ b/test/syscalls/linux/mkdir.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mknod.cc b/test/syscalls/linux/mknod.cc index 361ca299b..b1675b9c7 100644 --- a/test/syscalls/linux/mknod.cc +++ b/test/syscalls/linux/mknod.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mlock.cc b/test/syscalls/linux/mlock.cc index a492b2404..aee4f7d1a 100644 --- a/test/syscalls/linux/mlock.cc +++ b/test/syscalls/linux/mlock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mmap.cc b/test/syscalls/linux/mmap.cc index a4fb9d1e0..5b5b4c2e8 100644 --- a/test/syscalls/linux/mmap.cc +++ b/test/syscalls/linux/mmap.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mount.cc b/test/syscalls/linux/mount.cc index 201b83e87..3a17672aa 100644 --- a/test/syscalls/linux/mount.cc +++ b/test/syscalls/linux/mount.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mremap.cc b/test/syscalls/linux/mremap.cc index 01116c1ab..7298d4ca8 100644 --- a/test/syscalls/linux/mremap.cc +++ b/test/syscalls/linux/mremap.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/msync.cc b/test/syscalls/linux/msync.cc index 5afbfce72..ac7146017 100644 --- a/test/syscalls/linux/msync.cc +++ b/test/syscalls/linux/msync.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/munmap.cc b/test/syscalls/linux/munmap.cc index e20039950..067241f4d 100644 --- a/test/syscalls/linux/munmap.cc +++ b/test/syscalls/linux/munmap.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/open.cc b/test/syscalls/linux/open.cc index 22e4666c2..42646bb02 100644 --- a/test/syscalls/linux/open.cc +++ b/test/syscalls/linux/open.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/open_create.cc b/test/syscalls/linux/open_create.cc index b2cbd63d1..e5a85ef9d 100644 --- a/test/syscalls/linux/open_create.cc +++ b/test/syscalls/linux/open_create.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/partial_bad_buffer.cc b/test/syscalls/linux/partial_bad_buffer.cc index 71288ebc4..83b1ad4e4 100644 --- a/test/syscalls/linux/partial_bad_buffer.cc +++ b/test/syscalls/linux/partial_bad_buffer.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pause.cc b/test/syscalls/linux/pause.cc index 4e1148c24..8c05efd6f 100644 --- a/test/syscalls/linux/pause.cc +++ b/test/syscalls/linux/pause.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pipe.cc b/test/syscalls/linux/pipe.cc index abd10b11b..8698295b3 100644 --- a/test/syscalls/linux/pipe.cc +++ b/test/syscalls/linux/pipe.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/poll.cc b/test/syscalls/linux/poll.cc index cd2161bb1..9e5aa7fd0 100644 --- a/test/syscalls/linux/poll.cc +++ b/test/syscalls/linux/poll.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ppoll.cc b/test/syscalls/linux/ppoll.cc index f8c388c00..8245a11e8 100644 --- a/test/syscalls/linux/ppoll.cc +++ b/test/syscalls/linux/ppoll.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/prctl.cc b/test/syscalls/linux/prctl.cc index 854dec714..bce42dc74 100644 --- a/test/syscalls/linux/prctl.cc +++ b/test/syscalls/linux/prctl.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/prctl_setuid.cc b/test/syscalls/linux/prctl_setuid.cc index c1b561464..00dd6523e 100644 --- a/test/syscalls/linux/prctl_setuid.cc +++ b/test/syscalls/linux/prctl_setuid.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pread64.cc b/test/syscalls/linux/pread64.cc index 4e5bcfcde..5e3eb1735 100644 --- a/test/syscalls/linux/pread64.cc +++ b/test/syscalls/linux/pread64.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/preadv.cc b/test/syscalls/linux/preadv.cc index 4a31123d8..eebd129f2 100644 --- a/test/syscalls/linux/preadv.cc +++ b/test/syscalls/linux/preadv.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/preadv2.cc b/test/syscalls/linux/preadv2.cc index 58a4f9224..aac960130 100644 --- a/test/syscalls/linux/preadv2.cc +++ b/test/syscalls/linux/preadv2.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/priority.cc b/test/syscalls/linux/priority.cc index 3906c7132..1d9bdfa70 100644 --- a/test/syscalls/linux/priority.cc +++ b/test/syscalls/linux/priority.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/priority_execve.cc b/test/syscalls/linux/priority_execve.cc index 5604bd3d0..5cb343bad 100644 --- a/test/syscalls/linux/priority_execve.cc +++ b/test/syscalls/linux/priority_execve.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/proc.cc b/test/syscalls/linux/proc.cc index 7ba274226..654f26242 100644 --- a/test/syscalls/linux/proc.cc +++ b/test/syscalls/linux/proc.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/proc_net.cc b/test/syscalls/linux/proc_net.cc index 6060d0644..03d0665eb 100644 --- a/test/syscalls/linux/proc_net.cc +++ b/test/syscalls/linux/proc_net.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/proc_net_unix.cc b/test/syscalls/linux/proc_net_unix.cc index ea7c93012..6d745f728 100644 --- a/test/syscalls/linux/proc_net_unix.cc +++ b/test/syscalls/linux/proc_net_unix.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/proc_pid_smaps.cc b/test/syscalls/linux/proc_pid_smaps.cc index cf5c462f3..7f2e8f203 100644 --- a/test/syscalls/linux/proc_pid_smaps.cc +++ b/test/syscalls/linux/proc_pid_smaps.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/proc_pid_uid_gid_map.cc b/test/syscalls/linux/proc_pid_uid_gid_map.cc index 96c58c564..df70b7eb9 100644 --- a/test/syscalls/linux/proc_pid_uid_gid_map.cc +++ b/test/syscalls/linux/proc_pid_uid_gid_map.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/pselect.cc b/test/syscalls/linux/pselect.cc index 3294f6c14..4e43c4d7f 100644 --- a/test/syscalls/linux/pselect.cc +++ b/test/syscalls/linux/pselect.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ptrace.cc b/test/syscalls/linux/ptrace.cc index e0c56f1fc..4c212836c 100644 --- a/test/syscalls/linux/ptrace.cc +++ b/test/syscalls/linux/ptrace.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pty.cc b/test/syscalls/linux/pty.cc index 5b2dc9ccb..0485d187c 100644 --- a/test/syscalls/linux/pty.cc +++ b/test/syscalls/linux/pty.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pwrite64.cc b/test/syscalls/linux/pwrite64.cc index 485b1e48d..e1603fc2d 100644 --- a/test/syscalls/linux/pwrite64.cc +++ b/test/syscalls/linux/pwrite64.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pwritev2.cc b/test/syscalls/linux/pwritev2.cc index a6949f08e..db519f4e0 100644 --- a/test/syscalls/linux/pwritev2.cc +++ b/test/syscalls/linux/pwritev2.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/raw_socket_ipv4.cc b/test/syscalls/linux/raw_socket_ipv4.cc index 8b8d032cb..e20b5cb50 100644 --- a/test/syscalls/linux/raw_socket_ipv4.cc +++ b/test/syscalls/linux/raw_socket_ipv4.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/read.cc b/test/syscalls/linux/read.cc index eb1b5bc10..4430fa3c2 100644 --- a/test/syscalls/linux/read.cc +++ b/test/syscalls/linux/read.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/readv.cc b/test/syscalls/linux/readv.cc index 0b933673a..f327ec3a9 100644 --- a/test/syscalls/linux/readv.cc +++ b/test/syscalls/linux/readv.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/readv_common.cc b/test/syscalls/linux/readv_common.cc index 349b80d7f..35d2dd9e3 100644 --- a/test/syscalls/linux/readv_common.cc +++ b/test/syscalls/linux/readv_common.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/readv_common.h b/test/syscalls/linux/readv_common.h index e261d545a..b16179fca 100644 --- a/test/syscalls/linux/readv_common.h +++ b/test/syscalls/linux/readv_common.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/readv_socket.cc b/test/syscalls/linux/readv_socket.cc index cf22c395e..3c315cc02 100644 --- a/test/syscalls/linux/readv_socket.cc +++ b/test/syscalls/linux/readv_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/rename.cc b/test/syscalls/linux/rename.cc index c0cbc7cd9..c9d76c2e2 100644 --- a/test/syscalls/linux/rename.cc +++ b/test/syscalls/linux/rename.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/rlimits.cc b/test/syscalls/linux/rlimits.cc index 7b255d0f6..860f0f688 100644 --- a/test/syscalls/linux/rlimits.cc +++ b/test/syscalls/linux/rlimits.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/rtsignal.cc b/test/syscalls/linux/rtsignal.cc index ff948f9d5..81d193ffd 100644 --- a/test/syscalls/linux/rtsignal.cc +++ b/test/syscalls/linux/rtsignal.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sched.cc b/test/syscalls/linux/sched.cc index 60cb6c443..735e99411 100644 --- a/test/syscalls/linux/sched.cc +++ b/test/syscalls/linux/sched.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sched_yield.cc b/test/syscalls/linux/sched_yield.cc index fc45aa5c2..5d24f5b58 100644 --- a/test/syscalls/linux/sched_yield.cc +++ b/test/syscalls/linux/sched_yield.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/seccomp.cc b/test/syscalls/linux/seccomp.cc index 27740d7ef..e77586852 100644 --- a/test/syscalls/linux/seccomp.cc +++ b/test/syscalls/linux/seccomp.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/select.cc b/test/syscalls/linux/select.cc index 41e6043cc..88c010aec 100644 --- a/test/syscalls/linux/select.cc +++ b/test/syscalls/linux/select.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/semaphore.cc b/test/syscalls/linux/semaphore.cc index 1c47b6851..421318fcb 100644 --- a/test/syscalls/linux/semaphore.cc +++ b/test/syscalls/linux/semaphore.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sendfile.cc b/test/syscalls/linux/sendfile.cc index 15fd01ff0..2fbb3f4ef 100644 --- a/test/syscalls/linux/sendfile.cc +++ b/test/syscalls/linux/sendfile.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sendfile_socket.cc b/test/syscalls/linux/sendfile_socket.cc index e2ccf17ce..66adda515 100644 --- a/test/syscalls/linux/sendfile_socket.cc +++ b/test/syscalls/linux/sendfile_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/shm.cc b/test/syscalls/linux/shm.cc index 2c0f9b04a..eb7a3966f 100644 --- a/test/syscalls/linux/shm.cc +++ b/test/syscalls/linux/shm.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigaction.cc b/test/syscalls/linux/sigaction.cc index cdd2dbf31..9a53fd3e0 100644 --- a/test/syscalls/linux/sigaction.cc +++ b/test/syscalls/linux/sigaction.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigaltstack.cc b/test/syscalls/linux/sigaltstack.cc index 5741720f4..7d4a12c1d 100644 --- a/test/syscalls/linux/sigaltstack.cc +++ b/test/syscalls/linux/sigaltstack.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigaltstack_check.cc b/test/syscalls/linux/sigaltstack_check.cc index b71f812a8..5ac1b661d 100644 --- a/test/syscalls/linux/sigaltstack_check.cc +++ b/test/syscalls/linux/sigaltstack_check.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigiret.cc b/test/syscalls/linux/sigiret.cc index 1b7cecccb..a47c781ea 100644 --- a/test/syscalls/linux/sigiret.cc +++ b/test/syscalls/linux/sigiret.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigprocmask.cc b/test/syscalls/linux/sigprocmask.cc index 1aea1ecb8..654c6a47f 100644 --- a/test/syscalls/linux/sigprocmask.cc +++ b/test/syscalls/linux/sigprocmask.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigstop.cc b/test/syscalls/linux/sigstop.cc index e21d23d51..9c7210e17 100644 --- a/test/syscalls/linux/sigstop.cc +++ b/test/syscalls/linux/sigstop.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigtimedwait.cc b/test/syscalls/linux/sigtimedwait.cc index 1df9c013f..1e5bf5942 100644 --- a/test/syscalls/linux/sigtimedwait.cc +++ b/test/syscalls/linux/sigtimedwait.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_abstract.cc b/test/syscalls/linux/socket_abstract.cc index 639cd4e59..2faf678f7 100644 --- a/test/syscalls/linux/socket_abstract.cc +++ b/test/syscalls/linux/socket_abstract.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_blocking.cc b/test/syscalls/linux/socket_blocking.cc index c1bca467f..00c50d1bf 100644 --- a/test/syscalls/linux/socket_blocking.cc +++ b/test/syscalls/linux/socket_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_blocking.h b/test/syscalls/linux/socket_blocking.h index 5cddee54b..db26e5ef5 100644 --- a/test/syscalls/linux/socket_blocking.h +++ b/test/syscalls/linux/socket_blocking.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_filesystem.cc b/test/syscalls/linux/socket_filesystem.cc index 2653be158..f7cb72df4 100644 --- a/test/syscalls/linux/socket_filesystem.cc +++ b/test/syscalls/linux/socket_filesystem.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_generic.cc b/test/syscalls/linux/socket_generic.cc index d04d5abe0..f99f3fe62 100644 --- a/test/syscalls/linux/socket_generic.cc +++ b/test/syscalls/linux/socket_generic.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_generic.h b/test/syscalls/linux/socket_generic.h index cd826abcf..00ae7bfc3 100644 --- a/test/syscalls/linux/socket_generic.h +++ b/test/syscalls/linux/socket_generic.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_inet_loopback.cc b/test/syscalls/linux/socket_inet_loopback.cc index 14d7827c2..f86a0f30c 100644 --- a/test/syscalls/linux/socket_inet_loopback.cc +++ b/test/syscalls/linux/socket_inet_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_loopback_blocking.cc b/test/syscalls/linux/socket_ip_loopback_blocking.cc index 9cec7a71d..d7fc20aad 100644 --- a/test/syscalls/linux/socket_ip_loopback_blocking.cc +++ b/test/syscalls/linux/socket_ip_loopback_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_generic.cc b/test/syscalls/linux/socket_ip_tcp_generic.cc index 54f00cd9b..5b198f49d 100644 --- a/test/syscalls/linux/socket_ip_tcp_generic.cc +++ b/test/syscalls/linux/socket_ip_tcp_generic.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_generic.h b/test/syscalls/linux/socket_ip_tcp_generic.h index f38500d14..a3eff3c73 100644 --- a/test/syscalls/linux/socket_ip_tcp_generic.h +++ b/test/syscalls/linux/socket_ip_tcp_generic.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_generic_loopback.cc b/test/syscalls/linux/socket_ip_tcp_generic_loopback.cc index 1963d5deb..2c6ae17bf 100644 --- a/test/syscalls/linux/socket_ip_tcp_generic_loopback.cc +++ b/test/syscalls/linux/socket_ip_tcp_generic_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_loopback.cc b/test/syscalls/linux/socket_ip_tcp_loopback.cc index 7e36c35d2..831de53b8 100644 --- a/test/syscalls/linux/socket_ip_tcp_loopback.cc +++ b/test/syscalls/linux/socket_ip_tcp_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc b/test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc index 9e2a18d3e..d1ea8ef12 100644 --- a/test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc +++ b/test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc b/test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc index 54053360f..96c1b3b3d 100644 --- a/test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc +++ b/test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_udp_generic.cc b/test/syscalls/linux/socket_ip_tcp_udp_generic.cc index 5bf1de7c6..251817a9f 100644 --- a/test/syscalls/linux/socket_ip_tcp_udp_generic.cc +++ b/test/syscalls/linux/socket_ip_tcp_udp_generic.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_generic.cc b/test/syscalls/linux/socket_ip_udp_generic.cc index ac15154f2..044394ba7 100644 --- a/test/syscalls/linux/socket_ip_udp_generic.cc +++ b/test/syscalls/linux/socket_ip_udp_generic.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_generic.h b/test/syscalls/linux/socket_ip_udp_generic.h index 8b8fc7c6e..106c54e9f 100644 --- a/test/syscalls/linux/socket_ip_udp_generic.h +++ b/test/syscalls/linux/socket_ip_udp_generic.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_loopback.cc b/test/syscalls/linux/socket_ip_udp_loopback.cc index 0e4463649..fc124e9ef 100644 --- a/test/syscalls/linux/socket_ip_udp_loopback.cc +++ b/test/syscalls/linux/socket_ip_udp_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_loopback_blocking.cc b/test/syscalls/linux/socket_ip_udp_loopback_blocking.cc index 0c3b669bf..1c3d1c0ad 100644 --- a/test/syscalls/linux/socket_ip_udp_loopback_blocking.cc +++ b/test/syscalls/linux/socket_ip_udp_loopback_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc b/test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc index 7bf8597fe..7554b08d5 100644 --- a/test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc +++ b/test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc index 8e1c13ff4..3a068aacf 100644 --- a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h index b23de08d1..fb582b224 100644 --- a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc index 773d84b13..040bb176e 100644 --- a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc index c99958ed5..709172580 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.h b/test/syscalls/linux/socket_ipv4_udp_unbound.h index a780c0144..8e07bfbbf 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound.h +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc index 9dd9e1bd6..53dcd58cd 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h index 5cf9fa8eb..45e1d37ea 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc index 535a5fa10..ffbb8e6eb 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc index d6a8e428c..cb0105471 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_netdevice.cc b/test/syscalls/linux/socket_netdevice.cc index b4e9fe51b..6a5fa8965 100644 --- a/test/syscalls/linux/socket_netdevice.cc +++ b/test/syscalls/linux/socket_netdevice.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_netlink_route.cc b/test/syscalls/linux/socket_netlink_route.cc index ed4ae1c71..c8693225f 100644 --- a/test/syscalls/linux/socket_netlink_route.cc +++ b/test/syscalls/linux/socket_netlink_route.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_netlink_util.cc b/test/syscalls/linux/socket_netlink_util.cc index edf549544..728d25434 100644 --- a/test/syscalls/linux/socket_netlink_util.cc +++ b/test/syscalls/linux/socket_netlink_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_netlink_util.h b/test/syscalls/linux/socket_netlink_util.h index 44b1f148c..bea449107 100644 --- a/test/syscalls/linux/socket_netlink_util.h +++ b/test/syscalls/linux/socket_netlink_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_blocking.cc b/test/syscalls/linux/socket_non_blocking.cc index 1bcc6fb7f..73e6dc618 100644 --- a/test/syscalls/linux/socket_non_blocking.cc +++ b/test/syscalls/linux/socket_non_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_blocking.h b/test/syscalls/linux/socket_non_blocking.h index 287e096bb..bd3e02fd2 100644 --- a/test/syscalls/linux/socket_non_blocking.h +++ b/test/syscalls/linux/socket_non_blocking.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_stream.cc b/test/syscalls/linux/socket_non_stream.cc index d170008a4..3c599b6e8 100644 --- a/test/syscalls/linux/socket_non_stream.cc +++ b/test/syscalls/linux/socket_non_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_stream.h b/test/syscalls/linux/socket_non_stream.h index 02dd2a958..469fbe6a2 100644 --- a/test/syscalls/linux/socket_non_stream.h +++ b/test/syscalls/linux/socket_non_stream.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_stream_blocking.cc b/test/syscalls/linux/socket_non_stream_blocking.cc index 9e92628c3..76127d181 100644 --- a/test/syscalls/linux/socket_non_stream_blocking.cc +++ b/test/syscalls/linux/socket_non_stream_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_stream_blocking.h b/test/syscalls/linux/socket_non_stream_blocking.h index bde355452..6e205a039 100644 --- a/test/syscalls/linux/socket_non_stream_blocking.h +++ b/test/syscalls/linux/socket_non_stream_blocking.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream.cc b/test/syscalls/linux/socket_stream.cc index c8a8ad0f6..0417dd347 100644 --- a/test/syscalls/linux/socket_stream.cc +++ b/test/syscalls/linux/socket_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream.h b/test/syscalls/linux/socket_stream.h index 35e591e17..b837b8f8c 100644 --- a/test/syscalls/linux/socket_stream.h +++ b/test/syscalls/linux/socket_stream.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream_blocking.cc b/test/syscalls/linux/socket_stream_blocking.cc index f0f86c01c..8367460d2 100644 --- a/test/syscalls/linux/socket_stream_blocking.cc +++ b/test/syscalls/linux/socket_stream_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream_blocking.h b/test/syscalls/linux/socket_stream_blocking.h index 06113ad03..9fd19ff90 100644 --- a/test/syscalls/linux/socket_stream_blocking.h +++ b/test/syscalls/linux/socket_stream_blocking.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream_nonblock.cc b/test/syscalls/linux/socket_stream_nonblock.cc index a3202ffe4..b00748b97 100644 --- a/test/syscalls/linux/socket_stream_nonblock.cc +++ b/test/syscalls/linux/socket_stream_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream_nonblock.h b/test/syscalls/linux/socket_stream_nonblock.h index 491f53848..c3b7fad91 100644 --- a/test/syscalls/linux/socket_stream_nonblock.h +++ b/test/syscalls/linux/socket_stream_nonblock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc index 0be23e541..da69de37c 100644 --- a/test/syscalls/linux/socket_test_util.cc +++ b/test/syscalls/linux/socket_test_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h index dfabdf179..058313986 100644 --- a/test/syscalls/linux/socket_test_util.h +++ b/test/syscalls/linux/socket_test_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix.cc b/test/syscalls/linux/socket_unix.cc index fafb23ad1..bb3397fa2 100644 --- a/test/syscalls/linux/socket_unix.cc +++ b/test/syscalls/linux/socket_unix.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix.h b/test/syscalls/linux/socket_unix.h index d2a16afb2..3625cc404 100644 --- a/test/syscalls/linux/socket_unix.h +++ b/test/syscalls/linux/socket_unix.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_abstract.cc b/test/syscalls/linux/socket_unix_abstract.cc index c4a3c889c..8241bf997 100644 --- a/test/syscalls/linux/socket_unix_abstract.cc +++ b/test/syscalls/linux/socket_unix_abstract.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_abstract_nonblock.cc b/test/syscalls/linux/socket_unix_abstract_nonblock.cc index a69ee027e..9de0f6dfe 100644 --- a/test/syscalls/linux/socket_unix_abstract_nonblock.cc +++ b/test/syscalls/linux/socket_unix_abstract_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_blocking_local.cc b/test/syscalls/linux/socket_unix_blocking_local.cc index 57af118c5..320915b0f 100644 --- a/test/syscalls/linux/socket_unix_blocking_local.cc +++ b/test/syscalls/linux/socket_unix_blocking_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_dgram.cc b/test/syscalls/linux/socket_unix_dgram.cc index 5dd5e6d77..3e0f611d2 100644 --- a/test/syscalls/linux/socket_unix_dgram.cc +++ b/test/syscalls/linux/socket_unix_dgram.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_dgram.h b/test/syscalls/linux/socket_unix_dgram.h index 722a3d8e6..0764ef85b 100644 --- a/test/syscalls/linux/socket_unix_dgram.h +++ b/test/syscalls/linux/socket_unix_dgram.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_dgram_local.cc b/test/syscalls/linux/socket_unix_dgram_local.cc index da8f59704..4ba2c80ae 100644 --- a/test/syscalls/linux/socket_unix_dgram_local.cc +++ b/test/syscalls/linux/socket_unix_dgram_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_dgram_non_blocking.cc b/test/syscalls/linux/socket_unix_dgram_non_blocking.cc index 3becb513d..9fe86cee8 100644 --- a/test/syscalls/linux/socket_unix_dgram_non_blocking.cc +++ b/test/syscalls/linux/socket_unix_dgram_non_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_domain.cc b/test/syscalls/linux/socket_unix_domain.cc index f081c601f..fa3efc7f8 100644 --- a/test/syscalls/linux/socket_unix_domain.cc +++ b/test/syscalls/linux/socket_unix_domain.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_filesystem.cc b/test/syscalls/linux/socket_unix_filesystem.cc index 6a67da75f..5dbe67773 100644 --- a/test/syscalls/linux/socket_unix_filesystem.cc +++ b/test/syscalls/linux/socket_unix_filesystem.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_filesystem_nonblock.cc b/test/syscalls/linux/socket_unix_filesystem_nonblock.cc index c13a1e564..137db53c4 100644 --- a/test/syscalls/linux/socket_unix_filesystem_nonblock.cc +++ b/test/syscalls/linux/socket_unix_filesystem_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_non_stream.cc b/test/syscalls/linux/socket_unix_non_stream.cc index a565978f9..dafe82494 100644 --- a/test/syscalls/linux/socket_unix_non_stream.cc +++ b/test/syscalls/linux/socket_unix_non_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_non_stream.h b/test/syscalls/linux/socket_unix_non_stream.h index e4214d949..7478ab172 100644 --- a/test/syscalls/linux/socket_unix_non_stream.h +++ b/test/syscalls/linux/socket_unix_non_stream.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_non_stream_blocking_local.cc b/test/syscalls/linux/socket_unix_non_stream_blocking_local.cc index 6c435669b..98cf1fe8a 100644 --- a/test/syscalls/linux/socket_unix_non_stream_blocking_local.cc +++ b/test/syscalls/linux/socket_unix_non_stream_blocking_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_pair.cc b/test/syscalls/linux/socket_unix_pair.cc index c575fdcb2..bacfc11e4 100644 --- a/test/syscalls/linux/socket_unix_pair.cc +++ b/test/syscalls/linux/socket_unix_pair.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_pair_nonblock.cc b/test/syscalls/linux/socket_unix_pair_nonblock.cc index 1ae7f9b5e..583506f08 100644 --- a/test/syscalls/linux/socket_unix_pair_nonblock.cc +++ b/test/syscalls/linux/socket_unix_pair_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_seqpacket.cc b/test/syscalls/linux/socket_unix_seqpacket.cc index ad0af77e9..6f6367dd5 100644 --- a/test/syscalls/linux/socket_unix_seqpacket.cc +++ b/test/syscalls/linux/socket_unix_seqpacket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_seqpacket.h b/test/syscalls/linux/socket_unix_seqpacket.h index da8eb2b2b..30d9b9edf 100644 --- a/test/syscalls/linux/socket_unix_seqpacket.h +++ b/test/syscalls/linux/socket_unix_seqpacket.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_seqpacket_local.cc b/test/syscalls/linux/socket_unix_seqpacket_local.cc index e6484d9b4..b903a9e8f 100644 --- a/test/syscalls/linux/socket_unix_seqpacket_local.cc +++ b/test/syscalls/linux/socket_unix_seqpacket_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_stream.cc b/test/syscalls/linux/socket_unix_stream.cc index 95f454251..659c93945 100644 --- a/test/syscalls/linux/socket_unix_stream.cc +++ b/test/syscalls/linux/socket_unix_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_stream_blocking_local.cc b/test/syscalls/linux/socket_unix_stream_blocking_local.cc index ec0fc6955..ce0f1e50d 100644 --- a/test/syscalls/linux/socket_unix_stream_blocking_local.cc +++ b/test/syscalls/linux/socket_unix_stream_blocking_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_stream_local.cc b/test/syscalls/linux/socket_unix_stream_local.cc index bf4c5f2eb..6b840189c 100644 --- a/test/syscalls/linux/socket_unix_stream_local.cc +++ b/test/syscalls/linux/socket_unix_stream_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_stream_nonblock_local.cc b/test/syscalls/linux/socket_unix_stream_nonblock_local.cc index df80b105a..ebec4e0ec 100644 --- a/test/syscalls/linux/socket_unix_stream_nonblock_local.cc +++ b/test/syscalls/linux/socket_unix_stream_nonblock_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_abstract.cc b/test/syscalls/linux/socket_unix_unbound_abstract.cc index b6fe7a9ce..4b5832de8 100644 --- a/test/syscalls/linux/socket_unix_unbound_abstract.cc +++ b/test/syscalls/linux/socket_unix_unbound_abstract.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_dgram.cc b/test/syscalls/linux/socket_unix_unbound_dgram.cc index 1ec11a08d..2ddc5c11f 100644 --- a/test/syscalls/linux/socket_unix_unbound_dgram.cc +++ b/test/syscalls/linux/socket_unix_unbound_dgram.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_filesystem.cc b/test/syscalls/linux/socket_unix_unbound_filesystem.cc index d09142aa6..8cb03c450 100644 --- a/test/syscalls/linux/socket_unix_unbound_filesystem.cc +++ b/test/syscalls/linux/socket_unix_unbound_filesystem.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_seqpacket.cc b/test/syscalls/linux/socket_unix_unbound_seqpacket.cc index 21209b244..0575f2e1d 100644 --- a/test/syscalls/linux/socket_unix_unbound_seqpacket.cc +++ b/test/syscalls/linux/socket_unix_unbound_seqpacket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_stream.cc b/test/syscalls/linux/socket_unix_unbound_stream.cc index b95f9569e..091d546b3 100644 --- a/test/syscalls/linux/socket_unix_unbound_stream.cc +++ b/test/syscalls/linux/socket_unix_unbound_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/stat.cc b/test/syscalls/linux/stat.cc index 746318d09..80ba67496 100644 --- a/test/syscalls/linux/stat.cc +++ b/test/syscalls/linux/stat.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/stat_times.cc b/test/syscalls/linux/stat_times.cc index 8346e9a8e..9b53739a0 100644 --- a/test/syscalls/linux/stat_times.cc +++ b/test/syscalls/linux/stat_times.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/statfs.cc b/test/syscalls/linux/statfs.cc index e1e7fc707..aca51d30f 100644 --- a/test/syscalls/linux/statfs.cc +++ b/test/syscalls/linux/statfs.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sticky.cc b/test/syscalls/linux/sticky.cc index 58cf0d014..59fb5dfe6 100644 --- a/test/syscalls/linux/sticky.cc +++ b/test/syscalls/linux/sticky.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/symlink.cc b/test/syscalls/linux/symlink.cc index 318917f4b..494072a9b 100644 --- a/test/syscalls/linux/symlink.cc +++ b/test/syscalls/linux/symlink.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sync.cc b/test/syscalls/linux/sync.cc index 5b777b6eb..fe479390d 100644 --- a/test/syscalls/linux/sync.cc +++ b/test/syscalls/linux/sync.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sync_file_range.cc b/test/syscalls/linux/sync_file_range.cc index d11f58481..36cc42043 100644 --- a/test/syscalls/linux/sync_file_range.cc +++ b/test/syscalls/linux/sync_file_range.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sysinfo.cc b/test/syscalls/linux/sysinfo.cc index a0dd82640..1a71256da 100644 --- a/test/syscalls/linux/sysinfo.cc +++ b/test/syscalls/linux/sysinfo.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/syslog.cc b/test/syscalls/linux/syslog.cc index 5bd0d1cc3..9a7407d96 100644 --- a/test/syscalls/linux/syslog.cc +++ b/test/syscalls/linux/syslog.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sysret.cc b/test/syscalls/linux/sysret.cc index 8e10220eb..819fa655a 100644 --- a/test/syscalls/linux/sysret.cc +++ b/test/syscalls/linux/sysret.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/tcp_socket.cc b/test/syscalls/linux/tcp_socket.cc index 33620a874..e3f9f9f9d 100644 --- a/test/syscalls/linux/tcp_socket.cc +++ b/test/syscalls/linux/tcp_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/temp_umask.h b/test/syscalls/linux/temp_umask.h index f202dfa59..81a25440c 100644 --- a/test/syscalls/linux/temp_umask.h +++ b/test/syscalls/linux/temp_umask.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/tgkill.cc b/test/syscalls/linux/tgkill.cc index 2d258ef11..80acae5de 100644 --- a/test/syscalls/linux/tgkill.cc +++ b/test/syscalls/linux/tgkill.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/time.cc b/test/syscalls/linux/time.cc index 5a3dfd026..c7eead17e 100644 --- a/test/syscalls/linux/time.cc +++ b/test/syscalls/linux/time.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/timerfd.cc b/test/syscalls/linux/timerfd.cc index b85321795..9df53612f 100644 --- a/test/syscalls/linux/timerfd.cc +++ b/test/syscalls/linux/timerfd.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/timers.cc b/test/syscalls/linux/timers.cc index 14506eb12..fd42e81e1 100644 --- a/test/syscalls/linux/timers.cc +++ b/test/syscalls/linux/timers.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/tkill.cc b/test/syscalls/linux/tkill.cc index 3e8ce5327..bae377c69 100644 --- a/test/syscalls/linux/tkill.cc +++ b/test/syscalls/linux/tkill.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/truncate.cc b/test/syscalls/linux/truncate.cc index 2616a9147..e5cc5d97c 100644 --- a/test/syscalls/linux/truncate.cc +++ b/test/syscalls/linux/truncate.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/udp_bind.cc b/test/syscalls/linux/udp_bind.cc index 547eb2a6c..6d92bdbeb 100644 --- a/test/syscalls/linux/udp_bind.cc +++ b/test/syscalls/linux/udp_bind.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/udp_socket.cc b/test/syscalls/linux/udp_socket.cc index f39281d5c..31db8a2ad 100644 --- a/test/syscalls/linux/udp_socket.cc +++ b/test/syscalls/linux/udp_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/uidgid.cc b/test/syscalls/linux/uidgid.cc index d78a09b1e..bf1ca8679 100644 --- a/test/syscalls/linux/uidgid.cc +++ b/test/syscalls/linux/uidgid.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/uname.cc b/test/syscalls/linux/uname.cc index d22a34bd7..0a5d91017 100644 --- a/test/syscalls/linux/uname.cc +++ b/test/syscalls/linux/uname.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/unix_domain_socket_test_util.cc b/test/syscalls/linux/unix_domain_socket_test_util.cc index 2d7a530b9..6f49e3660 100644 --- a/test/syscalls/linux/unix_domain_socket_test_util.cc +++ b/test/syscalls/linux/unix_domain_socket_test_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/unix_domain_socket_test_util.h b/test/syscalls/linux/unix_domain_socket_test_util.h index 1b09aeae7..aae990245 100644 --- a/test/syscalls/linux/unix_domain_socket_test_util.h +++ b/test/syscalls/linux/unix_domain_socket_test_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/unlink.cc b/test/syscalls/linux/unlink.cc index b10aae025..b6f65e027 100644 --- a/test/syscalls/linux/unlink.cc +++ b/test/syscalls/linux/unlink.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/unshare.cc b/test/syscalls/linux/unshare.cc index 9dd6ec4b6..e32619efe 100644 --- a/test/syscalls/linux/unshare.cc +++ b/test/syscalls/linux/unshare.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/utimes.cc b/test/syscalls/linux/utimes.cc index bf776cd93..80716859a 100644 --- a/test/syscalls/linux/utimes.cc +++ b/test/syscalls/linux/utimes.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/vdso.cc b/test/syscalls/linux/vdso.cc index 0f6e1c7c6..19c80add8 100644 --- a/test/syscalls/linux/vdso.cc +++ b/test/syscalls/linux/vdso.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/vdso_clock_gettime.cc b/test/syscalls/linux/vdso_clock_gettime.cc index 0e936594b..759a50569 100644 --- a/test/syscalls/linux/vdso_clock_gettime.cc +++ b/test/syscalls/linux/vdso_clock_gettime.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/vfork.cc b/test/syscalls/linux/vfork.cc index 9999a909e..631a53654 100644 --- a/test/syscalls/linux/vfork.cc +++ b/test/syscalls/linux/vfork.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/vsyscall.cc b/test/syscalls/linux/vsyscall.cc index cb6840cc6..2c2303358 100644 --- a/test/syscalls/linux/vsyscall.cc +++ b/test/syscalls/linux/vsyscall.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/wait.cc b/test/syscalls/linux/wait.cc index fcd606bec..50d0725a7 100644 --- a/test/syscalls/linux/wait.cc +++ b/test/syscalls/linux/wait.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/write.cc b/test/syscalls/linux/write.cc index 7f80b2fa8..9b219cfd6 100644 --- a/test/syscalls/linux/write.cc +++ b/test/syscalls/linux/write.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/syscall_test_runner.go b/test/syscalls/syscall_test_runner.go index c4af28103..28f312b8b 100644 --- a/test/syscalls/syscall_test_runner.go +++ b/test/syscalls/syscall_test_runner.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/syscall_test_runner.sh b/test/syscalls/syscall_test_runner.sh index 87d62786b..864bb2de4 100755 --- a/test/syscalls/syscall_test_runner.sh +++ b/test/syscalls/syscall_test_runner.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/test/util/capability_util.cc b/test/util/capability_util.cc index d1dd95e76..5d733887b 100644 --- a/test/util/capability_util.cc +++ b/test/util/capability_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/capability_util.h b/test/util/capability_util.h index 8708f5e69..e968a2583 100644 --- a/test/util/capability_util.h +++ b/test/util/capability_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/cleanup.h b/test/util/cleanup.h index fb4724f97..c76482ef4 100644 --- a/test/util/cleanup.h +++ b/test/util/cleanup.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/epoll_util.cc b/test/util/epoll_util.cc index 0b95aa8cd..2e5051468 100644 --- a/test/util/epoll_util.cc +++ b/test/util/epoll_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/epoll_util.h b/test/util/epoll_util.h index 521e7a3d3..f233b37d5 100644 --- a/test/util/epoll_util.h +++ b/test/util/epoll_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/eventfd_util.h b/test/util/eventfd_util.h index 1fdb07d3b..cb9ce829c 100644 --- a/test/util/eventfd_util.h +++ b/test/util/eventfd_util.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/util/file_descriptor.h b/test/util/file_descriptor.h index be8812d01..fc5caa55b 100644 --- a/test/util/file_descriptor.h +++ b/test/util/file_descriptor.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/fs_util.cc b/test/util/fs_util.cc index 6bd424417..bc90bd78e 100644 --- a/test/util/fs_util.cc +++ b/test/util/fs_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/fs_util.h b/test/util/fs_util.h index 9412b2f71..eb7cdaa24 100644 --- a/test/util/fs_util.h +++ b/test/util/fs_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/fs_util_test.cc b/test/util/fs_util_test.cc index ce70d58aa..4e12076a1 100644 --- a/test/util/fs_util_test.cc +++ b/test/util/fs_util_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/logging.cc b/test/util/logging.cc index 86ea71df3..cc71d77b0 100644 --- a/test/util/logging.cc +++ b/test/util/logging.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/logging.h b/test/util/logging.h index 6e957b172..589166fab 100644 --- a/test/util/logging.h +++ b/test/util/logging.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/memory_util.h b/test/util/memory_util.h index 8f6e99ba6..8c77778ea 100644 --- a/test/util/memory_util.h +++ b/test/util/memory_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/mount_util.h b/test/util/mount_util.h index 468170646..7782e6bf2 100644 --- a/test/util/mount_util.h +++ b/test/util/mount_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/multiprocess_util.cc b/test/util/multiprocess_util.cc index 12637db8c..95f5f3b4f 100644 --- a/test/util/multiprocess_util.cc +++ b/test/util/multiprocess_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/multiprocess_util.h b/test/util/multiprocess_util.h index ba5f2601f..0aecd3439 100644 --- a/test/util/multiprocess_util.h +++ b/test/util/multiprocess_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/posix_error.cc b/test/util/posix_error.cc index ead9ede16..cebf7e0ac 100644 --- a/test/util/posix_error.cc +++ b/test/util/posix_error.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/posix_error.h b/test/util/posix_error.h index 2a66e2e94..b604f4f8f 100644 --- a/test/util/posix_error.h +++ b/test/util/posix_error.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/posix_error_test.cc b/test/util/posix_error_test.cc index c5427b8e5..d67270842 100644 --- a/test/util/posix_error_test.cc +++ b/test/util/posix_error_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/proc_util.cc b/test/util/proc_util.cc index 2d9eb1986..9d4db37c3 100644 --- a/test/util/proc_util.cc +++ b/test/util/proc_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/proc_util.h b/test/util/proc_util.h index e1ee2db9c..af209a51e 100644 --- a/test/util/proc_util.h +++ b/test/util/proc_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/proc_util_test.cc b/test/util/proc_util_test.cc index 75335415a..71dd2355e 100644 --- a/test/util/proc_util_test.cc +++ b/test/util/proc_util_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/rlimit_util.cc b/test/util/rlimit_util.cc index a9912c372..684253f78 100644 --- a/test/util/rlimit_util.cc +++ b/test/util/rlimit_util.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/util/rlimit_util.h b/test/util/rlimit_util.h index fa5cc70dc..873252a32 100644 --- a/test/util/rlimit_util.h +++ b/test/util/rlimit_util.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/util/save_util.cc b/test/util/save_util.cc index 5540e2146..05f52b80d 100644 --- a/test/util/save_util.cc +++ b/test/util/save_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/save_util.h b/test/util/save_util.h index 919e4af3d..90460701e 100644 --- a/test/util/save_util.h +++ b/test/util/save_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/signal_util.cc b/test/util/signal_util.cc index 3e2df32a6..26738864f 100644 --- a/test/util/signal_util.cc +++ b/test/util/signal_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/signal_util.h b/test/util/signal_util.h index 80f1808f6..7fd2af015 100644 --- a/test/util/signal_util.h +++ b/test/util/signal_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/temp_path.cc b/test/util/temp_path.cc index 48ce82d20..c5d8fc635 100644 --- a/test/util/temp_path.cc +++ b/test/util/temp_path.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/temp_path.h b/test/util/temp_path.h index 33eb6a72c..89302e0fd 100644 --- a/test/util/temp_path.h +++ b/test/util/temp_path.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/test_main.cc b/test/util/test_main.cc index 4c6b5e860..5c7ee0064 100644 --- a/test/util/test_main.cc +++ b/test/util/test_main.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/test_util.cc b/test/util/test_util.cc index 9b7cfa4dc..c52fd9a4a 100644 --- a/test/util/test_util.cc +++ b/test/util/test_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/test_util.h b/test/util/test_util.h index 905412b24..8f5eb5089 100644 --- a/test/util/test_util.h +++ b/test/util/test_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/test_util_test.cc b/test/util/test_util_test.cc index 5889651d1..b7300d9e5 100644 --- a/test/util/test_util_test.cc +++ b/test/util/test_util_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/thread_util.h b/test/util/thread_util.h index df09ac8cf..860e77531 100644 --- a/test/util/thread_util.h +++ b/test/util/thread_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/timer_util.cc b/test/util/timer_util.cc index 681fafb69..43a26b0d3 100644 --- a/test/util/timer_util.cc +++ b/test/util/timer_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/timer_util.h b/test/util/timer_util.h index 9bdc51a57..2cebfa5d1 100644 --- a/test/util/timer_util.h +++ b/test/util/timer_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/third_party/gvsync/atomicptr_unsafe.go b/third_party/gvsync/atomicptr_unsafe.go index da9f16240..53a943282 100644 --- a/third_party/gvsync/atomicptr_unsafe.go +++ b/third_party/gvsync/atomicptr_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/atomicptrtest/atomicptr_test.go b/third_party/gvsync/atomicptrtest/atomicptr_test.go index 15d0936d4..8fdc5112e 100644 --- a/third_party/gvsync/atomicptrtest/atomicptr_test.go +++ b/third_party/gvsync/atomicptrtest/atomicptr_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/downgradable_rwmutex_test.go b/third_party/gvsync/downgradable_rwmutex_test.go index 6517dd5dc..40c384b8b 100644 --- a/third_party/gvsync/downgradable_rwmutex_test.go +++ b/third_party/gvsync/downgradable_rwmutex_test.go @@ -1,5 +1,5 @@ // Copyright 2009 The Go Authors. All rights reserved. -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/downgradable_rwmutex_unsafe.go b/third_party/gvsync/downgradable_rwmutex_unsafe.go index 131f0a2ba..4d43eb765 100644 --- a/third_party/gvsync/downgradable_rwmutex_unsafe.go +++ b/third_party/gvsync/downgradable_rwmutex_unsafe.go @@ -1,5 +1,5 @@ // Copyright 2009 The Go Authors. All rights reserved. -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/gvsync.go b/third_party/gvsync/gvsync.go index 46a2565fd..3bbef13c3 100644 --- a/third_party/gvsync/gvsync.go +++ b/third_party/gvsync/gvsync.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/memmove_unsafe.go b/third_party/gvsync/memmove_unsafe.go index d483fc739..4c8aa9ab6 100644 --- a/third_party/gvsync/memmove_unsafe.go +++ b/third_party/gvsync/memmove_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/norace_unsafe.go b/third_party/gvsync/norace_unsafe.go index f9c88d13f..e3852db8c 100644 --- a/third_party/gvsync/norace_unsafe.go +++ b/third_party/gvsync/norace_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/race_unsafe.go b/third_party/gvsync/race_unsafe.go index 2cdcdf7f7..13c02a830 100644 --- a/third_party/gvsync/race_unsafe.go +++ b/third_party/gvsync/race_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/seqatomic_unsafe.go b/third_party/gvsync/seqatomic_unsafe.go index ef61503e2..c52d378f1 100644 --- a/third_party/gvsync/seqatomic_unsafe.go +++ b/third_party/gvsync/seqatomic_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/seqatomictest/seqatomic_test.go b/third_party/gvsync/seqatomictest/seqatomic_test.go index d0c373bae..2da73cf96 100644 --- a/third_party/gvsync/seqatomictest/seqatomic_test.go +++ b/third_party/gvsync/seqatomictest/seqatomic_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/third_party/gvsync/seqcount.go b/third_party/gvsync/seqcount.go index c7ae91cfa..2c9c2c3d6 100644 --- a/third_party/gvsync/seqcount.go +++ b/third_party/gvsync/seqcount.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/seqcount_test.go b/third_party/gvsync/seqcount_test.go index ee6579ed8..085e574b3 100644 --- a/third_party/gvsync/seqcount_test.go +++ b/third_party/gvsync/seqcount_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/tools/go_generics/generics.go b/tools/go_generics/generics.go index eaf5c4970..ca414d8cb 100644 --- a/tools/go_generics/generics.go +++ b/tools/go_generics/generics.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_stmts/input.go b/tools/go_generics/generics_tests/all_stmts/input.go index 19184a3fe..4791d1ff1 100644 --- a/tools/go_generics/generics_tests/all_stmts/input.go +++ b/tools/go_generics/generics_tests/all_stmts/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_stmts/output/output.go b/tools/go_generics/generics_tests/all_stmts/output/output.go index 51582346c..a53d84535 100644 --- a/tools/go_generics/generics_tests/all_stmts/output/output.go +++ b/tools/go_generics/generics_tests/all_stmts/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_types/input.go b/tools/go_generics/generics_tests/all_types/input.go index ed6e97c29..3575d02ec 100644 --- a/tools/go_generics/generics_tests/all_types/input.go +++ b/tools/go_generics/generics_tests/all_types/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_types/lib/lib.go b/tools/go_generics/generics_tests/all_types/lib/lib.go index 7e73e678e..988786496 100644 --- a/tools/go_generics/generics_tests/all_types/lib/lib.go +++ b/tools/go_generics/generics_tests/all_types/lib/lib.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_types/output/output.go b/tools/go_generics/generics_tests/all_types/output/output.go index ec09a6be4..41fd147a1 100644 --- a/tools/go_generics/generics_tests/all_types/output/output.go +++ b/tools/go_generics/generics_tests/all_types/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/consts/input.go b/tools/go_generics/generics_tests/consts/input.go index 394bcc262..04b95fcc6 100644 --- a/tools/go_generics/generics_tests/consts/input.go +++ b/tools/go_generics/generics_tests/consts/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/consts/output/output.go b/tools/go_generics/generics_tests/consts/output/output.go index 91a07fdc2..18d316cc9 100644 --- a/tools/go_generics/generics_tests/consts/output/output.go +++ b/tools/go_generics/generics_tests/consts/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/imports/input.go b/tools/go_generics/generics_tests/imports/input.go index 22e6641a6..0f032c2a1 100644 --- a/tools/go_generics/generics_tests/imports/input.go +++ b/tools/go_generics/generics_tests/imports/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/imports/output/output.go b/tools/go_generics/generics_tests/imports/output/output.go index 2555c0004..2488ca58c 100644 --- a/tools/go_generics/generics_tests/imports/output/output.go +++ b/tools/go_generics/generics_tests/imports/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/remove_typedef/input.go b/tools/go_generics/generics_tests/remove_typedef/input.go index d9c9b8530..cf632bae7 100644 --- a/tools/go_generics/generics_tests/remove_typedef/input.go +++ b/tools/go_generics/generics_tests/remove_typedef/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/remove_typedef/output/output.go b/tools/go_generics/generics_tests/remove_typedef/output/output.go index f111a9426..d44fd8e1c 100644 --- a/tools/go_generics/generics_tests/remove_typedef/output/output.go +++ b/tools/go_generics/generics_tests/remove_typedef/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/simple/input.go b/tools/go_generics/generics_tests/simple/input.go index 711687cf5..2a917f16c 100644 --- a/tools/go_generics/generics_tests/simple/input.go +++ b/tools/go_generics/generics_tests/simple/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/simple/output/output.go b/tools/go_generics/generics_tests/simple/output/output.go index 139c9bf9d..6bfa0b25b 100644 --- a/tools/go_generics/generics_tests/simple/output/output.go +++ b/tools/go_generics/generics_tests/simple/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/globals/globals_visitor.go b/tools/go_generics/globals/globals_visitor.go index daaa17b1d..7ae48c662 100644 --- a/tools/go_generics/globals/globals_visitor.go +++ b/tools/go_generics/globals/globals_visitor.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/globals/scope.go b/tools/go_generics/globals/scope.go index b75a91689..96c965ea2 100644 --- a/tools/go_generics/globals/scope.go +++ b/tools/go_generics/globals/scope.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/go_generics_unittest.sh b/tools/go_generics/go_generics_unittest.sh index e7553a071..44b22db91 100755 --- a/tools/go_generics/go_generics_unittest.sh +++ b/tools/go_generics/go_generics_unittest.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/tools/go_generics/go_merge/main.go b/tools/go_generics/go_merge/main.go index 2f83facf8..f6a331123 100644 --- a/tools/go_generics/go_merge/main.go +++ b/tools/go_generics/go_merge/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/imports.go b/tools/go_generics/imports.go index 57f7c3dce..3a7230c97 100644 --- a/tools/go_generics/imports.go +++ b/tools/go_generics/imports.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/remove.go b/tools/go_generics/remove.go index 139d03955..568a6bbd3 100644 --- a/tools/go_generics/remove.go +++ b/tools/go_generics/remove.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/rules_tests/template.go b/tools/go_generics/rules_tests/template.go index f3f31ae8e..aace61da1 100644 --- a/tools/go_generics/rules_tests/template.go +++ b/tools/go_generics/rules_tests/template.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/rules_tests/template_test.go b/tools/go_generics/rules_tests/template_test.go index 3a38c8629..b2a3446ef 100644 --- a/tools/go_generics/rules_tests/template_test.go +++ b/tools/go_generics/rules_tests/template_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_stateify/main.go b/tools/go_stateify/main.go index 9e2c8e106..db7a7107b 100644 --- a/tools/go_stateify/main.go +++ b/tools/go_stateify/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/tag_release.sh b/tools/tag_release.sh index 6906a952f..02a49cdf1 100755 --- a/tools/tag_release.sh +++ b/tools/tag_release.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2019 Google LLC +# Copyright 2019 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. diff --git a/tools/workspace_status.sh b/tools/workspace_status.sh index a0e646e45..64a905fc9 100755 --- a/tools/workspace_status.sh +++ b/tools/workspace_status.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/vdso/barrier.h b/vdso/barrier.h index 5b6c763f6..edba4afb5 100644 --- a/vdso/barrier.h +++ b/vdso/barrier.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/check_vdso.py b/vdso/check_vdso.py index 6f7d7e7ec..e41b09709 100644 --- a/vdso/check_vdso.py +++ b/vdso/check_vdso.py @@ -1,4 +1,4 @@ -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/vdso/compiler.h b/vdso/compiler.h index d65f148fb..54a510000 100644 --- a/vdso/compiler.h +++ b/vdso/compiler.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/cycle_clock.h b/vdso/cycle_clock.h index 309e07a3f..5d3fbb257 100644 --- a/vdso/cycle_clock.h +++ b/vdso/cycle_clock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/seqlock.h b/vdso/seqlock.h index ab2f3fda3..7a173174b 100644 --- a/vdso/seqlock.h +++ b/vdso/seqlock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/syscalls.h b/vdso/syscalls.h index 90fb424ce..f5865bb72 100644 --- a/vdso/syscalls.h +++ b/vdso/syscalls.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/vdso.cc b/vdso/vdso.cc index 550729035..6265ad217 100644 --- a/vdso/vdso.cc +++ b/vdso/vdso.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/vdso_time.cc b/vdso/vdso_time.cc index 9fc262f60..1bb4bb86b 100644 --- a/vdso/vdso_time.cc +++ b/vdso/vdso_time.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/vdso_time.h b/vdso/vdso_time.h index 464dadff2..70d079efc 100644 --- a/vdso/vdso_time.h +++ b/vdso/vdso_time.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. -- cgit v1.2.3 From 8972e47a2edb01d66c2fc6373a5663b68e3da82c Mon Sep 17 00:00:00 2001 From: Chris Kuiper Date: Thu, 2 May 2019 19:39:55 -0700 Subject: Support reception of multicast data on more than one socket This requires two changes: 1) Support for more than one socket to join a given multicast group. 2) Duplicate delivery of incoming multicast packets to all sockets listening for it. In addition, I tweaked the code (and added a test) to disallow duplicates IP_ADD_MEMBERSHIP calls for the same group and NIC. This is how Linux does it. PiperOrigin-RevId: 246437315 Change-Id: Icad8300b4a8c3f501d9b4cd283bd3beabef88b72 --- pkg/tcpip/stack/nic.go | 80 +++++++-- pkg/tcpip/stack/stack.go | 16 +- pkg/tcpip/stack/transport_demuxer.go | 6 +- pkg/tcpip/transport/udp/endpoint.go | 39 +++-- pkg/tcpip/transport/udp/endpoint_state.go | 12 +- test/syscalls/linux/socket_ipv4_udp_unbound.cc | 219 +++++++++++++++++++++++++ 6 files changed, 335 insertions(+), 37 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index 8008d9870..a4117d98e 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -42,6 +42,7 @@ type NIC struct { primary map[tcpip.NetworkProtocolNumber]*ilist.List endpoints map[NetworkEndpointID]*referencedNetworkEndpoint subnets []tcpip.Subnet + mcastJoins map[NetworkEndpointID]int32 stats NICStats } @@ -79,14 +80,15 @@ const ( func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint, loopback bool) *NIC { return &NIC{ - stack: stack, - id: id, - name: name, - linkEP: ep, - loopback: loopback, - demux: newTransportDemuxer(stack), - primary: make(map[tcpip.NetworkProtocolNumber]*ilist.List), - endpoints: make(map[NetworkEndpointID]*referencedNetworkEndpoint), + stack: stack, + id: id, + name: name, + linkEP: ep, + loopback: loopback, + demux: newTransportDemuxer(stack), + primary: make(map[tcpip.NetworkProtocolNumber]*ilist.List), + endpoints: make(map[NetworkEndpointID]*referencedNetworkEndpoint), + mcastJoins: make(map[NetworkEndpointID]int32), stats: NICStats{ Tx: DirectionStats{ Packets: &tcpip.StatCounter{}, @@ -384,20 +386,62 @@ func (n *NIC) removeEndpoint(r *referencedNetworkEndpoint) { n.mu.Unlock() } -// RemoveAddress removes an address from n. -func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error { - n.mu.Lock() +func (n *NIC) removeAddressLocked(addr tcpip.Address) *tcpip.Error { r := n.endpoints[NetworkEndpointID{addr}] if r == nil || !r.holdsInsertRef { - n.mu.Unlock() return tcpip.ErrBadLocalAddress } r.holdsInsertRef = false - n.mu.Unlock() - r.decRef() + r.decRefLocked() + + return nil +} + +// RemoveAddress removes an address from n. +func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error { + n.mu.Lock() + defer n.mu.Unlock() + return n.removeAddressLocked(addr) +} + +// joinGroup adds a new endpoint for the given multicast address, if none +// exists yet. Otherwise it just increments its count. +func (n *NIC) joinGroup(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error { + n.mu.Lock() + defer n.mu.Unlock() + id := NetworkEndpointID{addr} + joins := n.mcastJoins[id] + if joins == 0 { + if _, err := n.addAddressLocked(protocol, addr, NeverPrimaryEndpoint, false); err != nil { + return err + } + } + n.mcastJoins[id] = joins + 1 + return nil +} + +// leaveGroup decrements the count for the given multicast address, and when it +// reaches zero removes the endpoint for this address. +func (n *NIC) leaveGroup(addr tcpip.Address) *tcpip.Error { + n.mu.Lock() + defer n.mu.Unlock() + + id := NetworkEndpointID{addr} + joins := n.mcastJoins[id] + switch joins { + case 0: + // There are no joins with this address on this NIC. + return tcpip.ErrBadLocalAddress + case 1: + // This is the last one, clean up. + if err := n.removeAddressLocked(addr); err != nil { + return err + } + } + n.mcastJoins[id] = joins - 1 return nil } @@ -644,6 +688,14 @@ func (r *referencedNetworkEndpoint) decRef() { } } +// decRefLocked is the same as decRef but assumes that the NIC.mu mutex is +// locked. +func (r *referencedNetworkEndpoint) decRefLocked() { + if atomic.AddInt32(&r.refs, -1) == 0 { + r.nic.removeEndpointLocked(r) + } +} + // incRef increments the ref count. It must only be called when the caller is // known to be holding a reference to the endpoint, otherwise tryIncRef should // be used. diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index f204ca790..c82822ee2 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -1062,10 +1062,22 @@ func (s *Stack) RemoveTCPProbe() { // JoinGroup joins the given multicast group on the given NIC. func (s *Stack) JoinGroup(protocol tcpip.NetworkProtocolNumber, nicID tcpip.NICID, multicastAddr tcpip.Address) *tcpip.Error { // TODO: notify network of subscription via igmp protocol. - return s.AddAddressWithOptions(nicID, protocol, multicastAddr, NeverPrimaryEndpoint) + s.mu.RLock() + defer s.mu.RUnlock() + + if nic, ok := s.nics[nicID]; ok { + return nic.joinGroup(protocol, multicastAddr) + } + return tcpip.ErrUnknownNICID } // LeaveGroup leaves the given multicast group on the given NIC. func (s *Stack) LeaveGroup(protocol tcpip.NetworkProtocolNumber, nicID tcpip.NICID, multicastAddr tcpip.Address) *tcpip.Error { - return s.RemoveAddress(nicID, multicastAddr) + s.mu.RLock() + defer s.mu.RUnlock() + + if nic, ok := s.nics[nicID]; ok { + return nic.leaveGroup(multicastAddr) + } + return tcpip.ErrUnknownNICID } diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index e8b562ad9..66c564613 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -141,9 +141,9 @@ func (ep *multiPortEndpoint) selectEndpoint(id TransportEndpointID) TransportEnd // HandlePacket is called by the stack when new packets arrive to this transport // endpoint. func (ep *multiPortEndpoint) HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) { - // If this is a broadcast datagram, deliver the datagram to all endpoints - // managed by ep. - if id.LocalAddress == header.IPv4Broadcast { + // If this is a broadcast or multicast datagram, deliver the datagram to all + // endpoints managed by ep. + if id.LocalAddress == header.IPv4Broadcast || header.IsV4MulticastAddress(id.LocalAddress) || header.IsV6MulticastAddress(id.LocalAddress) { for i, endpoint := range ep.endpointsArr { // HandlePacket modifies vv, so each endpoint needs its own copy. if i == len(ep.endpointsArr)-1 { diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index db65a4e88..0ed0902b0 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -458,14 +458,22 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { return tcpip.ErrUnknownDevice } - if err := e.stack.JoinGroup(e.netProto, nicID, v.MulticastAddr); err != nil { - return err - } + memToInsert := multicastMembership{nicID: nicID, multicastAddr: v.MulticastAddr} e.mu.Lock() defer e.mu.Unlock() - e.multicastMemberships = append(e.multicastMemberships, multicastMembership{nicID, v.MulticastAddr}) + for _, mem := range e.multicastMemberships { + if mem == memToInsert { + return tcpip.ErrPortInUse + } + } + + if err := e.stack.JoinGroup(e.netProto, nicID, v.MulticastAddr); err != nil { + return err + } + + e.multicastMemberships = append(e.multicastMemberships, memToInsert) case tcpip.RemoveMembershipOption: if !header.IsV4MulticastAddress(v.MulticastAddr) && !header.IsV6MulticastAddress(v.MulticastAddr) { @@ -488,21 +496,28 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { return tcpip.ErrUnknownDevice } - if err := e.stack.LeaveGroup(e.netProto, nicID, v.MulticastAddr); err != nil { - return err - } + memToRemove := multicastMembership{nicID: nicID, multicastAddr: v.MulticastAddr} + memToRemoveIndex := -1 e.mu.Lock() defer e.mu.Unlock() + for i, mem := range e.multicastMemberships { - if mem.nicID == nicID && mem.multicastAddr == v.MulticastAddr { - // Only remove the first match, so that each added membership above is - // paired with exactly 1 removal. - e.multicastMemberships[i] = e.multicastMemberships[len(e.multicastMemberships)-1] - e.multicastMemberships = e.multicastMemberships[:len(e.multicastMemberships)-1] + if mem == memToRemove { + memToRemoveIndex = i break } } + if memToRemoveIndex == -1 { + return tcpip.ErrBadLocalAddress + } + + if err := e.stack.LeaveGroup(e.netProto, nicID, v.MulticastAddr); err != nil { + return err + } + + e.multicastMemberships[memToRemoveIndex] = e.multicastMemberships[len(e.multicastMemberships)-1] + e.multicastMemberships = e.multicastMemberships[:len(e.multicastMemberships)-1] case tcpip.MulticastLoopOption: e.mu.Lock() diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index 163dcbc13..74e8e9fd5 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -66,6 +66,12 @@ func (e *endpoint) loadRcvBufSizeMax(max int) { func (e *endpoint) afterLoad() { e.stack = stack.StackFromEnv + for _, m := range e.multicastMemberships { + if err := e.stack.JoinGroup(e.netProto, m.nicID, m.multicastAddr); err != nil { + panic(err) + } + } + if e.state != stateBound && e.state != stateConnected { return } @@ -103,10 +109,4 @@ func (e *endpoint) afterLoad() { if err != nil { panic(*err) } - - for _, m := range e.multicastMemberships { - if err := e.stack.JoinGroup(e.netProto, m.nicID, m.multicastAddr); err != nil { - panic(err) - } - } } diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc index 709172580..0ec828d8d 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc @@ -1207,5 +1207,224 @@ TEST_P(IPv4UDPUnboundSocketPairTest, TestJoinGroupInvalidIf) { SyscallFailsWithErrno(ENODEV)); } +// Check that multiple memberships are not allowed on the same socket. +TEST_P(IPv4UDPUnboundSocketPairTest, TestMultipleJoinsOnSingleSocket) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + auto fd = sockets->first_fd(); + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + + EXPECT_THAT( + setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), + SyscallSucceeds()); + + EXPECT_THAT( + setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group)), + SyscallFailsWithErrno(EADDRINUSE)); +} + +// Check that two sockets can join the same multicast group at the same time. +TEST_P(IPv4UDPUnboundSocketPairTest, TestTwoSocketsJoinSameMulticastGroup) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Drop the membership twice on each socket, the second call for each socket + // should fail. + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallFailsWithErrno(EADDRNOTAVAIL)); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallFailsWithErrno(EADDRNOTAVAIL)); +} + +// Check that two sockets can join the same multicast group at the same time, +// and both will receive data on it. +TEST_P(IPv4UDPUnboundSocketPairTest, TestMcastReceptionOnTwoSockets) { + std::unique_ptr socket_pairs[2] = { + ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()), + ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair())}; + + ip_mreq iface = {}, group = {}; + iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + auto receiver_addr = V4Any(); + int bound_port = 0; + + // Create two socketpairs with the exact same configuration. + for (auto& sockets : socket_pairs) { + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + ASSERT_THAT(setsockopt(sockets->second_fd(), SOL_SOCKET, SO_REUSEPORT, + &kSockOptOn, sizeof(kSockOptOn)), + SyscallSucceeds()); + ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + ASSERT_THAT(bind(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + // Get the port assigned. + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + // On the first iteration, save the port we are bound to. On the second + // iteration, verify the port is the same as the one from the first + // iteration. In other words, both sockets listen on the same port. + if (bound_port == 0) { + bound_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + } else { + EXPECT_EQ(bound_port, + reinterpret_cast(&receiver_addr.addr)->sin_port); + } + } + + // Send a multicast packet to the group from two different sockets and verify + // it is received by both sockets that joined that group. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = bound_port; + for (auto& sockets : socket_pairs) { + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet on both sockets. + for (auto& sockets : socket_pairs) { + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); + } + } +} + +// Check that on two sockets that joined a group and listen on ANY, dropping +// memberships one by one will continue to deliver packets to both sockets until +// both memberships have been dropped. +TEST_P(IPv4UDPUnboundSocketPairTest, + TestMcastReceptionWhenDroppingMemberships) { + std::unique_ptr socket_pairs[2] = { + ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()), + ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair())}; + + ip_mreq iface = {}, group = {}; + iface.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + auto receiver_addr = V4Any(); + int bound_port = 0; + + // Create two socketpairs with the exact same configuration. + for (auto& sockets : socket_pairs) { + ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_IF, + &iface, sizeof(iface)), + SyscallSucceeds()); + ASSERT_THAT(setsockopt(sockets->second_fd(), SOL_SOCKET, SO_REUSEPORT, + &kSockOptOn, sizeof(kSockOptOn)), + SyscallSucceeds()); + ASSERT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + ASSERT_THAT(bind(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + receiver_addr.addr_len), + SyscallSucceeds()); + // Get the port assigned. + socklen_t receiver_addr_len = receiver_addr.addr_len; + ASSERT_THAT(getsockname(sockets->second_fd(), + reinterpret_cast(&receiver_addr.addr), + &receiver_addr_len), + SyscallSucceeds()); + EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); + // On the first iteration, save the port we are bound to. On the second + // iteration, verify the port is the same as the one from the first + // iteration. In other words, both sockets listen on the same port. + if (bound_port == 0) { + bound_port = + reinterpret_cast(&receiver_addr.addr)->sin_port; + } else { + EXPECT_EQ(bound_port, + reinterpret_cast(&receiver_addr.addr)->sin_port); + } + } + + // Drop the membership of the first socket pair and verify data is still + // received. + ASSERT_THAT(setsockopt(socket_pairs[0]->second_fd(), IPPROTO_IP, + IP_DROP_MEMBERSHIP, &group, sizeof(group)), + SyscallSucceeds()); + // Send a packet from each socket_pair. + auto send_addr = V4Multicast(); + reinterpret_cast(&send_addr.addr)->sin_port = bound_port; + for (auto& sockets : socket_pairs) { + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + ASSERT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet on both sockets. + for (auto& sockets : socket_pairs) { + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); + } + } + + // Drop the membership of the second socket pair and verify data stops being + // received. + ASSERT_THAT(setsockopt(socket_pairs[1]->second_fd(), IPPROTO_IP, + IP_DROP_MEMBERSHIP, &group, sizeof(group)), + SyscallSucceeds()); + // Send a packet from each socket_pair. + for (auto& sockets : socket_pairs) { + char send_buf[200]; + ASSERT_THAT( + RetryEINTR(sendto)(sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&send_addr.addr), + send_addr.addr_len), + SyscallSucceedsWithValue(sizeof(send_buf))); + + char recv_buf[sizeof(send_buf)] = {}; + for (auto& sockets : socket_pairs) { + ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), recv_buf, + sizeof(recv_buf), MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); + } + } +} + } // namespace testing } // namespace gvisor -- cgit v1.2.3 From 2d8e90b31102fa784f1657153db99d6fe52b4e9d Mon Sep 17 00:00:00 2001 From: Chris Kuiper Date: Fri, 3 May 2019 07:01:38 -0700 Subject: Proper cleanup of sockets that used REUSEPORT Fixed a small logic error that broke proper accounting of MultiPortEndpoints. PiperOrigin-RevId: 246502126 Change-Id: I1a7d6ea134f811612e545676212899a3707bc2c2 --- pkg/tcpip/stack/transport_demuxer.go | 2 +- test/syscalls/linux/socket_inet_loopback.cc | 34 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index 66c564613..807c3ba5e 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -171,7 +171,7 @@ func (ep *multiPortEndpoint) singleRegisterEndpoint(t TransportEndpoint) { // A new endpoint is added into endpointsArr and its index there is // saved in endpointsMap. This will allows to remove endpoint from // the array fast. - ep.endpointsMap[ep] = len(ep.endpointsArr) + ep.endpointsMap[t] = len(ep.endpointsArr) ep.endpointsArr = append(ep.endpointsArr, t) } diff --git a/test/syscalls/linux/socket_inet_loopback.cc b/test/syscalls/linux/socket_inet_loopback.cc index f86a0f30c..b216d14cb 100644 --- a/test/syscalls/linux/socket_inet_loopback.cc +++ b/test/syscalls/linux/socket_inet_loopback.cc @@ -1040,6 +1040,40 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, PortReuseTwoSockets) { } } +// Check that when a socket was bound to an address with REUSEPORT and then +// closed, we can bind a different socket to the same address without needing +// REUSEPORT. +TEST_P(SocketMultiProtocolInetLoopbackTest, NoReusePortFollowingReusePort) { + auto const& param = GetParam(); + TestAddress const& test_addr = V4Loopback(); + sockaddr_storage addr = test_addr.addr; + + auto s = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); + int fd = s.get(); + socklen_t addrlen = test_addr.addr_len; + int portreuse = 1; + ASSERT_THAT( + setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &portreuse, sizeof(portreuse)), + SyscallSucceeds()); + ASSERT_THAT(bind(fd, reinterpret_cast(&addr), addrlen), + SyscallSucceeds()); + ASSERT_THAT(getsockname(fd, reinterpret_cast(&addr), &addrlen), + SyscallSucceeds()); + ASSERT_EQ(addrlen, test_addr.addr_len); + + s.reset(); + + // Open a new socket and bind to the same address, but w/o REUSEPORT. + s = ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); + fd = s.get(); + portreuse = 0; + ASSERT_THAT( + setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &portreuse, sizeof(portreuse)), + SyscallSucceeds()); + ASSERT_THAT(bind(fd, reinterpret_cast(&addr), addrlen), + SyscallSucceeds()); +} + INSTANTIATE_TEST_SUITE_P( AllFamlies, SocketMultiProtocolInetLoopbackTest, ::testing::Values(ProtocolTestParam{"TCP", SOCK_STREAM}, -- cgit v1.2.3 From 458fe955a74bca6c33cb321901d771cf146f5cc6 Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Fri, 3 May 2019 10:49:58 -0700 Subject: Implement support for SACK based recovery(RFC 6675). PiperOrigin-RevId: 246536003 Change-Id: I118b745f45040be9c70cb6a1028acdb06c78d8c9 --- pkg/tcpip/stack/stack.go | 14 +- pkg/tcpip/transport/tcp/connect.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 10 +- pkg/tcpip/transport/tcp/sack_scoreboard.go | 73 ++- pkg/tcpip/transport/tcp/sack_scoreboard_test.go | 105 ++- pkg/tcpip/transport/tcp/segment.go | 5 + pkg/tcpip/transport/tcp/snd.go | 723 +++++++++++++++------ pkg/tcpip/transport/tcp/tcp_sack_test.go | 216 +++++- pkg/tcpip/transport/tcp/tcp_test.go | 11 +- pkg/tcpip/transport/tcp/testing/context/context.go | 32 +- 10 files changed, 964 insertions(+), 227 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index c82822ee2..9d8e8cda5 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -102,6 +102,18 @@ type TCPFastRecoveryState struct { // MaxCwnd is the maximum value we are permitted to grow the congestion // window during recovery. This is set at the time we enter recovery. MaxCwnd int + + // HighRxt is the highest sequence number which has been retransmitted + // during the current loss recovery phase. + // See: RFC 6675 Section 2 for details. + HighRxt seqnum.Value + + // RescueRxt is the highest sequence number which has been + // optimistically retransmitted to prevent stalling of the ACK clock + // when there is loss at the end of the window and no new data is + // available for transmission. + // See: RFC 6675 Section 2 for details. + RescueRxt seqnum.Value } // TCPReceiverState holds a copy of the internal state of the receiver for @@ -1024,7 +1036,7 @@ func (s *Stack) TransportProtocolInstance(num tcpip.TransportProtocolNumber) Tra // AddTCPProbe installs a probe function that will be invoked on every segment // received by a given TCP endpoint. The probe function is passed a copy of the -// TCP endpoint state. +// TCP endpoint state before and after processing of the segment. // // NOTE: TCPProbe is added only to endpoints created after this call. Endpoints // created prior to this call will not call the probe function. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index eaa67aeb7..3b927d82e 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -790,7 +790,7 @@ func (e *endpoint) keepaliveTimerExpired() *tcpip.Error { // seg.seq = snd.nxt-1. e.keepalive.unacked++ e.keepalive.Unlock() - e.snd.sendSegment(buffer.VectorisedView{}, header.TCPFlagAck, e.snd.sndNxt-1) + e.snd.sendSegmentFromView(buffer.VectorisedView{}, header.TCPFlagAck, e.snd.sndNxt-1) e.resetKeepaliveTimer(false) return nil } diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 982f491cc..00962a63e 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1673,10 +1673,12 @@ func (e *endpoint) completeState() stack.TCPEndpointState { LastSendTime: e.snd.lastSendTime, DupAckCount: e.snd.dupAckCount, FastRecovery: stack.TCPFastRecoveryState{ - Active: e.snd.fr.active, - First: e.snd.fr.first, - Last: e.snd.fr.last, - MaxCwnd: e.snd.fr.maxCwnd, + Active: e.snd.fr.active, + First: e.snd.fr.first, + Last: e.snd.fr.last, + MaxCwnd: e.snd.fr.maxCwnd, + HighRxt: e.snd.fr.highRxt, + RescueRxt: e.snd.fr.rescueRxt, }, SndCwnd: e.snd.sndCwnd, Ssthresh: e.snd.sndSsthresh, diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard.go b/pkg/tcpip/transport/tcp/sack_scoreboard.go index 99560d5b4..1c5766a42 100644 --- a/pkg/tcpip/transport/tcp/sack_scoreboard.go +++ b/pkg/tcpip/transport/tcp/sack_scoreboard.go @@ -38,6 +38,13 @@ const ( // // +stateify savable type SACKScoreboard struct { + // smss is defined in RFC5681 as following: + // + // The SMSS is the size of the largest segment that the sender can + // transmit. This value can be based on the maximum transmission unit + // of the network, the path MTU discovery [RFC1191, RFC4821] algorithm, + // RMSS (see next item), or other factors. The size does not include + // the TCP/IP headers and options. smss uint16 maxSACKED seqnum.Value sacked seqnum.Size `state:"nosave"` @@ -138,6 +145,10 @@ func (s *SACKScoreboard) Insert(r header.SACKBlock) { // IsSACKED returns true if the a given range of sequence numbers denoted by r // are already covered by SACK information in the scoreboard. func (s *SACKScoreboard) IsSACKED(r header.SACKBlock) bool { + if s.Empty() { + return false + } + found := false s.ranges.DescendLessOrEqual(r, func(i btree.Item) bool { sacked := i.(header.SACKBlock) @@ -205,17 +216,46 @@ func (s *SACKScoreboard) Copy() (sackBlocks []header.SACKBlock, maxSACKED seqnum return sackBlocks, s.maxSACKED } -// IsLost implements the IsLost(SeqNum) operation defined in RFC 3517 section 4. -// -// This routine returns whether the given sequence number is considered to be -// lost. The routine returns true when either nDupAckThreshold discontiguous -// SACKed sequences have arrived above 'SeqNum' or (nDupAckThreshold * SMSS) -// bytes with sequence numbers greater than 'SeqNum' have been SACKed. -// Otherwise, the routine returns false. -func (s *SACKScoreboard) IsLost(r header.SACKBlock) bool { +// IsRangeLost implements the IsLost(SeqNum) operation defined in RFC 6675 +// section 4 but operates on a range of sequence numbers and returns true if +// there are at least nDupAckThreshold SACK blocks greater than the range being +// checked or if at least (nDupAckThreshold-1)*s.smss bytes have been SACKED +// with sequence numbers greater than the block being checked. +func (s *SACKScoreboard) IsRangeLost(r header.SACKBlock) bool { + if s.Empty() { + return false + } nDupSACK := 0 nDupSACKBytes := seqnum.Size(0) isLost := false + + // We need to check if the immediate lower (if any) sacked + // range contains or partially overlaps with r. + searchMore := true + s.ranges.DescendLessOrEqual(r, func(i btree.Item) bool { + sacked := i.(header.SACKBlock) + if sacked.Contains(r) { + searchMore = false + return false + } + if sacked.End.LessThanEq(r.Start) { + // all sequence numbers covered by sacked are below + // r so we continue searching. + return false + } + // There is a partial overlap. In this case we r.Start is + // between sacked.Start & sacked.End and r.End extends beyond + // sacked.End. + // Move r.Start to sacked.End and continuing searching blocks + // above r.Start. + r.Start = sacked.End + return false + }) + + if !searchMore { + return isLost + } + s.ranges.AscendGreaterOrEqual(r, func(i btree.Item) bool { sacked := i.(header.SACKBlock) if sacked.Contains(r) { @@ -232,6 +272,18 @@ func (s *SACKScoreboard) IsLost(r header.SACKBlock) bool { return isLost } +// IsLost implements the IsLost(SeqNum) operation defined in RFC3517 section +// 4. +// +// This routine returns whether the given sequence number is considered to be +// lost. The routine returns true when either nDupAckThreshold discontiguous +// SACKed sequences have arrived above 'SeqNum' or (nDupAckThreshold * SMSS) +// bytes with sequence numbers greater than 'SeqNum' have been SACKed. +// Otherwise, the routine returns false. +func (s *SACKScoreboard) IsLost(seq seqnum.Value) bool { + return s.IsRangeLost(header.SACKBlock{seq, seq.Add(1)}) +} + // Empty returns true if the SACK scoreboard has no entries, false otherwise. func (s *SACKScoreboard) Empty() bool { return s.ranges.Len() == 0 @@ -247,3 +299,8 @@ func (s *SACKScoreboard) Sacked() seqnum.Size { func (s *SACKScoreboard) MaxSACKED() seqnum.Value { return s.maxSACKED } + +// SMSS returns the sender's MSS as held by the SACK scoreboard. +func (s *SACKScoreboard) SMSS() uint16 { + return s.smss +} diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go index 8f6890cdf..b59eedc9d 100644 --- a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go +++ b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go @@ -97,31 +97,120 @@ func TestSACKScoreboardIsSACKED(t *testing.T) { } } -func TestSACKScoreboardIsLost(t *testing.T) { +func TestSACKScoreboardIsRangeLost(t *testing.T) { s := tcp.NewSACKScoreboard(10, 0) - s.Insert(header.SACKBlock{1, 50}) + s.Insert(header.SACKBlock{1, 25}) + s.Insert(header.SACKBlock{25, 50}) s.Insert(header.SACKBlock{51, 100}) s.Insert(header.SACKBlock{111, 120}) s.Insert(header.SACKBlock{101, 110}) s.Insert(header.SACKBlock{121, 141}) + s.Insert(header.SACKBlock{145, 146}) + s.Insert(header.SACKBlock{147, 148}) + s.Insert(header.SACKBlock{149, 150}) + s.Insert(header.SACKBlock{153, 154}) + s.Insert(header.SACKBlock{155, 156}) testCases := []struct { block header.SACKBlock lost bool }{ + // Block not covered by SACK block and has more than + // nDupAckThreshold discontiguous SACK blocks after it as well + // as (nDupAckThreshold -1) * 10 (smss) bytes that have been + // SACKED above the sequence number covered by this block. {block: header.SACKBlock{0, 1}, lost: true}, + + // These blocks have all been SACKed and should not be + // considered lost. {block: header.SACKBlock{1, 2}, lost: false}, + {block: header.SACKBlock{25, 26}, lost: false}, {block: header.SACKBlock{1, 45}, lost: false}, + + // Same as the first case above. {block: header.SACKBlock{50, 51}, lost: true}, - // This one should return true because there are - // > (nDupAckThreshold - 1) * 10 (smss) bytes that have been sacked above - // this sequence number. - {block: header.SACKBlock{119, 120}, lost: true}, + + // This block has been SACKed and should not be considered lost. + {block: header.SACKBlock{119, 120}, lost: false}, + + // This one should return true because there are > + // (nDupAckThreshold - 1) * 10 (smss) bytes that have been + // sacked above this sequence number. {block: header.SACKBlock{120, 121}, lost: true}, + + // This block has been SACKed and should not be considered lost. {block: header.SACKBlock{125, 126}, lost: false}, + + // This block has not been SACKed and there are nDupAckThreshold + // number of SACKed blocks after it. + {block: header.SACKBlock{141, 145}, lost: true}, + + // This block has not been SACKed and there are less than + // nDupAckThreshold SACKed sequences after it. + {block: header.SACKBlock{151, 152}, lost: false}, + } + for _, tc := range testCases { + if want, got := tc.lost, s.IsRangeLost(tc.block); got != want { + t.Errorf("s.IsRangeLost(%v) = %v, want %v", tc.block, got, want) + } + } +} + +func TestSACKScoreboardIsLost(t *testing.T) { + s := tcp.NewSACKScoreboard(10, 0) + s.Insert(header.SACKBlock{1, 25}) + s.Insert(header.SACKBlock{25, 50}) + s.Insert(header.SACKBlock{51, 100}) + s.Insert(header.SACKBlock{111, 120}) + s.Insert(header.SACKBlock{101, 110}) + s.Insert(header.SACKBlock{121, 141}) + s.Insert(header.SACKBlock{121, 141}) + s.Insert(header.SACKBlock{145, 146}) + s.Insert(header.SACKBlock{147, 148}) + s.Insert(header.SACKBlock{149, 150}) + s.Insert(header.SACKBlock{153, 154}) + s.Insert(header.SACKBlock{155, 156}) + testCases := []struct { + seq seqnum.Value + lost bool + }{ + // Sequence number not covered by SACK block and has more than + // nDupAckThreshold discontiguous SACK blocks after it as well + // as (nDupAckThreshold -1) * 10 (smss) bytes that have been + // SACKED above the sequence number. + {seq: 0, lost: true}, + + // These sequence numbers have all been SACKed and should not be + // considered lost. + {seq: 1, lost: false}, + {seq: 25, lost: false}, + {seq: 45, lost: false}, + + // Same as first case above. + {seq: 50, lost: true}, + + // This block has been SACKed and should not be considered lost. + {seq: 119, lost: false}, + + // This one should return true because there are > + // (nDupAckThreshold - 1) * 10 (smss) bytes that have been + // sacked above this sequence number. + {seq: 120, lost: true}, + + // This sequence number has been SACKed and should not be + // considered lost. + {seq: 125, lost: false}, + + // This sequence number has not been SACKed and there are + // nDupAckThreshold number of SACKed blocks after it. + {seq: 141, lost: true}, + + // This sequence number has not been SACKed and there are less + // than nDupAckThreshold SACKed sequences after it. + {seq: 151, lost: false}, } for _, tc := range testCases { - if want, got := tc.lost, s.IsLost(tc.block); got != want { - t.Errorf("s.IsLost(%v) = %v, want %v", tc.block, got, want) + if want, got := tc.lost, s.IsLost(tc.seq); got != want { + t.Errorf("s.IsLost(%v) = %v, want %v", tc.seq, got, want) } } } diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 187effb6b..450d9fbc1 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -179,3 +179,8 @@ func (s *segment) parse() bool { s.window = seqnum.Size(h.WindowSize()) return true } + +// sackBlock returns a header.SACKBlock that represents this segment. +func (s *segment) sackBlock() header.SACKBlock { + return header.SACKBlock{s.sequenceNumber, s.sequenceNumber.Add(s.logicalLen())} +} diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index 50743670e..afc1d0a55 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -172,6 +172,18 @@ type fastRecovery struct { // receiver intentionally sends duplicate acks to artificially inflate // the sender's cwnd. maxCwnd int + + // highRxt is the highest sequence number which has been retransmitted + // during the current loss recovery phase. + // See: RFC 6675 Section 2 for details. + highRxt seqnum.Value + + // rescueRxt is the highest sequence number which has been + // optimistically retransmitted to prevent stalling of the ACK clock + // when there is loss at the end of the window and no new data is + // available for transmission. + // See: RFC 6675 Section 2 for details. + rescueRxt seqnum.Value } func newSender(ep *endpoint, iss, irs seqnum.Value, sndWnd seqnum.Size, mss uint16, sndWndScale int) *sender { @@ -195,7 +207,9 @@ func newSender(ep *endpoint, iss, irs seqnum.Value, sndWnd seqnum.Size, mss uint maxSentAck: irs + 1, fr: fastRecovery{ // See: https://tools.ietf.org/html/rfc6582#section-3.2 Step 1. - last: iss, + last: iss, + highRxt: iss, + rescueRxt: iss, }, gso: ep.gso != nil, } @@ -212,12 +226,15 @@ func newSender(ep *endpoint, iss, irs seqnum.Value, sndWnd seqnum.Size, mss uint s.sndWndScale = uint8(sndWndScale) } - // Initialize SACK Scoreboard. - s.ep.scoreboard = NewSACKScoreboard(mss, iss) s.resendTimer.init(&s.resendWaker) s.updateMaxPayloadSize(int(ep.route.MTU()), 0) + // Initialize SACK Scoreboard after updating max payload size as we use + // the maxPayloadSize as the smss when determining if a segment is lost + // etc. + s.ep.scoreboard = NewSACKScoreboard(uint16(s.maxPayloadSize), iss) + return s } @@ -256,6 +273,16 @@ func (s *sender) updateMaxPayloadSize(mtu, count int) { s.ep.gso.MSS = uint16(m) } + if count == 0 { + // updateMaxPayloadSize is also called when the sender is created. + // and there is no data to send in such cases. Return immediately. + return + } + + // Update the scoreboard's smss to reflect the new lowered + // maxPayloadSize. + s.ep.scoreboard.smss = uint16(m) + s.outstanding -= count if s.outstanding < 0 { s.outstanding = 0 @@ -285,7 +312,7 @@ func (s *sender) updateMaxPayloadSize(mtu, count int) { // sendAck sends an ACK segment. func (s *sender) sendAck() { - s.sendSegment(buffer.VectorisedView{}, header.TCPFlagAck, s.sndNxt) + s.sendSegmentFromView(buffer.VectorisedView{}, header.TCPFlagAck, s.sndNxt) } // updateRTO updates the retransmit timeout when a new roud-trip time is @@ -350,17 +377,20 @@ func (s *sender) resendSegment() { // Resend the segment. if seg := s.writeList.Front(); seg != nil { if seg.data.Size() > s.maxPayloadSize { - available := s.maxPayloadSize - // Split this segment up. - nSeg := seg.clone() - nSeg.data.TrimFront(available) - nSeg.sequenceNumber.UpdateForward(seqnum.Size(available)) - s.writeList.InsertAfter(seg, nSeg) - seg.data.CapLength(available) - } - s.sendSegment(seg.data, seg.flags, seg.sequenceNumber) + s.splitSeg(seg, s.maxPayloadSize) + } + + // See: RFC 6675 section 5 Step 4.3 + // + // To prevent retransmission, set both the HighRXT and RescueRXT + // to the highest sequence number in the retransmitted segment. + s.fr.highRxt = seg.sequenceNumber.Add(seqnum.Size(seg.data.Size())) - 1 + s.fr.rescueRxt = seg.sequenceNumber.Add(seqnum.Size(seg.data.Size())) - 1 + s.sendSegment(seg) s.ep.stack.Stats().TCP.FastRetransmit.Increment() - s.ep.stack.Stats().TCP.Retransmits.Increment() + + // Run SetPipe() as per RFC 6675 section 5 Step 4.4 + s.SetPipe() } } @@ -386,6 +416,14 @@ func (s *sender) retransmitTimerExpired() bool { // below. s.rto *= 2 + // See: https://tools.ietf.org/html/rfc6582#section-3.2 Step 4. + // + // Retransmit timeouts: + // After a retransmit timeout, record the highest sequence number + // transmitted in the variable recover, and exit the fast recovery + // procedure if applicable. + s.fr.last = s.sndNxt - 1 + if s.fr.active { // We were attempting fast recovery but were not successful. // Leave the state. We don't need to update ssthresh because it @@ -393,11 +431,6 @@ func (s *sender) retransmitTimerExpired() bool { s.leaveFastRecovery() } - // See: https://tools.ietf.org/html/rfc6582#section-3.2 Step 4. - // We store the highest sequence number transmitted in cases where - // we were not in fast recovery. - s.fr.last = s.sndNxt - 1 - s.cc.HandleRTOExpired() // Mark the next segment to be sent as the first unacknowledged one and @@ -439,152 +472,323 @@ func (s *sender) pCount(seg *segment) int { return (size-1)/s.maxPayloadSize + 1 } -// sendData sends new data segments. It is called when data becomes available or -// when the send window opens up. -func (s *sender) sendData() { - limit := s.maxPayloadSize - if s.gso { - limit = int(s.ep.gso.MaxSize - header.TCPHeaderMaximumSize) - } - // Reduce the congestion window to min(IW, cwnd) per RFC 5681, page 10. - // "A TCP SHOULD set cwnd to no more than RW before beginning - // transmission if the TCP has not sent data in the interval exceeding - // the retrasmission timeout." - if !s.fr.active && time.Now().Sub(s.lastSendTime) > s.rto { - if s.sndCwnd > InitialCwnd { - s.sndCwnd = InitialCwnd - } +// splitSeg splits a given segment at the size specified and inserts the +// remainder as a new segment after the current one in the write list. +func (s *sender) splitSeg(seg *segment, size int) { + if seg.data.Size() <= size { + return } + // Split this segment up. + nSeg := seg.clone() + nSeg.data.TrimFront(size) + nSeg.sequenceNumber.UpdateForward(seqnum.Size(size)) + s.writeList.InsertAfter(seg, nSeg) + seg.data.CapLength(size) +} - seg := s.writeNext - end := s.sndUna.Add(s.sndWnd) - var dataSent bool - for ; seg != nil && s.outstanding < s.sndCwnd; seg = seg.Next() { - cwndLimit := (s.sndCwnd - s.outstanding) * s.maxPayloadSize - if cwndLimit < limit { - limit = cwndLimit - } - // We abuse the flags field to determine if we have already - // assigned a sequence number to this segment. - if seg.flags == 0 { - // Merge segments if allowed. - if seg.data.Size() != 0 { - available := int(s.sndNxt.Size(end)) - if available > limit { - available = limit +// NextSeg implements the RFC6675 NextSeg() operation. It returns segments that +// match rule 1, 3 and 4 of the NextSeg() operation defined in RFC6675. Rule 2 +// is handled by the normal send logic. +func (s *sender) NextSeg() (nextSeg1, nextSeg3, nextSeg4 *segment) { + var s3 *segment + var s4 *segment + smss := s.ep.scoreboard.SMSS() + // Step 1. + for seg := s.writeList.Front(); seg != nil; seg = seg.Next() { + if !s.isAssignedSequenceNumber(seg) { + break + } + segSeq := seg.sequenceNumber + if seg.data.Size() > int(smss) { + s.splitSeg(seg, int(smss)) + } + // See RFC 6675 Section 4 + // + // 1. If there exists a smallest unSACKED sequence number + // 'S2' that meets the following 3 criteria for determinig + // loss, the sequence range of one segment of up to SMSS + // octects starting with S2 MUST be returned. + if !s.ep.scoreboard.IsSACKED(header.SACKBlock{segSeq, segSeq.Add(1)}) { + // NextSeg(): + // + // (1.a) S2 is greater than HighRxt + // (1.b) S2 is less than highest octect covered by + // any received SACK. + if s.fr.highRxt.LessThan(segSeq) && segSeq.LessThan(s.ep.scoreboard.maxSACKED) { + // NextSeg(): + // (1.c) IsLost(S2) returns true. + if s.ep.scoreboard.IsLost(segSeq) { + return seg, s3, s4 } - - // nextTooBig indicates that the next segment was too - // large to entirely fit in the current segment. It would - // be possible to split the next segment and merge the - // portion that fits, but unexpectedly splitting segments - // can have user visible side-effects which can break - // applications. For example, RFC 7766 section 8 says - // that the length and data of a DNS response should be - // sent in the same TCP segment to avoid triggering bugs - // in poorly written DNS implementations. - var nextTooBig bool - - for seg.Next() != nil && seg.Next().data.Size() != 0 { - if seg.data.Size()+seg.Next().data.Size() > available { - nextTooBig = true - break - } - - seg.data.Append(seg.Next().data) - - // Consume the segment that we just merged in. - s.writeList.Remove(seg.Next()) + // NextSeg(): + // + // (3): If the conditions for rules (1) and (2) + // fail, but there exists an unSACKed sequence + // number S3 that meets the criteria for + // detecting loss given in steps 1.a and 1.b + // above (specifically excluding (1.c)) then one + // segment of upto SMSS octets starting with S3 + // SHOULD be returned. + if s3 == nil { + s3 = seg } - - if !nextTooBig && seg.data.Size() < available { - // Segment is not full. - if s.outstanding > 0 && atomic.LoadUint32(&s.ep.delay) != 0 { - // Nagle's algorithm. From Wikipedia: - // Nagle's algorithm works by combining a number of - // small outgoing messages and sending them all at - // once. Specifically, as long as there is a sent - // packet for which the sender has received no - // acknowledgment, the sender should keep buffering - // its output until it has a full packet's worth of - // output, thus allowing output to be sent all at - // once. - break - } - if atomic.LoadUint32(&s.ep.cork) != 0 { - // Hold back the segment until full. - break + } + // NextSeg(): + // + // (4) If the conditions for (1), (2) and (3) fail, + // but there exists outstanding unSACKED data, we + // provide the opportunity for a single "rescue" + // retransmission per entry into loss recovery. If + // HighACK is greater than RescueRxt, the one + // segment of upto SMSS octects that MUST include + // the highest outstanding unSACKed sequence number + // SHOULD be returned. + if s.fr.rescueRxt.LessThan(s.sndUna - 1) { + if s4 != nil { + if s4.sequenceNumber.LessThan(segSeq) { + s4 = seg } + } else { + s4 = seg } + s.fr.rescueRxt = s.fr.last } - - // Assign flags. We don't do it above so that we can merge - // additional data if Nagle holds the segment. - seg.sequenceNumber = s.sndNxt - seg.flags = header.TCPFlagAck | header.TCPFlagPsh } + } - var segEnd seqnum.Value - if seg.data.Size() == 0 { - if s.writeList.Back() != seg { - panic("FIN segments must be the final segment in the write list.") - } - seg.flags = header.TCPFlagAck | header.TCPFlagFin - segEnd = seg.sequenceNumber.Add(1) - } else { - // We're sending a non-FIN segment. - if seg.flags&header.TCPFlagFin != 0 { - panic("Netstack queues FIN segments without data.") - } - - if !seg.sequenceNumber.LessThan(end) { - break - } + return nil, s3, s4 +} +// maybeSendSegment tries to send the specified segment and either coalesces +// other segments into this one or splits the specified segment based on the +// lower of the specified limit value or the receivers window size specified by +// end. +func (s *sender) maybeSendSegment(seg *segment, limit int, end seqnum.Value) (sent bool) { + // We abuse the flags field to determine if we have already + // assigned a sequence number to this segment. + if !s.isAssignedSequenceNumber(seg) { + // Merge segments if allowed. + if seg.data.Size() != 0 { available := int(seg.sequenceNumber.Size(end)) if available > limit { available = limit } - if seg.data.Size() > available { - // Split this segment up. - nSeg := seg.clone() - nSeg.data.TrimFront(available) - nSeg.sequenceNumber.UpdateForward(seqnum.Size(available)) - s.writeList.InsertAfter(seg, nSeg) - seg.data.CapLength(available) + // nextTooBig indicates that the next segment was too + // large to entirely fit in the current segment. It + // would be possible to split the next segment and merge + // the portion that fits, but unexpectedly splitting + // segments can have user visible side-effects which can + // break applications. For example, RFC 7766 section 8 + // says that the length and data of a DNS response + // should be sent in the same TCP segment to avoid + // triggering bugs in poorly written DNS + // implementations. + var nextTooBig bool + for seg.Next() != nil && seg.Next().data.Size() != 0 { + if seg.data.Size()+seg.Next().data.Size() > available { + nextTooBig = true + break + } + seg.data.Append(seg.Next().data) + + // Consume the segment that we just merged in. + s.writeList.Remove(seg.Next()) + } + if !nextTooBig && seg.data.Size() < available { + // Segment is not full. + if s.outstanding > 0 && atomic.LoadUint32(&s.ep.delay) != 0 { + // Nagle's algorithm. From Wikipedia: + // Nagle's algorithm works by + // combining a number of small + // outgoing messages and sending them + // all at once. Specifically, as long + // as there is a sent packet for which + // the sender has received no + // acknowledgment, the sender should + // keep buffering its output until it + // has a full packet's worth of + // output, thus allowing output to be + // sent all at once. + return false + } + if atomic.LoadUint32(&s.ep.cork) != 0 { + // Hold back the segment until full. + return false + } } + } + + // Assign flags. We don't do it above so that we can merge + // additional data if Nagle holds the segment. + seg.sequenceNumber = s.sndNxt + seg.flags = header.TCPFlagAck | header.TCPFlagPsh + } - s.outstanding += s.pCount(seg) - segEnd = seg.sequenceNumber.Add(seqnum.Size(seg.data.Size())) + var segEnd seqnum.Value + if seg.data.Size() == 0 { + if s.writeList.Back() != seg { + panic("FIN segments must be the final segment in the write list.") + } + seg.flags = header.TCPFlagAck | header.TCPFlagFin + segEnd = seg.sequenceNumber.Add(1) + } else { + // We're sending a non-FIN segment. + if seg.flags&header.TCPFlagFin != 0 { + panic("Netstack queues FIN segments without data.") } - if !dataSent { - dataSent = true - // We are sending data, so we should stop the keepalive timer to - // ensure that no keepalives are sent while there is pending data. - s.ep.disableKeepaliveTimer() + if !seg.sequenceNumber.LessThan(end) { + return false + } + + available := int(seg.sequenceNumber.Size(end)) + if available == 0 { + return false } + if available > limit { + available = limit + } + + if seg.data.Size() > available { + s.splitSeg(seg, available) + } + + segEnd = seg.sequenceNumber.Add(seqnum.Size(seg.data.Size())) + } + + s.sendSegment(seg) - if !seg.xmitTime.IsZero() { - s.ep.stack.Stats().TCP.Retransmits.Increment() - if s.sndCwnd < s.sndSsthresh { - s.ep.stack.Stats().TCP.SlowStartRetransmits.Increment() + // Update sndNxt if we actually sent new data (as opposed to + // retransmitting some previously sent data). + if s.sndNxt.LessThan(segEnd) { + s.sndNxt = segEnd + } + + return true +} + +// handleSACKRecovery implements the loss recovery phase as described in RFC6675 +// section 5, step C. +func (s *sender) handleSACKRecovery(limit int, end seqnum.Value) (dataSent bool) { + s.SetPipe() + for s.outstanding < s.sndCwnd { + nextSeg, s3, s4 := s.NextSeg() + if nextSeg == nil { + // NextSeg(): + // + // Step (2): "If no sequence number 'S2' per rule (1) + // exists but there exists available unsent data and the + // receiver's advertised window allows, the sequence + // range of one segment of up to SMSS octets of + // previously unsent data starting with sequence number + // HighData+1 MUST be returned." + for seg := s.writeNext; seg != nil; seg = seg.Next() { + if s.isAssignedSequenceNumber(seg) && seg.sequenceNumber.LessThan(s.sndNxt) { + continue + } + // Step C.3 described below is handled by + // maybeSendSegment which increments sndNxt when + // a segment is transmitted. + // + // Step C.3 "If any of the data octets sent in + // (C.1) are above HighData, HighData must be + // updated to reflect the transmission of + // previously unsent data." + if sent := s.maybeSendSegment(seg, limit, end); !sent { + break + } + dataSent = true + s.outstanding++ + s.writeNext = seg.Next() + nextSeg = seg + break + } + if nextSeg != nil { + continue } } + rescueRtx := false + if nextSeg == nil && s3 != nil { + nextSeg = s3 + } + if nextSeg == nil && s4 != nil { + nextSeg = s4 + rescueRtx = true + } + if nextSeg == nil { + break + } + segEnd := nextSeg.sequenceNumber.Add(nextSeg.logicalLen()) + if !rescueRtx && nextSeg.sequenceNumber.LessThan(s.sndNxt) { + // RFC 6675, Step C.2 + // + // "If any of the data octets sent in (C.1) are below + // HighData, HighRxt MUST be set to the highest sequence + // number of the retransmitted segment unless NextSeg () + // rule (4) was invoked for this retransmission." + s.fr.highRxt = segEnd - 1 + } + + // RFC 6675, Step C.4. + // + // "The estimate of the amount of data outstanding in the network + // must be updated by incrementing pipe by the number of octets + // transmitted in (C.1)." + s.outstanding++ + dataSent = true + s.sendSegment(nextSeg) + } + return dataSent +} + +// sendData sends new data segments. It is called when data becomes available or +// when the send window opens up. +func (s *sender) sendData() { + limit := s.maxPayloadSize + if s.gso { + limit = int(s.ep.gso.MaxSize - header.TCPHeaderMaximumSize) + } + end := s.sndUna.Add(s.sndWnd) + + // Reduce the congestion window to min(IW, cwnd) per RFC 5681, page 10. + // "A TCP SHOULD set cwnd to no more than RW before beginning + // transmission if the TCP has not sent data in the interval exceeding + // the retrasmission timeout." + if !s.fr.active && time.Now().Sub(s.lastSendTime) > s.rto { + if s.sndCwnd > InitialCwnd { + s.sndCwnd = InitialCwnd + } + } - seg.xmitTime = time.Now() - s.sendSegment(seg.data, seg.flags, seg.sequenceNumber) + var dataSent bool - // Update sndNxt if we actually sent new data (as opposed to - // retransmitting some previously sent data). - if s.sndNxt.LessThan(segEnd) { - s.sndNxt = segEnd + // RFC 6675 recovery algorithm step C 1-5. + if s.fr.active && s.ep.sackPermitted { + dataSent = s.handleSACKRecovery(s.maxPayloadSize, end) + } else { + for seg := s.writeNext; seg != nil && s.outstanding < s.sndCwnd; seg = seg.Next() { + cwndLimit := (s.sndCwnd - s.outstanding) * s.maxPayloadSize + if cwndLimit < limit { + limit = cwndLimit + } + if s.isAssignedSequenceNumber(seg) && s.ep.sackPermitted && s.ep.scoreboard.IsSACKED(seg.sackBlock()) { + continue + } + if sent := s.maybeSendSegment(seg, limit, end); !sent { + break + } + dataSent = true + s.outstanding++ + s.writeNext = seg.Next() } } - // Remember the next segment we'll write. - s.writeNext = seg + if dataSent { + // We sent data, so we should stop the keepalive timer to ensure + // that no keepalives are sent while there is pending data. + s.ep.disableKeepaliveTimer() + } // Enable the timer if we have pending data and it's not enabled yet. if !s.resendTimer.enabled() && s.sndUna != s.sndNxt { @@ -599,91 +803,176 @@ func (s *sender) sendData() { func (s *sender) enterFastRecovery() { s.fr.active = true // Save state to reflect we're now in fast recovery. + // // See : https://tools.ietf.org/html/rfc5681#section-3.2 Step 3. - // We inflat the cwnd by 3 to account for the 3 packets which triggered + // We inflate the cwnd by 3 to account for the 3 packets which triggered // the 3 duplicate ACKs and are now not in flight. s.sndCwnd = s.sndSsthresh + 3 s.fr.first = s.sndUna s.fr.last = s.sndNxt - 1 s.fr.maxCwnd = s.sndCwnd + s.outstanding + if s.ep.sackPermitted { + s.ep.stack.Stats().TCP.SACKRecovery.Increment() + return + } s.ep.stack.Stats().TCP.FastRecovery.Increment() } func (s *sender) leaveFastRecovery() { s.fr.active = false - s.fr.first = 0 - s.fr.last = s.sndNxt - 1 s.fr.maxCwnd = 0 s.dupAckCount = 0 // Deflate cwnd. It had been artificially inflated when new dups arrived. s.sndCwnd = s.sndSsthresh - // As recovery is now complete, delete all SACK information for acked - // data. - s.ep.scoreboard.Delete(s.sndUna) s.cc.PostRecovery() } -// checkDuplicateAck is called when an ack is received. It manages the state -// related to duplicate acks and determines if a retransmit is needed according -// to the rules in RFC 6582 (NewReno). -func (s *sender) checkDuplicateAck(seg *segment) (rtx bool) { +func (s *sender) handleFastRecovery(seg *segment) (rtx bool) { ack := seg.ackNumber - if s.fr.active { - // We are in fast recovery mode. Ignore the ack if it's out of - // range. - if !ack.InRange(s.sndUna, s.sndNxt+1) { - return false - } + // We are in fast recovery mode. Ignore the ack if it's out of + // range. + if !ack.InRange(s.sndUna, s.sndNxt+1) { + return false + } - // Leave fast recovery if it acknowledges all the data covered by - // this fast recovery session. - if s.fr.last.LessThan(ack) { - s.leaveFastRecovery() - return false - } + // Leave fast recovery if it acknowledges all the data covered by + // this fast recovery session. + if s.fr.last.LessThan(ack) { + s.leaveFastRecovery() + return false + } - // Don't count this as a duplicate if it is carrying data or - // updating the window. - if seg.logicalLen() != 0 || s.sndWnd != seg.window { - return false + if s.ep.sackPermitted { + // When SACK is enabled we let retransmission be governed by + // the SACK logic. + return false + } + + // Don't count this as a duplicate if it is carrying data or + // updating the window. + if seg.logicalLen() != 0 || s.sndWnd != seg.window { + return false + } + + // Inflate the congestion window if we're getting duplicate acks + // for the packet we retransmitted. + if ack == s.fr.first { + // We received a dup, inflate the congestion window by 1 packet + // if we're not at the max yet. Only inflate the window if + // regular FastRecovery is in use, RFC6675 does not require + // inflating cwnd on duplicate ACKs. + if s.sndCwnd < s.fr.maxCwnd { + s.sndCwnd++ } + return false + } + + // A partial ack was received. Retransmit this packet and + // remember it so that we don't retransmit it again. We don't + // inflate the window because we're putting the same packet back + // onto the wire. + // + // N.B. The retransmit timer will be reset by the caller. + s.fr.first = ack + s.dupAckCount = 0 + return true +} + +// isAssignedSequenceNumber relies on the fact that we only set flags once a +// sequencenumber is assigned and that is only done right before we send the +// segment. As a result any segment that has a non-zero flag has a valid +// sequence number assigned to it. +func (s *sender) isAssignedSequenceNumber(seg *segment) bool { + return seg.flags != 0 +} - // Inflate the congestion window if we're getting duplicate acks - // for the packet we retransmitted. - if ack == s.fr.first { - // We received a dup, inflate the congestion window by 1 - // packet if we're not at the max yet. - if s.sndCwnd < s.fr.maxCwnd { - s.sndCwnd++ +// SetPipe implements the SetPipe() function described in RFC6675. Netstack +// maintains the congestion window in number of packets and not bytes, so +// SetPipe() here measures number of outstanding packets rather than actual +// outstanding bytes in the network. +func (s *sender) SetPipe() { + // If SACK isn't permitted or it is permitted but recovery is not active + // then ignore pipe calculations. + if !s.ep.sackPermitted || !s.fr.active { + return + } + pipe := 0 + smss := seqnum.Size(s.ep.scoreboard.SMSS()) + for s1 := s.writeList.Front(); s1 != nil && s1.data.Size() != 0 && s.isAssignedSequenceNumber(s1); s1 = s1.Next() { + // With GSO each segment can be much larger than SMSS. So check the segment + // in SMSS sized ranges. + segEnd := s1.sequenceNumber.Add(seqnum.Size(s1.data.Size())) + for startSeq := s1.sequenceNumber; startSeq.LessThan(segEnd); startSeq = startSeq.Add(smss) { + endSeq := startSeq.Add(smss) + if segEnd.LessThan(endSeq) { + endSeq = segEnd + } + sb := header.SACKBlock{startSeq, endSeq} + // SetPipe(): + // + // After initializing pipe to zero, the following steps are + // taken for each octet 'S1' in the sequence space between + // HighACK and HighData that has not been SACKed: + if !s1.sequenceNumber.LessThan(s.sndNxt) { + break + } + if s.ep.scoreboard.IsSACKED(sb) { + continue + } + + // SetPipe(): + // + // (a) If IsLost(S1) returns false, Pipe is incremened by 1. + // + // NOTE: here we mark the whole segment as lost. We do not try + // and test every byte in our write buffer as we maintain our + // pipe in terms of oustanding packets and not bytes. + if !s.ep.scoreboard.IsRangeLost(sb) { + pipe++ + } + // SetPipe(): + // (b) If S1 <= HighRxt, Pipe is incremented by 1. + if s1.sequenceNumber.LessThanEq(s.fr.highRxt) { + pipe++ } - return false } + } + s.outstanding = pipe +} - // A partial ack was received. Retransmit this packet and - // remember it so that we don't retransmit it again. We don't - // inflate the window because we're putting the same packet back - // onto the wire. - // - // N.B. The retransmit timer will be reset by the caller. - s.fr.first = ack - s.dupAckCount = 0 - return true +// checkDuplicateAck is called when an ack is received. It manages the state +// related to duplicate acks and determines if a retransmit is needed according +// to the rules in RFC 6582 (NewReno). +func (s *sender) checkDuplicateAck(seg *segment) (rtx bool) { + ack := seg.ackNumber + if s.fr.active { + return s.handleFastRecovery(seg) } // We're not in fast recovery yet. A segment is considered a duplicate // only if it doesn't carry any data and doesn't update the send window, // because if it does, it wasn't sent in response to an out-of-order - // segment. + // segment. If SACK is enabled then we have an additional check to see + // if the segment carries new SACK information. If it does then it is + // considered a duplicate ACK as per RFC6675. if ack != s.sndUna || seg.logicalLen() != 0 || s.sndWnd != seg.window || ack == s.sndNxt { - s.dupAckCount = 0 - return false + if !s.ep.sackPermitted || !seg.hasNewSACKInfo { + s.dupAckCount = 0 + return false + } } s.dupAckCount++ - // Do not enter fast recovery until we reach nDupAckThreshold. - if s.dupAckCount < nDupAckThreshold { + + // Do not enter fast recovery until we reach nDupAckThreshold or the + // first unacknowledged byte is considered lost as per SACK scoreboard. + if s.dupAckCount < nDupAckThreshold || (s.ep.sackPermitted && !s.ep.scoreboard.IsLost(s.sndUna)) { + // RFC 6675 Step 3. + s.fr.highRxt = s.sndUna - 1 + // Do run SetPipe() to calculate the outstanding segments. + s.SetPipe() return false } @@ -696,7 +985,6 @@ func (s *sender) checkDuplicateAck(seg *segment) (rtx bool) { s.dupAckCount = 0 return false } - s.cc.HandleNDupAcks() s.enterFastRecovery() s.dupAckCount = 0 @@ -737,6 +1025,7 @@ func (s *sender) handleRcvdSegment(seg *segment) { seg.hasNewSACKInfo = true } } + s.SetPipe() } // Count the duplicates and do the fast retransmit if needed. @@ -749,9 +1038,6 @@ func (s *sender) handleRcvdSegment(seg *segment) { ack := seg.ackNumber if (ack - 1).InRange(s.sndUna, s.sndNxt) { s.dupAckCount = 0 - // When an ack is received we must reset the timer. We stop it - // here and it will be restarted later if needed. - s.resendTimer.disable() // See : https://tools.ietf.org/html/rfc1323#section-3.3. // Specifically we should only update the RTO using TSEcr if the @@ -767,6 +1053,11 @@ func (s *sender) handleRcvdSegment(seg *segment) { elapsed := time.Duration(s.ep.timestamp()-seg.parsedOptions.TSEcr) * time.Millisecond s.updateRTO(elapsed) } + + // When an ack is received we must rearm the timer. + // RFC 6298 5.2 + s.resendTimer.enable(s.rto) + // Remove all acknowledged data from the write list. acked := s.sndUna.Size(ack) s.sndUna = ack @@ -792,7 +1083,13 @@ func (s *sender) handleRcvdSegment(seg *segment) { s.writeNext = seg.Next() } s.writeList.Remove(seg) - s.outstanding -= s.pCount(seg) + + // if SACK is enabled then Only reduce outstanding if + // the segment was not previously SACKED as these have + // already been accounted for in SetPipe(). + if !s.ep.sackPermitted || !s.ep.scoreboard.IsSACKED(seg.sackBlock()) { + s.outstanding -= s.pCount(seg) + } seg.decRef() ackLeft -= datalen } @@ -815,8 +1112,16 @@ func (s *sender) handleRcvdSegment(seg *segment) { if s.outstanding < 0 { s.outstanding = 0 } - } + s.SetPipe() + + // If all outstanding data was acknowledged the disable the timer. + // RFC 6298 Rule 5.3 + if s.sndUna == s.sndNxt { + s.outstanding = 0 + s.resendTimer.disable() + } + } // Now that we've popped all acknowledged data from the retransmit // queue, retransmit if needed. if rtx { @@ -827,12 +1132,26 @@ func (s *sender) handleRcvdSegment(seg *segment) { // that the window opened up, or the congestion window was inflated due // to a duplicate ack during fast recovery. This will also re-enable // the retransmit timer if needed. - s.sendData() + if !s.ep.sackPermitted || s.fr.active || s.dupAckCount == 0 || seg.hasNewSACKInfo { + s.sendData() + } } -// sendSegment sends a new segment containing the given payload, flags and -// sequence number. -func (s *sender) sendSegment(data buffer.VectorisedView, flags byte, seq seqnum.Value) *tcpip.Error { +// sendSegment sends the specified segment. +func (s *sender) sendSegment(seg *segment) *tcpip.Error { + if !seg.xmitTime.IsZero() { + s.ep.stack.Stats().TCP.Retransmits.Increment() + if s.sndCwnd < s.sndSsthresh { + s.ep.stack.Stats().TCP.SlowStartRetransmits.Increment() + } + } + seg.xmitTime = time.Now() + return s.sendSegmentFromView(seg.data, seg.flags, seg.sequenceNumber) +} + +// sendSegmentFromView sends a new segment containing the given payload, flags +// and sequence number. +func (s *sender) sendSegmentFromView(data buffer.VectorisedView, flags byte, seq seqnum.Value) *tcpip.Error { s.lastSendTime = time.Now() if seq == s.rttMeasureSeqNum { s.rttMeasureTime = s.lastSendTime @@ -843,5 +1162,19 @@ func (s *sender) sendSegment(data buffer.VectorisedView, flags byte, seq seqnum. // Remember the max sent ack. s.maxSentAck = rcvNxt + // Every time a packet containing data is sent (including a + // retransmission), if SACK is enabled then use the conservative timer + // described in RFC6675 Section 4.0, otherwise follow the standard time + // described in RFC6298 Section 5.2. + if data.Size() != 0 { + if s.ep.sackPermitted { + s.resendTimer.enable(s.rto) + } else { + if !s.resendTimer.enabled() { + s.resendTimer.enable(s.rto) + } + } + } + return s.ep.sendRaw(data, flags, seq, rcvNxt, rcvWnd) } diff --git a/pkg/tcpip/transport/tcp/tcp_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go index dbfbd5c4f..025d133be 100644 --- a/pkg/tcpip/transport/tcp/tcp_sack_test.go +++ b/pkg/tcpip/transport/tcp/tcp_sack_test.go @@ -16,22 +16,33 @@ package tcp_test import ( "fmt" + "log" "reflect" "testing" + "time" + "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/tcp" "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/tcp/testing/context" ) -// createConnectWithSACKPermittedOption creates and connects c.ep with the +// createConnectedWithSACKPermittedOption creates and connects c.ep with the // SACKPermitted option enabled if the stack in the context has the SACK support // enabled. func createConnectedWithSACKPermittedOption(c *context.Context) *context.RawEndpoint { return c.CreateConnectedWithOptions(header.TCPSynOptions{SACKPermitted: c.SACKEnabled()}) } +// createConnectedWithSACKAndTS creates and connects c.ep with the SACK & TS +// option enabled if the stack in the context has SACK and TS enabled. +func createConnectedWithSACKAndTS(c *context.Context) *context.RawEndpoint { + return c.CreateConnectedWithOptions(header.TCPSynOptions{SACKPermitted: c.SACKEnabled(), TS: true}) +} + func setStackSACKPermitted(t *testing.T, c *context.Context, enable bool) { t.Helper() if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, tcp.SACKEnabled(enable)); err != nil { @@ -348,3 +359,206 @@ func TestTrimSackBlockList(t *testing.T) { } } } + +func TestSACKRecovery(t *testing.T) { + const maxPayload = 10 + // See: tcp.makeOptions for why tsOptionSize is set to 12 here. + const tsOptionSize = 12 + // Enabling SACK means the payload size is reduced to account + // for the extra space required for the TCP options. + // + // We increase the MTU by 40 bytes to account for SACK and Timestamp + // options. + const maxTCPOptionSize = 40 + + c := context.New(t, uint32(header.TCPMinimumSize+header.IPv4MinimumSize+maxTCPOptionSize+maxPayload)) + defer c.Cleanup() + + c.Stack().AddTCPProbe(func(s stack.TCPEndpointState) { + // We use log.Printf instead of t.Logf here because this probe + // can fire even when the test function has finished. This is + // because closing the endpoint in cleanup() does not mean the + // actual worker loop terminates immediately as it still has to + // do a full TCP shutdown. But this test can finish running + // before the shutdown is done. Using t.Logf in such a case + // causes the test to panic due to logging after test finished. + log.Printf("state: %+v\n", s) + }) + setStackSACKPermitted(t, c, true) + createConnectedWithSACKAndTS(c) + + const iterations = 7 + data := buffer.NewView(2 * maxPayload * (tcp.InitialCwnd << (iterations + 1))) + for i := range data { + data[i] = byte(i) + } + + // Write all the data in one shot. Packets will only be written at the + // MTU size though. + if _, _, err := c.EP.Write(tcpip.SlicePayload(data), tcpip.WriteOptions{}); err != nil { + t.Fatalf("Write failed: %v", err) + } + + // Do slow start for a few iterations. + expected := tcp.InitialCwnd + bytesRead := 0 + for i := 0; i < iterations; i++ { + expected = tcp.InitialCwnd << uint(i) + if i > 0 { + // Acknowledge all the data received so far if not on + // first iteration. + c.SendAck(790, bytesRead) + } + + // Read all packets expected on this iteration. Don't + // acknowledge any of them just yet, so that we can measure the + // congestion window. + for j := 0; j < expected; j++ { + c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize) + bytesRead += maxPayload + } + + // Check we don't receive any more packets on this iteration. + // The timeout can't be too high or we'll trigger a timeout. + c.CheckNoPacketTimeout("More packets received than expected for this cwnd.", 50*time.Millisecond) + } + + // Send 3 duplicate acks. This should force an immediate retransmit of + // the pending packet and put the sender into fast recovery. + rtxOffset := bytesRead - maxPayload*expected + start := c.IRS.Add(seqnum.Size(rtxOffset) + 30 + 1) + end := start.Add(10) + for i := 0; i < 3; i++ { + c.SendAckWithSACK(790, rtxOffset, []header.SACKBlock{{start, end}}) + end = end.Add(10) + } + + // Receive the retransmitted packet. + c.ReceiveAndCheckPacketWithOptions(data, rtxOffset, maxPayload, tsOptionSize) + + tcpStats := c.Stack().Stats().TCP + stats := []struct { + stat *tcpip.StatCounter + name string + want uint64 + }{ + {tcpStats.FastRetransmit, "stats.TCP.FastRetransmit", 1}, + {tcpStats.Retransmits, "stats.TCP.Retransmits", 1}, + {tcpStats.SACKRecovery, "stats.TCP.SACKRecovery", 1}, + {tcpStats.FastRecovery, "stats.TCP.FastRecovery", 0}, + } + for _, s := range stats { + if got, want := s.stat.Value(), s.want; got != want { + t.Errorf("got %s.Value() = %v, want = %v", s.name, got, want) + } + } + + // Now send 7 mode duplicate ACKs. In SACK TCP dupAcks do not cause + // window inflation and sending of packets is completely handled by the + // SACK Recovery algorithm. We should see no packets being released, as + // the cwnd at this point after entering recovery should be half of the + // outstanding number of packets in flight. + for i := 0; i < 7; i++ { + c.SendAckWithSACK(790, rtxOffset, []header.SACKBlock{{start, end}}) + end = end.Add(10) + } + + recover := bytesRead + + // Ensure no new packets arrive. + c.CheckNoPacketTimeout("More packets received than expected during recovery after dupacks for this cwnd.", + 50*time.Millisecond) + + // Acknowledge half of the pending data. This along with the 10 sacked + // segments above should reduce the outstanding below the current + // congestion window allowing the sender to transmit data. + rtxOffset = bytesRead - expected*maxPayload/2 + + // Now send a partial ACK w/ a SACK block that indicates that the next 3 + // segments are lost and we have received 6 segments after the lost + // segments. This should cause the sender to immediately transmit all 3 + // segments in response to this ACK unlike in FastRecovery where only 1 + // segment is retransmitted per ACK. + start = c.IRS.Add(seqnum.Size(rtxOffset) + 30 + 1) + end = start.Add(60) + c.SendAckWithSACK(790, rtxOffset, []header.SACKBlock{{start, end}}) + + // At this point, we acked expected/2 packets and we SACKED 6 packets and + // 3 segments were considered lost due to the SACK block we sent. + // + // So total packets outstanding can be calculated as follows after 7 + // iterations of slow start -> 10/20/40/80/160/320/640. So expected + // should be 640 at start, then we went to recover at which point the + // cwnd should be set to 320 + 3 (for the 3 dupAcks which have left the + // network). + // Outstanding at this point after acking half the window + // (320 packets) will be: + // outstanding = 640-320-6(due to SACK block)-3 = 311 + // + // The last 3 is due to the fact that the first 3 packets after + // rtxOffset will be considered lost due to the SACK blocks sent. + // Receive the retransmit due to partial ack. + + c.ReceiveAndCheckPacketWithOptions(data, rtxOffset, maxPayload, tsOptionSize) + // Receive the 2 extra packets that should have been retransmitted as + // those should be considered lost and immediately retransmitted based + // on the SACK information in the previous ACK sent above. + for i := 0; i < 2; i++ { + c.ReceiveAndCheckPacketWithOptions(data, rtxOffset+maxPayload*(i+1), maxPayload, tsOptionSize) + } + + // Now we should get 9 more new unsent packets as the cwnd is 323 and + // outstanding is 311. + for i := 0; i < 9; i++ { + c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize) + bytesRead += maxPayload + } + + // In SACK recovery only the first segment is fast retransmitted when + // entering recovery. + if got, want := c.Stack().Stats().TCP.FastRetransmit.Value(), uint64(1); got != want { + t.Errorf("got stats.TCP.FastRetransmit.Value = %v, want = %v", got, want) + } + + if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(4); got != want { + t.Errorf("got stats.TCP.Retransmits.Value = %v, want = %v", got, want) + } + + c.CheckNoPacketTimeout("More packets received than expected during recovery after partial ack for this cwnd.", 50*time.Millisecond) + + // Acknowledge all pending data to recover point. + c.SendAck(790, recover) + + // At this point, the cwnd should reset to expected/2 and there are 9 + // packets outstanding. + // + // Now in the first iteration since there are 9 packets outstanding. + // We would expect to get expected/2 - 9 packets. But subsequent + // iterations will send us expected/2 + 1 (per iteration). + expected = expected/2 - 9 + for i := 0; i < iterations; i++ { + // Read all packets expected on this iteration. Don't + // acknowledge any of them just yet, so that we can measure the + // congestion window. + for j := 0; j < expected; j++ { + c.ReceiveAndCheckPacketWithOptions(data, bytesRead, maxPayload, tsOptionSize) + bytesRead += maxPayload + } + // Check we don't receive any more packets on this iteration. + // The timeout can't be too high or we'll trigger a timeout. + c.CheckNoPacketTimeout(fmt.Sprintf("More packets received(after deflation) than expected %d for this cwnd and iteration: %d.", expected, i), 50*time.Millisecond) + + // Acknowledge all the data received so far. + c.SendAck(790, bytesRead) + + // In cogestion avoidance, the packets trains increase by 1 in + // each iteration. + if i == 0 { + // After the first iteration we expect to get the full + // congestion window worth of packets in every + // iteration. + expected += 9 + } + expected++ + } +} diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index a8b290dae..6e3ba5922 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -1792,12 +1792,12 @@ func TestSynOptionsOnActiveConnect(t *testing.T) { // Receive SYN packet. b := c.GetPacket() - + mss := uint16(mtu - header.IPv4MinimumSize - header.TCPMinimumSize) checker.IPv4(t, b, checker.TCP( checker.DstPort(context.TestPort), checker.TCPFlags(header.TCPFlagSyn), - checker.TCPSynOptions(header.TCPSynOptions{MSS: mtu - header.IPv4MinimumSize - header.TCPMinimumSize, WS: wndScale}), + checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: wndScale}), ), ) @@ -1812,7 +1812,7 @@ func TestSynOptionsOnActiveConnect(t *testing.T) { checker.TCPFlags(header.TCPFlagSyn), checker.SrcPort(tcp.SourcePort()), checker.SeqNum(tcp.SequenceNumber()), - checker.TCPSynOptions(header.TCPSynOptions{MSS: mtu - header.IPv4MinimumSize - header.TCPMinimumSize, WS: wndScale}), + checker.TCPSynOptions(header.TCPSynOptions{MSS: mss, WS: wndScale}), ), ) @@ -2737,7 +2737,8 @@ func TestFastRecovery(t *testing.T) { // A partial ACK during recovery should reduce congestion window by the // number acked. Since we had "expected" packets outstanding before sending // partial ack and we acked expected/2 , the cwnd and outstanding should - // be expected/2 + 7. Which means the sender should not send any more packets + // be expected/2 + 10 (7 dupAcks + 3 for the original 3 dupacks that triggered + // fast recovery). Which means the sender should not send any more packets // till we ack this one. c.CheckNoPacketTimeout("More packets received than expected during recovery after partial ack for this cwnd.", 50*time.Millisecond) @@ -2843,7 +2844,7 @@ func TestRetransmit(t *testing.T) { } if got, want := c.Stack().Stats().TCP.Retransmits.Value(), uint64(1); got != want { - t.Errorf("got stats.TCP.Retransmit.Value = %v, want = %v", got, want) + t.Errorf("got stats.TCP.Retransmits.Value = %v, want = %v", got, want) } if got, want := c.Stack().Stats().TCP.SlowStartRetransmits.Value(), uint64(1); got != want { diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index fa721a7f8..e08eb6533 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -355,13 +355,27 @@ func (c *Context) SendPacket(payload []byte, h *Headers) { // SendAck sends an ACK packet. func (c *Context) SendAck(seq seqnum.Value, bytesReceived int) { + c.SendAckWithSACK(seq, bytesReceived, nil) +} + +// SendAckWithSACK sends an ACK packet which includes the sackBlocks specified. +func (c *Context) SendAckWithSACK(seq seqnum.Value, bytesReceived int, sackBlocks []header.SACKBlock) { + options := make([]byte, 40) + offset := 0 + if len(sackBlocks) > 0 { + offset += header.EncodeNOP(options[offset:]) + offset += header.EncodeNOP(options[offset:]) + offset += header.EncodeSACKBlocks(sackBlocks, options[offset:]) + } + c.SendPacket(nil, &Headers{ SrcPort: TestPort, DstPort: c.Port, Flags: header.TCPFlagAck, - SeqNum: seqnum.Value(testInitialSequenceNumber).Add(1), + SeqNum: seq, AckNum: c.IRS.Add(1 + seqnum.Size(bytesReceived)), RcvWnd: 30000, + TCPOpts: options[:offset], }) } @@ -369,9 +383,17 @@ func (c *Context) SendAck(seq seqnum.Value, bytesReceived int) { // verifies that the packet packet payload of packet matches the slice // of data indicated by offset & size. func (c *Context) ReceiveAndCheckPacket(data []byte, offset, size int) { + c.ReceiveAndCheckPacketWithOptions(data, offset, size, 0) +} + +// ReceiveAndCheckPacketWithOptions reads a packet from the link layer endpoint +// and verifies that the packet packet payload of packet matches the slice of +// data indicated by offset & size and skips optlen bytes in addition to the IP +// TCP headers when comparing the data. +func (c *Context) ReceiveAndCheckPacketWithOptions(data []byte, offset, size, optlen int) { b := c.GetPacket() checker.IPv4(c.t, b, - checker.PayloadLen(size+header.TCPMinimumSize), + checker.PayloadLen(size+header.TCPMinimumSize+optlen), checker.TCP( checker.DstPort(TestPort), checker.SeqNum(uint32(c.IRS.Add(seqnum.Size(1+offset)))), @@ -381,7 +403,7 @@ func (c *Context) ReceiveAndCheckPacket(data []byte, offset, size int) { ) pdata := data[offset:][:size] - if p := b[header.IPv4MinimumSize+header.TCPMinimumSize:]; bytes.Compare(pdata, p) != 0 { + if p := b[header.IPv4MinimumSize+header.TCPMinimumSize+optlen:]; bytes.Compare(pdata, p) != 0 { c.t.Fatalf("Data is different: expected %v, got %v", pdata, p) } } @@ -683,12 +705,14 @@ func (c *Context) CreateConnectedWithOptions(wantOptions header.TCPSynOptions) * b := c.GetPacket() // Validate that the syn has the timestamp option and a valid // TS value. + mss := uint16(c.linkEP.MTU() - header.IPv4MinimumSize - header.TCPMinimumSize) + checker.IPv4(c.t, b, checker.TCP( checker.DstPort(TestPort), checker.TCPFlags(header.TCPFlagSyn), checker.TCPSynOptions(header.TCPSynOptions{ - MSS: uint16(c.linkEP.MTU() - header.IPv4MinimumSize - header.TCPMinimumSize), + MSS: mss, TS: true, WS: defaultWindowScale, SACKPermitted: c.SACKEnabled(), -- cgit v1.2.3 From c1cdf18e7bd21a9785462914ca8aa2056c81369a Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Wed, 22 May 2019 13:44:07 -0700 Subject: UDP and TCP raw socket support. PiperOrigin-RevId: 249511348 Change-Id: I34539092cc85032d9473ff4dd308fc29dc9bfd6b --- pkg/sentry/socket/epsocket/provider.go | 4 + pkg/tcpip/stack/nic.go | 8 + pkg/tcpip/stack/transport_demuxer.go | 36 ++- pkg/tcpip/transport/raw/endpoint.go | 2 +- pkg/tcpip/transport/tcp/BUILD | 1 + pkg/tcpip/transport/tcp/protocol.go | 3 +- pkg/tcpip/transport/udp/BUILD | 2 +- pkg/tcpip/transport/udp/endpoint.go | 2 + pkg/tcpip/transport/udp/protocol.go | 7 +- test/syscalls/linux/BUILD | 18 ++ test/syscalls/linux/raw_socket_icmp.cc | 453 +++++++++++++++++++++++++++++ test/syscalls/linux/raw_socket_ipv4.cc | 501 +++++++++------------------------ 12 files changed, 653 insertions(+), 384 deletions(-) create mode 100644 test/syscalls/linux/raw_socket_icmp.cc (limited to 'pkg/tcpip/stack') diff --git a/pkg/sentry/socket/epsocket/provider.go b/pkg/sentry/socket/epsocket/provider.go index 5a89a63fb..fb1815c2d 100644 --- a/pkg/sentry/socket/epsocket/provider.go +++ b/pkg/sentry/socket/epsocket/provider.go @@ -70,6 +70,10 @@ func getTransportProtocol(ctx context.Context, stype transport.SockType, protoco switch protocol { case syscall.IPPROTO_ICMP: return header.ICMPv4ProtocolNumber, nil + case syscall.IPPROTO_UDP: + return header.UDPProtocolNumber, nil + case syscall.IPPROTO_TCP: + return header.TCPProtocolNumber, nil } } return 0, syserr.ErrInvalidArgument diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index a4117d98e..50d35de88 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -593,6 +593,14 @@ func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolN } transProto := state.proto + + // Raw socket packets are delivered based solely on the transport + // protocol number. We do not inspect the payload to ensure it's + // validly formed. + if !n.demux.deliverRawPacket(r, protocol, netHeader, vv) { + n.stack.demux.deliverRawPacket(r, protocol, netHeader, vv) + } + if len(vv.First()) < transProto.MinimumPacketSize() { n.stack.stats.MalformedRcvdPackets.Increment() return diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index 807c3ba5e..605bfadeb 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -286,20 +286,10 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto destEps = append(destEps, ep) } - // As in net/ipv4/ip_input.c:ip_local_deliver, attempt to deliver via - // raw endpoint first. If there are multipe raw endpoints, they all - // receive the packet. - foundRaw := false - for _, rawEP := range eps.rawEndpoints { - // Each endpoint gets its own copy of the packet for the sake - // of save/restore. - rawEP.HandlePacket(r, buffer.NewViewFromBytes(netHeader), vv.ToView().ToVectorisedView()) - foundRaw = true - } eps.mu.RUnlock() // Fail if we didn't find at least one matching transport endpoint. - if len(destEps) == 0 && !foundRaw { + if len(destEps) == 0 { // UDP packet could not be delivered to an unknown destination port. if protocol == header.UDPProtocolNumber { r.Stats().UDP.UnknownPortErrors.Increment() @@ -315,6 +305,30 @@ func (d *transportDemuxer) deliverPacket(r *Route, protocol tcpip.TransportProto return true } +// deliverRawPacket attempts to deliver the given packet and returns whether it +// was delivered successfully. +func (d *transportDemuxer) deliverRawPacket(r *Route, protocol tcpip.TransportProtocolNumber, netHeader buffer.View, vv buffer.VectorisedView) bool { + eps, ok := d.protocol[protocolIDs{r.NetProto, protocol}] + if !ok { + return false + } + + // As in net/ipv4/ip_input.c:ip_local_deliver, attempt to deliver via + // raw endpoint first. If there are multiple raw endpoints, they all + // receive the packet. + foundRaw := false + eps.mu.RLock() + for _, rawEP := range eps.rawEndpoints { + // Each endpoint gets its own copy of the packet for the sake + // of save/restore. + rawEP.HandlePacket(r, buffer.NewViewFromBytes(netHeader), vv.ToView().ToVectorisedView()) + foundRaw = true + } + eps.mu.RUnlock() + + return foundRaw +} + // deliverControlPacket attempts to deliver the given control packet. Returns // true if it found an endpoint, false otherwise. func (d *transportDemuxer) deliverControlPacket(net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv buffer.VectorisedView, id TransportEndpointID) bool { diff --git a/pkg/tcpip/transport/raw/endpoint.go b/pkg/tcpip/transport/raw/endpoint.go index 1a16a3607..e7b383ad5 100644 --- a/pkg/tcpip/transport/raw/endpoint.go +++ b/pkg/tcpip/transport/raw/endpoint.go @@ -280,7 +280,7 @@ func (ep *endpoint) finishWrite(payload tcpip.Payload, route *stack.Route) (uint switch ep.netProto { case header.IPv4ProtocolNumber: hdr := buffer.NewPrependable(len(payloadBytes) + int(route.MaxHeaderLength())) - if err := route.WritePacket(nil /* gso */, hdr, buffer.View(payloadBytes).ToVectorisedView(), header.ICMPv4ProtocolNumber, route.DefaultTTL()); err != nil { + if err := route.WritePacket(nil /* gso */, hdr, buffer.View(payloadBytes).ToVectorisedView(), ep.transProto, route.DefaultTTL()); err != nil { return 0, nil, err } diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index d44d63e95..e31b03f7d 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -49,6 +49,7 @@ go_library( "//pkg/tcpip/header", "//pkg/tcpip/seqnum", "//pkg/tcpip/stack", + "//pkg/tcpip/transport/raw", "//pkg/tmutex", "//pkg/waiter", "@com_github_google_btree//:go_default_library", diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index b86473891..d31a1edcb 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -29,6 +29,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/raw" "gvisor.googlesource.com/gvisor/pkg/waiter" ) @@ -104,7 +105,7 @@ func (*protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolN // NewRawEndpoint creates a new raw TCP endpoint. Raw TCP sockets are currently // unsupported. It implements stack.TransportProtocol.NewRawEndpoint. func (p *protocol) NewRawEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { - return nil, tcpip.ErrUnknownProtocol + return raw.NewEndpoint(stack, netProto, header.TCPProtocolNumber, waiterQueue) } // MinimumPacketSize returns the minimum valid tcp packet size. diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 361132a25..b9520d6e0 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -28,12 +28,12 @@ go_library( imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ - "//pkg/log", "//pkg/sleep", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/stack", + "//pkg/tcpip/transport/raw", "//pkg/waiter", ], ) diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 0ed0902b0..d9ca097c9 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -51,6 +51,8 @@ const ( // have concurrent goroutines make calls into the endpoint, they are properly // synchronized. // +// It implements tcpip.Endpoint. +// // +stateify savable type endpoint struct { // The following fields are initialized at creation time and do not diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index 8b47cce17..3d31dfbf1 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -25,6 +25,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/raw" "gvisor.googlesource.com/gvisor/pkg/waiter" ) @@ -48,10 +49,10 @@ func (*protocol) NewEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolN return newEndpoint(stack, netProto, waiterQueue), nil } -// NewRawEndpoint creates a new raw UDP endpoint. Raw UDP sockets are currently -// unsupported. It implements stack.TransportProtocol.NewRawEndpoint. +// NewRawEndpoint creates a new raw UDP endpoint. It implements +// stack.TransportProtocol.NewRawEndpoint. func (p *protocol) NewRawEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error) { - return nil, tcpip.ErrUnknownProtocol + return raw.NewEndpoint(stack, netProto, header.UDPProtocolNumber, waiterQueue) } // MinimumPacketSize returns the minimum valid udp packet size. diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 4e239617b..e8caf31fc 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1545,6 +1545,24 @@ cc_binary( linkstatic = 1, deps = [ ":socket_test_util", + ":unix_domain_socket_test_util", + "//test/util:capability_util", + "//test/util:file_descriptor", + "//test/util:test_main", + "//test/util:test_util", + "@com_google_absl//absl/base:core_headers", + "@com_google_googletest//:gtest", + ], +) + +cc_binary( + name = "raw_socket_icmp_test", + testonly = 1, + srcs = ["raw_socket_icmp.cc"], + linkstatic = 1, + deps = [ + ":socket_test_util", + ":unix_domain_socket_test_util", "//test/util:capability_util", "//test/util:file_descriptor", "//test/util:test_main", diff --git a/test/syscalls/linux/raw_socket_icmp.cc b/test/syscalls/linux/raw_socket_icmp.cc new file mode 100644 index 000000000..24d9dc79a --- /dev/null +++ b/test/syscalls/linux/raw_socket_icmp.cc @@ -0,0 +1,453 @@ +// Copyright 2019 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. + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "gtest/gtest.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/syscalls/linux/unix_domain_socket_test_util.h" +#include "test/util/capability_util.h" +#include "test/util/file_descriptor.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +namespace { + +// Compute the internet checksum of the ICMP header (assuming no payload). +static uint16_t Checksum(struct icmphdr* icmp) { + uint32_t total = 0; + uint16_t* num = reinterpret_cast(icmp); + + // This is just the ICMP header, so there's an even number of bytes. + static_assert( + sizeof(*icmp) % sizeof(*num) == 0, + "sizeof(struct icmphdr) is not an integer multiple of sizeof(uint16_t)"); + for (unsigned int i = 0; i < sizeof(*icmp); i += sizeof(*num)) { + total += *num; + num++; + } + + // Combine the upper and lower 16 bits. This happens twice in case the first + // combination causes a carry. + unsigned short upper = total >> 16; + unsigned short lower = total & 0xffff; + total = upper + lower; + upper = total >> 16; + lower = total & 0xffff; + total = upper + lower; + + return ~total; +} + +// The size of an empty ICMP packet and IP header together. +constexpr size_t kEmptyICMPSize = 28; + +// ICMP raw sockets get their own special tests because Linux automatically +// responds to ICMP echo requests, and thus a single echo request sent via +// loopback leads to 2 received ICMP packets. + +class RawSocketICMPTest : public ::testing::Test { + protected: + // Creates a socket to be used in tests. + void SetUp() override; + + // Closes the socket created by SetUp(). + void TearDown() override; + + // Checks that both an ICMP echo request and reply are received. Calls should + // be wrapped in ASSERT_NO_FATAL_FAILURE. + void ExpectICMPSuccess(const struct icmphdr& icmp); + + // Sends icmp via s_. + void SendEmptyICMP(const struct icmphdr& icmp); + + // Sends icmp via s_ to the given address. + void SendEmptyICMPTo(int sock, const struct sockaddr_in& addr, + const struct icmphdr& icmp); + + // Reads from s_ into recv_buf. + void ReceiveICMP(char* recv_buf, size_t recv_buf_len, size_t expected_size, + struct sockaddr_in* src); + + // Reads from sock into recv_buf. + void ReceiveICMPFrom(char* recv_buf, size_t recv_buf_len, + size_t expected_size, struct sockaddr_in* src, int sock); + + // The socket used for both reading and writing. + int s_; + + // The loopback address. + struct sockaddr_in addr_; +}; + +void RawSocketICMPTest::SetUp() { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT(s_ = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), SyscallSucceeds()); + + addr_ = {}; + + // "On raw sockets sin_port is set to the IP protocol." - ip(7). + addr_.sin_port = IPPROTO_IP; + addr_.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr_.sin_family = AF_INET; +} + +void RawSocketICMPTest::TearDown() { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + EXPECT_THAT(close(s_), SyscallSucceeds()); +} + +// We'll only read an echo in this case, as the kernel won't respond to the +// malformed ICMP checksum. +TEST_F(RawSocketICMPTest, SendAndReceiveBadChecksum) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 0; + icmp.un.echo.sequence = 2012; + icmp.un.echo.id = 2014; + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + + // Veryify that we get the echo, then that there's nothing else to read. + char recv_buf[kEmptyICMPSize]; + struct sockaddr_in src; + ASSERT_NO_FATAL_FAILURE( + ReceiveICMP(recv_buf, sizeof(recv_buf), sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); + // The packet should be identical to what we sent. + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &icmp, sizeof(icmp)), 0); + + // And there should be nothing left to read. + EXPECT_THAT(RetryEINTR(recv)(s_, recv_buf, sizeof(recv_buf), MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} +// +// Send and receive an ICMP packet. +TEST_F(RawSocketICMPTest, SendAndReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + // Prepare and send an ICMP packet. Use arbitrary junk for sequence and ID. + // None of that should matter for raw sockets - the kernel should still give + // us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 0; + icmp.un.echo.sequence = 2012; + icmp.un.echo.id = 2014; + icmp.checksum = Checksum(&icmp); + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + + ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); +} + +// We should be able to create multiple raw sockets for the same protocol and +// receive the same packet on both. +TEST_F(RawSocketICMPTest, MultipleSocketReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + FileDescriptor s2 = + ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)); + + // Prepare and send an ICMP packet. Use arbitrary junk for sequence and ID. + // None of that should matter for raw sockets - the kernel should still give + // us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 0; + icmp.un.echo.sequence = 2016; + icmp.un.echo.id = 2018; + icmp.checksum = Checksum(&icmp); + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + + // Both sockets will receive the echo request and reply in indeterminate + // order, so we'll need to read 2 packets from each. + + // Receive on socket 1. + constexpr int kBufSize = kEmptyICMPSize; + std::vector recv_buf1(2); + struct sockaddr_in src; + for (int i = 0; i < 2; i++) { + ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf1[i], + ABSL_ARRAYSIZE(recv_buf1[i]), + sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); + } + + // Receive on socket 2. + std::vector recv_buf2(2); + for (int i = 0; i < 2; i++) { + ASSERT_NO_FATAL_FAILURE( + ReceiveICMPFrom(recv_buf2[i], ABSL_ARRAYSIZE(recv_buf2[i]), + sizeof(struct icmphdr), &src, s2.get())); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); + } + + // Ensure both sockets receive identical packets. + int types[] = {ICMP_ECHO, ICMP_ECHOREPLY}; + for (int type : types) { + auto match_type = [=](char buf[kBufSize]) { + struct icmphdr* icmp = + reinterpret_cast(buf + sizeof(struct iphdr)); + return icmp->type == type; + }; + const char* icmp1 = + *std::find_if(recv_buf1.begin(), recv_buf1.end(), match_type); + const char* icmp2 = + *std::find_if(recv_buf2.begin(), recv_buf2.end(), match_type); + ASSERT_NE(icmp1, *recv_buf1.end()); + ASSERT_NE(icmp2, *recv_buf2.end()); + EXPECT_EQ(memcmp(icmp1 + sizeof(struct iphdr), icmp2 + sizeof(struct iphdr), + sizeof(icmp)), + 0); + } +} + +// A raw ICMP socket and ping socket should both receive the ICMP packets +// indended for the ping socket. +TEST_F(RawSocketICMPTest, RawAndPingSockets) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + FileDescriptor ping_sock = + ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)); + + // Ping sockets take care of the ICMP ID and checksum. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.un.echo.sequence = *static_cast(&icmp.un.echo.sequence); + ASSERT_THAT(RetryEINTR(sendto)(ping_sock.get(), &icmp, sizeof(icmp), 0, + reinterpret_cast(&addr_), + sizeof(addr_)), + SyscallSucceedsWithValue(sizeof(icmp))); + + // Receive on socket 1, which receives the echo request and reply in + // indeterminate order. + constexpr int kBufSize = kEmptyICMPSize; + std::vector recv_buf1(2); + struct sockaddr_in src; + for (int i = 0; i < 2; i++) { + ASSERT_NO_FATAL_FAILURE( + ReceiveICMP(recv_buf1[i], kBufSize, sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); + } + + // Receive on socket 2. Ping sockets only get the echo reply, not the initial + // echo. + char ping_recv_buf[kBufSize]; + ASSERT_THAT(RetryEINTR(recv)(ping_sock.get(), ping_recv_buf, kBufSize, 0), + SyscallSucceedsWithValue(sizeof(struct icmphdr))); + + // Ensure both sockets receive identical echo reply packets. + auto match_type_raw = [=](char buf[kBufSize]) { + struct icmphdr* icmp = + reinterpret_cast(buf + sizeof(struct iphdr)); + return icmp->type == ICMP_ECHOREPLY; + }; + char* raw_reply = + *std::find_if(recv_buf1.begin(), recv_buf1.end(), match_type_raw); + ASSERT_NE(raw_reply, *recv_buf1.end()); + EXPECT_EQ( + memcmp(raw_reply + sizeof(struct iphdr), ping_recv_buf, sizeof(icmp)), 0); +} + +// Test that connect() sends packets to the right place. +TEST_F(RawSocketICMPTest, SendAndReceiveViaConnect) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + + // Prepare and send an ICMP packet. Use arbitrary junk for sequence and ID. + // None of that should matter for raw sockets - the kernel should still give + // us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 0; + icmp.un.echo.sequence = 2003; + icmp.un.echo.id = 2004; + icmp.checksum = Checksum(&icmp); + ASSERT_THAT(send(s_, &icmp, sizeof(icmp), 0), + SyscallSucceedsWithValue(sizeof(icmp))); + + ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); +} + +// Bind to localhost, then send and receive packets. +TEST_F(RawSocketICMPTest, BindSendAndReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + bind(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 0; + icmp.un.echo.sequence = 2004; + icmp.un.echo.id = 2007; + icmp.checksum = Checksum(&icmp); + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + + ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); +} + +// Bind and connect to localhost and send/receive packets. +TEST_F(RawSocketICMPTest, BindConnectSendAndReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + bind(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + + // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, + // and ID. None of that should matter for raw sockets - the kernel should + // still give us the packet. + struct icmphdr icmp; + icmp.type = ICMP_ECHO; + icmp.code = 0; + icmp.checksum = 0; + icmp.un.echo.sequence = 2010; + icmp.un.echo.id = 7; + icmp.checksum = Checksum(&icmp); + ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + + ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); +} + +void RawSocketICMPTest::ExpectICMPSuccess(const struct icmphdr& icmp) { + // We're going to receive both the echo request and reply, but the order is + // indeterminate. + char recv_buf[kEmptyICMPSize]; + struct sockaddr_in src; + bool received_request = false; + bool received_reply = false; + + for (int i = 0; i < 2; i++) { + // Receive the packet. + ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf, ABSL_ARRAYSIZE(recv_buf), + sizeof(struct icmphdr), &src)); + EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); + struct icmphdr* recvd_icmp = + reinterpret_cast(recv_buf + sizeof(struct iphdr)); + switch (recvd_icmp->type) { + case ICMP_ECHO: + EXPECT_FALSE(received_request); + received_request = true; + // The packet should be identical to what we sent. + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &icmp, sizeof(icmp)), + 0); + break; + + case ICMP_ECHOREPLY: + EXPECT_FALSE(received_reply); + received_reply = true; + // Most fields should be the same. + EXPECT_EQ(recvd_icmp->code, icmp.code); + EXPECT_EQ(recvd_icmp->un.echo.sequence, icmp.un.echo.sequence); + EXPECT_EQ(recvd_icmp->un.echo.id, icmp.un.echo.id); + // A couple are different. + EXPECT_EQ(recvd_icmp->type, ICMP_ECHOREPLY); + // The checksum is computed in such a way that it is guaranteed to have + // changed. + EXPECT_NE(recvd_icmp->checksum, icmp.checksum); + break; + } + } + + ASSERT_TRUE(received_request); + ASSERT_TRUE(received_reply); +} + +void RawSocketICMPTest::SendEmptyICMP(const struct icmphdr& icmp) { + ASSERT_NO_FATAL_FAILURE(SendEmptyICMPTo(s_, addr_, icmp)); +} + +void RawSocketICMPTest::SendEmptyICMPTo(int sock, + const struct sockaddr_in& addr, + const struct icmphdr& icmp) { + // It's safe to use const_cast here because sendmsg won't modify the iovec or + // address. + struct iovec iov = {}; + iov.iov_base = static_cast(const_cast(&icmp)); + iov.iov_len = sizeof(icmp); + struct msghdr msg = {}; + msg.msg_name = static_cast(const_cast(&addr)); + msg.msg_namelen = sizeof(addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + ASSERT_THAT(sendmsg(sock, &msg, 0), SyscallSucceedsWithValue(sizeof(icmp))); +} + +void RawSocketICMPTest::ReceiveICMP(char* recv_buf, size_t recv_buf_len, + size_t expected_size, + struct sockaddr_in* src) { + ASSERT_NO_FATAL_FAILURE( + ReceiveICMPFrom(recv_buf, recv_buf_len, expected_size, src, s_)); +} + +void RawSocketICMPTest::ReceiveICMPFrom(char* recv_buf, size_t recv_buf_len, + size_t expected_size, + struct sockaddr_in* src, int sock) { + struct iovec iov = {}; + iov.iov_base = recv_buf; + iov.iov_len = recv_buf_len; + struct msghdr msg = {}; + msg.msg_name = src; + msg.msg_namelen = sizeof(*src); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + // We should receive the ICMP packet plus 20 bytes of IP header. + ASSERT_THAT(recvmsg(sock, &msg, 0), + SyscallSucceedsWithValue(expected_size + sizeof(struct iphdr))); +} + +} // namespace + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/raw_socket_ipv4.cc b/test/syscalls/linux/raw_socket_ipv4.cc index 7c7779f3e..352037c88 100644 --- a/test/syscalls/linux/raw_socket_ipv4.cc +++ b/test/syscalls/linux/raw_socket_ipv4.cc @@ -25,6 +25,7 @@ #include "gtest/gtest.h" #include "test/syscalls/linux/socket_test_util.h" +#include "test/syscalls/linux/unix_domain_socket_test_util.h" #include "test/util/capability_util.h" #include "test/util/file_descriptor.h" #include "test/util/test_util.h" @@ -37,8 +38,8 @@ namespace testing { namespace { -// Fixture for tests parameterized by address family (currently only AF_INET). -class RawSocketTest : public ::testing::Test { +// Fixture for tests parameterized by protocol. +class RawSocketTest : public ::testing::TestWithParam { protected: // Creates a socket to be used in tests. void SetUp() override; @@ -46,23 +47,17 @@ class RawSocketTest : public ::testing::Test { // Closes the socket created by SetUp(). void TearDown() override; - // Checks that both an ICMP echo request and reply are received. Calls should - // be wrapped in ASSERT_NO_FATAL_FAILURE. - void ExpectICMPSuccess(const struct icmphdr& icmp); + // Sends buf via s_. + void SendBuf(const char* buf, int buf_len); - void SendEmptyICMP(const struct icmphdr& icmp); + // Sends buf to the provided address via the provided socket. + void SendBufTo(int sock, const struct sockaddr_in& addr, const char* buf, + int buf_len); - void SendEmptyICMPTo(int sock, struct sockaddr_in* addr, - const struct icmphdr& icmp); + // Reads from s_ into recv_buf. + void ReceiveBuf(char* recv_buf, size_t recv_buf_len); - void ReceiveICMP(char* recv_buf, size_t recv_buf_len, size_t expected_size, - struct sockaddr_in* src); - - void ReceiveICMPFrom(char* recv_buf, size_t recv_buf_len, - size_t expected_size, struct sockaddr_in* src, int sock); - - // Compute the internet checksum of the ICMP header (assuming no payload). - unsigned short Checksum(struct icmphdr* icmp); + int Protocol() { return GetParam(); } // The socket used for both reading and writing. int s_; @@ -74,7 +69,7 @@ class RawSocketTest : public ::testing::Test { void RawSocketTest::SetUp() { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); - ASSERT_THAT(s_ = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), SyscallSucceeds()); + ASSERT_THAT(s_ = socket(AF_INET, SOCK_RAW, Protocol()), SyscallSucceeds()); addr_ = {}; @@ -92,177 +87,17 @@ void RawSocketTest::TearDown() { // We should be able to create multiple raw sockets for the same protocol. // BasicRawSocket::Setup creates the first one, so we only have to create one // more here. -TEST_F(RawSocketTest, MultipleCreation) { +TEST_P(RawSocketTest, MultipleCreation) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); int s2; - ASSERT_THAT(s2 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), SyscallSucceeds()); + ASSERT_THAT(s2 = socket(AF_INET, SOCK_RAW, Protocol()), SyscallSucceeds()); ASSERT_THAT(close(s2), SyscallSucceeds()); } -// We'll only read an echo in this case, as the kernel won't respond to the -// malformed ICMP checksum. -TEST_F(RawSocketTest, SendAndReceiveBadChecksum) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); - - // Prepare and send an ICMP packet. Use arbitrary junk for checksum, sequence, - // and ID. None of that should matter for raw sockets - the kernel should - // still give us the packet. - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.checksum = 0; - icmp.un.echo.sequence = 2012; - icmp.un.echo.id = 2014; - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); - - // Veryify that we get the echo, then that there's nothing else to read. - char recv_buf[sizeof(icmp) + sizeof(struct iphdr)]; - struct sockaddr_in src; - ASSERT_NO_FATAL_FAILURE( - ReceiveICMP(recv_buf, sizeof(recv_buf), sizeof(struct icmphdr), &src)); - EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); - // The packet should be identical to what we sent. - EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &icmp, sizeof(icmp)), 0); - - // And there should be nothing left to read. - EXPECT_THAT(RetryEINTR(recv)(s_, recv_buf, sizeof(recv_buf), MSG_DONTWAIT), - SyscallFailsWithErrno(EAGAIN)); -} - -// Send and receive an ICMP packet. -TEST_F(RawSocketTest, SendAndReceive) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); - - // Prepare and send an ICMP packet. Use arbitrary junk for sequence and ID. - // None of that should matter for raw sockets - the kernel should still give - // us the packet. - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.checksum = 0; - icmp.un.echo.sequence = 2012; - icmp.un.echo.id = 2014; - icmp.checksum = Checksum(&icmp); - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); - - ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); -} - -// We should be able to create multiple raw sockets for the same protocol and -// receive the same packet on both. -TEST_F(RawSocketTest, MultipleSocketReceive) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); - - FileDescriptor s2 = - ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)); - - // Prepare and send an ICMP packet. Use arbitrary junk for sequence and ID. - // None of that should matter for raw sockets - the kernel should still give - // us the packet. - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.checksum = 0; - icmp.un.echo.sequence = 2016; - icmp.un.echo.id = 2018; - icmp.checksum = Checksum(&icmp); - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); - - // Both sockets will receive the echo request and reply in indeterminate - // order, so we'll need to read 2 packets from each. - - // Receive on socket 1. - constexpr int kBufSize = sizeof(icmp) + sizeof(struct iphdr); - std::array recv_buf1; - struct sockaddr_in src; - for (int i = 0; i < 2; i++) { - ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf1[i], - ABSL_ARRAYSIZE(recv_buf1[i]), - sizeof(struct icmphdr), &src)); - EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); - } - - // Receive on socket 2. - std::array recv_buf2; - for (int i = 0; i < 2; i++) { - ASSERT_NO_FATAL_FAILURE( - ReceiveICMPFrom(recv_buf2[i], ABSL_ARRAYSIZE(recv_buf2[i]), - sizeof(struct icmphdr), &src, s2.get())); - EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); - } - - // Ensure both sockets receive identical packets. - int types[] = {ICMP_ECHO, ICMP_ECHOREPLY}; - for (int type : types) { - auto match_type = [=](char buf[kBufSize]) { - struct icmphdr* icmp = - reinterpret_cast(buf + sizeof(struct iphdr)); - return icmp->type == type; - }; - const char* icmp1 = - *std::find_if(recv_buf1.begin(), recv_buf1.end(), match_type); - const char* icmp2 = - *std::find_if(recv_buf2.begin(), recv_buf2.end(), match_type); - ASSERT_NE(icmp1, *recv_buf1.end()); - ASSERT_NE(icmp2, *recv_buf2.end()); - EXPECT_EQ(memcmp(icmp1 + sizeof(struct iphdr), icmp2 + sizeof(struct iphdr), - sizeof(icmp)), - 0); - } -} - -// A raw ICMP socket and ping socket should both receive the ICMP packets -// indended for the ping socket. -TEST_F(RawSocketTest, RawAndPingSockets) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); - - FileDescriptor ping_sock = - ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)); - - // Ping sockets take care of the ICMP ID and checksum. - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.un.echo.sequence = *static_cast(&icmp.un.echo.sequence); - ASSERT_THAT(RetryEINTR(sendto)(ping_sock.get(), &icmp, sizeof(icmp), 0, - reinterpret_cast(&addr_), - sizeof(addr_)), - SyscallSucceedsWithValue(sizeof(icmp))); - - // Receive on socket 1, which receives the echo request and reply in - // indeterminate order. - constexpr int kBufSize = sizeof(icmp) + sizeof(struct iphdr); - std::array recv_buf1; - struct sockaddr_in src; - for (int i = 0; i < 2; i++) { - ASSERT_NO_FATAL_FAILURE( - ReceiveICMP(recv_buf1[i], kBufSize, sizeof(struct icmphdr), &src)); - EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); - } - - // Receive on socket 2. Ping sockets only get the echo reply, not the initial - // echo. - char ping_recv_buf[kBufSize]; - ASSERT_THAT(RetryEINTR(recv)(ping_sock.get(), ping_recv_buf, kBufSize, 0), - SyscallSucceedsWithValue(sizeof(struct icmphdr))); - - // Ensure both sockets receive identical echo reply packets. - auto match_type_raw = [=](char buf[kBufSize]) { - struct icmphdr* icmp = - reinterpret_cast(buf + sizeof(struct iphdr)); - return icmp->type == ICMP_ECHOREPLY; - }; - char* raw_reply = - *std::find_if(recv_buf1.begin(), recv_buf1.end(), match_type_raw); - ASSERT_NE(raw_reply, *recv_buf1.end()); - EXPECT_EQ( - memcmp(raw_reply + sizeof(struct iphdr), ping_recv_buf, sizeof(icmp)), 0); -} - // Test that shutting down an unconnected socket fails. -TEST_F(RawSocketTest, FailShutdownWithoutConnect) { +TEST_P(RawSocketTest, FailShutdownWithoutConnect) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT(shutdown(s_, SHUT_WR), SyscallFailsWithErrno(ENOTCONN)); @@ -270,7 +105,7 @@ TEST_F(RawSocketTest, FailShutdownWithoutConnect) { } // Shutdown is a no-op for raw sockets (and datagram sockets in general). -TEST_F(RawSocketTest, ShutdownWriteNoop) { +TEST_P(RawSocketTest, ShutdownWriteNoop) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT( @@ -278,13 +113,14 @@ TEST_F(RawSocketTest, ShutdownWriteNoop) { SyscallSucceeds()); ASSERT_THAT(shutdown(s_, SHUT_WR), SyscallSucceeds()); + // Arbitrary. constexpr char kBuf[] = "noop"; ASSERT_THAT(RetryEINTR(write)(s_, kBuf, sizeof(kBuf)), SyscallSucceedsWithValue(sizeof(kBuf))); } // Shutdown is a no-op for raw sockets (and datagram sockets in general). -TEST_F(RawSocketTest, ShutdownReadNoop) { +TEST_P(RawSocketTest, ShutdownReadNoop) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT( @@ -292,29 +128,24 @@ TEST_F(RawSocketTest, ShutdownReadNoop) { SyscallSucceeds()); ASSERT_THAT(shutdown(s_, SHUT_RD), SyscallSucceeds()); - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.checksum = 0; - icmp.un.echo.sequence = 2012; - icmp.un.echo.id = 2014; - icmp.checksum = Checksum(&icmp); - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); - - char c[sizeof(icmp) + sizeof(struct iphdr)]; - ASSERT_THAT(read(s_, &c, sizeof(c)), - SyscallSucceedsWithValue(sizeof(icmp) + sizeof(struct iphdr))); + // Arbitrary. + constexpr char kBuf[] = "gdg"; + ASSERT_NO_FATAL_FAILURE(SendBuf(kBuf, sizeof(kBuf))); + + constexpr size_t kReadSize = sizeof(kBuf) + sizeof(struct iphdr); + char c[kReadSize]; + ASSERT_THAT(read(s_, &c, sizeof(c)), SyscallSucceedsWithValue(kReadSize)); } // Test that listen() fails. -TEST_F(RawSocketTest, FailListen) { +TEST_P(RawSocketTest, FailListen) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT(listen(s_, 1), SyscallFailsWithErrno(ENOTSUP)); } // Test that accept() fails. -TEST_F(RawSocketTest, FailAccept) { +TEST_P(RawSocketTest, FailAccept) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); struct sockaddr saddr; @@ -323,7 +154,7 @@ TEST_F(RawSocketTest, FailAccept) { } // Test that getpeername() returns nothing before connect(). -TEST_F(RawSocketTest, FailGetPeerNameBeforeConnect) { +TEST_P(RawSocketTest, FailGetPeerNameBeforeConnect) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); struct sockaddr saddr; @@ -333,7 +164,7 @@ TEST_F(RawSocketTest, FailGetPeerNameBeforeConnect) { } // Test that getpeername() returns something after connect(). -TEST_F(RawSocketTest, GetPeerName) { +TEST_P(RawSocketTest, GetPeerName) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT( @@ -347,7 +178,7 @@ TEST_F(RawSocketTest, GetPeerName) { } // Test that the socket is writable immediately. -TEST_F(RawSocketTest, PollWritableImmediately) { +TEST_P(RawSocketTest, PollWritableImmediately) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); struct pollfd pfd = {}; @@ -357,7 +188,7 @@ TEST_F(RawSocketTest, PollWritableImmediately) { } // Test that the socket isn't readable before receiving anything. -TEST_F(RawSocketTest, PollNotReadableInitially) { +TEST_P(RawSocketTest, PollNotReadableInitially) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); // Try to receive data with MSG_DONTWAIT, which returns immediately if there's @@ -368,12 +199,13 @@ TEST_F(RawSocketTest, PollNotReadableInitially) { } // Test that the socket becomes readable once something is written to it. -TEST_F(RawSocketTest, PollTriggeredOnWrite) { +TEST_P(RawSocketTest, PollTriggeredOnWrite) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); // Write something so that there's data to be read. - struct icmphdr icmp = {}; - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); + // Arbitrary. + constexpr char kBuf[] = "JP5"; + ASSERT_NO_FATAL_FAILURE(SendBuf(kBuf, sizeof(kBuf))); struct pollfd pfd = {}; pfd.fd = s_; @@ -382,7 +214,7 @@ TEST_F(RawSocketTest, PollTriggeredOnWrite) { } // Test that we can connect() to a valid IP (loopback). -TEST_F(RawSocketTest, ConnectToLoopback) { +TEST_P(RawSocketTest, ConnectToLoopback) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT( @@ -390,50 +222,18 @@ TEST_F(RawSocketTest, ConnectToLoopback) { SyscallSucceeds()); } -// Test that connect() sends packets to the right place. -TEST_F(RawSocketTest, SendAndReceiveViaConnect) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); - - ASSERT_THAT( - connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), - SyscallSucceeds()); - - // Prepare and send an ICMP packet. Use arbitrary junk for sequence and ID. - // None of that should matter for raw sockets - the kernel should still give - // us the packet. - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.checksum = 0; - icmp.un.echo.sequence = 2003; - icmp.un.echo.id = 2004; - icmp.checksum = Checksum(&icmp); - ASSERT_THAT(send(s_, &icmp, sizeof(icmp), 0), - SyscallSucceedsWithValue(sizeof(icmp))); - - ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); -} - // Test that calling send() without connect() fails. -TEST_F(RawSocketTest, SendWithoutConnectFails) { +TEST_P(RawSocketTest, SendWithoutConnectFails) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); - // Prepare and send an ICMP packet. Use arbitrary junk for sequence and ID. - // None of that should matter for raw sockets - the kernel should still give - // us the packet. - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.checksum = 0; - icmp.un.echo.sequence = 2017; - icmp.un.echo.id = 2019; - icmp.checksum = Checksum(&icmp); - ASSERT_THAT(send(s_, &icmp, sizeof(icmp), 0), + // Arbitrary. + constexpr char kBuf[] = "Endgame was good"; + ASSERT_THAT(send(s_, kBuf, sizeof(kBuf), 0), SyscallFailsWithErrno(EDESTADDRREQ)); } // Bind to localhost. -TEST_F(RawSocketTest, BindToLocalhost) { +TEST_P(RawSocketTest, BindToLocalhost) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT( @@ -442,7 +242,7 @@ TEST_F(RawSocketTest, BindToLocalhost) { } // Bind to a different address. -TEST_F(RawSocketTest, BindToInvalid) { +TEST_P(RawSocketTest, BindToInvalid) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); struct sockaddr_in bind_addr = {}; @@ -453,31 +253,86 @@ TEST_F(RawSocketTest, BindToInvalid) { SyscallFailsWithErrno(EADDRNOTAVAIL)); } +// Send and receive an packet. +TEST_P(RawSocketTest, SendAndReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + // Arbitrary. + constexpr char kBuf[] = "TB12"; + ASSERT_NO_FATAL_FAILURE(SendBuf(kBuf, sizeof(kBuf))); + + // Receive the packet and make sure it's identical. + char recv_buf[sizeof(kBuf) + sizeof(struct iphdr)]; + ASSERT_NO_FATAL_FAILURE(ReceiveBuf(recv_buf, sizeof(recv_buf))); + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), kBuf, sizeof(kBuf)), 0); +} + +// We should be able to create multiple raw sockets for the same protocol and +// receive the same packet on both. +TEST_P(RawSocketTest, MultipleSocketReceive) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + int s2; + ASSERT_THAT(s2 = socket(AF_INET, SOCK_RAW, Protocol()), SyscallSucceeds()); + + // Arbitrary. + constexpr char kBuf[] = "TB10"; + ASSERT_NO_FATAL_FAILURE(SendBuf(kBuf, sizeof(kBuf))); + + // Receive it on socket 1. + char recv_buf1[sizeof(kBuf) + sizeof(struct iphdr)]; + ASSERT_NO_FATAL_FAILURE(ReceiveBuf(recv_buf1, sizeof(recv_buf1))); + + // Receive it on socket 2. + char recv_buf2[sizeof(kBuf) + sizeof(struct iphdr)]; + ASSERT_NO_FATAL_FAILURE(RecvNoCmsg(s2, recv_buf2, sizeof(recv_buf2))); + + EXPECT_EQ(memcmp(recv_buf1 + sizeof(struct iphdr), + recv_buf2 + sizeof(struct iphdr), sizeof(kBuf)), + 0); + + ASSERT_THAT(close(s2), SyscallSucceeds()); +} + +// Test that connect sends packets to the right place. +TEST_P(RawSocketTest, SendAndReceiveViaConnect) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + ASSERT_THAT( + connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), + SyscallSucceeds()); + + // Arbitrary. + constexpr char kBuf[] = "JH4"; + ASSERT_THAT(send(s_, kBuf, sizeof(kBuf), 0), + SyscallSucceedsWithValue(sizeof(kBuf))); + + // Receive the packet and make sure it's identical. + char recv_buf[sizeof(kBuf) + sizeof(struct iphdr)]; + ASSERT_NO_FATAL_FAILURE(ReceiveBuf(recv_buf, sizeof(recv_buf))); + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), kBuf, sizeof(kBuf)), 0); +} + // Bind to localhost, then send and receive packets. -TEST_F(RawSocketTest, BindSendAndReceive) { +TEST_P(RawSocketTest, BindSendAndReceive) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT( bind(s_, reinterpret_cast(&addr_), sizeof(addr_)), SyscallSucceeds()); - // Prepare and send an ICMP packet. Use arbitrary junk for sequence and ID. - // None of that should matter for raw sockets - the kernel should still give - // us the packet. - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.checksum = 0; - icmp.un.echo.sequence = 2004; - icmp.un.echo.id = 2007; - icmp.checksum = Checksum(&icmp); - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); - - ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); + // Arbitrary. + constexpr char kBuf[] = "DR16"; + ASSERT_NO_FATAL_FAILURE(SendBuf(kBuf, sizeof(kBuf))); + + // Receive the packet and make sure it's identical. + char recv_buf[sizeof(kBuf) + sizeof(struct iphdr)]; + ASSERT_NO_FATAL_FAILURE(ReceiveBuf(recv_buf, sizeof(recv_buf))); + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), kBuf, sizeof(kBuf)), 0); } // Bind and connect to localhost and send/receive packets. -TEST_F(RawSocketTest, BindConnectSendAndReceive) { +TEST_P(RawSocketTest, BindConnectSendAndReceive) { SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); ASSERT_THAT( @@ -487,132 +342,44 @@ TEST_F(RawSocketTest, BindConnectSendAndReceive) { connect(s_, reinterpret_cast(&addr_), sizeof(addr_)), SyscallSucceeds()); - // Prepare and send an ICMP packet. Use arbitrary junk for sequence - // and ID. None of that should matter for raw sockets - the kernel should - // still give us the packet. - struct icmphdr icmp; - icmp.type = ICMP_ECHO; - icmp.code = 0; - icmp.checksum = 0; - icmp.un.echo.sequence = 2010; - icmp.un.echo.id = 7; - icmp.checksum = Checksum(&icmp); - ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(icmp)); - - ASSERT_NO_FATAL_FAILURE(ExpectICMPSuccess(icmp)); -} + // Arbitrary. + constexpr char kBuf[] = "DG88"; + ASSERT_NO_FATAL_FAILURE(SendBuf(kBuf, sizeof(kBuf))); -void RawSocketTest::ExpectICMPSuccess(const struct icmphdr& icmp) { - // We're going to receive both the echo request and reply, but the order is - // indeterminate. - char recv_buf[sizeof(icmp) + sizeof(struct iphdr)]; - struct sockaddr_in src; - bool received_request = false; - bool received_reply = false; - - for (int i = 0; i < 2; i++) { - // Receive the packet. - ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf, ABSL_ARRAYSIZE(recv_buf), - sizeof(struct icmphdr), &src)); - EXPECT_EQ(memcmp(&src, &addr_, sizeof(src)), 0); - struct icmphdr* recvd_icmp = - reinterpret_cast(recv_buf + sizeof(struct iphdr)); - switch (recvd_icmp->type) { - case ICMP_ECHO: - EXPECT_FALSE(received_request); - received_request = true; - // The packet should be identical to what we sent. - EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &icmp, sizeof(icmp)), - 0); - break; - - case ICMP_ECHOREPLY: - EXPECT_FALSE(received_reply); - received_reply = true; - // Most fields should be the same. - EXPECT_EQ(recvd_icmp->code, icmp.code); - EXPECT_EQ(recvd_icmp->un.echo.sequence, icmp.un.echo.sequence); - EXPECT_EQ(recvd_icmp->un.echo.id, icmp.un.echo.id); - // A couple are different. - EXPECT_EQ(recvd_icmp->type, ICMP_ECHOREPLY); - // The checksum is computed in such a way that it is guaranteed to have - // changed. - EXPECT_NE(recvd_icmp->checksum, icmp.checksum); - break; - } - } - - ASSERT_TRUE(received_request); - ASSERT_TRUE(received_reply); + // Receive the packet and make sure it's identical. + char recv_buf[sizeof(kBuf) + sizeof(struct iphdr)]; + ASSERT_NO_FATAL_FAILURE(ReceiveBuf(recv_buf, sizeof(recv_buf))); + EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), kBuf, sizeof(kBuf)), 0); } -void RawSocketTest::SendEmptyICMP(const struct icmphdr& icmp) { - ASSERT_NO_FATAL_FAILURE(SendEmptyICMPTo(s_, &addr_, icmp)); +void RawSocketTest::SendBuf(const char* buf, int buf_len) { + ASSERT_NO_FATAL_FAILURE(SendBufTo(s_, addr_, buf, buf_len)); } -void RawSocketTest::SendEmptyICMPTo(int sock, struct sockaddr_in* addr, - const struct icmphdr& icmp) { - // It's safe to use const_cast here because sendmsg won't modify the iovec. +void RawSocketTest::SendBufTo(int sock, const struct sockaddr_in& addr, + const char* buf, int buf_len) { + // It's safe to use const_cast here because sendmsg won't modify the iovec or + // address. struct iovec iov = {}; - iov.iov_base = static_cast(const_cast(&icmp)); - iov.iov_len = sizeof(icmp); + iov.iov_base = static_cast(const_cast(buf)); + iov.iov_len = static_cast(buf_len); struct msghdr msg = {}; - msg.msg_name = addr; - msg.msg_namelen = sizeof(*addr); + msg.msg_name = static_cast(const_cast(&addr)); + msg.msg_namelen = sizeof(addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; - ASSERT_THAT(sendmsg(sock, &msg, 0), SyscallSucceedsWithValue(sizeof(icmp))); -} - -unsigned short RawSocketTest::Checksum(struct icmphdr* icmp) { - unsigned int total = 0; - unsigned short* num = reinterpret_cast(icmp); - - // This is just the ICMP header, so there's an even number of bytes. - for (unsigned int i = 0; i < sizeof(*icmp); i += sizeof(*num)) { - total += *num; - num++; - } - - // Combine the upper and lower 16 bits. This happens twice in case the first - // combination causes a carry. - unsigned short upper = total >> 16; - unsigned short lower = total & 0xffff; - total = upper + lower; - upper = total >> 16; - lower = total & 0xffff; - total = upper + lower; - - return ~total; + ASSERT_THAT(sendmsg(sock, &msg, 0), SyscallSucceedsWithValue(buf_len)); } -void RawSocketTest::ReceiveICMP(char* recv_buf, size_t recv_buf_len, - size_t expected_size, struct sockaddr_in* src) { - ASSERT_NO_FATAL_FAILURE( - ReceiveICMPFrom(recv_buf, recv_buf_len, expected_size, src, s_)); +void RawSocketTest::ReceiveBuf(char* recv_buf, size_t recv_buf_len) { + ASSERT_NO_FATAL_FAILURE(RecvNoCmsg(s_, recv_buf, recv_buf_len)); } -void RawSocketTest::ReceiveICMPFrom(char* recv_buf, size_t recv_buf_len, - size_t expected_size, - struct sockaddr_in* src, int sock) { - struct iovec iov = {}; - iov.iov_base = recv_buf; - iov.iov_len = recv_buf_len; - struct msghdr msg = {}; - msg.msg_name = src; - msg.msg_namelen = sizeof(*src); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - // We should receive the ICMP packet plus 20 bytes of IP header. - ASSERT_THAT(recvmsg(sock, &msg, 0), - SyscallSucceedsWithValue(expected_size + sizeof(struct iphdr))); -} +INSTANTIATE_TEST_SUITE_P(AllInetTests, RawSocketTest, + ::testing::Values(IPPROTO_TCP, IPPROTO_UDP)); } // namespace -- cgit v1.2.3 From e4b395db49e9e90659bd3d366f62aa258a3c7157 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 24 May 2019 12:28:15 -0700 Subject: Remove unused wakers These wakers are uselessly allocated and passed around; nothing ever listens for notifications on them. The code here appears to be vestigial, so removing it and allowing a nil waker to be passed seems appropriate. PiperOrigin-RevId: 249879320 Change-Id: Icd209fb77cc0dd4e5c49d7a9f2adc32bf88b4b71 --- pkg/tcpip/stack/linkaddrcache.go | 10 ++++++---- pkg/tcpip/transport/icmp/endpoint.go | 8 +------- pkg/tcpip/transport/raw/endpoint.go | 8 +------- pkg/tcpip/transport/udp/endpoint.go | 7 +------ 4 files changed, 9 insertions(+), 24 deletions(-) (limited to 'pkg/tcpip/stack') diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index 42b9768ae..b952ad20f 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -138,8 +138,10 @@ func (e *linkAddrEntry) changeState(ns entryState) { e.s = ns } -func (e *linkAddrEntry) addWaker(w *sleep.Waker) { - e.wakers[w] = struct{}{} +func (e *linkAddrEntry) maybeAddWaker(w *sleep.Waker) { + if w != nil { + e.wakers[w] = struct{}{} + } } func (e *linkAddrEntry) removeWaker(w *sleep.Waker) { @@ -217,7 +219,7 @@ func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, lo return "", nil, tcpip.ErrNoLinkAddress case incomplete: // Address resolution is still in progress. - entry.addWaker(waker) + entry.maybeAddWaker(waker) return "", entry.done, tcpip.ErrWouldBlock default: panic(fmt.Sprintf("invalid cache entry state: %s", s)) @@ -230,7 +232,7 @@ func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, lo // Add 'incomplete' entry in the cache to mark that resolution is in progress. e := c.makeAndAddEntry(k, "") - e.addWaker(waker) + e.maybeAddWaker(waker) go c.startAddressResolution(k, linkRes, localAddr, linkEP, e.done) // S/R-SAFE: link non-savable; wakers dropped synchronously. diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index cc384dd3d..e2b90ef10 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -18,7 +18,6 @@ import ( "encoding/binary" "sync" - "gvisor.googlesource.com/gvisor/pkg/sleep" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" @@ -274,13 +273,8 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c } if route.IsResolutionRequired() { - waker := &sleep.Waker{} - if ch, err := route.Resolve(waker); err != nil { + if ch, err := route.Resolve(nil); err != nil { if err == tcpip.ErrWouldBlock { - // Link address needs to be resolved. - // Resolution was triggered the background. - // Better luck next time. - route.RemoveWaker(waker) return 0, ch, tcpip.ErrNoLinkAddress } return 0, nil, err diff --git a/pkg/tcpip/transport/raw/endpoint.go b/pkg/tcpip/transport/raw/endpoint.go index e7b383ad5..1daf5823f 100644 --- a/pkg/tcpip/transport/raw/endpoint.go +++ b/pkg/tcpip/transport/raw/endpoint.go @@ -29,7 +29,6 @@ package raw import ( "sync" - "gvisor.googlesource.com/gvisor/pkg/sleep" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" @@ -259,13 +258,8 @@ func (ep *endpoint) finishWrite(payload tcpip.Payload, route *stack.Route) (uint // network address). If that requires blocking (e.g. to use ARP), // return a channel on which the caller can wait. if route.IsResolutionRequired() { - waker := &sleep.Waker{} - if ch, err := route.Resolve(waker); err != nil { + if ch, err := route.Resolve(nil); err != nil { if err == tcpip.ErrWouldBlock { - // Link address needs to be resolved. - // Resolution was triggered the background. - // Better luck next time. - route.RemoveWaker(waker) return 0, ch, tcpip.ErrNoLinkAddress } return 0, nil, err diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index d9ca097c9..3d52a4f31 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -18,7 +18,6 @@ import ( "math" "sync" - "gvisor.googlesource.com/gvisor/pkg/sleep" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" @@ -346,12 +345,8 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c } if route.IsResolutionRequired() { - waker := &sleep.Waker{} - if ch, err := route.Resolve(waker); err != nil { + if ch, err := route.Resolve(nil); err != nil { if err == tcpip.ErrWouldBlock { - // Link address needs to be resolved. Resolution was triggered the background. - // Better luck next time. - route.RemoveWaker(waker) return 0, ch, tcpip.ErrNoLinkAddress } return 0, nil, err -- cgit v1.2.3