@@ -1084,6 +1084,23 @@ netdev_afxdp_destruct(struct netdev *netdev)
ovs_mutex_destroy(&dev->mutex);
}
+int
+netdev_afxdp_verify_mtu_size(const struct netdev *netdev OVS_UNUSED, int mtu)
+{
+ /*
+ * If a device is used in xdpmode skb, no driver-specific MTU size is
+ * checked and any value is allowed resulting in packet drops.
+ * This check will verify the maximum supported value based on the
+ * buffer size allocated and the additional headroom required.
+ */
+ if (mtu > (FRAME_SIZE - OVS_XDP_HEADROOM -
+ XDP_PACKET_HEADROOM - VLAN_ETH_HEADER_LEN)) {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
int
netdev_afxdp_get_custom_stats(const struct netdev *netdev,
struct netdev_custom_stats *custom_stats)
@@ -39,6 +39,7 @@ int netdev_afxdp_rxq_construct(struct netdev_rxq *rxq_);
void netdev_afxdp_rxq_destruct(struct netdev_rxq *rxq_);
int netdev_afxdp_construct(struct netdev *netdev_);
void netdev_afxdp_destruct(struct netdev *netdev_);
+int netdev_afxdp_verify_mtu_size(const struct netdev *netdev, int mtu);
int netdev_afxdp_rxq_recv(struct netdev_rxq *rxq_,
struct dp_packet_batch *batch,
@@ -1593,6 +1593,15 @@ netdev_linux_set_mtu(struct netdev *netdev_, int mtu)
goto exit;
}
+#ifdef HAVE_AF_XDP
+ if (netdev_get_class(netdev_) == &netdev_afxdp_class) {
+ error = netdev_afxdp_verify_mtu_size(netdev_, mtu);
+ if (error) {
+ goto exit;
+ }
+ }
+#endif
+
if (netdev->cache_valid & VALID_MTU) {
error = netdev->netdev_mtu_error;
if (error || netdev->mtu == mtu) {
Drivers natively supporting AF_XDP will check that a configured MTU size will not exceed the allowed size for AF_XDP. However, when the skb compatibility mode is used there is no check and any value is accepted. This, for example, is the case when using the TAP interface. This fix adds a check to make sure only AF_XDP valid values are excepted. Signed-off-by: Eelco Chaudron <echaudro@redhat.com> --- v1 -> v2: Included (subtracted) ethernet and vlan header from the MTU size to match kernel/driver MTU behavior. Use netdev class compare rather than based on name string lib/netdev-afxdp.c | 17 +++++++++++++++++ lib/netdev-afxdp.h | 1 + lib/netdev-linux.c | 9 +++++++++ 3 files changed, 27 insertions(+)