[v8,1/3] pcap: support MTU set for linux interfaces

Message ID 20220620083944.51517-2-ido@cgstowernetworks.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series pcap: support MTU set for linux interfaces |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Ido Goshen June 20, 2022, 8:39 a.m. UTC
  Support rte_eth_dev_set_mtu for pcap ifaces vdevs by
setting the underlying OS network interface's MTU.
Support is for pcap ifaces only and not for pcap files.
Support is for Linux only.

Bugzilla ID: 961
Signed-off-by: Ido Goshen <ido@cgstowernetworks.com>
---
 doc/guides/rel_notes/release_22_07.rst |  3 ++
 drivers/net/pcap/pcap_ethdev.c         | 42 ++++++++++++++++++++++++++
 drivers/net/pcap/pcap_osdep.h          |  1 +
 drivers/net/pcap/pcap_osdep_freebsd.c  |  7 +++++
 drivers/net/pcap/pcap_osdep_linux.c    | 21 +++++++++++++
 drivers/net/pcap/pcap_osdep_windows.c  |  7 +++++
 6 files changed, 81 insertions(+)
  

Patch

diff --git a/doc/guides/rel_notes/release_22_07.rst b/doc/guides/rel_notes/release_22_07.rst
index dd371952c3..a966973302 100644
--- a/doc/guides/rel_notes/release_22_07.rst
+++ b/doc/guides/rel_notes/release_22_07.rst
@@ -220,6 +220,9 @@  New Features
   Merged l3fwd-acl code into l3fwd as l3fwd-acl contains duplicate
   and common functions to l3fwd.
 
+* **Updated pcap driver.**
+
+ * Added support for MTU on Linux network interfaces.
 
 Removed Items
 -------------
diff --git a/drivers/net/pcap/pcap_ethdev.c b/drivers/net/pcap/pcap_ethdev.c
index ec29fd6bc5..2221c53051 100644
--- a/drivers/net/pcap/pcap_ethdev.c
+++ b/drivers/net/pcap/pcap_ethdev.c
@@ -807,6 +807,47 @@  eth_stats_reset(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static int
+eth_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
+{
+	unsigned int i;
+	struct pmd_internals *internals = dev->data->dev_private;
+	int is_supported = 0;
+	int is_err = 0;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		struct pcap_rx_queue *queue = &internals->rx_queue[i];
+
+		if ((strcmp(queue->type, ETH_PCAP_IFACE_ARG) == 0) ||
+				(strcmp(queue->type, ETH_PCAP_RX_IFACE_ARG) == 0) ||
+				(strcmp(queue->type, ETH_PCAP_RX_IFACE_IN_ARG) == 0)) {
+			is_supported = 1;
+			if (osdep_iface_mtu_set(queue->name, mtu) < 0)
+				is_err = 1;
+		}
+	}
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		struct pcap_tx_queue *queue = &internals->tx_queue[i];
+
+		if ((strcmp(queue->type, ETH_PCAP_IFACE_ARG) == 0) ||
+				(strcmp(queue->type, ETH_PCAP_TX_IFACE_ARG) == 0)) {
+			is_supported = 1;
+			if (osdep_iface_mtu_set(queue->name, mtu) < 0)
+				is_err = 1;
+		}
+	}
+
+	if (!is_supported)
+		return -ENOTSUP;
+
+	if (is_err)
+		return -1;
+
+	PMD_LOG(INFO, "MTU set %s %u\n", dev->device->name, mtu);
+	return 0;
+}
+
 static inline void
 infinite_rx_ring_free(struct rte_ring *pkts)
 {
@@ -1004,6 +1045,7 @@  static const struct eth_dev_ops ops = {
 	.link_update = eth_link_update,
 	.stats_get = eth_stats_get,
 	.stats_reset = eth_stats_reset,
+	.mtu_set = eth_mtu_set,
 };
 
 static int
diff --git a/drivers/net/pcap/pcap_osdep.h b/drivers/net/pcap/pcap_osdep.h
index bf41cba982..043677ec77 100644
--- a/drivers/net/pcap/pcap_osdep.h
+++ b/drivers/net/pcap/pcap_osdep.h
@@ -14,5 +14,6 @@  extern int eth_pcap_logtype;
 
 int osdep_iface_index_get(const char *name);
 int osdep_iface_mac_get(const char *name, struct rte_ether_addr *mac);
+int osdep_iface_mtu_set(const char *name, uint16_t mtu);
 
 #endif
diff --git a/drivers/net/pcap/pcap_osdep_freebsd.c b/drivers/net/pcap/pcap_osdep_freebsd.c
index 20556b3e92..a9961ba3e3 100644
--- a/drivers/net/pcap/pcap_osdep_freebsd.c
+++ b/drivers/net/pcap/pcap_osdep_freebsd.c
@@ -57,3 +57,10 @@  osdep_iface_mac_get(const char *if_name, struct rte_ether_addr *mac)
 	rte_free(buf);
 	return 0;
 }
+
+int
+osdep_iface_mtu_set(__rte_unused const char *if_name, __rte_unused uint16_t mtu)
+{
+	PMD_LOG(ERR, "mtu set not supported on freebsd\n");
+	return -ENOTSUP;
+}
diff --git a/drivers/net/pcap/pcap_osdep_linux.c b/drivers/net/pcap/pcap_osdep_linux.c
index 97033f57c5..b0b4a716fe 100644
--- a/drivers/net/pcap/pcap_osdep_linux.c
+++ b/drivers/net/pcap/pcap_osdep_linux.c
@@ -40,3 +40,24 @@  osdep_iface_mac_get(const char *if_name, struct rte_ether_addr *mac)
 	close(if_fd);
 	return 0;
 }
+
+int
+osdep_iface_mtu_set(const char *if_name, uint16_t mtu)
+{
+	struct ifreq ifr;
+	int if_fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+	if (if_fd == -1)
+		return -1;
+
+	rte_strscpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
+	ifr.ifr_mtu = mtu;
+	if (ioctl(if_fd, SIOCSIFMTU, &ifr)) {
+		PMD_LOG(ERR, "%s mtu set to %d failed\n", if_name, mtu);
+		close(if_fd);
+		return -1;
+	}
+
+	close(if_fd);
+	return 0;
+}
diff --git a/drivers/net/pcap/pcap_osdep_windows.c b/drivers/net/pcap/pcap_osdep_windows.c
index 1d398dc7ed..db34fc49e2 100644
--- a/drivers/net/pcap/pcap_osdep_windows.c
+++ b/drivers/net/pcap/pcap_osdep_windows.c
@@ -116,3 +116,10 @@  osdep_iface_mac_get(const char *device_name, struct rte_ether_addr *mac)
 	free(info);
 	return ret;
 }
+
+int
+osdep_iface_mtu_set(__rte_unused const char *device_name, __rte_unused uint16_t mtu)
+{
+	PMD_LOG(ERR, "mtu set not supported on Windows\n");
+	return -ENOTSUP;
+}