Skip to content

Commit c096321

Browse files
committed
Add flag to restrict GRO/GSO to MTU size
When customers are using AF_PACKET based apps on top of the Layer2NetworkConfiguration, GRO-ed packets might exceed the configured buffer size.
1 parent 7a72925 commit c096321

File tree

6 files changed

+88
-20
lines changed

6 files changed

+88
-20
lines changed

api/v1alpha1/layer2networkconfiguration_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ type Layer2NetworkConfigurationSpec struct {
5858
// Enable ARP / ND suppression
5959
NeighSuppression *bool `json:"neighSuppression,omitempty"`
6060

61+
// Disable segmentation offload on the interface in tx and rx path
62+
DisableSegmentation bool `json:"disableSegmentation,omitempty"`
63+
6164
// VRF to attach Layer2 network to, default if not set
6265
VRF string `json:"vrf,omitempty"`
6366

config/crd/bases/network.schiff.telekom.de_layer2networkconfigurations.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ spec:
7373
createMacVLANInterface:
7474
description: Create MACVLAN attach interface
7575
type: boolean
76+
disableSegmentation:
77+
description: Disable segmentation offload on the interface in tx and
78+
rx path
79+
type: boolean
7680
id:
7781
description: VLAN Id of the layer 2 network
7882
type: integer

pkg/nl/create.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package nl
22

33
import (
4+
"encoding/binary"
45
"fmt"
56
"net"
67
"os"
@@ -221,6 +222,31 @@ func (n *Manager) setNeighSuppression(link netlink.Link, mode bool) error {
221222
return nil
222223
}
223224

225+
func (n *Manager) setGroGsoMaxSize(link netlink.Link, size int) error {
226+
req := nl.NewNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
227+
228+
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
229+
msg.Index = int32(link.Attrs().Index)
230+
req.AddData(msg)
231+
232+
uSize := uint32(size)
233+
234+
b := make([]byte, binary.Size(uSize))
235+
nl.NativeEndian().PutUint32(b, uSize)
236+
237+
groData := nl.NewRtAttr(unix.IFLA_GRO_MAX_SIZE, b)
238+
req.AddData(groData)
239+
240+
gsoData := nl.NewRtAttr(unix.IFLA_GSO_MAX_SIZE, b)
241+
req.AddData(gsoData)
242+
243+
_, err := n.toolkit.ExecuteNetlinkRequest(req, unix.NETLINK_ROUTE, 0)
244+
if err != nil {
245+
return fmt.Errorf("error executing request: %w", err)
246+
}
247+
return nil
248+
}
249+
224250
func boolToByte(x bool) []byte {
225251
if x {
226252
return []byte{1}

pkg/nl/layer2.go

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,25 @@ import (
1616
const (
1717
interfaceConfigTimeout = 500 * time.Millisecond
1818
neighFilePermissions = 0o600
19+
defaultGroGsoMaxSize = 65536 // Default value for GRO/GSO max size, can be overridden by MTU
1920
)
2021

2122
var procSysNetPath = "/proc/sys/net"
2223

2324
type Layer2Information struct {
24-
VlanID int
25-
MTU int
26-
VNI int
27-
VRF string
28-
AnycastMAC *net.HardwareAddr
29-
AnycastGateways []*netlink.Addr
30-
AdvertiseNeighbors bool
31-
NeighSuppression *bool
32-
bridge *netlink.Bridge
33-
vxlan *netlink.Vxlan
34-
macvlanBridge *netlink.Veth
35-
macvlanHost *netlink.Veth
25+
VlanID int
26+
MTU int
27+
VNI int
28+
VRF string
29+
AnycastMAC *net.HardwareAddr
30+
AnycastGateways []*netlink.Addr
31+
AdvertiseNeighbors bool
32+
NeighSuppression *bool
33+
DisableSegmentation bool
34+
bridge *netlink.Bridge
35+
vxlan *netlink.Vxlan
36+
macvlanBridge *netlink.Veth
37+
macvlanHost *netlink.Veth
3638
}
3739

3840
type NeighborInformation struct {
@@ -140,6 +142,9 @@ func (n *Manager) setupBridge(info *Layer2Information, masterIdx int) (*netlink.
140142
if err := n.configureBridge(bridge.Name); err != nil {
141143
return nil, err
142144
}
145+
if err := n.setGroGsoMaxSize(bridge, info.GroGsoMaxSize()); err != nil {
146+
return nil, err
147+
}
143148

144149
// Wait 500ms before configuring anycast gateways on newly added interface
145150
time.Sleep(interfaceConfigTimeout)
@@ -347,6 +352,9 @@ func (n *Manager) setMTU(current, desired *Layer2Information) error {
347352
return fmt.Errorf("error setting veth macvlan side MTU: %w", err)
348353
}
349354
}
355+
if err := n.setGroGsoMaxSize(current.bridge, desired.GroGsoMaxSize()); err != nil {
356+
return fmt.Errorf("error setting GRO/GSO max size: %w", err)
357+
}
350358
return nil
351359
}
352360

@@ -593,3 +601,10 @@ func (info *Layer2Information) MacVLANBridgeID() int {
593601
}
594602
return info.macvlanBridge.Attrs().Index
595603
}
604+
605+
func (info *Layer2Information) GroGsoMaxSize() int {
606+
if info.DisableSegmentation {
607+
return info.MTU
608+
}
609+
return defaultGroGsoMaxSize
610+
}

pkg/nl/nl_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ var _ = Describe("ReconcileL2()", func() {
540540
}
541541

542542
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
543+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
543544
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return(nil, errors.New("error listing addresses"))
544545

545546
err := nm.ReconcileL2(current, desired)
@@ -561,6 +562,7 @@ var _ = Describe("ReconcileL2()", func() {
561562
}
562563

563564
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
565+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
564566
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.ParseIP("2001::"))}}, nil)
565567

566568
err := nm.ReconcileL2(current, desired)
@@ -582,6 +584,7 @@ var _ = Describe("ReconcileL2()", func() {
582584
}
583585

584586
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
587+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
585588
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
586589
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(errors.New("unable to set link down"))
587590

@@ -604,6 +607,7 @@ var _ = Describe("ReconcileL2()", func() {
604607
}
605608

606609
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
610+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
607611
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
608612
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
609613
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(errors.New("unable to change MAC address"))
@@ -627,6 +631,7 @@ var _ = Describe("ReconcileL2()", func() {
627631
}
628632

629633
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
634+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
630635
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
631636
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
632637
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -651,6 +656,7 @@ var _ = Describe("ReconcileL2()", func() {
651656
}
652657

653658
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
659+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
654660
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
655661
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
656662
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -678,6 +684,7 @@ var _ = Describe("ReconcileL2()", func() {
678684
}
679685

680686
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
687+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
681688
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
682689
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
683690
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -706,6 +713,7 @@ var _ = Describe("ReconcileL2()", func() {
706713
}
707714

708715
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
716+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
709717
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
710718
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
711719
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -738,6 +746,7 @@ var _ = Describe("ReconcileL2()", func() {
738746
}
739747

740748
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
749+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
741750
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
742751
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
743752
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -766,6 +775,7 @@ var _ = Describe("ReconcileL2()", func() {
766775
}
767776

768777
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
778+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
769779
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
770780
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
771781
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -795,6 +805,7 @@ var _ = Describe("ReconcileL2()", func() {
795805
}
796806

797807
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
808+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
798809
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
799810
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
800811
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -825,6 +836,7 @@ var _ = Describe("ReconcileL2()", func() {
825836
}
826837

827838
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
839+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
828840
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
829841
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
830842
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -856,6 +868,7 @@ var _ = Describe("ReconcileL2()", func() {
856868
}
857869

858870
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
871+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
859872
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
860873
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
861874
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -888,6 +901,7 @@ var _ = Describe("ReconcileL2()", func() {
888901
}
889902

890903
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
904+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
891905
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
892906
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
893907
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -921,6 +935,7 @@ var _ = Describe("ReconcileL2()", func() {
921935
}
922936

923937
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(4)
938+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
924939
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
925940
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
926941
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -953,6 +968,7 @@ var _ = Describe("ReconcileL2()", func() {
953968
}
954969

955970
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(2)
971+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
956972
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
957973
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
958974
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -989,6 +1005,7 @@ var _ = Describe("ReconcileL2()", func() {
9891005
}
9901006

9911007
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(2)
1008+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
9921009
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
9931010
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
9941011
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -1058,6 +1075,7 @@ var _ = Describe("ReconcileL2()", func() {
10581075
}
10591076

10601077
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(2)
1078+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
10611079
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
10621080
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
10631081
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)
@@ -1120,6 +1138,7 @@ var _ = Describe("ReconcileL2()", func() {
11201138
}
11211139

11221140
netlinkMock.EXPECT().LinkSetMTU(gomock.Any(), gomock.Any()).Return(nil).Times(2)
1141+
netlinkMock.EXPECT().ExecuteNetlinkRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return([][]byte{}, nil)
11231142
netlinkMock.EXPECT().AddrList(gomock.Any(), gomock.Any()).Return([]netlink.Addr{{IPNet: netlink.NewIPNet(net.IPv4(0, 0, 0, 0))}}, nil)
11241143
netlinkMock.EXPECT().LinkSetDown(gomock.Any()).Return(nil)
11251144
netlinkMock.EXPECT().LinkSetHardwareAddr(gomock.Any(), gomock.Any()).Return(nil)

pkg/reconciler/layer2.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,15 @@ func (r *reconcile) getDesired(l2vnis []networkv1alpha1.Layer2NetworkConfigurati
178178
}
179179

180180
desired = append(desired, nl.Layer2Information{
181-
VlanID: spec.ID,
182-
MTU: spec.MTU,
183-
VNI: spec.VNI,
184-
VRF: spec.VRF,
185-
AnycastMAC: anycastMAC,
186-
AnycastGateways: anycastGateways,
187-
AdvertiseNeighbors: spec.AdvertiseNeighbors,
188-
NeighSuppression: spec.NeighSuppression,
181+
VlanID: spec.ID,
182+
MTU: spec.MTU,
183+
VNI: spec.VNI,
184+
VRF: spec.VRF,
185+
AnycastMAC: anycastMAC,
186+
AnycastGateways: anycastGateways,
187+
AdvertiseNeighbors: spec.AdvertiseNeighbors,
188+
NeighSuppression: spec.NeighSuppression,
189+
DisableSegmentation: spec.DisableSegmentation,
189190
})
190191
}
191192

0 commit comments

Comments
 (0)