Skip to content

Commit

Permalink
Bugfix: Fix incorrect Pod MTU when WireGuard enabled
Browse files Browse the repository at this point in the history
The default tunnel type is GENEVE, when the WireGuard encryption
is enabled, the Pod MTU calculator still deducts the GENEVE overhead
directly, which causes a MTU error.

This patch will calculate all MTU deduction in function
CalculateMTUDeduction, including WireGuard and Multicluster.

Signed-off-by: Jiajing Hu <hjiajing@vmware.com>
  • Loading branch information
hjiajing committed Jan 23, 2024
1 parent 48d7f7b commit 67eb290
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 61 deletions.
1 change: 1 addition & 0 deletions cmd/antrea-agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ func run(o *Options) error {
AuthenticationMode: ipsecAuthenticationMode,
},
EnableMulticlusterGW: enableMulticlusterGW,
MulticlusterConfig: o.config.Multicluster,
}

wireguardConfig := &config.WireGuardConfig{
Expand Down
4 changes: 0 additions & 4 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -1194,10 +1194,6 @@ func (i *Initializer) getInterfaceMTU(transportInterface *net.Interface) (int, e

isIPv6 := i.nodeConfig.NodeIPv6Addr != nil
mtu -= i.networkConfig.CalculateMTUDeduction(isIPv6)

if i.networkConfig.TrafficEncryptionMode == config.TrafficEncryptionModeIPSec {
mtu -= config.IPSecESPOverhead
}
return mtu, nil
}

Expand Down
31 changes: 22 additions & 9 deletions pkg/agent/config/node_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ package config
import (
"fmt"
"net"
"strings"

agentConfig "antrea.io/antrea/pkg/config/agent"
"antrea.io/antrea/pkg/ovs/ovsconfig"
)

Expand Down Expand Up @@ -201,14 +203,15 @@ type NetworkConfig struct {
TransportIfaceCIDRs []string
IPv4Enabled bool
IPv6Enabled bool
// MTUDeduction only counts IPv4 tunnel overhead, no IPsec and WireGuard overhead.
// MTUDeduction is the MTU deduction for encapsulation and encryption in cluster.
MTUDeduction int
// Set by the defaultMTU config option or auto discovered.
// Auto discovery will use MTU value of the Node's transport interface.
// For Encap and Hybrid mode, InterfaceMTU will be adjusted to account for
// encap header.
InterfaceMTU int
EnableMulticlusterGW bool
MulticlusterConfig agentConfig.MulticlusterConfig
}

// IsIPv4Enabled returns true if the cluster network supports IPv4. Legal cases are:
Expand Down Expand Up @@ -265,23 +268,33 @@ func (nc *NetworkConfig) NeedsDirectRoutingToPeer(peerIP net.IP, localIP *net.IP
}

func (nc *NetworkConfig) CalculateMTUDeduction(isIPv6 bool) int {
var mtuDeduction int
if nc.TrafficEncapMode.SupportsEncap() && isIPv6 {
nc.MTUDeduction += ipv6ExtraOverhead
}
// When WireGuard is enabled, NetworkConfig.TunnelType will be ignored, so we deduct MTU based on WireGuardOverhead.
if nc.TrafficEncryptionMode == TrafficEncryptionModeWireGuard {
nc.MTUDeduction = WireGuardOverhead
return nc.MTUDeduction
} else if nc.TrafficEncryptionMode == TrafficEncryptionModeIPSec {
nc.MTUDeduction = IPSecESPOverhead
}

// When Multi-cluster Gateway is enabled, we need to reduce MTU for potential cross-cluster traffic.
if nc.TrafficEncapMode.SupportsEncap() || nc.EnableMulticlusterGW {
if nc.TunnelType == ovsconfig.VXLANTunnel {
mtuDeduction = vxlanOverhead
nc.MTUDeduction += vxlanOverhead
} else if nc.TunnelType == ovsconfig.GeneveTunnel {
mtuDeduction = geneveOverhead
nc.MTUDeduction += geneveOverhead
} else if nc.TunnelType == ovsconfig.GRETunnel {
mtuDeduction = greOverhead
nc.MTUDeduction += greOverhead
}
}

if nc.TrafficEncapMode.SupportsEncap() && isIPv6 {
mtuDeduction += ipv6ExtraOverhead
// When multi-cluster WireGuard is enabled, we need to reduce MTU for potential cross-cluster traffic.
if nc.EnableMulticlusterGW && strings.EqualFold(nc.MulticlusterConfig.TrafficEncryptionMode, TrafficEncryptionModeWireGuard.String()) {
nc.MTUDeduction += WireGuardOverhead
}
nc.MTUDeduction = mtuDeduction
return mtuDeduction
return nc.MTUDeduction
}

// ServiceConfig includes K8s Service CIDR and available IP addresses for NodePort.
Expand Down
35 changes: 35 additions & 0 deletions pkg/agent/config/node_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"github.com/stretchr/testify/assert"

agentConfig "antrea.io/antrea/pkg/config/agent"
"antrea.io/antrea/pkg/ovs/ovsconfig"
)

Expand Down Expand Up @@ -306,6 +307,40 @@ func TestCalculateMTUDeduction(t *testing.T) {
isIPv6: true,
expectedMTUDeduction: 70,
},
{
name: "WireGuard enabled",
nc: &NetworkConfig{TrafficEncryptionMode: TrafficEncryptionModeWireGuard},
expectedMTUDeduction: 80,
},
{
name: "Multicluster enabled with Geneve encap",
nc: &NetworkConfig{TunnelType: ovsconfig.GeneveTunnel, EnableMulticlusterGW: true},
expectedMTUDeduction: 50,
},
{
name: "Geneve encap with Multicluster WireGuard enabled",
nc: &NetworkConfig{
TunnelType: ovsconfig.GeneveTunnel,
EnableMulticlusterGW: true,
MulticlusterConfig: agentConfig.MulticlusterConfig{TrafficEncryptionMode: "wireGuard"},
},
expectedMTUDeduction: 130,
},
{
name: "Geneve encap with IPSec enabled",
nc: &NetworkConfig{TunnelType: ovsconfig.GeneveTunnel, TrafficEncryptionMode: TrafficEncryptionModeIPSec},
expectedMTUDeduction: 88,
},
{
name: "VXLan encap with IPSec enabled",
nc: &NetworkConfig{TunnelType: ovsconfig.VXLANTunnel, TrafficEncryptionMode: TrafficEncryptionModeIPSec},
expectedMTUDeduction: 88,
},
{
name: "GRE encap with IPSec enabled",
nc: &NetworkConfig{TunnelType: ovsconfig.GRETunnel, TrafficEncryptionMode: TrafficEncryptionModeIPSec},
expectedMTUDeduction: 76,
},
}

for _, tt := range tests {
Expand Down
2 changes: 1 addition & 1 deletion pkg/agent/multicluster/mc_route_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func NewMCDefaultRouteController(
controller.wireGuardConfig = &config.WireGuardConfig{
Port: multiclusterConfig.WireGuard.Port,
Name: multiclusterWireGuardInterface,
MTU: controller.nodeConfig.NodeTransportInterfaceMTU - controller.networkConfig.MTUDeduction - config.WireGuardOverhead,
MTU: controller.nodeConfig.NodeTransportInterfaceMTU,
}
}
controller.gwInformer.Informer().AddEventHandlerWithResyncPeriod(
Expand Down
2 changes: 1 addition & 1 deletion test/e2e-secondary-network/secondary_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (data *TestData) pingBetweenInterfaces(t *testing.T) error {
} else {
IPToPing = antreae2e.PodIPs{IPv6: &ip}
}
err := data.e2eTestData.RunPingCommandFromTestPod(antreae2e.PodInfo{Name: podData[sourcePod].nameOfPods, OS: osType, NodeName: clusterInfo.controlPlaneNodeName, Namespace: nameSpace}, nameSpace, &IPToPing, ctrName, count, size)
err := data.e2eTestData.RunPingCommandFromTestPod(antreae2e.PodInfo{Name: podData[sourcePod].nameOfPods, OS: osType, NodeName: clusterInfo.controlPlaneNodeName, Namespace: nameSpace}, nameSpace, &IPToPing, ctrName, count, size, true)
if err == nil {
logs.Infof("Ping '%s' -> '%s'( Interface: %s, IP Address: %s): OK", podData[sourcePod].nameOfPods, podData[targetPod].nameOfPods, podData[targetPod].nameOfInterfacePerPod[targetInterface], secondaryIpAddress)
} else {
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/antreaipam_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ func testAntreaIPAMPodConnectivitySameNode(t *testing.T, data *TestData) {
defer deletePodWrapper(t, data, PodInfos[i].Namespace, PodInfos[i].Name)
}

data.runPingMesh(t, PodInfos, agnhostContainerName)
data.runPingMesh(t, PodInfos, agnhostContainerName, 0)
}

func testAntreaIPAMPodConnectivityDifferentNodes(t *testing.T, data *TestData) {
Expand All @@ -296,7 +296,7 @@ func testAntreaIPAMPodConnectivityDifferentNodes(t *testing.T, data *TestData) {
}
PodInfos = append(PodInfos, createdPodInfos...)
}
data.runPingMesh(t, PodInfos, agnhostContainerName)
data.runPingMesh(t, PodInfos, agnhostContainerName, 0)
}

func testAntreaIPAMStatefulSet(t *testing.T, data *TestData, dedicatedIPPoolKey *string) {
Expand Down
Loading

0 comments on commit 67eb290

Please sign in to comment.