Skip to content

Commit

Permalink
[BPF] set MTU on bpfin/out.cali to match host
Browse files Browse the repository at this point in the history
Set the MTU to match the smallest MTU of the host devices as per the
current autodetection. That makes sure that if large MTU is used, the
extra device does not create a bottleneck with a small MTU. Also when
MTU changes, on host devices, it get adjusted automatically. If an
overlay is used, the special device MTU is adjusted to the size of the
overlay.

Fixes #8918
  • Loading branch information
tomastigera committed Jun 27, 2024
1 parent 211f008 commit c337121
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 5 deletions.
19 changes: 17 additions & 2 deletions felix/dataplane/linux/bpf_ep_mgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,9 @@ type bpfEndpointManager struct {
polNameToMatchIDs map[string]set.Set[polprog.RuleMatchID]
dirtyRules set.Set[polprog.RuleMatchID]

natInIdx int
natOutIdx int
natInIdx int
natOutIdx int
bpfIfaceMTU int

v4 *bpfEndpointManagerDataplane
v6 *bpfEndpointManagerDataplane
Expand Down Expand Up @@ -437,6 +438,7 @@ func NewTestEpMgr(
new(environment.FakeFeatureDetector),
nil,
nil,
1500,
)
}

Expand All @@ -456,6 +458,7 @@ func newBPFEndpointManager(
featureDetector environment.FeatureDetectorIface,
healthAggregator *health.HealthAggregator,
dataplanefeatures *environment.Features,
bpfIfaceMTU int,
) (*bpfEndpointManager, error) {
if livenessCallback == nil {
livenessCallback = func() {}
Expand Down Expand Up @@ -623,6 +626,7 @@ func newBPFEndpointManager(
}
}

m.bpfIfaceMTU = bpfIfaceMTU
if err := m.dp.ensureBPFDevices(); err != nil {
return nil, fmt.Errorf("ensure BPF devices: %w", err)
} else {
Expand Down Expand Up @@ -3192,6 +3196,7 @@ func (m *bpfEndpointManager) ensureBPFDevices() error {
if err != nil {
la := netlink.NewLinkAttrs()
la.Name = bpfInDev
la.MTU = m.bpfIfaceMTU
nat := &netlink.Veth{
LinkAttrs: la,
PeerName: bpfOutDev,
Expand All @@ -3204,6 +3209,7 @@ func (m *bpfEndpointManager) ensureBPFDevices() error {
return fmt.Errorf("missing %s after add: %w", bpfInDev, err)
}
}

if state := bpfin.Attrs().OperState; state != netlink.OperUp {
log.WithField("state", state).Info(bpfInDev)
if err := netlink.LinkSetUp(bpfin); err != nil {
Expand All @@ -3221,6 +3227,15 @@ func (m *bpfEndpointManager) ensureBPFDevices() error {
}
}

err = netlink.LinkSetMTU(bpfin, m.bpfIfaceMTU)
if err != nil {
return fmt.Errorf("failed to set MTU to %d on %s: %w", m.bpfIfaceMTU, bpfInDev, err)
}
err = netlink.LinkSetMTU(bpfout, m.bpfIfaceMTU)
if err != nil {
return fmt.Errorf("failed to set MTU to %d on %s: %w", m.bpfIfaceMTU, bpfOutDev, err)
}

m.natInIdx = bpfin.Attrs().Index
m.natOutIdx = bpfout.Attrs().Index

Expand Down
1 change: 1 addition & 0 deletions felix/dataplane/linux/bpf_ep_mgr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ var _ = Describe("BPF Endpoint Manager", func() {
&environment.FakeFeatureDetector{},
nil,
environment.NewFeatureDetector(nil).GetFeatures(),
1250,
)
Expect(err).NotTo(HaveOccurred())
bpfEpMgr.v4.hostIP = net.ParseIP("1.2.3.4")
Expand Down
1 change: 1 addition & 0 deletions felix/dataplane/linux/int_dataplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,7 @@ func NewIntDataplaneDriver(config Config) *InternalDataplane {
featureDetector,
config.HealthAggregator,
dataplaneFeatures,
podMTU,
)

if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions felix/fv/bpf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5165,9 +5165,9 @@ func dumpIfStateMap(felix *infrastructure.Felix) ifstate.MapMem {
return m
}

func ensureAllNodesBPFProgramsAttached(felixes []*infrastructure.Felix) {
func ensureAllNodesBPFProgramsAttached(felixes []*infrastructure.Felix, ifacesExtra ...string) {
for _, felix := range felixes {
ensureBPFProgramsAttachedOffset(2, felix)
ensureBPFProgramsAttachedOffset(2, felix, ifacesExtra...)
}
}

Expand Down
16 changes: 15 additions & 1 deletion felix/fv/mtu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
"github.com/projectcalico/calico/libcalico-go/lib/options"
)

var _ = infrastructure.DatastoreDescribe("VXLAN topology before adding host IPs to IP sets", []apiconfig.DatastoreType{apiconfig.EtcdV3, apiconfig.Kubernetes}, func(getInfra infrastructure.InfraFactory) {
var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ VXLAN topology before adding host IPs to IP sets", []apiconfig.DatastoreType{apiconfig.EtcdV3, apiconfig.Kubernetes}, func(getInfra infrastructure.InfraFactory) {
var (
infra infrastructure.DatastoreInfra
tc infrastructure.TopologyContainers
Expand All @@ -46,6 +46,17 @@ var _ = infrastructure.DatastoreDescribe("VXLAN topology before adding host IPs
return strings.TrimSpace(out)
}, "60s", "500ms").Should(Equal(fmt.Sprint(mtu)))
}
if BPFMode() {
felix := tc.Felixes[0]
EventuallyWithOffset(1, func() string {
out, _ := felix.ExecOutput("ip", "link", "show", "dev", "bpfin.cali")
return out
}, "5s", "500ms").Should(ContainSubstring(fmt.Sprintf("mtu %d", mtu)))
EventuallyWithOffset(1, func() string {
out, _ := felix.ExecOutput("ip", "link", "show", "dev", "bpfout.cali")
return out
}, "5s", "500ms").Should(ContainSubstring(fmt.Sprintf("mtu %d", mtu)))
}
}

vxlanOverhead := func(ipv6 bool) int {
Expand All @@ -59,6 +70,9 @@ var _ = infrastructure.DatastoreDescribe("VXLAN topology before adding host IPs
if CurrentGinkgoTestDescription().Failed {
for _, felix := range tc.Felixes {
felix.Exec("ip", "link")
if BPFMode() {
felix.Exec("calico-bpf", "ifstate", "dump")
}
}
infra.DumpErrorData()
}
Expand Down

0 comments on commit c337121

Please sign in to comment.