Add SetMTU to change the mtu of device.

The method will be primarily used with RTM_[NEW|SET]LINK when IFLA_MTU
is present.

PiperOrigin-RevId: 646264847
This commit is contained in:
Jing Chen
2024-06-24 16:58:13 -07:00
committed by gVisor bot
parent a967130bae
commit 8ef3239b0b
28 changed files with 276 additions and 27 deletions
+12 -3
View File
@@ -139,7 +139,6 @@ var _ stack.GSOEndpoint = (*Endpoint)(nil)
//
// +stateify savable
type Endpoint struct {
mtu uint32
LinkEPCapabilities stack.LinkEndpointCapabilities
SupportedGSOKind stack.SupportedGSO
@@ -148,6 +147,8 @@ type Endpoint struct {
dispatcher stack.NetworkDispatcher
// +checklocks:mu
linkAddr tcpip.LinkAddress
// +checklocks:mu
mtu uint32
// Outbound packet queue.
q *queue
@@ -223,12 +224,20 @@ func (e *Endpoint) IsAttached() bool {
return e.dispatcher != nil
}
// MTU implements stack.LinkEndpoint.MTU. It returns the value initialized
// during construction.
// MTU implements stack.LinkEndpoint.MTU.
func (e *Endpoint) MTU() uint32 {
e.mu.RLock()
defer e.mu.RUnlock()
return e.mtu
}
// SetMTU implements stack.LinkEndpoint.SetMTU.
func (e *Endpoint) SetMTU(mtu uint32) {
e.mu.Lock()
defer e.mu.Unlock()
e.mtu = mtu
}
// Capabilities implements stack.LinkEndpoint.Capabilities.
func (e *Endpoint) Capabilities() stack.LinkEndpointCapabilities {
return e.LinkEPCapabilities
+14
View File
@@ -32,3 +32,17 @@ func TestSetLinkAddress(t *testing.T) {
}
}
}
func TestSetMTU(t *testing.T) {
expectedMTU := []uint32{1000, 3000}
size, mtu := 10, uint32(2000)
e := New(size, mtu, tcpip.LinkAddress("xyz"))
defer e.Close()
for _, mtu := range expectedMTU {
e.SetMTU(mtu)
if want, v := mtu, e.MTU(); want != v {
t.Errorf("MTU() = %v, want %v", v, want)
}
}
}
+14 -5
View File
@@ -120,9 +120,6 @@ type endpoint struct {
// hash outbound packets to specific channels based on the packet hash.
fds []fdInfo
// mtu (maximum transmission unit) is the maximum size of a packet.
mtu uint32
// hdrSize specifies the link-layer header size. If set to 0, no header
// is added/removed; otherwise an ethernet header is used.
hdrSize int
@@ -172,6 +169,10 @@ type endpoint struct {
//
// +checklocks:mu
addr tcpip.LinkAddress
// mtu (maximum transmission unit) is the maximum size of a packet.
// +checklocks:mu
mtu uint32
}
// Options specify the details about the fd-based endpoint to be created.
@@ -454,12 +455,20 @@ func (e *endpoint) IsAttached() bool {
return e.dispatcher != nil
}
// MTU implements stack.LinkEndpoint.MTU. It returns the value initialized
// during construction.
// MTU implements stack.LinkEndpoint.MTU.
func (e *endpoint) MTU() uint32 {
e.mu.RLock()
defer e.mu.RUnlock()
return e.mtu
}
// SetMTU implements stack.LinkEndpoint.SetMTU.
func (e *endpoint) SetMTU(mtu uint32) {
e.mu.Lock()
defer e.mu.Unlock()
e.mtu = mtu
}
// Capabilities implements stack.LinkEndpoint.Capabilities.
func (e *endpoint) Capabilities() stack.LinkEndpointCapabilities {
return e.caps
+13
View File
@@ -194,6 +194,19 @@ func TestSetAddress(t *testing.T) {
}
}
func TestMTU(t *testing.T) {
mtus := []uint32{200, 300}
c := newContext(t, &Options{MTU: mtu})
defer c.cleanup()
for _, m := range mtus {
c.ep.SetMTU(m)
if want, v := m, c.ep.MTU(); want != v {
t.Errorf("MTU() = %v, want %v", v, want)
}
}
}
func testWritePacket(t *testing.T, plen int, eth bool, gsoMaxSize uint32, hash uint32) {
c := newContext(t, &Options{Address: laddr, MTU: mtu, EthernetHeader: eth, GSOMaxSize: gsoMaxSize})
defer c.cleanup()
+3
View File
@@ -62,6 +62,9 @@ func (*endpoint) MTU() uint32 {
return 65536
}
// SetMTU implements stack.LinkEndpoint.SetMTU. It has no impact.
func (*endpoint) SetMTU(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 {
+7
View File
@@ -49,6 +49,13 @@ func (m *InjectableEndpoint) MTU() uint32 {
return minMTU
}
// SetMTU implements stack.LinkEndpoint.
func (m *InjectableEndpoint) SetMTU(mtu uint32) {
for _, endpoint := range m.routes {
endpoint.SetMTU(mtu)
}
}
// Capabilities implements stack.LinkEndpoint.
func (m *InjectableEndpoint) Capabilities() stack.LinkEndpointCapabilities {
minCapabilities := stack.LinkEndpointCapabilities(^uint(0))
+13
View File
@@ -29,6 +29,19 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/stack"
)
func TestInjectableEndpointMTU(t *testing.T) {
endpoint, _, _ := makeTestInjectableEndpoint(t)
mtus := []uint32{100, 200}
for _, mtu := range mtus {
endpoint.SetMTU(mtu)
if want, v := mtu, endpoint.MTU(); want != v {
t.Errorf("MTU() = %v, want %v", v, want)
}
}
}
func TestInjectableEndpointRawDispatch(t *testing.T) {
endpoint, sock, dstIP := makeTestInjectableEndpoint(t)
+5
View File
@@ -99,6 +99,11 @@ func (e *Endpoint) MTU() uint32 {
return e.child.MTU()
}
// SetMTU implements stack.LinkEndpoint.
func (e *Endpoint) SetMTU(mtu uint32) {
e.child.SetMTU(mtu)
}
// Capabilities implements stack.LinkEndpoint.
func (e *Endpoint) Capabilities() stack.LinkEndpointCapabilities {
return e.child.Capabilities()
+26
View File
@@ -33,6 +33,7 @@ var _ stack.LinkEndpoint = (*parentEndpoint)(nil)
var _ stack.NetworkDispatcher = (*parentEndpoint)(nil)
type childEndpoint struct {
mtu uint32
addr tcpip.LinkAddress
stack.LinkEndpoint
dispatcher stack.NetworkDispatcher
@@ -56,6 +57,14 @@ func (c *childEndpoint) SetLinkAddress(addr tcpip.LinkAddress) {
c.addr = addr
}
func (c *childEndpoint) MTU() uint32 {
return c.mtu
}
func (c *childEndpoint) SetMTU(mtu uint32) {
c.mtu = mtu
}
type counterDispatcher struct {
count int
}
@@ -141,6 +150,23 @@ func TestSetLinkAddress(t *testing.T) {
}
}
func TestMTU(t *testing.T) {
var (
childEP childEndpoint
ep parentEndpoint
disp counterDispatcher
)
mtus := []uint32{1500, 2000}
ep.Endpoint.Init(&childEP, &disp)
for _, mtu := range mtus {
ep.Endpoint.SetMTU(mtu)
if want, v := mtu, ep.MTU(); want != v {
t.Errorf("LinkAddress() = %v, want %v", v, want)
}
}
}
func TestMain(m *testing.M) {
refs.SetLeakMode(refs.LeaksPanic)
code := m.Run()
@@ -35,6 +35,7 @@ type nullEndpoint struct {
func (*nullEndpoint) MTU() uint32 {
return math.MaxUint32
}
func (*nullEndpoint) SetMTU(uint32) {}
func (*nullEndpoint) Capabilities() stack.LinkEndpointCapabilities {
return 0
}
+11 -1
View File
@@ -46,13 +46,14 @@ func New(linkAddr1, linkAddr2 tcpip.LinkAddress, mtu uint32) (*Endpoint, *Endpoi
// +stateify savable
type Endpoint struct {
linked *Endpoint
mtu uint32
mu sync.RWMutex `state:"nosave"`
// +checklocks:mu
dispatcher stack.NetworkDispatcher
// +checklocks:mu
linkAddr tcpip.LinkAddress
// +checklocks:mu
mtu uint32
}
func (e *Endpoint) deliverPackets(pkts stack.PacketBufferList) {
@@ -101,9 +102,18 @@ func (*Endpoint) Wait() {}
// MTU implements stack.LinkEndpoint.
func (e *Endpoint) MTU() uint32 {
e.mu.RLock()
defer e.mu.RUnlock()
return e.mtu
}
// SetMTU implements stack.LinkEndpoint.
func (e *Endpoint) SetMTU(mtu uint32) {
e.mu.Lock()
defer e.mu.Unlock()
e.mtu = mtu
}
// Capabilities implements stack.LinkEndpoint.
func (*Endpoint) Capabilities() stack.LinkEndpointCapabilities {
return 0
+14
View File
@@ -33,3 +33,17 @@ func TestSetAddress(t *testing.T) {
}
}
}
func TestMTU(t *testing.T) {
mtus := []uint32{1000, 2000}
e := &Endpoint{
mtu: 10,
}
for _, mtu := range mtus {
e.SetMTU(mtu)
if want, v := mtu, e.MTU(); want != v {
t.Errorf("MTU() = %v, want %v", v, want)
}
}
}
+12 -6
View File
@@ -148,10 +148,6 @@ var _ stack.GSOEndpoint = (*endpoint)(nil)
// +stateify savable
type endpoint struct {
// mtu (maximum transmission unit) is the maximum size of a packet.
// mtu is immutable.
mtu uint32
// bufferSize is the size of each individual buffer.
// bufferSize is immutable.
bufferSize uint32
@@ -206,6 +202,9 @@ type endpoint struct {
//
// +checklocks:mu
addr tcpip.LinkAddress
// mtu (maximum transmission unit) is the maximum size of a packet.
// +checklocks:mu
mtu uint32
}
// New creates a new shared-memory-based endpoint. Buffers will be broken up
@@ -323,12 +322,19 @@ func (e *endpoint) IsAttached() bool {
return e.workerStarted
}
// MTU implements stack.LinkEndpoint.MTU. It returns the value initialized
// during construction.
// MTU implements stack.LinkEndpoint.MTU.
func (e *endpoint) MTU() uint32 {
e.mu.RLock()
defer e.mu.RUnlock()
return e.mtu
}
func (e *endpoint) SetMTU(mtu uint32) {
e.mu.Lock()
defer e.mu.Unlock()
e.mtu = mtu
}
// Capabilities implements stack.LinkEndpoint.Capabilities.
func (e *endpoint) Capabilities() stack.LinkEndpointCapabilities {
return e.caps
+12 -6
View File
@@ -28,10 +28,6 @@ import (
)
type serverEndpoint struct {
// mtu (maximum transmission unit) is the maximum size of a packet.
// mtu is immutable.
mtu uint32
// bufferSize is the size of each individual buffer.
// bufferSize is immutable.
bufferSize uint32
@@ -80,6 +76,9 @@ type serverEndpoint struct {
//
// +checklocks:mu
addr tcpip.LinkAddress
// mtu (maximum transmission unit) is the maximum size of a packet.
// +checklocks:mu
mtu uint32
}
// NewServerEndpoint creates a new shared-memory-based endpoint. Buffers will be
@@ -180,12 +179,19 @@ func (e *serverEndpoint) IsAttached() bool {
return e.workerStarted
}
// MTU implements stack.LinkEndpoint.MTU. It returns the value initialized
// during construction.
// MTU implements stack.LinkEndpoint.MTU.
func (e *serverEndpoint) MTU() uint32 {
e.mu.RLock()
defer e.mu.RUnlock()
return e.mtu
}
func (e *serverEndpoint) SetMTU(mtu uint32) {
e.mu.Lock()
defer e.mu.Unlock()
e.mtu = mtu
}
// Capabilities implements stack.LinkEndpoint.Capabilities.
func (e *serverEndpoint) Capabilities() stack.LinkEndpointCapabilities {
return e.caps
@@ -431,6 +431,34 @@ func TestSetLinkAddress(t *testing.T) {
}
}
func TestMTU(t *testing.T) {
q, err := sharedmem.NewQueuePair(sharedmem.QueueOptions{})
if err != nil {
q.Close()
t.Fatalf("failed to create sharedmem queue: %s", err)
}
defer q.Close()
ep, err := sharedmem.NewServerEndpoint(sharedmem.Options{
MTU: defaultMTU,
BufferSize: defaultBufferSize,
LinkAddress: remoteLinkAddr,
TX: q.TXQueueConfig(),
RX: q.RXQueueConfig(),
PeerFD: 123,
})
if err != nil {
t.Fatalf("failed to create sharedmem endpoint: %s", err)
}
mtus := []uint32{1000, 2000}
for _, mtu := range mtus {
ep.SetMTU(mtu)
if want, v := mtu, ep.MTU(); want != v {
t.Errorf("MTU() = %v, want %v", v, want)
}
}
}
func TestMain(m *testing.M) {
refs.SetLeakMode(refs.LeaksPanic)
code := m.Run()
@@ -835,6 +835,20 @@ func TestSetLinkAddress(t *testing.T) {
}
}
func TestMTU(t *testing.T) {
c := newTestContext(t, 20000, 1500, "")
defer c.cleanup()
mtus := []uint32{1000, 2000}
for _, mtu := range mtus {
c.ep.SetMTU(mtu)
if want, v := mtu, c.ep.MTU(); want != v {
t.Errorf("MTU() = %v, want %v", v, want)
}
}
}
func TestMain(m *testing.M) {
refs.SetLeakMode(refs.LeaksPanic)
code := m.Run()
+12 -3
View File
@@ -39,7 +39,6 @@ const backlogQueueSize = 64
// +stateify savable
type Endpoint struct {
pair *Endpoint
mtu uint32
backlogQueue *chan vethPacket
@@ -55,6 +54,8 @@ type Endpoint struct {
//
// +checklocks:mu
linkAddr tcpip.LinkAddress
// +checklocks:mu
mtu uint32
}
// NewPair creates a new veth pair.
@@ -143,12 +144,20 @@ func (e *Endpoint) IsAttached() bool {
return e.dispatcher != nil
}
// MTU implements stack.LinkEndpoint.MTU. It returns the value initialized
// during construction.
// MTU implements stack.LinkEndpoint.MTU.
func (e *Endpoint) MTU() uint32 {
e.mu.RLock()
defer e.mu.RUnlock()
return e.mtu
}
// SetMTU implements stack.LinkEndpoint.SetMTU.
func (e *Endpoint) SetMTU(mtu uint32) {
e.mu.Lock()
defer e.mu.Unlock()
e.mtu = mtu
}
// Capabilities implements stack.LinkEndpoint.Capabilities.
func (e *Endpoint) Capabilities() stack.LinkEndpointCapabilities {
return stack.CapabilityRXChecksumOffload | stack.CapabilityTXChecksumOffload | stack.CapabilitySaveRestore
+14
View File
@@ -129,6 +129,20 @@ func TestDestroyDevices(t *testing.T) {
}
}
func TestMTU(t *testing.T) {
mtus := []uint32{100, 200}
e, e2 := veth.NewPair(1500)
defer e.Close()
defer e2.Close()
for _, mtu := range mtus {
e.SetMTU(mtu)
if want, v := mtu, e.MTU(); want != v {
t.Errorf("MTU() = %v, want %v", v, want)
}
}
}
func TestMain(m *testing.M) {
refs.SetLeakMode(refs.LeaksPanic)
code := m.Run()
+6
View File
@@ -108,6 +108,12 @@ func (e *Endpoint) MTU() uint32 {
return e.lower.MTU()
}
// SetMTU implements stack.LinkEndpoint.SetMTU. It just forwards the request to
// the lower endpoint.
func (e *Endpoint) SetMTU(mtu uint32) {
e.lower.SetMTU(mtu)
}
// Capabilities implements stack.LinkEndpoint.Capabilities. It just forwards the
// request to the lower endpoint.
func (e *Endpoint) Capabilities() stack.LinkEndpointCapabilities {
+4
View File
@@ -61,6 +61,10 @@ func (e *countedEndpoint) MTU() uint32 {
return e.mtu
}
func (e *countedEndpoint) SetMTU(mtu uint32) {
e.mtu = mtu
}
func (e *countedEndpoint) Capabilities() stack.LinkEndpointCapabilities {
return e.capabilities
}

Some files were not shown because too many files have changed in this diff Show More