DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs
@ 2021-04-10  9:18 Min Hu (Connor)
  2021-04-12 23:08 ` Ferruh Yigit
                   ` (8 more replies)
  0 siblings, 9 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-10  9:18 UTC (permalink / raw)
  To: dev; +Cc: thomas, ferruh.yigit, andrew.rybchenko

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 lib/librte_ethdev/rte_ethdev.c | 158 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 155 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 6b5cfd6..93ad8b3 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -199,6 +199,9 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL || devargs_str == NULL)
+		return -EINVAL;
+
 	memset(iter, 0, sizeof(*iter));
 
 	/*
@@ -293,7 +296,7 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
-	if (iter->cls == NULL) /* invalid ethdev iterator */
+	if (iter == NULL || iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
 	do { /* loop to try all matching rte_device */
@@ -322,7 +325,7 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
-	if (iter->bus_str == NULL)
+	if (iter == NULL || iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
 	free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */
@@ -428,6 +431,9 @@ rte_eth_dev_allocated(const char *name)
 {
 	struct rte_eth_dev *ethdev;
 
+	if (name == NULL)
+		return NULL;
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -472,6 +478,9 @@ rte_eth_dev_allocate(const char *name)
 	struct rte_eth_dev *eth_dev = NULL;
 	size_t name_len;
 
+	if (name == NULL)
+		return NULL;
+
 	name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN);
 	if (name_len == 0) {
 		RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n");
@@ -525,6 +534,9 @@ rte_eth_dev_attach_secondary(const char *name)
 	uint16_t i;
 	struct rte_eth_dev *eth_dev = NULL;
 
+	if (name == NULL)
+		return NULL;
+
 	eth_dev_shared_data_prepare();
 
 	/* Synchronize port attachment to primary port creation and release. */
@@ -622,6 +634,9 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL)
+		return -EINVAL;
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -678,6 +693,9 @@ rte_eth_dev_owner_set(const uint16_t port_id,
 {
 	int ret;
 
+	if (owner == NULL)
+		return -EINVAL;
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -741,6 +759,9 @@ rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 	int ret = 0;
 	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
 
+	if (owner == NULL)
+		return -EINVAL;
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -820,7 +841,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 {
 	uint16_t pid;
 
-	if (name == NULL) {
+	if (name == NULL || port_id == NULL) {
 		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
 		return -EINVAL;
 	}
@@ -1297,6 +1318,9 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	int ret;
 	uint16_t old_mtu;
 
+	if (dev_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -1576,6 +1600,9 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 void
 rte_eth_dev_internal_reset(struct rte_eth_dev *dev)
 {
+	if (dev == NULL)
+		return;
+
 	if (dev->data->dev_started) {
 		RTE_ETHDEV_LOG(ERR, "Port %u must be stopped to allow reset\n",
 			dev->data->port_id);
@@ -2137,6 +2164,9 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	int i;
 	int count;
 
+	if (conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -2309,6 +2339,9 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 	int count;
 	int ret;
 
+	if (conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
@@ -2459,6 +2492,9 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL)
+		return -EINVAL;
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2491,6 +2527,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
 
+	if (queue_id >= dev->data->nb_tx_queues) {
+		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
+			       dev->data->nb_tx_queues);
+		return -EINVAL;
+	}
+
 	/* Call driver to free pending mbufs. */
 	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
 					       free_cnt);
@@ -2606,6 +2648,9 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 {
 	struct rte_eth_dev *dev;
 
+	if (eth_link == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -2626,6 +2671,9 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 {
 	struct rte_eth_dev *dev;
 
+	if (eth_link == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -2667,6 +2715,9 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL || eth_link == NULL)
+		return -EINVAL;
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2683,6 +2734,9 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
 	struct rte_eth_dev *dev;
 
+	if (stats == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -3257,6 +3311,9 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 {
 	struct rte_eth_dev *dev;
 
+	if (fw_version == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -3278,6 +3335,9 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	if (dev_info == NULL)
+		return -EINVAL;
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3325,6 +3385,9 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 	struct rte_eth_dev *dev;
 	const uint32_t *all_ptypes;
 
+	if (ptypes == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
@@ -3434,6 +3497,9 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 {
 	struct rte_eth_dev *dev;
 
+	if (mac_addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
@@ -3446,6 +3512,9 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 {
 	struct rte_eth_dev *dev;
 
+	if (mtu == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -3695,6 +3764,9 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 {
 	struct rte_eth_dev *dev;
 
+	if (fc_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
@@ -3707,6 +3779,9 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 {
 	struct rte_eth_dev *dev;
 
+	if (fc_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
@@ -3724,6 +3799,9 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (pfc_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
@@ -3795,6 +3873,9 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	struct rte_eth_dev *dev;
 	int ret;
 
+	if (reta_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
@@ -3822,6 +3903,9 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 	struct rte_eth_dev *dev;
 	int ret;
 
+	if (reta_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	/* Check mask bits */
@@ -3843,6 +3927,9 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
 	int ret;
 
+	if (rss_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
@@ -3871,6 +3958,9 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (rss_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
@@ -4026,6 +4116,9 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 	uint64_t pool_mask;
 	int ret;
 
+	if (addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
@@ -4076,6 +4169,9 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 	struct rte_eth_dev *dev;
 	int index;
 
+	if (addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
@@ -4107,6 +4203,9 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 	struct rte_eth_dev *dev;
 	int ret;
 
+	if (addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	if (!rte_is_valid_assigned_ether_addr(addr))
@@ -4162,6 +4261,9 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 	int ret;
 	struct rte_eth_dev *dev;
 
+	if (addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -4264,6 +4366,9 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (mirror_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
@@ -4447,6 +4552,9 @@ rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	struct rte_eth_dev_callback dev_cb;
 	int rc = 0;
 
+	if (dev == NULL)
+		return -EINVAL;
+
 	rte_spinlock_lock(&eth_dev_cb_lock);
 	TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) {
 		if (cb_lst->cb_fn == NULL || cb_lst->event != event)
@@ -4568,6 +4676,9 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 	const struct rte_memzone *mz;
 	int rc;
 
+	if (dev == NULL || ring_name == NULL)
+		return NULL;
+
 	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
 			queue_id, ring_name);
 	if (rc >= RTE_MEMZONE_NAMESIZE) {
@@ -4602,6 +4713,9 @@ rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name,
 	const struct rte_memzone *mz;
 	int rc = 0;
 
+	if (dev == NULL || ring_name == NULL)
+		return -EINVAL;
+
 	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
 			queue_id, ring_name);
 	if (rc >= RTE_MEMZONE_NAMESIZE) {
@@ -4628,6 +4742,9 @@ rte_eth_dev_create(struct rte_device *device, const char *name,
 	struct rte_eth_dev *ethdev;
 	int retval;
 
+	if (device == NULL)
+		return -EINVAL;
+
 	RTE_FUNC_PTR_OR_ERR_RET(*ethdev_init, -EINVAL);
 
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
@@ -5207,6 +5324,9 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 {
 	struct rte_eth_dev *dev;
 
+	if (timestamp == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5221,6 +5341,9 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (timestamp == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5247,6 +5370,9 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 {
 	struct rte_eth_dev *dev;
 
+	if (timestamp == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5260,6 +5386,9 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 {
 	struct rte_eth_dev *dev;
 
+	if (timestamp == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5273,6 +5402,9 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 {
 	struct rte_eth_dev *dev;
 
+	if (clock == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5370,6 +5502,9 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (dcb_info == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -5421,6 +5556,9 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (cap == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -5432,6 +5570,9 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 int
 rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 {
+	if (dev == NULL || queue_id >= RTE_MAX_QUEUES_PER_PORT)
+		return -EINVAL;
+
 	if (dev->data->rx_queue_state[queue_id] ==
 	    RTE_ETH_QUEUE_STATE_HAIRPIN)
 		return 1;
@@ -5441,6 +5582,9 @@ rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 int
 rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 {
+	if (dev == NULL || queue_id >= RTE_MAX_QUEUES_PER_PORT)
+		return -EINVAL;
+
 	if (dev->data->tx_queue_state[queue_id] ==
 	    RTE_ETH_QUEUE_STATE_HAIRPIN)
 		return 1;
@@ -5487,6 +5631,9 @@ rte_eth_switch_domain_alloc(uint16_t *domain_id)
 {
 	uint16_t i;
 
+	if (domain_id == NULL)
+		return -EINVAL;
+
 	*domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
 
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
@@ -5590,6 +5737,9 @@ rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)
 	unsigned int i;
 	int result = 0;
 
+	if (dargs == NULL || eth_da == NULL)
+		return -EINVAL;
+
 	memset(eth_da, 0, sizeof(*eth_da));
 
 	result = eth_dev_devargs_tokenise(&args, dargs);
@@ -5629,6 +5779,8 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
 	struct rte_eth_representor_info *info = NULL;
 	size_t size;
 
+	if (ethdev == NULL)
+		return -EINVAL;
 	if (type == RTE_ETH_REPRESENTOR_NONE)
 		return 0;
 	if (repr_id == NULL)
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
@ 2021-04-12 23:08 ` Ferruh Yigit
  2021-04-13  3:23   ` Min Hu (Connor)
  2021-04-13  3:22 ` [dpdk-dev] [PATCH v2] " Min Hu (Connor)
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-12 23:08 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: thomas, andrew.rybchenko

On 4/10/2021 10:18 AM, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>

Thanks Connor for the patch, please find a few minor comments below.

<...>

> @@ -3822,6 +3903,9 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
>   	struct rte_eth_dev *dev;
>   	int ret;
>   
> +	if (reta_conf == NULL)
> +		return -EINVAL;
> +

The 'eth_check_reta_mask()' & 'eth_check_reta_entry()' static fucntions are also 
checking 'reta_conf' against NULL, they may be removed after these checks.

<...>

> @@ -4447,6 +4552,9 @@ rte_eth_dev_callback_process(struct rte_eth_dev *dev,
>   	struct rte_eth_dev_callback dev_cb;
>   	int rc = 0;
>   
> +	if (dev == NULL)
> +		return -EINVAL;
> +

This is internal API, not sure if needed to verify 'dev' here, it won't hurt of 
course, but just to prevent unnecessary checks. No strong option.

Same comment for all internal functions that changed.

<...>

> @@ -5370,6 +5502,9 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
>   {
>   	struct rte_eth_dev *dev;
>   
> +	if (dcb_info == NULL)
> +		return -EINVAL;
> +

Function documentation in the header file, doesn't list '-EINVAL' as a return 
value, whenever a new return value is returned, it needs to be documented.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v2] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
  2021-04-12 23:08 ` Ferruh Yigit
@ 2021-04-13  3:22 ` Min Hu (Connor)
  2021-04-13  8:44   ` Andrew Rybchenko
  2021-04-29 17:48   ` Tyler Retzlaff
  2021-04-14 11:11 ` [dpdk-dev] [PATCH v3] " Min Hu (Connor)
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-13  3:22 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
v2:
* Removed unnecessary checks.
* Deleted checks in internal API.
* Added documentation in the header file.

---
 lib/librte_ethdev/rte_ethdev.c | 131 ++++++++++++++++++++++++++++++++++++++---
 lib/librte_ethdev/rte_ethdev.h |  21 ++++++-
 2 files changed, 140 insertions(+), 12 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 6b5cfd6..e1655b5 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -199,6 +199,9 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL || devargs_str == NULL)
+		return -EINVAL;
+
 	memset(iter, 0, sizeof(*iter));
 
 	/*
@@ -293,7 +296,7 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
-	if (iter->cls == NULL) /* invalid ethdev iterator */
+	if (iter == NULL || iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
 	do { /* loop to try all matching rte_device */
@@ -322,7 +325,7 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
-	if (iter->bus_str == NULL)
+	if (iter == NULL || iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
 	free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */
@@ -622,6 +625,9 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL)
+		return -EINVAL;
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -678,6 +684,9 @@ rte_eth_dev_owner_set(const uint16_t port_id,
 {
 	int ret;
 
+	if (owner == NULL)
+		return -EINVAL;
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -741,6 +750,9 @@ rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 	int ret = 0;
 	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
 
+	if (owner == NULL)
+		return -EINVAL;
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -820,7 +832,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 {
 	uint16_t pid;
 
-	if (name == NULL) {
+	if (name == NULL || port_id == NULL) {
 		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
 		return -EINVAL;
 	}
@@ -1297,6 +1309,9 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	int ret;
 	uint16_t old_mtu;
 
+	if (dev_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -2137,6 +2152,9 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	int i;
 	int count;
 
+	if (conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -2309,6 +2327,9 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 	int count;
 	int ret;
 
+	if (conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
@@ -2459,6 +2480,9 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL)
+		return -EINVAL;
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2491,6 +2515,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
 
+	if (queue_id >= dev->data->nb_tx_queues) {
+		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
+			       dev->data->nb_tx_queues);
+		return -EINVAL;
+	}
+
 	/* Call driver to free pending mbufs. */
 	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
 					       free_cnt);
@@ -2606,6 +2636,9 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 {
 	struct rte_eth_dev *dev;
 
+	if (eth_link == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -2626,6 +2659,9 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 {
 	struct rte_eth_dev *dev;
 
+	if (eth_link == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -2667,6 +2703,9 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL || eth_link == NULL)
+		return -EINVAL;
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2683,6 +2722,9 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
 	struct rte_eth_dev *dev;
 
+	if (stats == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -3257,6 +3299,9 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 {
 	struct rte_eth_dev *dev;
 
+	if (fw_version == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -3278,6 +3323,9 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	if (dev_info == NULL)
+		return -EINVAL;
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3325,6 +3373,9 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 	struct rte_eth_dev *dev;
 	const uint32_t *all_ptypes;
 
+	if (ptypes == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
@@ -3434,6 +3485,9 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 {
 	struct rte_eth_dev *dev;
 
+	if (mac_addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
@@ -3446,6 +3500,9 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 {
 	struct rte_eth_dev *dev;
 
+	if (mtu == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -3695,6 +3752,9 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 {
 	struct rte_eth_dev *dev;
 
+	if (fc_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
@@ -3707,6 +3767,9 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 {
 	struct rte_eth_dev *dev;
 
+	if (fc_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
@@ -3724,6 +3787,9 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (pfc_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
@@ -3744,9 +3810,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3763,9 +3826,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3795,6 +3855,9 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	struct rte_eth_dev *dev;
 	int ret;
 
+	if (reta_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
@@ -3822,6 +3885,9 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 	struct rte_eth_dev *dev;
 	int ret;
 
+	if (reta_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	/* Check mask bits */
@@ -3843,6 +3909,9 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
 	int ret;
 
+	if (rss_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
@@ -3871,6 +3940,9 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (rss_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
@@ -4026,6 +4098,9 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 	uint64_t pool_mask;
 	int ret;
 
+	if (addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
@@ -4076,6 +4151,9 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 	struct rte_eth_dev *dev;
 	int index;
 
+	if (addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
@@ -4107,6 +4185,9 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 	struct rte_eth_dev *dev;
 	int ret;
 
+	if (addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	if (!rte_is_valid_assigned_ether_addr(addr))
@@ -4162,6 +4243,9 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 	int ret;
 	struct rte_eth_dev *dev;
 
+	if (addr == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -4264,6 +4348,9 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (mirror_conf == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
@@ -4602,6 +4689,9 @@ rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name,
 	const struct rte_memzone *mz;
 	int rc = 0;
 
+	if (dev == NULL || ring_name == NULL)
+		return -EINVAL;
+
 	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
 			queue_id, ring_name);
 	if (rc >= RTE_MEMZONE_NAMESIZE) {
@@ -5207,6 +5297,9 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 {
 	struct rte_eth_dev *dev;
 
+	if (timestamp == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5221,6 +5314,9 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (timestamp == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5247,6 +5343,9 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 {
 	struct rte_eth_dev *dev;
 
+	if (timestamp == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5260,6 +5359,9 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 {
 	struct rte_eth_dev *dev;
 
+	if (timestamp == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5273,6 +5375,9 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 {
 	struct rte_eth_dev *dev;
 
+	if (clock == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
@@ -5370,6 +5475,9 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (dcb_info == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -5421,6 +5529,9 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 
+	if (cap == NULL)
+		return -EINVAL;
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
@@ -5629,6 +5740,8 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
 	struct rte_eth_representor_info *info = NULL;
 	size_t size;
 
+	if (ethdev == NULL)
+		return -EINVAL;
 	if (type == RTE_ETH_REPRESENTOR_NONE)
 		return 0;
 	if (repr_id == NULL)
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 3b773b6..5c03e9a 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3427,6 +3434,7 @@ rte_eth_tx_buffer_count_callback(struct rte_mbuf **pkts, uint16_t unsent,
  *     -ENODEV: Invalid interface
  *     -EIO: device is removed
  *     -ENOTSUP: Driver does not support function
+ *     -EINVAL: Bad parameter
  *   Success: >= 0
  *     0-n: Number of packets freed. More packets may still remain in ring that
  *     are in use.
@@ -3774,6 +3782,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3845,7 +3854,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4044,6 +4054,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4112,6 +4123,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4628,6 +4640,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4694,6 +4707,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4797,6 +4811,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs
  2021-04-12 23:08 ` Ferruh Yigit
@ 2021-04-13  3:23   ` Min Hu (Connor)
  0 siblings, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-13  3:23 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: thomas, andrew.rybchenko

Hi, Ferruh,
	Thanks for your comment.
	All has been fixed in v2, please check it out.
	Thanks.

在 2021/4/13 7:08, Ferruh Yigit 写道:
> On 4/10/2021 10:18 AM, Min Hu (Connor) wrote:
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and 
>> variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple 
>> process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> 
> Thanks Connor for the patch, please find a few minor comments below.
> 
> <...>
> 
>> @@ -3822,6 +3903,9 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
>>       struct rte_eth_dev *dev;
>>       int ret;
>> +    if (reta_conf == NULL)
>> +        return -EINVAL;
>> +
> 
> The 'eth_check_reta_mask()' & 'eth_check_reta_entry()' static fucntions 
> are also checking 'reta_conf' against NULL, they may be removed after 
> these checks.
> 
> <...>
> 
>> @@ -4447,6 +4552,9 @@ rte_eth_dev_callback_process(struct rte_eth_dev 
>> *dev,
>>       struct rte_eth_dev_callback dev_cb;
>>       int rc = 0;
>> +    if (dev == NULL)
>> +        return -EINVAL;
>> +
> 
> This is internal API, not sure if needed to verify 'dev' here, it won't 
> hurt of course, but just to prevent unnecessary checks. No strong option.
> 
> Same comment for all internal functions that changed.
> 
> <...>
> 
>> @@ -5370,6 +5502,9 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
>>   {
>>       struct rte_eth_dev *dev;
>> +    if (dcb_info == NULL)
>> +        return -EINVAL;
>> +
> 
> Function documentation in the header file, doesn't list '-EINVAL' as a 
> return value, whenever a new return value is returned, it needs to be 
> documented.
> .

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: add sanity checks in control APIs
  2021-04-13  3:22 ` [dpdk-dev] [PATCH v2] " Min Hu (Connor)
@ 2021-04-13  8:44   ` Andrew Rybchenko
  2021-04-13  8:58     ` Thomas Monjalon
  2021-04-14 11:12     ` Min Hu (Connor)
  2021-04-29 17:48   ` Tyler Retzlaff
  1 sibling, 2 replies; 65+ messages in thread
From: Andrew Rybchenko @ 2021-04-13  8:44 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: ferruh.yigit, thomas

On 4/13/21 6:22 AM, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>

Many thanks for working on it. Few notes below.

[snip]

> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index 6b5cfd6..e1655b5 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -678,6 +684,9 @@ rte_eth_dev_owner_set(const uint16_t port_id,
>  {
>  	int ret;
>  
> +	if (owner == NULL)
> +		return -EINVAL;
> +

Here and in many-many cases below I think the order of checks
is important in cases when different error codes are returned.
When there is no any very good reasons why arguments should
be checked in different order, arguments should be checked in
order specified in function prototype. In this cases (and many
cases below), port_id should be checked first.

In this particular case it means that the pointer check
should be done in a static helper function.

One more point is error logging in the case of failure.
Right now I'd use RTE_ETHDEV_LOG(ERR, ...). May be later we'll
find out that some of messages should be made INFO or DEBUG.
Something like:
   RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
port_id);

I'm not 100% sure in format, but my requirements are:
 - log messages should be unique
 - log messages should be human readable (i.e. I'd avoid
   usage of function name)
 - log messages should provide enough information to understand
   what went wrong and provide context (basically it correlates
   with uniqueness requirement)

@Thomas, @Ferruh, what do you think? It would be good if we
reach an argement before mass changes are done?

> @@ -2491,6 +2515,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
>  
> +	if (queue_id >= dev->data->nb_tx_queues) {
> +		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
> +			       dev->data->nb_tx_queues);
> +		return -EINVAL;
> +	}
> +

I'm not 100% sure that it is a control path.

>  	/* Call driver to free pending mbufs. */
>  	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
>  					       free_cnt);

[snip]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: add sanity checks in control APIs
  2021-04-13  8:44   ` Andrew Rybchenko
@ 2021-04-13  8:58     ` Thomas Monjalon
  2021-04-13  9:24       ` Ferruh Yigit
  2021-04-14 11:12     ` Min Hu (Connor)
  1 sibling, 1 reply; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-13  8:58 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: Min Hu (Connor), dev, ferruh.yigit

13/04/2021 10:44, Andrew Rybchenko:
> On 4/13/21 6:22 AM, Min Hu (Connor) wrote:
> > @@ -678,6 +684,9 @@ rte_eth_dev_owner_set(const uint16_t port_id,
> >  {
> >  	int ret;
> >  
> > +	if (owner == NULL)
> > +		return -EINVAL;
> > +
> 
> Here and in many-many cases below I think the order of checks
> is important in cases when different error codes are returned.
> When there is no any very good reasons why arguments should
> be checked in different order, arguments should be checked in
> order specified in function prototype. In this cases (and many
> cases below), port_id should be checked first.
> 
> In this particular case it means that the pointer check
> should be done in a static helper function.
> 
> One more point is error logging in the case of failure.
> Right now I'd use RTE_ETHDEV_LOG(ERR, ...). May be later we'll
> find out that some of messages should be made INFO or DEBUG.
> Something like:
>    RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
> port_id);
> 
> I'm not 100% sure in format, but my requirements are:
>  - log messages should be unique
>  - log messages should be human readable (i.e. I'd avoid
>    usage of function name)
>  - log messages should provide enough information to understand
>    what went wrong and provide context (basically it correlates
>    with uniqueness requirement)
> 
> @Thomas, @Ferruh, what do you think? It would be good if we
> reach an argement before mass changes are done?

I agree with all your comments Andrew.


> > @@ -2491,6 +2515,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
> >  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> >  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
> >  
> > +	if (queue_id >= dev->data->nb_tx_queues) {
> > +		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
> > +			       dev->data->nb_tx_queues);
> > +		return -EINVAL;
> > +	}
> > +
> 
> I'm not 100% sure that it is a control path.

Indeed it can be used in the data path of some algorithms.




^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: add sanity checks in control APIs
  2021-04-13  8:58     ` Thomas Monjalon
@ 2021-04-13  9:24       ` Ferruh Yigit
  0 siblings, 0 replies; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-13  9:24 UTC (permalink / raw)
  To: Thomas Monjalon, Andrew Rybchenko; +Cc: Min Hu (Connor), dev

On 4/13/2021 9:58 AM, Thomas Monjalon wrote:
> 13/04/2021 10:44, Andrew Rybchenko:
>> On 4/13/21 6:22 AM, Min Hu (Connor) wrote:
>>> @@ -678,6 +684,9 @@ rte_eth_dev_owner_set(const uint16_t port_id,
>>>   {
>>>   	int ret;
>>>   
>>> +	if (owner == NULL)
>>> +		return -EINVAL;
>>> +
>>
>> Here and in many-many cases below I think the order of checks
>> is important in cases when different error codes are returned.
>> When there is no any very good reasons why arguments should
>> be checked in different order, arguments should be checked in
>> order specified in function prototype. In this cases (and many
>> cases below), port_id should be checked first.
>>
>> In this particular case it means that the pointer check
>> should be done in a static helper function.
>>
>> One more point is error logging in the case of failure.
>> Right now I'd use RTE_ETHDEV_LOG(ERR, ...). May be later we'll
>> find out that some of messages should be made INFO or DEBUG.
>> Something like:
>>     RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
>> port_id);
>>
>> I'm not 100% sure in format, but my requirements are:
>>   - log messages should be unique
>>   - log messages should be human readable (i.e. I'd avoid
>>     usage of function name)
>>   - log messages should provide enough information to understand
>>     what went wrong and provide context (basically it correlates
>>     with uniqueness requirement)
>>
>> @Thomas, @Ferruh, what do you think? It would be good if we
>> reach an argement before mass changes are done?
> 
> I agree with all your comments Andrew.
> 

+1

> 
>>> @@ -2491,6 +2515,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
>>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
>>>   
>>> +	if (queue_id >= dev->data->nb_tx_queues) {
>>> +		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
>>> +			       dev->data->nb_tx_queues);
>>> +		return -EINVAL;
>>> +	}
>>> +
>>
>> I'm not 100% sure that it is a control path.
> 
> Indeed it can be used in the data path of some algorithms.
> 
> 
> 


^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v3] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
  2021-04-12 23:08 ` Ferruh Yigit
  2021-04-13  3:22 ` [dpdk-dev] [PATCH v2] " Min Hu (Connor)
@ 2021-04-14 11:11 ` Min Hu (Connor)
  2021-04-14 12:00   ` Andrew Rybchenko
  2021-04-15  0:52 ` [dpdk-dev] [PATCH v4] " Min Hu (Connor)
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-14 11:11 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, andrew.rybchenko, thomas

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
v3:
* set port_id checked first.
* add error logging.

v2:
* Removed unnecessary checks.
* Deleted checks in internal API.
* Added documentation in the header file.
---
 lib/librte_ethdev/rte_ethdev.c | 274 ++++++++++++++++++++++++++++++++++++++---
 lib/librte_ethdev/rte_ethdev.h |  20 ++-
 2 files changed, 271 insertions(+), 23 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 6b5cfd6..dfebcc9 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -199,6 +199,9 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL || devargs_str == NULL)
+		return -EINVAL;
+
 	memset(iter, 0, sizeof(*iter));
 
 	/*
@@ -293,7 +296,7 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
-	if (iter->cls == NULL) /* invalid ethdev iterator */
+	if (iter == NULL || iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
 	do { /* loop to try all matching rte_device */
@@ -322,7 +325,7 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
-	if (iter->bus_str == NULL)
+	if (iter == NULL || iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
 	free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */
@@ -622,6 +625,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get owner id by NULL\n");
+		return -EINVAL;
+	}
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -645,6 +653,12 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 		return -ENODEV;
 	}
 
+	if (new_owner == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!eth_is_valid_owner_id(new_owner->id) &&
 	    !eth_is_valid_owner_id(old_owner_id)) {
 		RTE_ETHDEV_LOG(ERR,
@@ -738,23 +752,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
-	int ret = 0;
-	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
-
-	eth_dev_shared_data_prepare();
+	struct rte_eth_dev *ethdev;
 
-	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
 
-	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
+	ethdev = &rte_eth_devices[port_id];
+	if (!eth_dev_is_allocated(ethdev)) {
 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
 			port_id);
-		ret = -ENODEV;
-	} else {
-		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
+		return -ENODEV;
+	}
+
+	if (owner == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u owner by NULL\n",
+			port_id);
+		return -EINVAL;
 	}
 
+	eth_dev_shared_data_prepare();
+
+	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
-	return ret;
+
+	return 0;
 }
 
 int
@@ -820,7 +841,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 {
 	uint16_t pid;
 
-	if (name == NULL) {
+	if (name == NULL || port_id == NULL) {
 		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
 		return -EINVAL;
 	}
@@ -1299,6 +1320,12 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (dev_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to configure ethdev port %u to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
@@ -2139,6 +2166,12 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
@@ -2310,6 +2343,13 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Tx hairpin queue to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
@@ -2459,6 +2499,11 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set error callback for NULL\n");
+		return -EINVAL;
+	}
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2491,6 +2536,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
 
+	if (queue_id >= dev->data->nb_tx_queues) {
+		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
+			       dev->data->nb_tx_queues);
+		return -EINVAL;
+	}
+
 	/* Call driver to free pending mbufs. */
 	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
 					       free_cnt);
@@ -2607,6 +2658,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u link by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	if (dev->data->dev_conf.intr_conf.lsc &&
@@ -2627,6 +2685,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u nowait link by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	if (dev->data->dev_conf.intr_conf.lsc &&
@@ -2667,6 +2732,9 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL || eth_link == NULL)
+		return -EINVAL;
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2685,6 +2753,12 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (stats == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u stats by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	memset(stats, 0, sizeof(*stats));
 
@@ -3258,6 +3332,13 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (fw_version == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u fw version by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
@@ -3278,6 +3359,14 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (dev_info == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u info by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3285,7 +3374,6 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	dev_info->rx_desc_lim = lim;
@@ -3326,6 +3414,13 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 	const uint32_t *all_ptypes;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u supported ptypes by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
@@ -3435,6 +3530,13 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (mac_addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MAC address by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
 
@@ -3448,6 +3550,12 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (mtu == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MTU by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	*mtu = dev->data->mtu;
 	return 0;
@@ -3696,6 +3804,13 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u flow conf by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
 	memset(fc_conf, 0, sizeof(*fc_conf));
@@ -3708,6 +3823,13 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
 		return -EINVAL;
@@ -3725,6 +3847,13 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (pfc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u priority flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
 		return -EINVAL;
@@ -3744,9 +3873,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3763,9 +3889,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3796,6 +3919,13 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss reta to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
@@ -3824,6 +3954,12 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to query ethdev port %u rss reta by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
@@ -3845,6 +3981,12 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss hash to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
@@ -3872,6 +4014,13 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u rss hash conf by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
@@ -4027,6 +4176,13 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to add ethdev port %u MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
@@ -4077,6 +4233,13 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 	int index;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to remove ethdev port %u MAC address by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
 
@@ -4109,6 +4272,12 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u default MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!rte_is_valid_assigned_ether_addr(addr))
 		return -EINVAL;
 
@@ -4164,6 +4333,12 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u uc hash table to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	if (rte_is_zero_ether_addr(addr)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
@@ -4265,6 +4440,13 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (mirror_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u mirror rule to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
 		return -EINVAL;
@@ -4602,6 +4784,9 @@ rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name,
 	const struct rte_memzone *mz;
 	int rc = 0;
 
+	if (dev == NULL || ring_name == NULL)
+		return -EINVAL;
+
 	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
 			queue_id, ring_name);
 	if (rc >= RTE_MEMZONE_NAMESIZE) {
@@ -5208,6 +5393,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Rx timestamp by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
@@ -5222,6 +5414,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Tx timestamp by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
@@ -5248,6 +5447,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u time by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
@@ -5261,6 +5467,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to write ethdev port %u time to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
@@ -5274,6 +5487,13 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (clock == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u clock by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
@@ -5372,6 +5592,12 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (dcb_info == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u dcb info by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
 
@@ -5423,6 +5649,12 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (cap == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u hairpin capability by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
 	memset(cap, 0, sizeof(*cap));
@@ -5629,6 +5861,8 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
 	struct rte_eth_representor_info *info = NULL;
 	size_t size;
 
+	if (ethdev == NULL)
+		return -EINVAL;
 	if (type == RTE_ETH_REPRESENTOR_NONE)
 		return 0;
 	if (repr_id == NULL)
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 3b773b6..c1e5d4b 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3774,6 +3781,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3845,7 +3853,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4044,6 +4053,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4112,6 +4122,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4628,6 +4639,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4694,6 +4706,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4797,6 +4810,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: add sanity checks in control APIs
  2021-04-13  8:44   ` Andrew Rybchenko
  2021-04-13  8:58     ` Thomas Monjalon
@ 2021-04-14 11:12     ` Min Hu (Connor)
  1 sibling, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-14 11:12 UTC (permalink / raw)
  To: Andrew Rybchenko, dev; +Cc: ferruh.yigit, thomas

Hi, Thanks Andrew,
	All has been fixed in v3, please review it, thanks.

在 2021/4/13 16:44, Andrew Rybchenko 写道:
> On 4/13/21 6:22 AM, Min Hu (Connor) wrote:
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> 
> Many thanks for working on it. Few notes below.
> 
> [snip]
> 
>> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
>> index 6b5cfd6..e1655b5 100644
>> --- a/lib/librte_ethdev/rte_ethdev.c
>> +++ b/lib/librte_ethdev/rte_ethdev.c
>> @@ -678,6 +684,9 @@ rte_eth_dev_owner_set(const uint16_t port_id,
>>   {
>>   	int ret;
>>   
>> +	if (owner == NULL)
>> +		return -EINVAL;
>> +
> 
> Here and in many-many cases below I think the order of checks
> is important in cases when different error codes are returned.
> When there is no any very good reasons why arguments should
> be checked in different order, arguments should be checked in
> order specified in function prototype. In this cases (and many
> cases below), port_id should be checked first.
> 
> In this particular case it means that the pointer check
> should be done in a static helper function.
> 
> One more point is error logging in the case of failure.
> Right now I'd use RTE_ETHDEV_LOG(ERR, ...). May be later we'll
> find out that some of messages should be made INFO or DEBUG.
> Something like:
>     RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
> port_id);
> 
> I'm not 100% sure in format, but my requirements are:
>   - log messages should be unique
>   - log messages should be human readable (i.e. I'd avoid
>     usage of function name)
>   - log messages should provide enough information to understand
>     what went wrong and provide context (basically it correlates
>     with uniqueness requirement)
> 
> @Thomas, @Ferruh, what do you think? It would be good if we
> reach an argement before mass changes are done?
> 
>> @@ -2491,6 +2515,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
>>   
>> +	if (queue_id >= dev->data->nb_tx_queues) {
>> +		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
>> +			       dev->data->nb_tx_queues);
>> +		return -EINVAL;
>> +	}
>> +
> 
> I'm not 100% sure that it is a control path.
> 
>>   	/* Call driver to free pending mbufs. */
>>   	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
>>   					       free_cnt);
> 
> [snip]
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v3] ethdev: add sanity checks in control APIs
  2021-04-14 11:11 ` [dpdk-dev] [PATCH v3] " Min Hu (Connor)
@ 2021-04-14 12:00   ` Andrew Rybchenko
  2021-04-15  0:52     ` Min Hu (Connor)
  0 siblings, 1 reply; 65+ messages in thread
From: Andrew Rybchenko @ 2021-04-14 12:00 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: ferruh.yigit, thomas

On 4/14/21 2:11 PM, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org

Please, see below. Error logging is missing in few cases and
I'd like to understand why.

> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
> v3:
> * set port_id checked first.
> * add error logging.
> 
> v2:
> * Removed unnecessary checks.
> * Deleted checks in internal API.
> * Added documentation in the header file.
> ---
>  lib/librte_ethdev/rte_ethdev.c | 274 ++++++++++++++++++++++++++++++++++++++---
>  lib/librte_ethdev/rte_ethdev.h |  20 ++-
>  2 files changed, 271 insertions(+), 23 deletions(-)
> 
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index 6b5cfd6..dfebcc9 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -199,6 +199,9 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>  	char *cls_str = NULL;
>  	int str_size;
>  
> +	if (iter == NULL || devargs_str == NULL)
> +		return -EINVAL;
> +

Is error logging skipped here intentially? Why?

>  	memset(iter, 0, sizeof(*iter));
>  
>  	/*
> @@ -293,7 +296,7 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>  uint16_t
>  rte_eth_iterator_next(struct rte_dev_iterator *iter)
>  {
> -	if (iter->cls == NULL) /* invalid ethdev iterator */
> +	if (iter == NULL || iter->cls == NULL) /* invalid ethdev iterator */
>  		return RTE_MAX_ETHPORTS;

Is error logging skipped here intentially? Why?

>  
>  	do { /* loop to try all matching rte_device */
> @@ -322,7 +325,7 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
>  void
>  rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
>  {
> -	if (iter->bus_str == NULL)
> +	if (iter == NULL || iter->bus_str == NULL)
>  		return; /* nothing to free in pure class filter */

Is error logging skipped here intentially? Why?

>  	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
>  	free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */

[snip]

> @@ -2491,6 +2536,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
>  
> +	if (queue_id >= dev->data->nb_tx_queues) {
> +		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
> +			       dev->data->nb_tx_queues);
> +		return -EINVAL;
> +	}
> +

Again, it is not always a control path. So, I'm not sure that we should
add the check there.

>  	/* Call driver to free pending mbufs. */
>  	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
>  					       free_cnt);

[snip]

> @@ -2667,6 +2732,9 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
>  int
>  rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
>  {
> +	if (str == NULL || eth_link == NULL)
> +		return -EINVAL;
> +

Is error logging skipped here intentionally? Why?

>  	if (eth_link->link_status == ETH_LINK_DOWN)
>  		return snprintf(str, len, "Link down");
>  	else

[snip]

> @@ -4602,6 +4784,9 @@ rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name,
>  	const struct rte_memzone *mz;
>  	int rc = 0;
>  
> +	if (dev == NULL || ring_name == NULL)
> +		return -EINVAL;
> +

Same question about logging here.

>  	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
>  			queue_id, ring_name);
>  	if (rc >= RTE_MEMZONE_NAMESIZE) {

[snip]

> @@ -5629,6 +5861,8 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
>  	struct rte_eth_representor_info *info = NULL;
>  	size_t size;
>  
> +	if (ethdev == NULL)
> +		return -EINVAL;

Question about logging here as well.

>  	if (type == RTE_ETH_REPRESENTOR_NONE)
>  		return 0;
>  	if (repr_id == NULL)

[snip]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
                   ` (2 preceding siblings ...)
  2021-04-14 11:11 ` [dpdk-dev] [PATCH v3] " Min Hu (Connor)
@ 2021-04-15  0:52 ` Min Hu (Connor)
  2021-04-15  8:15   ` Andrew Rybchenko
  2021-04-15 12:04   ` Kevin Traynor
  2021-04-15 11:09 ` [dpdk-dev] [PATCH v5] " Min Hu (Connor)
                   ` (4 subsequent siblings)
  8 siblings, 2 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-15  0:52 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
v4:
* add error logging.
* delete check in control path API.

v3:
* set port_id checked first.
* add error logging.

v2:
* Removed unnecessary checks.
* Deleted checks in internal API.
* Added documentation in the header file.
---
 lib/librte_ethdev/rte_ethdev.c | 288 ++++++++++++++++++++++++++++++++++++++---
 lib/librte_ethdev/rte_ethdev.h |  20 ++-
 2 files changed, 287 insertions(+), 21 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 6b5cfd6..e734a30 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -199,6 +199,16 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to iterator init for NULL\n");
+		return -EINVAL;
+	}
+
+	if (devargs_str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to iterate matching NULL\n");
+		return -EINVAL;
+	}
+
 	memset(iter, 0, sizeof(*iter));
 
 	/*
@@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to iterate next for NULL\n");
+		return RTE_MAX_ETHPORTS;
+	}
+
 	if (iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
@@ -322,6 +337,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to iterator clear up for NULL\n");
+		return;
+	}
+
 	if (iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
@@ -622,6 +642,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get owner id by NULL\n");
+		return -EINVAL;
+	}
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -645,6 +670,12 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 		return -ENODEV;
 	}
 
+	if (new_owner == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!eth_is_valid_owner_id(new_owner->id) &&
 	    !eth_is_valid_owner_id(old_owner_id)) {
 		RTE_ETHDEV_LOG(ERR,
@@ -738,23 +769,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
-	int ret = 0;
-	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
-
-	eth_dev_shared_data_prepare();
+	struct rte_eth_dev *ethdev;
 
-	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
 
-	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
+	ethdev = &rte_eth_devices[port_id];
+	if (!eth_dev_is_allocated(ethdev)) {
 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
 			port_id);
-		ret = -ENODEV;
-	} else {
-		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
+		return -ENODEV;
 	}
 
+	if (owner == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u owner by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	eth_dev_shared_data_prepare();
+
+	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
-	return ret;
+
+	return 0;
 }
 
 int
@@ -820,7 +858,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 {
 	uint16_t pid;
 
-	if (name == NULL) {
+	if (name == NULL || port_id == NULL) {
 		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
 		return -EINVAL;
 	}
@@ -1299,6 +1337,12 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (dev_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to configure ethdev port %u to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
@@ -2139,6 +2183,12 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
@@ -2310,6 +2360,13 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Tx hairpin queue to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
@@ -2459,6 +2516,11 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set error callback for NULL\n");
+		return -EINVAL;
+	}
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2607,6 +2669,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u link by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	if (dev->data->dev_conf.intr_conf.lsc &&
@@ -2627,6 +2696,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u nowait link by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	if (dev->data->dev_conf.intr_conf.lsc &&
@@ -2667,6 +2743,16 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to convert link to NULL\n");
+		return -EINVAL;
+	}
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to convert NULL to string\n");
+		return -EINVAL;
+	}
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2685,6 +2771,12 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (stats == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u stats by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	memset(stats, 0, sizeof(*stats));
 
@@ -3258,6 +3350,13 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (fw_version == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u fw version by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
@@ -3278,6 +3377,14 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (dev_info == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u info by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3285,7 +3392,6 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	dev_info->rx_desc_lim = lim;
@@ -3326,6 +3432,13 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 	const uint32_t *all_ptypes;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u supported ptypes by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
@@ -3435,6 +3548,13 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (mac_addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MAC address by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
 
@@ -3448,6 +3568,12 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (mtu == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MTU by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	*mtu = dev->data->mtu;
 	return 0;
@@ -3696,6 +3822,13 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u flow conf by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
 	memset(fc_conf, 0, sizeof(*fc_conf));
@@ -3708,6 +3841,13 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
 		return -EINVAL;
@@ -3725,6 +3865,13 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (pfc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u priority flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
 		return -EINVAL;
@@ -3744,9 +3891,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3763,9 +3907,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3796,6 +3937,13 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss reta to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
@@ -3824,6 +3972,12 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to query ethdev port %u rss reta by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
@@ -3845,6 +3999,12 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss hash to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
@@ -3872,6 +4032,13 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u rss hash conf by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
@@ -4027,6 +4194,13 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to add ethdev port %u MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
@@ -4077,6 +4251,13 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 	int index;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to remove ethdev port %u MAC address by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
 
@@ -4109,6 +4290,12 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u default MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!rte_is_valid_assigned_ether_addr(addr))
 		return -EINVAL;
 
@@ -4164,6 +4351,12 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u uc hash table to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	if (rte_is_zero_ether_addr(addr)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
@@ -4265,6 +4458,13 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (mirror_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u mirror rule to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
 		return -EINVAL;
@@ -5208,6 +5408,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Rx timestamp by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
@@ -5222,6 +5429,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Tx timestamp by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
@@ -5248,6 +5462,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u time by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
@@ -5261,6 +5482,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to write ethdev port %u time to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
@@ -5274,6 +5502,13 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (clock == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u clock by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
@@ -5372,6 +5607,12 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (dcb_info == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u dcb info by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
 
@@ -5423,6 +5664,12 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
+	if (cap == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u hairpin capability by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
 	memset(cap, 0, sizeof(*cap));
@@ -5629,6 +5876,11 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
 	struct rte_eth_representor_info *info = NULL;
 	size_t size;
 
+	if (ethdev == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get device representor info from NULL\n");
+		return -EINVAL;
+	}
+
 	if (type == RTE_ETH_REPRESENTOR_NONE)
 		return 0;
 	if (repr_id == NULL)
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 3b773b6..c1e5d4b 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3774,6 +3781,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3845,7 +3853,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4044,6 +4053,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4112,6 +4122,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4628,6 +4639,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4694,6 +4706,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4797,6 +4810,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v3] ethdev: add sanity checks in control APIs
  2021-04-14 12:00   ` Andrew Rybchenko
@ 2021-04-15  0:52     ` Min Hu (Connor)
  0 siblings, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-15  0:52 UTC (permalink / raw)
  To: Andrew Rybchenko, dev; +Cc: ferruh.yigit, thomas

Hi, Andrew,
	All has been fixed in v4, check it out, thanks.

在 2021/4/14 20:00, Andrew Rybchenko 写道:
> On 4/14/21 2:11 PM, Min Hu (Connor) wrote:
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
> 
> Please, see below. Error logging is missing in few cases and
> I'd like to understand why.
> 
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> ---
>> v3:
>> * set port_id checked first.
>> * add error logging.
>>
>> v2:
>> * Removed unnecessary checks.
>> * Deleted checks in internal API.
>> * Added documentation in the header file.
>> ---
>>   lib/librte_ethdev/rte_ethdev.c | 274 ++++++++++++++++++++++++++++++++++++++---
>>   lib/librte_ethdev/rte_ethdev.h |  20 ++-
>>   2 files changed, 271 insertions(+), 23 deletions(-)
>>
>> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
>> index 6b5cfd6..dfebcc9 100644
>> --- a/lib/librte_ethdev/rte_ethdev.c
>> +++ b/lib/librte_ethdev/rte_ethdev.c
>> @@ -199,6 +199,9 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>>   	char *cls_str = NULL;
>>   	int str_size;
>>   
>> +	if (iter == NULL || devargs_str == NULL)
>> +		return -EINVAL;
>> +
> 
> Is error logging skipped here intentially? Why?
> 
>>   	memset(iter, 0, sizeof(*iter));
>>   
>>   	/*
>> @@ -293,7 +296,7 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>>   uint16_t
>>   rte_eth_iterator_next(struct rte_dev_iterator *iter)
>>   {
>> -	if (iter->cls == NULL) /* invalid ethdev iterator */
>> +	if (iter == NULL || iter->cls == NULL) /* invalid ethdev iterator */
>>   		return RTE_MAX_ETHPORTS;
> 
> Is error logging skipped here intentially? Why?
> 
>>   
>>   	do { /* loop to try all matching rte_device */
>> @@ -322,7 +325,7 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
>>   void
>>   rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
>>   {
>> -	if (iter->bus_str == NULL)
>> +	if (iter == NULL || iter->bus_str == NULL)
>>   		return; /* nothing to free in pure class filter */
> 
> Is error logging skipped here intentially? Why?
> 
>>   	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
>>   	free(RTE_CAST_FIELD(iter, cls_str, char *)); /* workaround const */
> 
> [snip]
> 
>> @@ -2491,6 +2536,12 @@ rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
>>   
>> +	if (queue_id >= dev->data->nb_tx_queues) {
>> +		RTE_ETHDEV_LOG(ERR, "Queue id should be < %u.",
>> +			       dev->data->nb_tx_queues);
>> +		return -EINVAL;
>> +	}
>> +
> 
> Again, it is not always a control path. So, I'm not sure that we should
> add the check there.
> 
>>   	/* Call driver to free pending mbufs. */
>>   	ret = (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
>>   					       free_cnt);
> 
> [snip]
> 
>> @@ -2667,6 +2732,9 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
>>   int
>>   rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
>>   {
>> +	if (str == NULL || eth_link == NULL)
>> +		return -EINVAL;
>> +
> 
> Is error logging skipped here intentionally? Why?
> 
>>   	if (eth_link->link_status == ETH_LINK_DOWN)
>>   		return snprintf(str, len, "Link down");
>>   	else
> 
> [snip]
> 
>> @@ -4602,6 +4784,9 @@ rte_eth_dma_zone_free(const struct rte_eth_dev *dev, const char *ring_name,
>>   	const struct rte_memzone *mz;
>>   	int rc = 0;
>>   
>> +	if (dev == NULL || ring_name == NULL)
>> +		return -EINVAL;
>> +
> 
> Same question about logging here.
> 
>>   	rc = eth_dev_dma_mzone_name(z_name, sizeof(z_name), dev->data->port_id,
>>   			queue_id, ring_name);
>>   	if (rc >= RTE_MEMZONE_NAMESIZE) {
> 
> [snip]
> 
>> @@ -5629,6 +5861,8 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
>>   	struct rte_eth_representor_info *info = NULL;
>>   	size_t size;
>>   
>> +	if (ethdev == NULL)
>> +		return -EINVAL;
> 
> Question about logging here as well.
> 
>>   	if (type == RTE_ETH_REPRESENTOR_NONE)
>>   		return 0;
>>   	if (repr_id == NULL)
> 
> [snip]
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15  0:52 ` [dpdk-dev] [PATCH v4] " Min Hu (Connor)
@ 2021-04-15  8:15   ` Andrew Rybchenko
  2021-04-15 11:09     ` Min Hu (Connor)
  2021-04-15 11:57     ` Thomas Monjalon
  2021-04-15 12:04   ` Kevin Traynor
  1 sibling, 2 replies; 65+ messages in thread
From: Andrew Rybchenko @ 2021-04-15  8:15 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: ferruh.yigit, thomas

On 4/15/21 3:52 AM, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org

Many thanks. I'll keep log messages gramma review to native
speekers. Content looks good to me.

One minor issue below lost on previous review.

Other than that,

Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>

[snip]

> @@ -1299,6 +1337,12 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (dev_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to configure ethdev port %u to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];

I think it is better to keep:
    RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
    dev = &rte_eth_devices[port_id];
together since they are tightly related. I.e. I'd even remove
empty line between them when it is present and add args
sanity check after the dev assignment.
     >
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);

In theory, the first argument is sufficient to make the ops
check, but I think it is the right solution to keep it as is
since current tendency is to check operation support when
driver callback is really required and we're going to use it.
However, if we do it just after port_id check, we'll have a
way to check for callback support without any side effects
if we provide invalid argument value. I.e. if -ENOTSUP is
returned, callback is not supported, if -EINVAL, callback is
supported (but argument is invalid and nothing done).
However, it looks a bit fragile and not always possible.
Thoughts on it are welcome.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v5] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
                   ` (3 preceding siblings ...)
  2021-04-15  0:52 ` [dpdk-dev] [PATCH v4] " Min Hu (Connor)
@ 2021-04-15 11:09 ` Min Hu (Connor)
  2021-04-15 15:38   ` Ferruh Yigit
                     ` (2 more replies)
  2021-04-16  6:52 ` [dpdk-dev] [PATCH v6] " Min Hu (Connor)
                   ` (3 subsequent siblings)
  8 siblings, 3 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-15 11:09 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, andrew.rybchenko, thomas

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
v5:
* Keep "RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV)"
  and "dev = &rte_eth_devices[port_id]" together.

v4:
* add error logging.
* delete check in control path API.

v3:
* set port_id checked first.
* add error logging.

v2:
* Removed unnecessary checks.
* Deleted checks in internal API.
* Added documentation in the header file.
---
 lib/librte_ethdev/rte_ethdev.c | 313 ++++++++++++++++++++++++++++++++++++-----
 lib/librte_ethdev/rte_ethdev.h |  20 ++-
 2 files changed, 293 insertions(+), 40 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 3059aa5..95115a5 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -199,6 +199,16 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to iterator init for NULL\n");
+		return -EINVAL;
+	}
+
+	if (devargs_str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to iterate matching NULL\n");
+		return -EINVAL;
+	}
+
 	memset(iter, 0, sizeof(*iter));
 
 	/*
@@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to iterate next for NULL\n");
+		return RTE_MAX_ETHPORTS;
+	}
+
 	if (iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
@@ -322,6 +337,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to iterator clear up for NULL\n");
+		return;
+	}
+
 	if (iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
@@ -622,6 +642,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get owner id by NULL\n");
+		return -EINVAL;
+	}
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -645,6 +670,12 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 		return -ENODEV;
 	}
 
+	if (new_owner == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!eth_is_valid_owner_id(new_owner->id) &&
 	    !eth_is_valid_owner_id(old_owner_id)) {
 		RTE_ETHDEV_LOG(ERR,
@@ -738,23 +769,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
-	int ret = 0;
-	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
-
-	eth_dev_shared_data_prepare();
+	struct rte_eth_dev *ethdev;
 
-	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
 
-	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
+	ethdev = &rte_eth_devices[port_id];
+	if (!eth_dev_is_allocated(ethdev)) {
 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
 			port_id);
-		ret = -ENODEV;
-	} else {
-		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
+		return -ENODEV;
 	}
 
+	if (owner == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u owner by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	eth_dev_shared_data_prepare();
+
+	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
-	return ret;
+
+	return 0;
 }
 
 int
@@ -820,7 +858,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 {
 	uint16_t pid;
 
-	if (name == NULL) {
+	if (name == NULL || port_id == NULL) {
 		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
 		return -EINVAL;
 	}
@@ -1298,9 +1336,14 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	uint16_t old_mtu;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
+	if (dev_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to configure ethdev port %u to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -2138,8 +2181,14 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	int count;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
@@ -2311,6 +2360,13 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Tx hairpin queue to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
 		return -EINVAL;
@@ -2459,6 +2515,11 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set error callback for NULL\n");
+		return -EINVAL;
+	}
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2609,6 +2670,12 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u link by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
@@ -2629,6 +2696,12 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u nowait link by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
@@ -2667,6 +2740,16 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to convert link to NULL\n");
+		return -EINVAL;
+	}
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to convert NULL to string\n");
+		return -EINVAL;
+	}
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2684,8 +2767,14 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (stats == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u stats by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(stats, 0, sizeof(*stats));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
@@ -3260,6 +3349,12 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (fw_version == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u fw version by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
 							fw_version, fw_size));
@@ -3278,16 +3373,21 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (dev_info == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u info by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
 	 */
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	dev = &rte_eth_devices[port_id];
-
 	dev_info->rx_desc_lim = lim;
 	dev_info->tx_desc_lim = lim;
 	dev_info->device = dev->device;
@@ -3327,6 +3427,13 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u supported ptypes by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
@@ -3436,6 +3543,13 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (mac_addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MAC address by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
 
 	return 0;
@@ -3447,8 +3561,14 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (mtu == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MTU by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	*mtu = dev->data->mtu;
 	return 0;
 }
@@ -3697,6 +3817,13 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u flow conf by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
 	memset(fc_conf, 0, sizeof(*fc_conf));
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf));
@@ -3708,12 +3835,19 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf));
 }
@@ -3725,12 +3859,19 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (pfc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u priority flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	/* High water, low water validation are device specific */
 	if  (*dev->dev_ops->priority_flow_ctrl_set)
 		return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set)
@@ -3744,9 +3885,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3763,9 +3901,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3796,13 +3931,19 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss reta to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
-
 	/* Check entry value */
 	ret = eth_check_reta_entry(reta_conf, reta_size,
 				dev->data->nb_rx_queues);
@@ -3823,13 +3964,19 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to query ethdev port %u rss reta by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf,
 							    reta_size));
@@ -3844,14 +3991,19 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss hash to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
 
 	rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
-
-	dev = &rte_eth_devices[port_id];
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3873,6 +4025,13 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u rss hash conf by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
 								   rss_conf));
@@ -4028,6 +4187,13 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to add ethdev port %u MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
 	if (rte_is_zero_ether_addr(addr)) {
@@ -4078,6 +4244,13 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to remove ethdev port %u MAC address by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
 
 	index = eth_dev_get_mac_addr_index(port_id, addr);
@@ -4108,11 +4281,17 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u default MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	if (!rte_is_valid_assigned_ether_addr(addr))
 		return -EINVAL;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
 	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
@@ -4163,8 +4342,14 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u uc hash table to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rte_is_zero_ether_addr(addr)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
 			port_id);
@@ -4265,6 +4450,14 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (mirror_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u mirror rule to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
 		return -EINVAL;
@@ -4291,7 +4484,6 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP);
 
 	return eth_err(port_id, (*dev->dev_ops->mirror_rule_set)(dev,
@@ -5210,6 +5402,12 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Rx timestamp by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp)
 				(dev, timestamp, flags));
@@ -5224,6 +5422,12 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Tx timestamp by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp)
 				(dev, timestamp));
@@ -5250,6 +5454,12 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u time by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev,
 								timestamp));
@@ -5263,6 +5473,12 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to write ethdev port %u time to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev,
 								timestamp));
@@ -5276,6 +5492,12 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (clock == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u clock by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
 }
@@ -5361,8 +5583,14 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (dcb_info == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u dcb info by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP);
@@ -5412,8 +5640,14 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (cap == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u hairpin capability by NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
 	memset(cap, 0, sizeof(*cap));
 	return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
@@ -5619,6 +5853,11 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
 	struct rte_eth_representor_info *info = NULL;
 	size_t size;
 
+	if (ethdev == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Failed to get device representor info from NULL\n");
+		return -EINVAL;
+	}
+
 	if (type == RTE_ETH_REPRESENTOR_NONE)
 		return 0;
 	if (repr_id == NULL)
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 6c7c728..29f69ed 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3774,6 +3781,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3845,7 +3853,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4044,6 +4053,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4112,6 +4122,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4623,6 +4634,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4689,6 +4701,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4792,6 +4805,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15  8:15   ` Andrew Rybchenko
@ 2021-04-15 11:09     ` Min Hu (Connor)
  2021-04-15 11:57     ` Thomas Monjalon
  1 sibling, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-15 11:09 UTC (permalink / raw)
  To: Andrew Rybchenko, dev; +Cc: ferruh.yigit, thomas



在 2021/4/15 16:15, Andrew Rybchenko 写道:
> On 4/15/21 3:52 AM, Min Hu (Connor) wrote:
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
> 
> Many thanks. I'll keep log messages gramma review to native
> speekers. Content looks good to me.
> 
> One minor issue below lost on previous review.
> 
> Other than that,
> 
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> 
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> 
> [snip]
> 
>> @@ -1299,6 +1337,12 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (dev_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to configure ethdev port %u to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
> 
> I think it is better to keep:
>      RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>      dev = &rte_eth_devices[port_id];
> together since they are tightly related. I.e. I'd even remove
> empty line between them when it is present and add args
> sanity check after the dev assignment.
>       >
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
> 
Thanks Andrew, this has been fixed in v5.

> In theory, the first argument is sufficient to make the ops
> check, but I think it is the right solution to keep it as is
> since current tendency is to check operation support when
> driver callback is really required and we're going to use it.
> However, if we do it just after port_id check, we'll have a
> way to check for callback support without any side effects
> if we provide invalid argument value. I.e. if -ENOTSUP is
> returned, callback is not supported, if -EINVAL, callback is
> supported (but argument is invalid and nothing done).
> However, it looks a bit fragile and not always possible.
> Thoughts on it are welcome.
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15  8:15   ` Andrew Rybchenko
  2021-04-15 11:09     ` Min Hu (Connor)
@ 2021-04-15 11:57     ` Thomas Monjalon
  2021-04-15 12:03       ` Andrew Rybchenko
  1 sibling, 1 reply; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-15 11:57 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: Min Hu (Connor), dev, ferruh.yigit

15/04/2021 10:15, Andrew Rybchenko:
> >  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
> 
> In theory, the first argument is sufficient to make the ops
> check, but I think it is the right solution to keep it as is
> since current tendency is to check operation support when
> driver callback is really required and we're going to use it.
> However, if we do it just after port_id check, we'll have a
> way to check for callback support without any side effects
> if we provide invalid argument value. I.e. if -ENOTSUP is
> returned, callback is not supported, if -EINVAL, callback is
> supported (but argument is invalid and nothing done).
> However, it looks a bit fragile and not always possible.
> Thoughts on it are welcome.

Sorry I don't understand it fully.
You say we should check for ENOTSUP at the very beginning?



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15 11:57     ` Thomas Monjalon
@ 2021-04-15 12:03       ` Andrew Rybchenko
  2021-04-15 12:20         ` Thomas Monjalon
  0 siblings, 1 reply; 65+ messages in thread
From: Andrew Rybchenko @ 2021-04-15 12:03 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Min Hu (Connor), dev, ferruh.yigit

On 4/15/21 2:57 PM, Thomas Monjalon wrote:
> 15/04/2021 10:15, Andrew Rybchenko:
>>>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
>> In theory, the first argument is sufficient to make the ops
>> check, but I think it is the right solution to keep it as is
>> since current tendency is to check operation support when
>> driver callback is really required and we're going to use it.
>> However, if we do it just after port_id check, we'll have a
>> way to check for callback support without any side effects
>> if we provide invalid argument value. I.e. if -ENOTSUP is
>> returned, callback is not supported, if -EINVAL, callback is
>> supported (but argument is invalid and nothing done).
>> However, it looks a bit fragile and not always possible.
>> Thoughts on it are welcome.
> Sorry I don't understand it fully.
> You say we should check for ENOTSUP at the very beginning?

I'm just trying to consider it and understand if it would be
right or wrong.


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15  0:52 ` [dpdk-dev] [PATCH v4] " Min Hu (Connor)
  2021-04-15  8:15   ` Andrew Rybchenko
@ 2021-04-15 12:04   ` Kevin Traynor
  2021-04-15 12:15     ` Thomas Monjalon
  2021-04-16  7:00     ` Min Hu (Connor)
  1 sibling, 2 replies; 65+ messages in thread
From: Kevin Traynor @ 2021-04-15 12:04 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko

On 15/04/2021 01:52, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 

Hi Connor,

A few general comments,

--
Some of the functions have unit tests, you could consider adding unit
tests for the new checks. Considering the checks are not subtle and
unlikely to be messed up in future, not adding unit tests is not a
blocker imho.

--
It took me a while to get what you meant with "by NULL". It's usage
seems like in "Death by taxes". Perhaps "because NULL ptr" would be a
better way to phrase this generically, but I think it is more useful to
say what is NULL.

e.g. "Failed to convert NULL to string\n" is very generic and would be
better as "Failed to convert NULL link to string\n" . ok, still a bit
generic but more of a clue.

I won't comment on each log message individually but I've added a few
suggestions here and there.
--

Did you check the usage of these functions in DPDK, and if the return
value is handled ok? e.g. RTE_ETH_FOREACH_MATCHING_DEV will keep calling
iterator functions. I'm not sure that having a return check is needed in
that case, but there could be other cases where you want to take some
different action now.

some other comments inlined,

> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
> v4:
> * add error logging.
> * delete check in control path API.
> 
> v3:
> * set port_id checked first.
> * add error logging.
> 
> v2:
> * Removed unnecessary checks.
> * Deleted checks in internal API.
> * Added documentation in the header file.
> ---
>  lib/librte_ethdev/rte_ethdev.c | 288 ++++++++++++++++++++++++++++++++++++++---
>  lib/librte_ethdev/rte_ethdev.h |  20 ++-
>  2 files changed, 287 insertions(+), 21 deletions(-)
> 
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index 6b5cfd6..e734a30 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -199,6 +199,16 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>  	char *cls_str = NULL;
>  	int str_size;
>  
> +	if (iter == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to iterator init for NULL\n");

"Failed to init iterator for NULL iterator\n"

> +		return -EINVAL;
> +	}
> +
> +	if (devargs_str == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to iterate matching NULL\n");

"Failed to init iterator for NULL devargs\n"

> +		return -EINVAL;
> +	}
> +
>  	memset(iter, 0, sizeof(*iter));
>  
>  	/*
> @@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>  uint16_t
>  rte_eth_iterator_next(struct rte_dev_iterator *iter)
>  {
> +	if (iter == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to iterate next for NULL\n");
> +		return RTE_MAX_ETHPORTS;
> +	}
> +
>  	if (iter->cls == NULL) /* invalid ethdev iterator */
>  		return RTE_MAX_ETHPORTS;
>  
> @@ -322,6 +337,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
>  void
>  rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
>  {
> +	if (iter == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to iterator clear up for NULL\n");
> +		return;
> +	}
> +
>  	if (iter->bus_str == NULL)
>  		return; /* nothing to free in pure class filter */
>  	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
> @@ -622,6 +642,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
>  int
>  rte_eth_dev_owner_new(uint64_t *owner_id)
>  {
> +	if (owner_id == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get owner id by NULL\n");
> +		return -EINVAL;
> +	}
> +
>  	eth_dev_shared_data_prepare();
>  
>  	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
> @@ -645,6 +670,12 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
>  		return -ENODEV;
>  	}
>  
> +	if (new_owner == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if (!eth_is_valid_owner_id(new_owner->id) &&
>  	    !eth_is_valid_owner_id(old_owner_id)) {
>  		RTE_ETHDEV_LOG(ERR,
> @@ -738,23 +769,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
>  int
>  rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
>  {
> -	int ret = 0;
> -	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
> -
> -	eth_dev_shared_data_prepare();
> +	struct rte_eth_dev *ethdev;
>  
> -	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
>  
> -	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
> +	ethdev = &rte_eth_devices[port_id];
> +	if (!eth_dev_is_allocated(ethdev)) {
>  		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
>  			port_id);
> -		ret = -ENODEV;
> -	} else {
> -		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
> +		return -ENODEV;
>  	}
>  
> +	if (owner == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u owner by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}

This fn uses both %u and %"PRIu16" for port_id

> +
> +	eth_dev_shared_data_prepare();
> +
> +	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
> +	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
>  	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
> -	return ret;
> +
> +	return 0;
>  }
>  
>  int
> @@ -820,7 +858,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
>  {
>  	uint16_t pid;
>  
> -	if (name == NULL) {
> +	if (name == NULL || port_id == NULL) {

Most of the other new checks have individual checks for NULL ptrs, this
one doesn't. I'm not sure if it needs individual checks, but it is
better to be consistent.

>  		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
>  		return -EINVAL;
>  	}
> @@ -1299,6 +1337,12 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (dev_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to configure ethdev port %u to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
> @@ -2139,6 +2183,12 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	if (rx_queue_id >= dev->data->nb_rx_queues) {
>  		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
> @@ -2310,6 +2360,13 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
>  	int ret;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Tx hairpin queue to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	if (tx_queue_id >= dev->data->nb_tx_queues) {
>  		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
> @@ -2459,6 +2516,11 @@ int
>  rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
>  		buffer_tx_error_fn cbfn, void *userdata)
>  {
> +	if (buffer == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to set error callback for NULL\n");
> +		return -EINVAL;
> +	}
> +
>  	buffer->error_callback = cbfn;
>  	buffer->error_userdata = userdata;
>  	return 0;
> @@ -2607,6 +2669,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (eth_link == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u link by NULL\n",

"by NULL" does not read nicely to me. How about
"Failed to get ethdev port %u for NULL link"

> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	if (dev->data->dev_conf.intr_conf.lsc &&
> @@ -2627,6 +2696,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (eth_link == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u nowait link by NULL\n",
> +			port_id);

Same comment as for previous function, except you'll probably want to
keep nowait somewhere to distinguish.
"Failed to get nowait ethdev port %u for NULL link" ?

> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	if (dev->data->dev_conf.intr_conf.lsc &&
> @@ -2667,6 +2743,16 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
>  int
>  rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
>  {

The messages are very generic, especially the second one. Suggestions below

> +	if (str == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to convert link to NULL\n");

"Failed to convert link to NULL string\n"

> +		return -EINVAL;
> +	}

You should probably also check the 'len' param for str here also.

> +
> +	if (eth_link == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to convert NULL to string\n");

"Failed to convert NULL link to string\n"

> +		return -EINVAL;
> +	}
> +
>  	if (eth_link->link_status == ETH_LINK_DOWN)
>  		return snprintf(str, len, "Link down");
>  	else
> @@ -2685,6 +2771,12 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (stats == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u stats by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	memset(stats, 0, sizeof(*stats));
>  
> @@ -3258,6 +3350,13 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (fw_version == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u fw version by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}

Some of the drivers already check for NULL ptrs and some don't. It means
some checks could be removed from the drivers, but it doesn't seem a
worthwhile effort unless they are needing some rework anyway.

'fw_size == 0' could also be checked here

> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
> @@ -3278,6 +3377,14 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
>  	};
>  	int diag;
>  
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (dev_info == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u info by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	/*
>  	 * Init dev_info before port_id check since caller does not have
>  	 * return status and does not know if get is successful or not.
> @@ -3285,7 +3392,6 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
>  	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
>  	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
>  
> -	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);

This is a slight change in behaviour. With an invalid port, previously
dev_info was memset to 0. Does it need to be? I guess no.

At the very least the comment block is incorrect and should be changed.

>  	dev = &rte_eth_devices[port_id];
>  
>  	dev_info->rx_desc_lim = lim;
> @@ -3326,6 +3432,13 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>  	const uint32_t *all_ptypes;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (ptypes == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u supported ptypes by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +

'num == 0' could be checked here too.

>  	dev = &rte_eth_devices[port_id];
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
>  	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
> @@ -3435,6 +3548,13 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (mac_addr == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MAC address by NULL\n",

"by NULL" doesn't read correctly.
"Failed to get ethdev port %u MAC address for NULL param\n"

> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
>  
> @@ -3448,6 +3568,12 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (mtu == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MTU by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	*mtu = dev->data->mtu;
>  	return 0;
> @@ -3696,6 +3822,13 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (fc_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u flow conf by NULL\n",

I would at least add "flow *ctrl* conf" e.g.
"Failed to get ethdev port %u flow ctrl conf for NULL param\n"

> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
>  	memset(fc_conf, 0, sizeof(*fc_conf));
> @@ -3708,6 +3841,13 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (fc_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u flow conf to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
>  		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
>  		return -EINVAL;
> @@ -3725,6 +3865,13 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (pfc_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u priority flow conf to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
>  		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
>  		return -EINVAL;
> @@ -3744,9 +3891,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
>  {
>  	uint16_t i, num;
>  
> -	if (!reta_conf)
> -		return -EINVAL;
> -
>  	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
>  	for (i = 0; i < num; i++) {
>  		if (reta_conf[i].mask)
> @@ -3763,9 +3907,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
>  {
>  	uint16_t i, idx, shift;
>  
> -	if (!reta_conf)
> -		return -EINVAL;
> -
>  	if (max_rxq == 0) {
>  		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
>  		return -EINVAL;
> @@ -3796,6 +3937,13 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
>  	int ret;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (reta_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss reta to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +

You may want to check reta_size as well in these rss functions?

>  	/* Check mask bits */
>  	ret = eth_check_reta_mask(reta_conf, reta_size);
>  	if (ret < 0)
> @@ -3824,6 +3972,12 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (reta_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to query ethdev port %u rss reta by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	/* Check mask bits */
>  	ret = eth_check_reta_mask(reta_conf, reta_size);
>  	if (ret < 0)
> @@ -3845,6 +3999,12 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (rss_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss hash to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	ret = rte_eth_dev_info_get(port_id, &dev_info);
>  	if (ret != 0)
>  		return ret;
> @@ -3872,6 +4032,13 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (rss_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u rss hash conf by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
>  	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
> @@ -4027,6 +4194,13 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
>  	int ret;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (addr == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to add ethdev port %u MAC address to NULL\n",
> +			port_id);

This message is a bit confusing. Perhaps,
"Failed to add NULL MAC address to ethdev port %u\n"

thanks,
Kevin.

> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
>  
> @@ -4077,6 +4251,13 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
>  	int index;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (addr == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to remove ethdev port %u MAC address by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
>  
> @@ -4109,6 +4290,12 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (addr == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u default MAC address to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if (!rte_is_valid_assigned_ether_addr(addr))
>  		return -EINVAL;
>  
> @@ -4164,6 +4351,12 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (addr == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u uc hash table to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	if (rte_is_zero_ether_addr(addr)) {
>  		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
> @@ -4265,6 +4458,13 @@ rte_eth_mirror_rule_set(uint16_t port_id,
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (mirror_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u mirror rule to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if (mirror_conf->rule_type == 0) {
>  		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
>  		return -EINVAL;
> @@ -5208,6 +5408,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (timestamp == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Rx timestamp by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
> @@ -5222,6 +5429,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (timestamp == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Tx timestamp by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
> @@ -5248,6 +5462,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (timestamp == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u time by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
> @@ -5261,6 +5482,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (timestamp == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to write ethdev port %u time to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
> @@ -5274,6 +5502,13 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>  	struct rte_eth_dev *dev;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (clock == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u clock by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
> @@ -5372,6 +5607,12 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (dcb_info == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u dcb info by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
>  
> @@ -5423,6 +5664,12 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  
> +	if (cap == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u hairpin capability by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	dev = &rte_eth_devices[port_id];
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
>  	memset(cap, 0, sizeof(*cap));
> @@ -5629,6 +5876,11 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
>  	struct rte_eth_representor_info *info = NULL;
>  	size_t size;
>  
> +	if (ethdev == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get device representor info from NULL\n");
> +		return -EINVAL;
> +	}
> +
>  	if (type == RTE_ETH_REPRESENTOR_NONE)
>  		return 0;
>  	if (repr_id == NULL)
> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
> index 3b773b6..c1e5d4b 100644
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
>   *   - (0) if successful.
>   *   - (-ENOTSUP) if the function is not supported in PMD driver.
>   *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
>  
> @@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
>   *   - (0) if successful.
>   *   - (-ENOTSUP) if the function is not supported in PMD driver.
>   *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
>  
> @@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
>   * @param eth_link
>   *   Link status returned by rte_eth_link_get function
>   * @return
> - *   Number of bytes written to str array.
> + *   Number of bytes written to str array or -EINVAL if bad parameter.
>   */
>  __rte_experimental
>  int rte_eth_link_to_str(char *str, size_t len,
> @@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
>   * @return
>   *   - (0) if successful
>   *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
>  
> @@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
>   *   - (0) if successful.
>   *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
>   *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
>  
> @@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
>   *   - (-ENOTSUP) if operation is not supported.
>   *   - (-ENODEV) if *port_id* invalid.
>   *   - (-EIO) if device is removed.
> + *   - (-EINVAL) if bad parameter.
>   *   - (>0) if *fw_size* is not enough to store firmware version, return
>   *          the size of the non truncated string.
>   */
> @@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
>   *           only num entries will be filled into the ptypes array, but the full
>   *           count of supported ptypes will be returned.
>   *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>  				     uint32_t *ptypes, int num);
> @@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
>   * @return
>   *   - (0) if successful.
>   *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
>  
> @@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
>   * @param userdata
>   *   Arbitrary parameter to be passed to the callback function
>   * @return
> - *   0 on success, or -1 on error with rte_errno set appropriately
> + *   0 on success, or -EINVAL if bad parameter
>   */
>  int
>  rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
> @@ -3774,6 +3781,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
>   *   - (-ENOTSUP) if hardware doesn't support flow control.
>   *   - (-ENODEV)  if *port_id* invalid.
>   *   - (-EIO)  if device is removed.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
>  			      struct rte_eth_fc_conf *fc_conf);
> @@ -3845,7 +3853,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
>   *   - (0) if successful, or *mac_addr* didn't exist.
>   *   - (-ENOTSUP) if hardware doesn't support.
>   *   - (-ENODEV) if *port* invalid.
> - *   - (-EADDRINUSE) if attempting to remove the default MAC address
> + *   - (-EADDRINUSE) if attempting to remove the default MAC address.
> + *   - (-EINVAL) if MAC address is invalid.
>   */
>  int rte_eth_dev_mac_addr_remove(uint16_t port_id,
>  				struct rte_ether_addr *mac_addr);
> @@ -4044,6 +4053,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
>   *   - (-ENODEV) if port identifier is invalid.
>   *   - (-EIO) if device is removed.
>   *   - (-ENOTSUP) if hardware doesn't support RSS.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int
>  rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
> @@ -4112,6 +4122,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
>   *   - (-ENODEV) if port identifier is invalid.
>   *   - (-EIO) if device is removed.
>   *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-EINVAL) if bad parameter.
>   */
>  int rte_eth_dev_get_dcb_info(uint16_t port_id,
>  			     struct rte_eth_dcb_info *dcb_info);
> @@ -4628,6 +4639,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
>   *
>   * @return
>   *   - 0: Success.
> + *   - -EINVAL: Bad parameter.
>   */
>  int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
>  
> @@ -4694,6 +4706,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
>   *   - 0: Success.
>   *   - -ENODEV: The port ID is invalid.
>   *   - -ENOTSUP: The function is not supported by the Ethernet driver.
> + *   - -EINVAL: if bad parameter.
>   */
>  __rte_experimental
>  int
> @@ -4797,6 +4810,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
>   * @return
>   *   - (0) if successful.
>   *   - (-ENOTSUP) if hardware doesn't support.
> + *   - (-EINVAL) if bad parameter.
>   */
>  __rte_experimental
>  int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
> 


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15 12:04   ` Kevin Traynor
@ 2021-04-15 12:15     ` Thomas Monjalon
  2021-04-16  7:01       ` Min Hu (Connor)
  2021-04-16  7:00     ` Min Hu (Connor)
  1 sibling, 1 reply; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-15 12:15 UTC (permalink / raw)
  To: Min Hu (Connor), Kevin Traynor; +Cc: dev, ferruh.yigit, andrew.rybchenko

15/04/2021 14:04, Kevin Traynor:
> On 15/04/2021 01:52, Min Hu (Connor) wrote:
> > +	if (iter == NULL) {
> > +		RTE_ETHDEV_LOG(ERR, "Failed to iterator init for NULL\n");
> 
> "Failed to init iterator for NULL iterator\n"

The word "Failed" looks weird in these checks.
What about "Cannot"?
Example: "Cannot init NULL iterator"

> > +	if (devargs_str == NULL) {
> > +		RTE_ETHDEV_LOG(ERR, "Failed to iterate matching NULL\n");
> 
> "Failed to init iterator for NULL devargs\n"

"Cannot init iterator for NULL devargs"

> > +	if (owner == NULL) {
> > +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u owner by NULL\n",
> > +			port_id);
> > +		return -EINVAL;
> > +	}
> 
> This fn uses both %u and %"PRIu16" for port_id

I don't see the benefit of PRIu16.

> > +	if (str == NULL) {
> > +		RTE_ETHDEV_LOG(ERR, "Failed to convert link to NULL\n");
> 
> "Failed to convert link to NULL string\n"

"Cannot convert link in NULL string"

> > +	if (eth_link == NULL) {
> > +		RTE_ETHDEV_LOG(ERR, "Failed to convert NULL to string\n");
> 
> "Failed to convert NULL link to string\n"

"Cannot convert NULL link"




^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15 12:03       ` Andrew Rybchenko
@ 2021-04-15 12:20         ` Thomas Monjalon
  2021-04-15 12:43           ` Andrew Rybchenko
  0 siblings, 1 reply; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-15 12:20 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: Min Hu (Connor), dev, ferruh.yigit

15/04/2021 14:03, Andrew Rybchenko:
> On 4/15/21 2:57 PM, Thomas Monjalon wrote:
> > 15/04/2021 10:15, Andrew Rybchenko:
> >>>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
> >> In theory, the first argument is sufficient to make the ops
> >> check, but I think it is the right solution to keep it as is
> >> since current tendency is to check operation support when
> >> driver callback is really required and we're going to use it.
> >> However, if we do it just after port_id check, we'll have a
> >> way to check for callback support without any side effects
> >> if we provide invalid argument value. I.e. if -ENOTSUP is
> >> returned, callback is not supported, if -EINVAL, callback is
> >> supported (but argument is invalid and nothing done).
> >> However, it looks a bit fragile and not always possible.
> >> Thoughts on it are welcome.
> > Sorry I don't understand it fully.
> > You say we should check for ENOTSUP at the very beginning?
> 
> I'm just trying to consider it and understand if it would be
> right or wrong.

I think it's better to check things when they are required.
If the application does not give the right parameter,
it won't be caught until a supporting device will be used.

If the appplication gives the wrong parameter on purpose,
because it won't be supported, then it's better not calling the function.



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15 12:20         ` Thomas Monjalon
@ 2021-04-15 12:43           ` Andrew Rybchenko
  0 siblings, 0 replies; 65+ messages in thread
From: Andrew Rybchenko @ 2021-04-15 12:43 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Min Hu (Connor), dev, ferruh.yigit

On 4/15/21 3:20 PM, Thomas Monjalon wrote:
> 15/04/2021 14:03, Andrew Rybchenko:
>> On 4/15/21 2:57 PM, Thomas Monjalon wrote:
>>> 15/04/2021 10:15, Andrew Rybchenko:
>>>>>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
>>>> In theory, the first argument is sufficient to make the ops
>>>> check, but I think it is the right solution to keep it as is
>>>> since current tendency is to check operation support when
>>>> driver callback is really required and we're going to use it.
>>>> However, if we do it just after port_id check, we'll have a
>>>> way to check for callback support without any side effects
>>>> if we provide invalid argument value. I.e. if -ENOTSUP is
>>>> returned, callback is not supported, if -EINVAL, callback is
>>>> supported (but argument is invalid and nothing done).
>>>> However, it looks a bit fragile and not always possible.
>>>> Thoughts on it are welcome.
>>> Sorry I don't understand it fully.
>>> You say we should check for ENOTSUP at the very beginning?
>>
>> I'm just trying to consider it and understand if it would be
>> right or wrong.
> 
> I think it's better to check things when they are required.
> If the application does not give the right parameter,
> it won't be caught until a supporting device will be used.
> 
> If the appplication gives the wrong parameter on purpose,
> because it won't be supported, then it's better not calling the function.
> 

OK, makes sense.


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v5] ethdev: add sanity checks in control APIs
  2021-04-15 11:09 ` [dpdk-dev] [PATCH v5] " Min Hu (Connor)
@ 2021-04-15 15:38   ` Ferruh Yigit
  2021-04-16  7:02     ` Min Hu (Connor)
  2021-04-16 16:19     ` Stephen Hemminger
  2021-04-15 15:45   ` Ferruh Yigit
  2021-04-16 16:25   ` Stephen Hemminger
  2 siblings, 2 replies; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-15 15:38 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: andrew.rybchenko, thomas

On 4/15/2021 12:09 PM, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

Hi Connor,

Please find a few comments below, with they are addressed:

Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

> @@ -738,23 +769,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
>   int
>   rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
>   {
> -	int ret = 0;
> -	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
> -
> -	eth_dev_shared_data_prepare();
> +	struct rte_eth_dev *ethdev;
>   
> -	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
>   

Not sure '-1' is a good return value, what do you think sending '-ENODEV' as it 
is mostly done in the file?

Also emptly line can be removed as suggested by Andrew.

<...>

> @@ -2138,8 +2181,14 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
>   	int count;
>   
>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> -
>   	dev = &rte_eth_devices[port_id];
> +
> +	if (conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
> +			port_id);

When the line is long, can you break the message part to next line, to reduce 
the length at least a few columns, like:

RTE_ETHDEV_LOG(ERR,
	"Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
	port_id);

Same for all long messages.

<...>

> @@ -5619,6 +5853,11 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
>   	struct rte_eth_representor_info *info = NULL;
>   	size_t size;
>   
> +	if (ethdev == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get device representor info from NULL\n");
> +		return -EINVAL;
> +	}
> +

This is also an internal function, not sure if we should verify the 'ehtdev' here.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v5] ethdev: add sanity checks in control APIs
  2021-04-15 11:09 ` [dpdk-dev] [PATCH v5] " Min Hu (Connor)
  2021-04-15 15:38   ` Ferruh Yigit
@ 2021-04-15 15:45   ` Ferruh Yigit
  2021-04-15 16:21     ` Thomas Monjalon
  2021-04-16 16:25   ` Stephen Hemminger
  2 siblings, 1 reply; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-15 15:45 UTC (permalink / raw)
  To: Min Hu (Connor), thomas, andrew.rybchenko; +Cc: dev

On 4/15/2021 12:09 PM, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

<...>

> @@ -2684,8 +2767,14 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
>   	struct rte_eth_dev *dev;
>   
>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> -
>   	dev = &rte_eth_devices[port_id];
> +
> +	if (stats == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u stats by NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>   	memset(stats, 0, sizeof(*stats));
>   
>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);

Not exactly related to this patch, but related to the API input, some input that 
is filled by API is memset first before passing it to the PMD, which makes 
sense. And for this we have two different ordering with dev_ops check:

1.
memset(input)
check dev_ops, return error if not supported
call dev_ops

2.
check dev_ops, return error if not supported
memset(input)
call dev_ops

Connor, Thomas, Andrew,
Do you think does it have any benifit to unify it, and is one better than other?

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v5] ethdev: add sanity checks in control APIs
  2021-04-15 15:45   ` Ferruh Yigit
@ 2021-04-15 16:21     ` Thomas Monjalon
  2021-04-16  7:04       ` Min Hu (Connor)
  0 siblings, 1 reply; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-15 16:21 UTC (permalink / raw)
  To: Min Hu (Connor), andrew.rybchenko, Ferruh Yigit; +Cc: dev

15/04/2021 17:45, Ferruh Yigit:
> Not exactly related to this patch, but related to the API input, some input that 
> is filled by API is memset first before passing it to the PMD, which makes 
> sense. And for this we have two different ordering with dev_ops check:
> 
> 1.
> memset(input)
> check dev_ops, return error if not supported
> call dev_ops
> 
> 2.
> check dev_ops, return error if not supported
> memset(input)
> call dev_ops
> 
> Connor, Thomas, Andrew,
> Do you think does it have any benifit to unify it, and is one better than other?

Yes good catch.
It deserves a separate patch to not memset if not needed.
We must check if supported before memset.



^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v6] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
                   ` (4 preceding siblings ...)
  2021-04-15 11:09 ` [dpdk-dev] [PATCH v5] " Min Hu (Connor)
@ 2021-04-16  6:52 ` Min Hu (Connor)
  2021-04-16 10:22   ` Kevin Traynor
  2021-04-16 11:00 ` [dpdk-dev] [PATCH v7] " Min Hu (Connor)
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-16  6:52 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, ktraynor, thomas, andrew.rybchenko

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
v6:
* Change logging grammar.
* "Failed to" change to "Cannot".
* Break the message part to next line.
* Delete param check for internal function.

v5:
* Keep "RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV)"
  and "dev = &rte_eth_devices[port_id]" together.

v4:
* add error logging.
* delete check in control path API.

v3:
* set port_id checked first.
* add error logging.

v2:
* Removed unnecessary checks.
* Deleted checks in internal API.
* Added documentation in the header file.
---
 lib/librte_ethdev/rte_ethdev.c | 365 +++++++++++++++++++++++++++++++++++++----
 lib/librte_ethdev/rte_ethdev.h |  20 ++-
 2 files changed, 349 insertions(+), 36 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 6b5cfd6..9ddd5d7 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -199,6 +199,16 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot init iterator for NULL iterator\n");
+		return -EINVAL;
+	}
+
+	if (devargs_str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot init iterator for NULL devargs\n");
+		return -EINVAL;
+	}
+
 	memset(iter, 0, sizeof(*iter));
 
 	/*
@@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot iterate next for NULL\n");
+		return RTE_MAX_ETHPORTS;
+	}
+
 	if (iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
@@ -322,6 +337,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot iterator clear up for NULL iter\n");
+		return;
+	}
+
 	if (iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
@@ -622,6 +642,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get owner id for NULL param\n");
+		return -EINVAL;
+	}
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -645,6 +670,13 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 		return -ENODEV;
 	}
 
+	if (new_owner == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u owner to NULL new_owner\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!eth_is_valid_owner_id(new_owner->id) &&
 	    !eth_is_valid_owner_id(old_owner_id)) {
 		RTE_ETHDEV_LOG(ERR,
@@ -738,23 +770,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
-	int ret = 0;
-	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
-
-	eth_dev_shared_data_prepare();
-
-	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	struct rte_eth_dev *ethdev;
 
-	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	ethdev = &rte_eth_devices[port_id];
+	if (!eth_dev_is_allocated(ethdev)) {
 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
 			port_id);
-		ret = -ENODEV;
-	} else {
-		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
+		return -ENODEV;
 	}
 
+	if (owner == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %"PRIu16" owner for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	eth_dev_shared_data_prepare();
+
+	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
-	return ret;
+
+	return 0;
 }
 
 int
@@ -825,6 +864,11 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 		return -EINVAL;
 	}
 
+	if (port_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get port id for NULL param\n");
+		return -EINVAL;
+	}
+
 	RTE_ETH_FOREACH_VALID_DEV(pid)
 		if (!strcmp(name, eth_dev_shared_data->data[pid].name)) {
 			*port_id = pid;
@@ -1298,9 +1342,15 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	uint16_t old_mtu;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
+	if (dev_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot configure ethdev port %u to NULL dev_conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -2138,8 +2188,15 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	int count;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Rx hairpin queue to NULL conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
@@ -2311,6 +2368,14 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Tx hairpin queue to NULL conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
 		return -EINVAL;
@@ -2459,6 +2524,12 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set error callback for NULL buffer\n");
+		return -EINVAL;
+	}
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2609,6 +2680,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u link for NULL eth_link\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
@@ -2629,6 +2707,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get nowait ethdev port %u for NULL link\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
@@ -2667,6 +2752,22 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert link to NULL string\n");
+		return -EINVAL;
+	}
+
+	if (len == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot convert link to string with zero len\n");
+		return -EINVAL;
+	}
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert NULL link to string\n");
+		return -EINVAL;
+	}
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2684,8 +2785,15 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (stats == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u stats for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(stats, 0, sizeof(*stats));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
@@ -3260,6 +3368,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (fw_version == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u fw version for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (fw_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u fw version with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
 							fw_version, fw_size));
@@ -3278,6 +3400,13 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	if (dev_info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u info for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3327,6 +3456,21 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported ptypes for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (num == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported ptypes with zero num\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
@@ -3436,6 +3580,14 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (mac_addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u MAC address for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
 
 	return 0;
@@ -3447,8 +3599,15 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (mtu == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u MTU for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	*mtu = dev->data->mtu;
 	return 0;
 }
@@ -3697,6 +3856,14 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u flow conf for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
 	memset(fc_conf, 0, sizeof(*fc_conf));
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf));
@@ -3708,12 +3875,20 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf));
 }
@@ -3725,12 +3900,20 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (pfc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u priority flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	/* High water, low water validation are device specific */
 	if  (*dev->dev_ops->priority_flow_ctrl_set)
 		return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set)
@@ -3744,9 +3927,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3763,9 +3943,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3796,13 +3973,27 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss reta to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (reta_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss reta with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
-
 	/* Check entry value */
 	ret = eth_check_reta_entry(reta_conf, reta_size,
 				dev->data->nb_rx_queues);
@@ -3823,13 +4014,20 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot query ethdev port %u rss reta for NULL reta_conf\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf,
 							    reta_size));
@@ -3844,14 +4042,20 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss hash to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
 
 	rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
-
-	dev = &rte_eth_devices[port_id];
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3873,6 +4077,14 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u rss hash conf for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
 								   rss_conf));
@@ -4028,6 +4240,14 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot add NULL MAC address to ethdev port %u\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
 	if (rte_is_zero_ether_addr(addr)) {
@@ -4078,6 +4298,14 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot remove ethdev port %u MAC address for NULL addr\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
 
 	index = eth_dev_get_mac_addr_index(port_id, addr);
@@ -4108,11 +4336,18 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u default MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	if (!rte_is_valid_assigned_ether_addr(addr))
 		return -EINVAL;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
 	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
@@ -4163,8 +4398,15 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u uc hash table to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rte_is_zero_ether_addr(addr)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
 			port_id);
@@ -4265,6 +4507,15 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (mirror_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u mirror rule to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
 		return -EINVAL;
@@ -4291,7 +4542,6 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP);
 
 	return eth_err(port_id, (*dev->dev_ops->mirror_rule_set)(dev,
@@ -5210,6 +5460,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Rx timestamp for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp)
 				(dev, timestamp, flags));
@@ -5224,6 +5481,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Tx timestamp for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp)
 				(dev, timestamp));
@@ -5250,6 +5514,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u time for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev,
 								timestamp));
@@ -5263,6 +5534,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot write ethdev port %u time to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev,
 								timestamp));
@@ -5276,6 +5554,13 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (clock == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u clock for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
 }
@@ -5371,8 +5656,15 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (dcb_info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u dcb info for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP);
@@ -5422,8 +5714,15 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (cap == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin capability for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
 	memset(cap, 0, sizeof(*cap));
 	return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 3b773b6..c1e5d4b 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3774,6 +3781,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3845,7 +3853,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4044,6 +4053,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4112,6 +4122,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4628,6 +4639,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4694,6 +4706,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4797,6 +4810,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15 12:04   ` Kevin Traynor
  2021-04-15 12:15     ` Thomas Monjalon
@ 2021-04-16  7:00     ` Min Hu (Connor)
  2021-04-16 10:09       ` Kevin Traynor
  1 sibling, 1 reply; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-16  7:00 UTC (permalink / raw)
  To: Kevin Traynor, dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko

Thanks Kevin,
	all is fixed in v6, please review it, thanks.
	Some comments are below.

在 2021/4/15 20:04, Kevin Traynor 写道:
> On 15/04/2021 01:52, Min Hu (Connor) wrote:
>> This patch adds more sanity checks in control path APIs.
>>
> 
> Hi Connor,
> 
> A few general comments,
> 
> --
> Some of the functions have unit tests, you could consider adding unit
> tests for the new checks. Considering the checks are not subtle and
> unlikely to be messed up in future, not adding unit tests is not a
> blocker imho.
> 
> --
> It took me a while to get what you meant with "by NULL". It's usage
> seems like in "Death by taxes". Perhaps "because NULL ptr" would be a
> better way to phrase this generically, but I think it is more useful to
> say what is NULL.
> 
> e.g. "Failed to convert NULL to string\n" is very generic and would be
> better as "Failed to convert NULL link to string\n" . ok, still a bit
> generic but more of a clue.
> 
> I won't comment on each log message individually but I've added a few
> suggestions here and there.
> --
> 
> Did you check the usage of these functions in DPDK, and if the return
> value is handled ok? e.g. RTE_ETH_FOREACH_MATCHING_DEV will keep calling
> iterator functions. I'm not sure that having a return check is needed in
> that case, but there could be other cases where you want to take some
> different action now.
> 
As iterator functions are all APIs, they may be used by APP directly.
I think param check is necessary.
> some other comments inlined,
> 
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> ---
>> v4:
>> * add error logging.
>> * delete check in control path API.
>>
>> v3:
>> * set port_id checked first.
>> * add error logging.
>>
>> v2:
>> * Removed unnecessary checks.
>> * Deleted checks in internal API.
>> * Added documentation in the header file.
>> ---
>>   lib/librte_ethdev/rte_ethdev.c | 288 ++++++++++++++++++++++++++++++++++++++---
>>   lib/librte_ethdev/rte_ethdev.h |  20 ++-
>>   2 files changed, 287 insertions(+), 21 deletions(-)
>>
>> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
>> index 6b5cfd6..e734a30 100644
>> --- a/lib/librte_ethdev/rte_ethdev.c
>> +++ b/lib/librte_ethdev/rte_ethdev.c
>> @@ -199,6 +199,16 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>>   	char *cls_str = NULL;
>>   	int str_size;
>>   
>> +	if (iter == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to iterator init for NULL\n");
> 
> "Failed to init iterator for NULL iterator\n"
> 
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (devargs_str == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to iterate matching NULL\n");
> 
> "Failed to init iterator for NULL devargs\n"
> 
>> +		return -EINVAL;
>> +	}
>> +
>>   	memset(iter, 0, sizeof(*iter));
>>   
>>   	/*
>> @@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>>   uint16_t
>>   rte_eth_iterator_next(struct rte_dev_iterator *iter)
>>   {
>> +	if (iter == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to iterate next for NULL\n");
>> +		return RTE_MAX_ETHPORTS;
>> +	}
>> +
>>   	if (iter->cls == NULL) /* invalid ethdev iterator */
>>   		return RTE_MAX_ETHPORTS;
>>   
>> @@ -322,6 +337,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
>>   void
>>   rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
>>   {
>> +	if (iter == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to iterator clear up for NULL\n");
>> +		return;
>> +	}
>> +
>>   	if (iter->bus_str == NULL)
>>   		return; /* nothing to free in pure class filter */
>>   	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
>> @@ -622,6 +642,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
>>   int
>>   rte_eth_dev_owner_new(uint64_t *owner_id)
>>   {
>> +	if (owner_id == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get owner id by NULL\n");
>> +		return -EINVAL;
>> +	}
>> +
>>   	eth_dev_shared_data_prepare();
>>   
>>   	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
>> @@ -645,6 +670,12 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
>>   		return -ENODEV;
>>   	}
>>   
>> +	if (new_owner == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u owner to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (!eth_is_valid_owner_id(new_owner->id) &&
>>   	    !eth_is_valid_owner_id(old_owner_id)) {
>>   		RTE_ETHDEV_LOG(ERR,
>> @@ -738,23 +769,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
>>   int
>>   rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
>>   {
>> -	int ret = 0;
>> -	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
>> -
>> -	eth_dev_shared_data_prepare();
>> +	struct rte_eth_dev *ethdev;
>>   
>> -	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
>> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
>>   
>> -	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
>> +	ethdev = &rte_eth_devices[port_id];
>> +	if (!eth_dev_is_allocated(ethdev)) {
>>   		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
>>   			port_id);
>> -		ret = -ENODEV;
>> -	} else {
>> -		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
>> +		return -ENODEV;
>>   	}
>>   
>> +	if (owner == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u owner by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
> 
> This fn uses both %u and %"PRIu16" for port_id
> 
>> +
>> +	eth_dev_shared_data_prepare();
>> +
>> +	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
>> +	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
>>   	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
>> -	return ret;
>> +
>> +	return 0;
>>   }
>>   
>>   int
>> @@ -820,7 +858,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
>>   {
>>   	uint16_t pid;
>>   
>> -	if (name == NULL) {
>> +	if (name == NULL || port_id == NULL) {
> 
> Most of the other new checks have individual checks for NULL ptrs, this
> one doesn't. I'm not sure if it needs individual checks, but it is
> better to be consistent.
> 
>>   		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
>>   		return -EINVAL;
>>   	}
>> @@ -1299,6 +1337,12 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (dev_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to configure ethdev port %u to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
>> @@ -2139,6 +2183,12 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	if (rx_queue_id >= dev->data->nb_rx_queues) {
>>   		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
>> @@ -2310,6 +2360,13 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
>>   	int ret;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Tx hairpin queue to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	if (tx_queue_id >= dev->data->nb_tx_queues) {
>>   		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
>> @@ -2459,6 +2516,11 @@ int
>>   rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
>>   		buffer_tx_error_fn cbfn, void *userdata)
>>   {
>> +	if (buffer == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to set error callback for NULL\n");
>> +		return -EINVAL;
>> +	}
>> +
>>   	buffer->error_callback = cbfn;
>>   	buffer->error_userdata = userdata;
>>   	return 0;
>> @@ -2607,6 +2669,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (eth_link == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u link by NULL\n",
> 
> "by NULL" does not read nicely to me. How about
> "Failed to get ethdev port %u for NULL link"
> 
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	if (dev->data->dev_conf.intr_conf.lsc &&
>> @@ -2627,6 +2696,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (eth_link == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u nowait link by NULL\n",
>> +			port_id);
> 
> Same comment as for previous function, except you'll probably want to
> keep nowait somewhere to distinguish.
> "Failed to get nowait ethdev port %u for NULL link" ?
> 
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	if (dev->data->dev_conf.intr_conf.lsc &&
>> @@ -2667,6 +2743,16 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
>>   int
>>   rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
>>   {
> 
> The messages are very generic, especially the second one. Suggestions below
> 
>> +	if (str == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to convert link to NULL\n");
> 
> "Failed to convert link to NULL string\n"
> 
>> +		return -EINVAL;
>> +	}
> 
> You should probably also check the 'len' param for str here also.
> 
>> +
>> +	if (eth_link == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to convert NULL to string\n");
> 
> "Failed to convert NULL link to string\n"
> 
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (eth_link->link_status == ETH_LINK_DOWN)
>>   		return snprintf(str, len, "Link down");
>>   	else
>> @@ -2685,6 +2771,12 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (stats == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u stats by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	memset(stats, 0, sizeof(*stats));
>>   
>> @@ -3258,6 +3350,13 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (fw_version == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u fw version by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
> 
> Some of the drivers already check for NULL ptrs and some don't. It means
> some checks could be removed from the drivers, but it doesn't seem a
> worthwhile effort unless they are needing some rework anyway.
Agreed, this may be fixed in next patch.
> 
> 'fw_size == 0' could also be checked here
> 
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
>> @@ -3278,6 +3377,14 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
>>   	};
>>   	int diag;
>>   
>> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (dev_info == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u info by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	/*
>>   	 * Init dev_info before port_id check since caller does not have
>>   	 * return status and does not know if get is successful or not.
>> @@ -3285,7 +3392,6 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
>>   	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
>>   	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
>>   
>> -	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> 
> This is a slight change in behaviour. With an invalid port, previously
> dev_info was memset to 0. Does it need to be? I guess no.
> 
> At the very least the comment block is incorrect and should be changed.
> 
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	dev_info->rx_desc_lim = lim;
>> @@ -3326,6 +3432,13 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>>   	const uint32_t *all_ptypes;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (ptypes == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u supported ptypes by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
> 
> 'num == 0' could be checked here too.
> 
>>   	dev = &rte_eth_devices[port_id];
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
>>   	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
>> @@ -3435,6 +3548,13 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (mac_addr == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MAC address by NULL\n",
> 
> "by NULL" doesn't read correctly.
> "Failed to get ethdev port %u MAC address for NULL param\n"
> 
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
>>   
>> @@ -3448,6 +3568,12 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (mtu == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u MTU by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	*mtu = dev->data->mtu;
>>   	return 0;
>> @@ -3696,6 +3822,13 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (fc_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u flow conf by NULL\n",
> 
> I would at least add "flow *ctrl* conf" e.g.
> "Failed to get ethdev port %u flow ctrl conf for NULL param\n"
> 
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
>>   	memset(fc_conf, 0, sizeof(*fc_conf));
>> @@ -3708,6 +3841,13 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (fc_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u flow conf to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
>>   		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
>>   		return -EINVAL;
>> @@ -3725,6 +3865,13 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (pfc_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u priority flow conf to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
>>   		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
>>   		return -EINVAL;
>> @@ -3744,9 +3891,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
>>   {
>>   	uint16_t i, num;
>>   
>> -	if (!reta_conf)
>> -		return -EINVAL;
>> -
>>   	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
>>   	for (i = 0; i < num; i++) {
>>   		if (reta_conf[i].mask)
>> @@ -3763,9 +3907,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
>>   {
>>   	uint16_t i, idx, shift;
>>   
>> -	if (!reta_conf)
>> -		return -EINVAL;
>> -
>>   	if (max_rxq == 0) {
>>   		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
>>   		return -EINVAL;
>> @@ -3796,6 +3937,13 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
>>   	int ret;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (reta_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss reta to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
> 
> You may want to check reta_size as well in these rss functions?
> 
>>   	/* Check mask bits */
>>   	ret = eth_check_reta_mask(reta_conf, reta_size);
>>   	if (ret < 0)
>> @@ -3824,6 +3972,12 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (reta_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to query ethdev port %u rss reta by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	/* Check mask bits */
>>   	ret = eth_check_reta_mask(reta_conf, reta_size);
>>   	if (ret < 0)
>> @@ -3845,6 +3999,12 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (rss_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to update ethdev port %u rss hash to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	ret = rte_eth_dev_info_get(port_id, &dev_info);
>>   	if (ret != 0)
>>   		return ret;
>> @@ -3872,6 +4032,13 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (rss_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u rss hash conf by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
>>   	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
>> @@ -4027,6 +4194,13 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
>>   	int ret;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (addr == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to add ethdev port %u MAC address to NULL\n",
>> +			port_id);
> 
> This message is a bit confusing. Perhaps,
> "Failed to add NULL MAC address to ethdev port %u\n"
> 
> thanks,
> Kevin.
> 
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
>>   
>> @@ -4077,6 +4251,13 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
>>   	int index;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (addr == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to remove ethdev port %u MAC address by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
>>   
>> @@ -4109,6 +4290,12 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (addr == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u default MAC address to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (!rte_is_valid_assigned_ether_addr(addr))
>>   		return -EINVAL;
>>   
>> @@ -4164,6 +4351,12 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (addr == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u uc hash table to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	if (rte_is_zero_ether_addr(addr)) {
>>   		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
>> @@ -4265,6 +4458,13 @@ rte_eth_mirror_rule_set(uint16_t port_id,
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (mirror_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to set ethdev port %u mirror rule to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (mirror_conf->rule_type == 0) {
>>   		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
>>   		return -EINVAL;
>> @@ -5208,6 +5408,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (timestamp == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Rx timestamp by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
>> @@ -5222,6 +5429,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (timestamp == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u Tx timestamp by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
>> @@ -5248,6 +5462,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (timestamp == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u time by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
>> @@ -5261,6 +5482,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (timestamp == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to write ethdev port %u time to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
>> @@ -5274,6 +5502,13 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
>>   	struct rte_eth_dev *dev;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +
>> +	if (clock == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to read ethdev port %u clock by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
>> @@ -5372,6 +5607,12 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (dcb_info == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u dcb info by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
>>   
>> @@ -5423,6 +5664,12 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   
>> +	if (cap == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u hairpin capability by NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	dev = &rte_eth_devices[port_id];
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
>>   	memset(cap, 0, sizeof(*cap));
>> @@ -5629,6 +5876,11 @@ rte_eth_representor_id_get(const struct rte_eth_dev *ethdev,
>>   	struct rte_eth_representor_info *info = NULL;
>>   	size_t size;
>>   
>> +	if (ethdev == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Failed to get device representor info from NULL\n");
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (type == RTE_ETH_REPRESENTOR_NONE)
>>   		return 0;
>>   	if (repr_id == NULL)
>> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
>> index 3b773b6..c1e5d4b 100644
>> --- a/lib/librte_ethdev/rte_ethdev.h
>> +++ b/lib/librte_ethdev/rte_ethdev.h
>> @@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
>>    *   - (0) if successful.
>>    *   - (-ENOTSUP) if the function is not supported in PMD driver.
>>    *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
>>   
>> @@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
>>    *   - (0) if successful.
>>    *   - (-ENOTSUP) if the function is not supported in PMD driver.
>>    *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
>>   
>> @@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
>>    * @param eth_link
>>    *   Link status returned by rte_eth_link_get function
>>    * @return
>> - *   Number of bytes written to str array.
>> + *   Number of bytes written to str array or -EINVAL if bad parameter.
>>    */
>>   __rte_experimental
>>   int rte_eth_link_to_str(char *str, size_t len,
>> @@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
>>    * @return
>>    *   - (0) if successful
>>    *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
>>   
>> @@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
>>    *   - (0) if successful.
>>    *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
>>    *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
>>   
>> @@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
>>    *   - (-ENOTSUP) if operation is not supported.
>>    *   - (-ENODEV) if *port_id* invalid.
>>    *   - (-EIO) if device is removed.
>> + *   - (-EINVAL) if bad parameter.
>>    *   - (>0) if *fw_size* is not enough to store firmware version, return
>>    *          the size of the non truncated string.
>>    */
>> @@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
>>    *           only num entries will be filled into the ptypes array, but the full
>>    *           count of supported ptypes will be returned.
>>    *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>>   				     uint32_t *ptypes, int num);
>> @@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
>>    * @return
>>    *   - (0) if successful.
>>    *   - (-ENODEV) if *port_id* invalid.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
>>   
>> @@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
>>    * @param userdata
>>    *   Arbitrary parameter to be passed to the callback function
>>    * @return
>> - *   0 on success, or -1 on error with rte_errno set appropriately
>> + *   0 on success, or -EINVAL if bad parameter
>>    */
>>   int
>>   rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
>> @@ -3774,6 +3781,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
>>    *   - (-ENOTSUP) if hardware doesn't support flow control.
>>    *   - (-ENODEV)  if *port_id* invalid.
>>    *   - (-EIO)  if device is removed.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
>>   			      struct rte_eth_fc_conf *fc_conf);
>> @@ -3845,7 +3853,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
>>    *   - (0) if successful, or *mac_addr* didn't exist.
>>    *   - (-ENOTSUP) if hardware doesn't support.
>>    *   - (-ENODEV) if *port* invalid.
>> - *   - (-EADDRINUSE) if attempting to remove the default MAC address
>> + *   - (-EADDRINUSE) if attempting to remove the default MAC address.
>> + *   - (-EINVAL) if MAC address is invalid.
>>    */
>>   int rte_eth_dev_mac_addr_remove(uint16_t port_id,
>>   				struct rte_ether_addr *mac_addr);
>> @@ -4044,6 +4053,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
>>    *   - (-ENODEV) if port identifier is invalid.
>>    *   - (-EIO) if device is removed.
>>    *   - (-ENOTSUP) if hardware doesn't support RSS.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int
>>   rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
>> @@ -4112,6 +4122,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
>>    *   - (-ENODEV) if port identifier is invalid.
>>    *   - (-EIO) if device is removed.
>>    *   - (-ENOTSUP) if hardware doesn't support.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   int rte_eth_dev_get_dcb_info(uint16_t port_id,
>>   			     struct rte_eth_dcb_info *dcb_info);
>> @@ -4628,6 +4639,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
>>    *
>>    * @return
>>    *   - 0: Success.
>> + *   - -EINVAL: Bad parameter.
>>    */
>>   int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
>>   
>> @@ -4694,6 +4706,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
>>    *   - 0: Success.
>>    *   - -ENODEV: The port ID is invalid.
>>    *   - -ENOTSUP: The function is not supported by the Ethernet driver.
>> + *   - -EINVAL: if bad parameter.
>>    */
>>   __rte_experimental
>>   int
>> @@ -4797,6 +4810,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
>>    * @return
>>    *   - (0) if successful.
>>    *   - (-ENOTSUP) if hardware doesn't support.
>> + *   - (-EINVAL) if bad parameter.
>>    */
>>   __rte_experimental
>>   int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
>>
> 
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-15 12:15     ` Thomas Monjalon
@ 2021-04-16  7:01       ` Min Hu (Connor)
  0 siblings, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-16  7:01 UTC (permalink / raw)
  To: Thomas Monjalon, Kevin Traynor; +Cc: dev, ferruh.yigit, andrew.rybchenko

Hi, Thomas,
	v6 has been sent to fix it, please check it out, thanks.

在 2021/4/15 20:15, Thomas Monjalon 写道:
> 15/04/2021 14:04, Kevin Traynor:
>> On 15/04/2021 01:52, Min Hu (Connor) wrote:
>>> +	if (iter == NULL) {
>>> +		RTE_ETHDEV_LOG(ERR, "Failed to iterator init for NULL\n");
>>
>> "Failed to init iterator for NULL iterator\n"
> 
> The word "Failed" looks weird in these checks.
> What about "Cannot"?
> Example: "Cannot init NULL iterator"
> 
>>> +	if (devargs_str == NULL) {
>>> +		RTE_ETHDEV_LOG(ERR, "Failed to iterate matching NULL\n");
>>
>> "Failed to init iterator for NULL devargs\n"
> 
> "Cannot init iterator for NULL devargs"
> 
>>> +	if (owner == NULL) {
>>> +		RTE_ETHDEV_LOG(ERR, "Failed to get ethdev port %u owner by NULL\n",
>>> +			port_id);
>>> +		return -EINVAL;
>>> +	}
>>
>> This fn uses both %u and %"PRIu16" for port_id
> 
> I don't see the benefit of PRIu16.
> 
>>> +	if (str == NULL) {
>>> +		RTE_ETHDEV_LOG(ERR, "Failed to convert link to NULL\n");
>>
>> "Failed to convert link to NULL string\n"
> 
> "Cannot convert link in NULL string"
> 
>>> +	if (eth_link == NULL) {
>>> +		RTE_ETHDEV_LOG(ERR, "Failed to convert NULL to string\n");
>>
>> "Failed to convert NULL link to string\n"
> 
> "Cannot convert NULL link"
> 
> 
> 
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v5] ethdev: add sanity checks in control APIs
  2021-04-15 15:38   ` Ferruh Yigit
@ 2021-04-16  7:02     ` Min Hu (Connor)
  2021-04-16 16:19     ` Stephen Hemminger
  1 sibling, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-16  7:02 UTC (permalink / raw)
  To: Ferruh Yigit, dev; +Cc: andrew.rybchenko, thomas

Hi, Ferruh,
	v6 has been sent to fix it, please check it out, thanks.

在 2021/4/15 23:38, Ferruh Yigit 写道:
> On 4/15/2021 12:09 PM, Min Hu (Connor) wrote:
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and 
>> variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple 
>> process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> 
> Hi Connor,
> 
> Please find a few comments below, with they are addressed:
> 
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> 
>> @@ -738,23 +769,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
>>   int
>>   rte_eth_dev_owner_get(const uint16_t port_id, struct 
>> rte_eth_dev_owner *owner)
>>   {
>> -    int ret = 0;
>> -    struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
>> -
>> -    eth_dev_shared_data_prepare();
>> +    struct rte_eth_dev *ethdev;
>> -    rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
>> +    RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
> 
> Not sure '-1' is a good return value, what do you think sending 
> '-ENODEV' as it is mostly done in the file?
> 
> Also emptly line can be removed as suggested by Andrew.
> 
> <...>
> 
>> @@ -2138,8 +2181,14 @@ rte_eth_rx_hairpin_queue_setup(uint16_t 
>> port_id, uint16_t rx_queue_id,
>>       int count;
>>       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> -
>>       dev = &rte_eth_devices[port_id];
>> +
>> +    if (conf == NULL) {
>> +        RTE_ETHDEV_LOG(ERR, "Failed to setup ethdev port %u Rx 
>> hairpin queue to NULL\n",
>> +            port_id);
> 
> When the line is long, can you break the message part to next line, to 
> reduce the length at least a few columns, like:
> 
> RTE_ETHDEV_LOG(ERR,
>      "Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
>      port_id);
> 
> Same for all long messages.
> 
> <...>
> 
>> @@ -5619,6 +5853,11 @@ rte_eth_representor_id_get(const struct 
>> rte_eth_dev *ethdev,
>>       struct rte_eth_representor_info *info = NULL;
>>       size_t size;
>> +    if (ethdev == NULL) {
>> +        RTE_ETHDEV_LOG(ERR, "Failed to get device representor info 
>> from NULL\n");
>> +        return -EINVAL;
>> +    }
>> +
> 
> This is also an internal function, not sure if we should verify the 
> 'ehtdev' here.
> .

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v5] ethdev: add sanity checks in control APIs
  2021-04-15 16:21     ` Thomas Monjalon
@ 2021-04-16  7:04       ` Min Hu (Connor)
  0 siblings, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-16  7:04 UTC (permalink / raw)
  To: Thomas Monjalon, andrew.rybchenko, Ferruh Yigit; +Cc: dev



在 2021/4/16 0:21, Thomas Monjalon 写道:
> 15/04/2021 17:45, Ferruh Yigit:
>> Not exactly related to this patch, but related to the API input, some input that
>> is filled by API is memset first before passing it to the PMD, which makes
>> sense. And for this we have two different ordering with dev_ops check:
>>
>> 1.
>> memset(input)
>> check dev_ops, return error if not supported
>> call dev_ops
>>
>> 2.
>> check dev_ops, return error if not supported
>> memset(input)
>> call dev_ops
>>
>> Connor, Thomas, Andrew,
>> Do you think does it have any benifit to unify it, and is one better than other?
> 
> Yes good catch.
> It deserves a separate patch to not memset if not needed.
> We must check if supported before memset.
>
Agreed, I will send next patch to fix it.

>
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-16  7:00     ` Min Hu (Connor)
@ 2021-04-16 10:09       ` Kevin Traynor
  2021-04-16 10:44         ` Min Hu (Connor)
  0 siblings, 1 reply; 65+ messages in thread
From: Kevin Traynor @ 2021-04-16 10:09 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko

On 16/04/2021 08:00, Min Hu (Connor) wrote:
> Thanks Kevin,
> 	all is fixed in v6, please review it, thanks.
> 	Some comments are below.
> 
> 在 2021/4/15 20:04, Kevin Traynor 写道:
>> On 15/04/2021 01:52, Min Hu (Connor) wrote:
>>> This patch adds more sanity checks in control path APIs.
>>>
>>
>> Hi Connor,
>>
>> A few general comments,
>>
>> --
>> Some of the functions have unit tests, you could consider adding unit
>> tests for the new checks. Considering the checks are not subtle and
>> unlikely to be messed up in future, not adding unit tests is not a
>> blocker imho.
>>
>> --
>> It took me a while to get what you meant with "by NULL". It's usage
>> seems like in "Death by taxes". Perhaps "because NULL ptr" would be a
>> better way to phrase this generically, but I think it is more useful to
>> say what is NULL.
>>
>> e.g. "Failed to convert NULL to string\n" is very generic and would be
>> better as "Failed to convert NULL link to string\n" . ok, still a bit
>> generic but more of a clue.
>>
>> I won't comment on each log message individually but I've added a few
>> suggestions here and there.

Thanks, I think it looks a lot nicer to read in v6 my completely
subjective biased opinion :-)

>> --
>>
>> Did you check the usage of these functions in DPDK, and if the return
>> value is handled ok? e.g. RTE_ETH_FOREACH_MATCHING_DEV will keep calling
>> iterator functions. I'm not sure that having a return check is needed in
>> that case, but there could be other cases where you want to take some
>> different action now.
>>
> As iterator functions are all APIs, they may be used by APP directly.
> I think param check is necessary.

The point is that it would continue to call the functions even after it
caught this error, so would continue to print error messages. Yes, that
is much better than a seg fault and maybe in this case that is ok. I
will leave it to maintainers to decided.

I was just wondering if there was additional things similar to this in
DPDK where handling these new errors could now be improved too. I don't
think it has to be a prerequisite for this patch, as this patch is still
an improvement.

>> some other comments inlined,
>>
>>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>>> Fixes: f8244c6399d9 ("ethdev: increase port id range")


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v6] ethdev: add sanity checks in control APIs
  2021-04-16  6:52 ` [dpdk-dev] [PATCH v6] " Min Hu (Connor)
@ 2021-04-16 10:22   ` Kevin Traynor
  2021-04-16 11:00     ` Min Hu (Connor)
  2021-04-16 16:28     ` Stephen Hemminger
  0 siblings, 2 replies; 65+ messages in thread
From: Kevin Traynor @ 2021-04-16 10:22 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko

On 16/04/2021 07:52, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

<snip>

> @@ -1298,9 +1342,15 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  	uint16_t old_mtu;
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> -
>  	dev = &rte_eth_devices[port_id];
>  
> +	if (dev_conf == NULL) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot configure ethdev port %u to NULL dev_conf\n",

The others use a natural sounding names instead of argument name. If you
wanted to match that it could be "..to NULL conf"

> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
>  
>  	if (dev->data->dev_started) {

<snip>

> @@ -2609,6 +2680,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	dev = &rte_eth_devices[port_id];
>  
> +	if (eth_link == NULL) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u link for NULL eth_link\n",

^^^

> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if (dev->data->dev_conf.intr_conf.lsc &&
>  	    dev->data->dev_started)
>  		rte_eth_linkstatus_get(dev, eth_link);
> @@ -2629,6 +2707,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	dev = &rte_eth_devices[port_id];
>  
> +	if (eth_link == NULL) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get nowait ethdev port %u for NULL link\n",

^^^
I would probably stick with "link" for both these functions, rather than
 argument name "eth_link" in one "link" in other.

> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if (dev->data->dev_conf.intr_conf.lsc &&
>  	    dev->data->dev_started)
>  		rte_eth_linkstatus_get(dev, eth_link);

Thanks Connor. There are only minor nits, so
Acked-by: Kevin Traynor <ktraynor@redhat.com>


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: add sanity checks in control APIs
  2021-04-16 10:09       ` Kevin Traynor
@ 2021-04-16 10:44         ` Min Hu (Connor)
  0 siblings, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-16 10:44 UTC (permalink / raw)
  To: Kevin Traynor, dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko



在 2021/4/16 18:09, Kevin Traynor 写道:
> On 16/04/2021 08:00, Min Hu (Connor) wrote:
>> Thanks Kevin,
>> 	all is fixed in v6, please review it, thanks.
>> 	Some comments are below.
>>
>> 在 2021/4/15 20:04, Kevin Traynor 写道:
>>> On 15/04/2021 01:52, Min Hu (Connor) wrote:
>>>> This patch adds more sanity checks in control path APIs.
>>>>
>>>
>>> Hi Connor,
>>>
>>> A few general comments,
>>>
>>> --
>>> Some of the functions have unit tests, you could consider adding unit
>>> tests for the new checks. Considering the checks are not subtle and
>>> unlikely to be messed up in future, not adding unit tests is not a
>>> blocker imho.
>>>
>>> --
>>> It took me a while to get what you meant with "by NULL". It's usage
>>> seems like in "Death by taxes". Perhaps "because NULL ptr" would be a
>>> better way to phrase this generically, but I think it is more useful to
>>> say what is NULL.
>>>
>>> e.g. "Failed to convert NULL to string\n" is very generic and would be
>>> better as "Failed to convert NULL link to string\n" . ok, still a bit
>>> generic but more of a clue.
>>>
>>> I won't comment on each log message individually but I've added a few
>>> suggestions here and there.
> 
> Thanks, I think it looks a lot nicer to read in v6 my completely
> subjective biased opinion :-)
> 
>>> --
>>>
>>> Did you check the usage of these functions in DPDK, and if the return
>>> value is handled ok? e.g. RTE_ETH_FOREACH_MATCHING_DEV will keep calling
>>> iterator functions. I'm not sure that having a return check is needed in
>>> that case, but there could be other cases where you want to take some
>>> different action now.
>>>
>> As iterator functions are all APIs, they may be used by APP directly.
>> I think param check is necessary.
> 
> The point is that it would continue to call the functions even after it
> caught this error, so would continue to print error messages. Yes, that
> is much better than a seg fault and maybe in this case that is ok. I
> will leave it to maintainers to decided.
> 
> I was just wondering if there was additional things similar to this in
> DPDK where handling these new errors could now be improved too. I don't
> think it has to be a prerequisite for this patch, as this patch is still
> an improvement.
> 
Thanks Kevin.
Well, for what your metioned, I will try to look for it.
If found, I will send another patch or initiate discussions.
Thanks.
>>> some other comments inlined,
>>>
>>>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>>>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>>>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>>>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>>>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>>>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> 
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v7] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
                   ` (5 preceding siblings ...)
  2021-04-16  6:52 ` [dpdk-dev] [PATCH v6] " Min Hu (Connor)
@ 2021-04-16 11:00 ` Min Hu (Connor)
  2021-04-16 11:31   ` Ferruh Yigit
  2021-04-16 12:02   ` Thomas Monjalon
  2021-04-17  7:39 ` [dpdk-dev] [PATCH v8] " Min Hu (Connor)
  2021-04-21 12:36 ` [dpdk-dev] [PATCH v10] " Min Hu (Connor)
  8 siblings, 2 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-16 11:00 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, ktraynor, thomas, andrew.rybchenko

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Kevin Traynor <ktraynor@redhat.com>
---
v7:
* use a natural sounding names instead of argument name.

v6:
* Change logging grammar.
* "Failed to" change to "Cannot".
* Break the message part to next line.
* Delete param check for internal function.

v5:
* Keep "RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV)"
  and "dev = &rte_eth_devices[port_id]" together.

v4:
* add error logging.
* delete check in control path API.

v3:
* set port_id checked first.
* add error logging.

v2:
* Removed unnecessary checks.
* Deleted checks in internal API.
* Added documentation in the header file.
---
 lib/librte_ethdev/rte_ethdev.c | 365 +++++++++++++++++++++++++++++++++++++----
 lib/librte_ethdev/rte_ethdev.h |  20 ++-
 2 files changed, 349 insertions(+), 36 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 6b5cfd6..0c23128 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -199,6 +199,16 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot init iterator for NULL iterator\n");
+		return -EINVAL;
+	}
+
+	if (devargs_str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot init iterator for NULL devargs\n");
+		return -EINVAL;
+	}
+
 	memset(iter, 0, sizeof(*iter));
 
 	/*
@@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot iterate next for NULL\n");
+		return RTE_MAX_ETHPORTS;
+	}
+
 	if (iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
@@ -322,6 +337,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot iterator clear up for NULL iter\n");
+		return;
+	}
+
 	if (iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
@@ -622,6 +642,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get owner id for NULL param\n");
+		return -EINVAL;
+	}
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -645,6 +670,13 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 		return -ENODEV;
 	}
 
+	if (new_owner == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u owner to NULL new_owner\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!eth_is_valid_owner_id(new_owner->id) &&
 	    !eth_is_valid_owner_id(old_owner_id)) {
 		RTE_ETHDEV_LOG(ERR,
@@ -738,23 +770,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
-	int ret = 0;
-	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
-
-	eth_dev_shared_data_prepare();
-
-	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	struct rte_eth_dev *ethdev;
 
-	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	ethdev = &rte_eth_devices[port_id];
+	if (!eth_dev_is_allocated(ethdev)) {
 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
 			port_id);
-		ret = -ENODEV;
-	} else {
-		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
+		return -ENODEV;
 	}
 
+	if (owner == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %"PRIu16" owner for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	eth_dev_shared_data_prepare();
+
+	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
-	return ret;
+
+	return 0;
 }
 
 int
@@ -825,6 +864,11 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 		return -EINVAL;
 	}
 
+	if (port_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get port id for NULL param\n");
+		return -EINVAL;
+	}
+
 	RTE_ETH_FOREACH_VALID_DEV(pid)
 		if (!strcmp(name, eth_dev_shared_data->data[pid].name)) {
 			*port_id = pid;
@@ -1298,9 +1342,15 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	uint16_t old_mtu;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
+	if (dev_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot configure ethdev port %u to NULL conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -2138,8 +2188,15 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	int count;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Rx hairpin queue to NULL conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
@@ -2311,6 +2368,14 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Tx hairpin queue to NULL conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
 		return -EINVAL;
@@ -2459,6 +2524,12 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set error callback for NULL buffer\n");
+		return -EINVAL;
+	}
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2609,6 +2680,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u link for NULL link\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
@@ -2629,6 +2707,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get nowait ethdev port %u for NULL link\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
@@ -2667,6 +2752,22 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert link to NULL string\n");
+		return -EINVAL;
+	}
+
+	if (len == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot convert link to string with zero len\n");
+		return -EINVAL;
+	}
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert NULL link to string\n");
+		return -EINVAL;
+	}
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2684,8 +2785,15 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (stats == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u stats for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(stats, 0, sizeof(*stats));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
@@ -3260,6 +3368,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (fw_version == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u fw version for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (fw_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u fw version with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
 							fw_version, fw_size));
@@ -3278,6 +3400,13 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	if (dev_info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u info for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3327,6 +3456,21 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported ptypes for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (num == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported ptypes with zero num\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
@@ -3436,6 +3580,14 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (mac_addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u MAC address for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
 
 	return 0;
@@ -3447,8 +3599,15 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (mtu == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u MTU for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	*mtu = dev->data->mtu;
 	return 0;
 }
@@ -3697,6 +3856,14 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u flow conf for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
 	memset(fc_conf, 0, sizeof(*fc_conf));
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf));
@@ -3708,12 +3875,20 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf));
 }
@@ -3725,12 +3900,20 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (pfc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u priority flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	/* High water, low water validation are device specific */
 	if  (*dev->dev_ops->priority_flow_ctrl_set)
 		return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set)
@@ -3744,9 +3927,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3763,9 +3943,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3796,13 +3973,27 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss reta to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (reta_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss reta with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
-
 	/* Check entry value */
 	ret = eth_check_reta_entry(reta_conf, reta_size,
 				dev->data->nb_rx_queues);
@@ -3823,13 +4014,20 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot query ethdev port %u rss reta for NULL reta_conf\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf,
 							    reta_size));
@@ -3844,14 +4042,20 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss hash to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
 
 	rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
-
-	dev = &rte_eth_devices[port_id];
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3873,6 +4077,14 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u rss hash conf for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
 								   rss_conf));
@@ -4028,6 +4240,14 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot add NULL MAC address to ethdev port %u\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
 	if (rte_is_zero_ether_addr(addr)) {
@@ -4078,6 +4298,14 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot remove ethdev port %u MAC address for NULL addr\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
 
 	index = eth_dev_get_mac_addr_index(port_id, addr);
@@ -4108,11 +4336,18 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u default MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	if (!rte_is_valid_assigned_ether_addr(addr))
 		return -EINVAL;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
 	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
@@ -4163,8 +4398,15 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u uc hash table to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rte_is_zero_ether_addr(addr)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
 			port_id);
@@ -4265,6 +4507,15 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (mirror_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u mirror rule to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
 		return -EINVAL;
@@ -4291,7 +4542,6 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP);
 
 	return eth_err(port_id, (*dev->dev_ops->mirror_rule_set)(dev,
@@ -5210,6 +5460,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Rx timestamp for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp)
 				(dev, timestamp, flags));
@@ -5224,6 +5481,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Tx timestamp for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp)
 				(dev, timestamp));
@@ -5250,6 +5514,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u time for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev,
 								timestamp));
@@ -5263,6 +5534,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot write ethdev port %u time to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev,
 								timestamp));
@@ -5276,6 +5554,13 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (clock == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u clock for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
 }
@@ -5371,8 +5656,15 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (dcb_info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u dcb info for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP);
@@ -5422,8 +5714,15 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (cap == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin capability for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
 	memset(cap, 0, sizeof(*cap));
 	return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 3b773b6..c1e5d4b 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3774,6 +3781,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3845,7 +3853,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4044,6 +4053,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4112,6 +4122,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4628,6 +4639,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4694,6 +4706,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4797,6 +4810,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v6] ethdev: add sanity checks in control APIs
  2021-04-16 10:22   ` Kevin Traynor
@ 2021-04-16 11:00     ` Min Hu (Connor)
  2021-04-16 16:28     ` Stephen Hemminger
  1 sibling, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-16 11:00 UTC (permalink / raw)
  To: Kevin Traynor, dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko

Hi, Kevin and all
	fixed in v7, thanks.

在 2021/4/16 18:22, Kevin Traynor 写道:
> On 16/04/2021 07:52, Min Hu (Connor) wrote:
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> 
> <snip>
> 
>> @@ -1298,9 +1342,15 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>>   	uint16_t old_mtu;
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> -
>>   	dev = &rte_eth_devices[port_id];
>>   
>> +	if (dev_conf == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot configure ethdev port %u to NULL dev_conf\n",
> 
> The others use a natural sounding names instead of argument name. If you
> wanted to match that it could be "..to NULL conf"
> 
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
>>   
>>   	if (dev->data->dev_started) {
> 
> <snip>
> 
>> @@ -2609,6 +2680,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	dev = &rte_eth_devices[port_id];
>>   
>> +	if (eth_link == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u link for NULL eth_link\n",
> 
> ^^^
> 
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (dev->data->dev_conf.intr_conf.lsc &&
>>   	    dev->data->dev_started)
>>   		rte_eth_linkstatus_get(dev, eth_link);
>> @@ -2629,6 +2707,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	dev = &rte_eth_devices[port_id];
>>   
>> +	if (eth_link == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get nowait ethdev port %u for NULL link\n",
> 
> ^^^
> I would probably stick with "link" for both these functions, rather than
>   argument name "eth_link" in one "link" in other.
> 
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (dev->data->dev_conf.intr_conf.lsc &&
>>   	    dev->data->dev_started)
>>   		rte_eth_linkstatus_get(dev, eth_link);
> 
> Thanks Connor. There are only minor nits, so
> Acked-by: Kevin Traynor <ktraynor@redhat.com>
> 
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v7] ethdev: add sanity checks in control APIs
  2021-04-16 11:00 ` [dpdk-dev] [PATCH v7] " Min Hu (Connor)
@ 2021-04-16 11:31   ` Ferruh Yigit
  2021-04-16 12:02   ` Thomas Monjalon
  1 sibling, 0 replies; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-16 11:31 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: ktraynor, thomas, andrew.rybchenko

On 4/16/2021 12:00 PM, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Acked-by: Kevin Traynor <ktraynor@redhat.com>

Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v7] ethdev: add sanity checks in control APIs
  2021-04-16 11:00 ` [dpdk-dev] [PATCH v7] " Min Hu (Connor)
  2021-04-16 11:31   ` Ferruh Yigit
@ 2021-04-16 12:02   ` Thomas Monjalon
  2021-04-17  7:39     ` Min Hu (Connor)
  1 sibling, 1 reply; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-16 12:02 UTC (permalink / raw)
  To: Min Hu (Connor), ferruh.yigit, andrew.rybchenko; +Cc: dev, ktraynor

16/04/2021 13:00, Min Hu (Connor):
> +	if (iter == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Cannot init iterator for NULL iterator\n");

Don't you think it would be better as
"Cannot init NULL iterator"?

>  rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
>  {
> +	if (iter == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Cannot iterator clear up for NULL iter\n");

Cannot clean up NULL iterator.

>  rte_eth_dev_owner_new(uint64_t *owner_id)
>  {
> +	if (owner_id == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Cannot get owner id for NULL param\n");

Cannot return owner id.

> @@ -825,6 +864,11 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
> +	if (port_id == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Cannot get port id for NULL param\n");

Cannot return port ID

etc for all other messages

Do you agree with the idea?



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v5] ethdev: add sanity checks in control APIs
  2021-04-15 15:38   ` Ferruh Yigit
  2021-04-16  7:02     ` Min Hu (Connor)
@ 2021-04-16 16:19     ` Stephen Hemminger
  1 sibling, 0 replies; 65+ messages in thread
From: Stephen Hemminger @ 2021-04-16 16:19 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: Min Hu (Connor), dev, andrew.rybchenko, thomas

On Thu, 15 Apr 2021 16:38:16 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> When the line is long, can you break the message part to next line, to reduce 
> the length at least a few columns, like:
> 
> RTE_ETHDEV_LOG(ERR,
> 	"Failed to setup ethdev port %u Rx hairpin queue to NULL\n",
> 	port_id);
> 
> Same for all long messages.

Why does message have to be so long?
   "Port %u failed: NULL Rx hairpin queue"

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v5] ethdev: add sanity checks in control APIs
  2021-04-15 11:09 ` [dpdk-dev] [PATCH v5] " Min Hu (Connor)
  2021-04-15 15:38   ` Ferruh Yigit
  2021-04-15 15:45   ` Ferruh Yigit
@ 2021-04-16 16:25   ` Stephen Hemminger
  2 siblings, 0 replies; 65+ messages in thread
From: Stephen Hemminger @ 2021-04-16 16:25 UTC (permalink / raw)
  To: Min Hu (Connor); +Cc: dev, ferruh.yigit, andrew.rybchenko, thomas

On Thu, 15 Apr 2021 19:09:19 +0800
"Min Hu (Connor)" <humin29@huawei.com> wrote:

> +		RTE_ETHDEV_LOG(ERR, "Failed to get owner id by NULL\n");

This message is awkward wording.

It would be good time to fix something that has causes problems.
Redefine RTE_ETHDEV_LOG to include the function name.
There are several places where same log message can come from different
ethdev functions.

Then change the error you added to:
	RTE_ETHDEV_LOG(ERR, "NULL owner id");

Which would result in:
	eth_dev_owner_set: NULL owner id





^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v6] ethdev: add sanity checks in control APIs
  2021-04-16 10:22   ` Kevin Traynor
  2021-04-16 11:00     ` Min Hu (Connor)
@ 2021-04-16 16:28     ` Stephen Hemminger
  2021-04-17  0:28       ` Min Hu (Connor)
  2021-04-17  7:42       ` Min Hu (Connor)
  1 sibling, 2 replies; 65+ messages in thread
From: Stephen Hemminger @ 2021-04-16 16:28 UTC (permalink / raw)
  To: Kevin Traynor
  Cc: Min Hu (Connor), dev, ferruh.yigit, thomas, andrew.rybchenko

On Fri, 16 Apr 2021 11:22:02 +0100
Kevin Traynor <ktraynor@redhat.com> wrote:

> > +	if (dev_conf == NULL) {
> > +		RTE_ETHDEV_LOG(ERR,
> > +			"Cannot configure ethdev port %u to NULL dev_conf\n",  
> 
> The others use a natural sounding names instead of argument name. If you
> wanted to match that it could be "..to NULL conf"

I would prefer that error messages don't try to be English sentences.
The wording ends up awkward. and overly wordy.
If function name is automatically included by RTE_ETHDEV_LOG() then
Just:
		RTE_ETHDEV_LOG(ERR, "NULL ethdev")
should be enough for programmer to find/fix the problem

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v6] ethdev: add sanity checks in control APIs
  2021-04-16 16:28     ` Stephen Hemminger
@ 2021-04-17  0:28       ` Min Hu (Connor)
  2021-04-17 21:37         ` Thomas Monjalon
  2021-04-17  7:42       ` Min Hu (Connor)
  1 sibling, 1 reply; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-17  0:28 UTC (permalink / raw)
  To: Stephen Hemminger, Kevin Traynor
  Cc: dev, ferruh.yigit, thomas, andrew.rybchenko



在 2021/4/17 0:28, Stephen Hemminger 写道:
> On Fri, 16 Apr 2021 11:22:02 +0100
> Kevin Traynor <ktraynor@redhat.com> wrote:
> 
>>> +	if (dev_conf == NULL) {
>>> +		RTE_ETHDEV_LOG(ERR,
>>> +			"Cannot configure ethdev port %u to NULL dev_conf\n",
>>
>> The others use a natural sounding names instead of argument name. If you
>> wanted to match that it could be "..to NULL conf"
> 
> I would prefer that error messages don't try to be English sentences.
> The wording ends up awkward. and overly wordy.
> If function name is automatically included by RTE_ETHDEV_LOG() then
> Just:
> 		RTE_ETHDEV_LOG(ERR, "NULL ethdev")
> should be enough for programmer to find/fix the problem
> .
Hi, Stephen,
	Your opinion is quit different from that of Andrew Rybchenko.
	Andrew does not support show function name in the log:
	"- log messages should be human readable (i.e. I'd avoid
    usage of function name)"

	@Andrew ,@Thoms, @Ferruh, @Kevin, so, what's your opinion ?
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v8] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
                   ` (6 preceding siblings ...)
  2021-04-16 11:00 ` [dpdk-dev] [PATCH v7] " Min Hu (Connor)
@ 2021-04-17  7:39 ` Min Hu (Connor)
  2021-04-20 10:04   ` Thomas Monjalon
  2021-04-21  2:36   ` [dpdk-dev] [PATCH v9] " Ferruh Yigit
  2021-04-21 12:36 ` [dpdk-dev] [PATCH v10] " Min Hu (Connor)
  8 siblings, 2 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-17  7:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, andrew.rybchenko, thomas, ktraynor, stephen

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Kevin Traynor <ktraynor@redhat.com>
---
v8:
* Change logging style.

v7:
* Use a natural sounding names instead of argument name.

v6:
* Change logging grammar.
* "Failed to" change to "Cannot".
* Break the message part to next line.
* Delete param check for internal function.

v5:
* Keep "RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV)"
  and "dev = &rte_eth_devices[port_id]" together.

v4:
* add error logging.
* delete check in control path API.

v3:
* set port_id checked first.
* add error logging.

v2:
* Removed unnecessary checks.
* Deleted checks in internal API.
* Added documentation in the header file.
---
 lib/librte_ethdev/rte_ethdev.c | 365 +++++++++++++++++++++++++++++++++++++----
 lib/librte_ethdev/rte_ethdev.h |  20 ++-
 2 files changed, 349 insertions(+), 36 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 6b5cfd6..60f9ab3 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -199,6 +199,16 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot init NULL iterator\n");
+		return -EINVAL;
+	}
+
+	if (devargs_str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot init iterator for NULL devargs\n");
+		return -EINVAL;
+	}
+
 	memset(iter, 0, sizeof(*iter));
 
 	/*
@@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot iterate next NULL iter\n");
+		return RTE_MAX_ETHPORTS;
+	}
+
 	if (iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
@@ -322,6 +337,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot clean up NULL iterator\n");
+		return;
+	}
+
 	if (iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
@@ -622,6 +642,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot return owner id\n");
+		return -EINVAL;
+	}
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -645,6 +670,13 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 		return -ENODEV;
 	}
 
+	if (new_owner == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u owner to NULL new_owner\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!eth_is_valid_owner_id(new_owner->id) &&
 	    !eth_is_valid_owner_id(old_owner_id)) {
 		RTE_ETHDEV_LOG(ERR,
@@ -738,23 +770,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
-	int ret = 0;
-	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
-
-	eth_dev_shared_data_prepare();
-
-	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	struct rte_eth_dev *ethdev;
 
-	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	ethdev = &rte_eth_devices[port_id];
+	if (!eth_dev_is_allocated(ethdev)) {
 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
 			port_id);
-		ret = -ENODEV;
-	} else {
-		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
+		return -ENODEV;
 	}
 
+	if (owner == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %"PRIu16" owner for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	eth_dev_shared_data_prepare();
+
+	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
-	return ret;
+
+	return 0;
 }
 
 int
@@ -825,6 +864,11 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 		return -EINVAL;
 	}
 
+	if (port_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot return port ID\n");
+		return -EINVAL;
+	}
+
 	RTE_ETH_FOREACH_VALID_DEV(pid)
 		if (!strcmp(name, eth_dev_shared_data->data[pid].name)) {
 			*port_id = pid;
@@ -1298,9 +1342,15 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	uint16_t old_mtu;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
+	if (dev_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot configure ethdev port %u to NULL conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -2138,8 +2188,15 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	int count;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Rx hairpin queue to NULL conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
@@ -2311,6 +2368,14 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Tx hairpin queue to NULL conf\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
 		return -EINVAL;
@@ -2459,6 +2524,12 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set error callback for NULL buffer\n");
+		return -EINVAL;
+	}
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2609,6 +2680,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u link for NULL link\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
@@ -2629,6 +2707,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get nowait ethdev port %u for NULL link\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_conf.intr_conf.lsc &&
 	    dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
@@ -2667,6 +2752,22 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert link to NULL string\n");
+		return -EINVAL;
+	}
+
+	if (len == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot convert link to string with zero len\n");
+		return -EINVAL;
+	}
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert NULL link to string\n");
+		return -EINVAL;
+	}
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2684,8 +2785,15 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (stats == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u stats for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(stats, 0, sizeof(*stats));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
@@ -3260,6 +3368,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (fw_version == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u fw version for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (fw_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u fw version with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
 							fw_version, fw_size));
@@ -3278,6 +3400,13 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	if (dev_info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u info for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3327,6 +3456,21 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported ptypes for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (num == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported ptypes with zero num\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
@@ -3436,6 +3580,14 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (mac_addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u MAC address for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
 
 	return 0;
@@ -3447,8 +3599,15 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (mtu == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u MTU for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	*mtu = dev->data->mtu;
 	return 0;
 }
@@ -3697,6 +3856,14 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u flow conf for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
 	memset(fc_conf, 0, sizeof(*fc_conf));
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf));
@@ -3708,12 +3875,20 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf));
 }
@@ -3725,12 +3900,20 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (pfc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u priority flow conf to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	/* High water, low water validation are device specific */
 	if  (*dev->dev_ops->priority_flow_ctrl_set)
 		return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set)
@@ -3744,9 +3927,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3763,9 +3943,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3796,13 +3973,27 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss reta to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (reta_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss reta with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
-
 	/* Check entry value */
 	ret = eth_check_reta_entry(reta_conf, reta_size,
 				dev->data->nb_rx_queues);
@@ -3823,13 +4014,20 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot query ethdev port %u rss reta for NULL reta_conf\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf,
 							    reta_size));
@@ -3844,14 +4042,20 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u rss hash to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
 
 	rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
-
-	dev = &rte_eth_devices[port_id];
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3873,6 +4077,14 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u rss hash conf for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
 								   rss_conf));
@@ -4028,6 +4240,14 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot add NULL MAC address to ethdev port %u\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
 	if (rte_is_zero_ether_addr(addr)) {
@@ -4078,6 +4298,14 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot remove ethdev port %u MAC address for NULL addr\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
 
 	index = eth_dev_get_mac_addr_index(port_id, addr);
@@ -4108,11 +4336,18 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u default MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	if (!rte_is_valid_assigned_ether_addr(addr))
 		return -EINVAL;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
 	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
@@ -4163,8 +4398,15 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u uc hash table to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rte_is_zero_ether_addr(addr)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
 			port_id);
@@ -4265,6 +4507,15 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (mirror_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u mirror rule to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
 		return -EINVAL;
@@ -4291,7 +4542,6 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP);
 
 	return eth_err(port_id, (*dev->dev_ops->mirror_rule_set)(dev,
@@ -5210,6 +5460,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Rx timestamp for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp)
 				(dev, timestamp, flags));
@@ -5224,6 +5481,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Tx timestamp for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp)
 				(dev, timestamp));
@@ -5250,6 +5514,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u time for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev,
 								timestamp));
@@ -5263,6 +5534,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot write ethdev port %u time to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev,
 								timestamp));
@@ -5276,6 +5554,13 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (clock == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u clock for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
 }
@@ -5371,8 +5656,15 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (dcb_info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u dcb info for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP);
@@ -5422,8 +5714,15 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (cap == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin capability for NULL param\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
 	memset(cap, 0, sizeof(*cap));
 	return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 3b773b6..c1e5d4b 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2702,6 +2702,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2717,6 +2718,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2752,7 +2754,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2997,6 +2999,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3041,6 +3044,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3060,6 +3064,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3103,6 +3108,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3153,6 +3159,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3347,7 +3354,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3774,6 +3781,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3845,7 +3853,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4044,6 +4053,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4112,6 +4122,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4628,6 +4639,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4694,6 +4706,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4797,6 +4810,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v7] ethdev: add sanity checks in control APIs
  2021-04-16 12:02   ` Thomas Monjalon
@ 2021-04-17  7:39     ` Min Hu (Connor)
  0 siblings, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-17  7:39 UTC (permalink / raw)
  To: Thomas Monjalon, ferruh.yigit, andrew.rybchenko; +Cc: dev, ktraynor



在 2021/4/16 20:02, Thomas Monjalon 写道:
> 16/04/2021 13:00, Min Hu (Connor):
>> +	if (iter == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot init iterator for NULL iterator\n");
> 
> Don't you think it would be better as
> "Cannot init NULL iterator"?
> 
>>   rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
>>   {
>> +	if (iter == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot iterator clear up for NULL iter\n");
> 
> Cannot clean up NULL iterator.
> 
>>   rte_eth_dev_owner_new(uint64_t *owner_id)
>>   {
>> +	if (owner_id == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot get owner id for NULL param\n");
> 
> Cannot return owner id.
> 
>> @@ -825,6 +864,11 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
>> +	if (port_id == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot get port id for NULL param\n");
> 
> Cannot return port ID
> 
> etc for all other messages
> 
> Do you agree with the idea?
> 
Hi, Thomos, fixed in v10, thanks.
> 
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v6] ethdev: add sanity checks in control APIs
  2021-04-16 16:28     ` Stephen Hemminger
  2021-04-17  0:28       ` Min Hu (Connor)
@ 2021-04-17  7:42       ` Min Hu (Connor)
  1 sibling, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-17  7:42 UTC (permalink / raw)
  To: Stephen Hemminger, Kevin Traynor
  Cc: dev, ferruh.yigit, thomas, andrew.rybchenko



在 2021/4/17 0:28, Stephen Hemminger 写道:
> On Fri, 16 Apr 2021 11:22:02 +0100
> Kevin Traynor <ktraynor@redhat.com> wrote:
> 
>>> +	if (dev_conf == NULL) {
>>> +		RTE_ETHDEV_LOG(ERR,
>>> +			"Cannot configure ethdev port %u to NULL dev_conf\n",
>>
>> The others use a natural sounding names instead of argument name. If you
>> wanted to match that it could be "..to NULL conf"
> 
> I would prefer that error messages don't try to be English sentences.
> The wording ends up awkward. and overly wordy.
> If function name is automatically included by RTE_ETHDEV_LOG() then
> Just:
> 		RTE_ETHDEV_LOG(ERR, "NULL ethdev")
> should be enough for programmer to find/fix the problem
> .
Hi, Stephen, thanks your for comment.
But I am on side with Andrew Rybchenko.
"- log messages should be human readable (i.e. I'd avoid
    usage of function name)"
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v6] ethdev: add sanity checks in control APIs
  2021-04-17  0:28       ` Min Hu (Connor)
@ 2021-04-17 21:37         ` Thomas Monjalon
  2021-04-19  0:34           ` Min Hu (Connor)
  0 siblings, 1 reply; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-17 21:37 UTC (permalink / raw)
  To: Stephen Hemminger, Min Hu (Connor)
  Cc: Kevin Traynor, dev, ferruh.yigit, andrew.rybchenko

17/04/2021 02:28, Min Hu (Connor):
> 
> 在 2021/4/17 0:28, Stephen Hemminger 写道:
> > On Fri, 16 Apr 2021 11:22:02 +0100
> > Kevin Traynor <ktraynor@redhat.com> wrote:
> > 
> >>> +	if (dev_conf == NULL) {
> >>> +		RTE_ETHDEV_LOG(ERR,
> >>> +			"Cannot configure ethdev port %u to NULL dev_conf\n",
> >>
> >> The others use a natural sounding names instead of argument name. If you
> >> wanted to match that it could be "..to NULL conf"
> > 
> > I would prefer that error messages don't try to be English sentences.
> > The wording ends up awkward. and overly wordy.
> > If function name is automatically included by RTE_ETHDEV_LOG() then
> > Just:
> > 		RTE_ETHDEV_LOG(ERR, "NULL ethdev")
> > should be enough for programmer to find/fix the problem
> > .
> Hi, Stephen,
> 	Your opinion is quit different from that of Andrew Rybchenko.
> 	Andrew does not support show function name in the log:
> 	"- log messages should be human readable (i.e. I'd avoid
>     usage of function name)"
> 
> 	@Andrew ,@Thoms, @Ferruh, @Kevin, so, what's your opinion ?

I prefer human readable messages which are unique enough to be "grepped".



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v6] ethdev: add sanity checks in control APIs
  2021-04-17 21:37         ` Thomas Monjalon
@ 2021-04-19  0:34           ` Min Hu (Connor)
  0 siblings, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-19  0:34 UTC (permalink / raw)
  To: Thomas Monjalon, Stephen Hemminger
  Cc: Kevin Traynor, dev, ferruh.yigit, andrew.rybchenko



在 2021/4/18 5:37, Thomas Monjalon 写道:
> 17/04/2021 02:28, Min Hu (Connor):
>>
>> 在 2021/4/17 0:28, Stephen Hemminger 写道:
>>> On Fri, 16 Apr 2021 11:22:02 +0100
>>> Kevin Traynor <ktraynor@redhat.com> wrote:
>>>
>>>>> +	if (dev_conf == NULL) {
>>>>> +		RTE_ETHDEV_LOG(ERR,
>>>>> +			"Cannot configure ethdev port %u to NULL dev_conf\n",
>>>>
>>>> The others use a natural sounding names instead of argument name. If you
>>>> wanted to match that it could be "..to NULL conf"
>>>
>>> I would prefer that error messages don't try to be English sentences.
>>> The wording ends up awkward. and overly wordy.
>>> If function name is automatically included by RTE_ETHDEV_LOG() then
>>> Just:
>>> 		RTE_ETHDEV_LOG(ERR, "NULL ethdev")
>>> should be enough for programmer to find/fix the problem
>>> .
>> Hi, Stephen,
>> 	Your opinion is quit different from that of Andrew Rybchenko.
>> 	Andrew does not support show function name in the log:
>> 	"- log messages should be human readable (i.e. I'd avoid
>>      usage of function name)"
>>
>> 	@Andrew ,@Thoms, @Ferruh, @Kevin, so, what's your opinion ?
> 
> I prefer human readable messages which are unique enough to be "grepped".
> 
Agree with Thomas, thanks.
> 
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v8] ethdev: add sanity checks in control APIs
  2021-04-17  7:39 ` [dpdk-dev] [PATCH v8] " Min Hu (Connor)
@ 2021-04-20 10:04   ` Thomas Monjalon
  2021-04-20 13:59     ` Ferruh Yigit
  2021-04-20 14:20     ` Kevin Traynor
  2021-04-21  2:36   ` [dpdk-dev] [PATCH v9] " Ferruh Yigit
  1 sibling, 2 replies; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-20 10:04 UTC (permalink / raw)
  To: Min Hu (Connor); +Cc: dev, ferruh.yigit, andrew.rybchenko, ktraynor, stephen

Thanks for the work.
Few last comments below.

17/04/2021 09:39, Min Hu (Connor):
> @@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>  uint16_t
>  rte_eth_iterator_next(struct rte_dev_iterator *iter)
>  {
> +	if (iter == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Cannot iterate next NULL iter\n");

I would remove "next".
Cannot iterate NULL iter

> @@ -2629,6 +2707,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	dev = &rte_eth_devices[port_id];
>  
> +	if (eth_link == NULL) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get nowait ethdev port %u for NULL link\n",
> +			port_id);

"nowait ethdev" is not correct.
I think you can just remove "nowait".

> +	if (fw_version == NULL) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u fw version for NULL param\n",
[...]
> +	if (fw_size == 0) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u fw version with zero size\n",
> +			port_id);

s/fw/FW/

> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot update ethdev port %u rss reta to NULL\n",
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot update ethdev port %u rss reta with zero size\n",

s/rss reta/RSS RETA/

> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot update ethdev port %u rss hash to NULL\n",

s/rss/RSS/




^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v8] ethdev: add sanity checks in control APIs
  2021-04-20 10:04   ` Thomas Monjalon
@ 2021-04-20 13:59     ` Ferruh Yigit
  2021-04-20 14:20     ` Kevin Traynor
  1 sibling, 0 replies; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-20 13:59 UTC (permalink / raw)
  To: Thomas Monjalon, Min Hu (Connor); +Cc: dev, andrew.rybchenko, ktraynor, stephen

On 4/20/2021 11:04 AM, Thomas Monjalon wrote:
> Thanks for the work.
> Few last comments below.
> 
> 17/04/2021 09:39, Min Hu (Connor):
>> @@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>>   uint16_t
>>   rte_eth_iterator_next(struct rte_dev_iterator *iter)
>>   {
>> +	if (iter == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot iterate next NULL iter\n");
> 
> I would remove "next".
> Cannot iterate NULL iter
> 
>> @@ -2629,6 +2707,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	dev = &rte_eth_devices[port_id];
>>   
>> +	if (eth_link == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get nowait ethdev port %u for NULL link\n",
>> +			port_id);
> 
> "nowait ethdev" is not correct.
> I think you can just remove "nowait".
> 
>> +	if (fw_version == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u fw version for NULL param\n",
> [...]
>> +	if (fw_size == 0) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u fw version with zero size\n",
>> +			port_id);
> 
> s/fw/FW/
> 
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot update ethdev port %u rss reta to NULL\n",
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot update ethdev port %u rss reta with zero size\n",
> 
> s/rss reta/RSS RETA/
> 
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot update ethdev port %u rss hash to NULL\n",
> 
> s/rss/RSS/
> 
> 
> 

Hi Thomas, Connor,

The issues seems only syntax issues, I can fix them so that we can get the patch 
for -rc1, I will send a new version soon.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v8] ethdev: add sanity checks in control APIs
  2021-04-20 10:04   ` Thomas Monjalon
  2021-04-20 13:59     ` Ferruh Yigit
@ 2021-04-20 14:20     ` Kevin Traynor
  2021-04-20 14:33       ` Thomas Monjalon
  1 sibling, 1 reply; 65+ messages in thread
From: Kevin Traynor @ 2021-04-20 14:20 UTC (permalink / raw)
  To: Thomas Monjalon, Min Hu (Connor)
  Cc: dev, ferruh.yigit, andrew.rybchenko, stephen

On 20/04/2021 11:04, Thomas Monjalon wrote:
> Thanks for the work.
> Few last comments below.
> 
> 17/04/2021 09:39, Min Hu (Connor):
>> @@ -293,6 +303,11 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
>>  uint16_t
>>  rte_eth_iterator_next(struct rte_dev_iterator *iter)
>>  {
>> +	if (iter == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot iterate next NULL iter\n");
> 
> I would remove "next".
> Cannot iterate NULL iter
> 
>> @@ -2629,6 +2707,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
>>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>  	dev = &rte_eth_devices[port_id];
>>  
>> +	if (eth_link == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get nowait ethdev port %u for NULL link\n",
>> +			port_id);
> 
> "nowait ethdev" is not correct.
> I think you can just remove "nowait".
> 

The 'nowait' was just to distinguish from the otherwise identical
message in rte_eth_link_get(). Probably it can be some way better worded.

>> +	if (fw_version == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u fw version for NULL param\n",
> [...]
>> +	if (fw_size == 0) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u fw version with zero size\n",
>> +			port_id);
> 
> s/fw/FW/
> 
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot update ethdev port %u rss reta to NULL\n",
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot update ethdev port %u rss reta with zero size\n",
> 
> s/rss reta/RSS RETA/
> 
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot update ethdev port %u rss hash to NULL\n",
> 
> s/rss/RSS/
> 
> 
> 


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v8] ethdev: add sanity checks in control APIs
  2021-04-20 14:20     ` Kevin Traynor
@ 2021-04-20 14:33       ` Thomas Monjalon
  0 siblings, 0 replies; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-20 14:33 UTC (permalink / raw)
  To: Min Hu (Connor), Kevin Traynor
  Cc: dev, ferruh.yigit, andrew.rybchenko, stephen

20/04/2021 16:20, Kevin Traynor:
> On 20/04/2021 11:04, Thomas Monjalon wrote:
> > 17/04/2021 09:39, Min Hu (Connor):
> >> +	if (eth_link == NULL) {
> >> +		RTE_ETHDEV_LOG(ERR,
> >> +			"Cannot get nowait ethdev port %u for NULL link\n",
> >> +			port_id);
> > 
> > "nowait ethdev" is not correct.
> > I think you can just remove "nowait".
> 
> The 'nowait' was just to distinguish from the otherwise identical
> message in rte_eth_link_get(). Probably it can be some way better worded.

Given they are alternative functions,
I think it is OK to have the same message.
We should not be lost in the code too much when looking for it.



^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-17  7:39 ` [dpdk-dev] [PATCH v8] " Min Hu (Connor)
  2021-04-20 10:04   ` Thomas Monjalon
@ 2021-04-21  2:36   ` Ferruh Yigit
  2021-04-21 10:48     ` Thomas Monjalon
  2021-04-21 11:28     ` Andrew Rybchenko
  1 sibling, 2 replies; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-21  2:36 UTC (permalink / raw)
  To: Thomas Monjalon, Andrew Rybchenko, Gaetan Rivet,
	Stephen Hemminger, Qi Zhang, Ali Alnubani, Yuanhan Liu,
	Matan Azrad, Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: Ferruh Yigit, dev, Min Hu (Connor), stable, Kevin Traynor

From: "Min Hu (Connor)" <humin29@huawei.com>

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Kevin Traynor <ktraynor@redhat.com>
---

It seems I underestimated finding good log messages ;), not sure if they
are complete, please comment, we can have more versions until they are
good.

v9
* Updated more functions that were missing log messages
  - rte_eth_hairpin_get_peer_ports
  - rte_eth_tx_buffer_init
  - rte_eth_xstats_get_id_by_name
  - rte_eth_dev_set_ptypes
  - rte_eth_dev_udp_tunnel_port_add
  - rte_eth_fec_get_capability
  - rte_eth_fec_get
  - rte_eth_dev_get_reg_info

* Updated log messages

* Change order of verification for some functions to be sure
  verification order is parameter order

* Remove empty line between port_id check and ethdev assignment

* Joined some lines barely above 80 columns for code readability
---
 lib/librte_ethdev/rte_ethdev.c | 677 +++++++++++++++++++++++++--------
 lib/librte_ethdev/rte_ethdev.h |  22 +-
 2 files changed, 544 insertions(+), 155 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index d5adf4ff0575..9c0df59464be 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -195,6 +195,17 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL iterator\n");
+		return -EINVAL;
+	}
+
+	if (devargs_str == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot initialize iterator from NULL device description string\n");
+		return -EINVAL;
+	}
+
 	memset(iter, 0, sizeof(*iter));
 	memset(&devargs, 0, sizeof(devargs));
 
@@ -289,6 +300,12 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get next device from NULL iterator\n");
+		return RTE_MAX_ETHPORTS;
+	}
+
 	if (iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
@@ -318,6 +335,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot do clean up from NULL iterator\n");
+		return;
+	}
+
 	if (iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
@@ -618,6 +640,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get new owner ID to NULL\n");
+		return -EINVAL;
+	}
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -641,6 +668,13 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 		return -ENODEV;
 	}
 
+	if (new_owner == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u owner from NULL owner\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!eth_is_valid_owner_id(new_owner->id) &&
 	    !eth_is_valid_owner_id(old_owner_id)) {
 		RTE_ETHDEV_LOG(ERR,
@@ -734,23 +768,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
-	int ret = 0;
-	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
-
-	eth_dev_shared_data_prepare();
+	struct rte_eth_dev *ethdev;
 
-	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	ethdev = &rte_eth_devices[port_id];
 
-	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
+	if (!eth_dev_is_allocated(ethdev)) {
 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
 			port_id);
-		ret = -ENODEV;
-	} else {
-		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
+		return -ENODEV;
+	}
+
+	if (owner == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u owner to NULL\n",
+			port_id);
+		return -EINVAL;
 	}
 
+	eth_dev_shared_data_prepare();
+
+	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
-	return ret;
+
+	return 0;
 }
 
 int
@@ -800,7 +841,8 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	if (name == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u name to NULL\n",
+			port_id);
 		return -EINVAL;
 	}
 
@@ -817,7 +859,12 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 	uint16_t pid;
 
 	if (name == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
+		RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
+		return -EINVAL;
+	}
+
+	if (port_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get port ID to NULL\n");
 		return -EINVAL;
 	}
 
@@ -945,8 +992,8 @@ rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (!dev->data->dev_started) {
 		RTE_ETHDEV_LOG(ERR,
 			"Port %u must be started before start any queue\n",
@@ -974,9 +1021,7 @@ rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id)
 		return 0;
 	}
 
-	return eth_err(port_id, dev->dev_ops->rx_queue_start(dev,
-							     rx_queue_id));
-
+	return eth_err(port_id, dev->dev_ops->rx_queue_start(dev, rx_queue_id));
 }
 
 int
@@ -986,7 +1031,6 @@ rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	ret = eth_dev_validate_rx_queue(dev, rx_queue_id);
@@ -1010,7 +1054,6 @@ rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id)
 	}
 
 	return eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id));
-
 }
 
 int
@@ -1020,8 +1063,8 @@ rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (!dev->data->dev_started) {
 		RTE_ETHDEV_LOG(ERR,
 			"Port %u must be started before start any queue\n",
@@ -1059,7 +1102,6 @@ rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	ret = eth_dev_validate_tx_queue(dev, tx_queue_id);
@@ -1083,7 +1125,6 @@ rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id)
 	}
 
 	return eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id));
-
 }
 
 static int
@@ -1294,9 +1335,15 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	uint16_t old_mtu;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
+	if (dev_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot configure ethdev port %u from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -1697,7 +1744,6 @@ rte_eth_dev_start(uint16_t port_id)
 	int ret, ret_stop;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
@@ -1778,7 +1824,6 @@ rte_eth_dev_set_link_up(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_up, -ENOTSUP);
@@ -1791,7 +1836,6 @@ rte_eth_dev_set_link_down(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_down, -ENOTSUP);
@@ -1848,7 +1892,6 @@ rte_eth_dev_is_removed(uint16_t port_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
-
 	dev = &rte_eth_devices[port_id];
 
 	if (dev->state == RTE_ETH_DEV_REMOVED)
@@ -1949,8 +1992,8 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	void **rxq;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
@@ -2134,12 +2177,20 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	int count;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
 	}
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Rx hairpin queue from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
 	if (ret != 0)
 		return ret;
@@ -2205,8 +2256,8 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
 		return -EINVAL;
@@ -2307,10 +2358,19 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
 		return -EINVAL;
 	}
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Tx hairpin queue from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
 	if (ret != 0)
 		return ret;
@@ -2372,6 +2432,7 @@ rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
 	dev = &rte_eth_devices[tx_port];
+
 	if (dev->data->dev_started == 0) {
 		RTE_ETHDEV_LOG(ERR, "Tx port %d is not started\n", tx_port);
 		return -EBUSY;
@@ -2395,6 +2456,7 @@ rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
 	dev = &rte_eth_devices[tx_port];
+
 	if (dev->data->dev_started == 0) {
 		RTE_ETHDEV_LOG(ERR, "Tx port %d is already stopped\n", tx_port);
 		return -EBUSY;
@@ -2417,11 +2479,23 @@ rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
 	struct rte_eth_dev *dev;
 	int ret;
 
-	if (peer_ports == NULL || len == 0)
-		return -EINVAL;
-
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (peer_ports == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin peer ports to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (len == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin peer ports to array with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_get_peer_ports,
 				-ENOTSUP);
 
@@ -2455,6 +2529,12 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set Tx buffer error callback to NULL buffer\n");
+		return -EINVAL;
+	}
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2465,8 +2545,10 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
 {
 	int ret = 0;
 
-	if (buffer == NULL)
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL buffer\n");
 		return -EINVAL;
+	}
 
 	buffer->size = size;
 	if (buffer->error_callback == NULL) {
@@ -2480,11 +2562,12 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
 int
 rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
 {
-	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	struct rte_eth_dev *dev;
 	int ret;
 
-	/* Validate Input Data. Bail if not valid or not supported. */
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
 
 	/* Call driver to free pending mbufs. */
@@ -2541,8 +2624,8 @@ rte_eth_promiscuous_get(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	return dev->data->promiscuous;
 }
 
@@ -2592,8 +2675,8 @@ rte_eth_allmulticast_get(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	return dev->data->all_multicast;
 }
 
@@ -2605,8 +2688,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	if (dev->data->dev_conf.intr_conf.lsc &&
-	    dev->data->dev_started)
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
 	else {
 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
@@ -2625,8 +2713,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	if (dev->data->dev_conf.intr_conf.lsc &&
-	    dev->data->dev_started)
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
 	else {
 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
@@ -2663,6 +2756,22 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert link to NULL string\n");
+		return -EINVAL;
+	}
+
+	if (len == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot convert link to string with zero size\n");
+		return -EINVAL;
+	}
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert to string from NULL link\n");
+		return -EINVAL;
+	}
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2680,8 +2789,14 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (stats == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u stats to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(stats, 0, sizeof(*stats));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
@@ -2761,13 +2876,17 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
-	if (!id) {
-		RTE_ETHDEV_LOG(ERR, "Id pointer is NULL\n");
+	if (xstat_name == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u xstats ID from NULL xstat name\n",
+			port_id);
 		return -ENOMEM;
 	}
 
-	if (!xstat_name) {
-		RTE_ETHDEV_LOG(ERR, "xstat_name pointer is NULL\n");
+	if (id == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u xstats ID to NULL\n",
+			port_id);
 		return -ENOMEM;
 	}
 
@@ -3055,12 +3174,13 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
 	ret = eth_dev_get_xstats_count(port_id);
 	if (ret < 0)
 		return ret;
 	expected_entries = (uint16_t)ret;
 	struct rte_eth_xstat xstats[expected_entries];
-	dev = &rte_eth_devices[port_id];
 	basic_count = eth_dev_get_xstats_basic_count(dev);
 
 	/* Return max number of stats if no ids given */
@@ -3144,7 +3264,6 @@ rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
@@ -3210,11 +3329,8 @@ eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP);
-
 	if (is_rx && (queue_id >= dev->data->nb_rx_queues))
 		return -EINVAL;
 
@@ -3224,11 +3340,10 @@ eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
 	if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
 		return -EINVAL;
 
-	return (*dev->dev_ops->queue_stats_mapping_set)
-			(dev, queue_id, stat_idx, is_rx);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP);
+	return (*dev->dev_ops->queue_stats_mapping_set) (dev, queue_id, stat_idx, is_rx);
 }
 
-
 int
 rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
 		uint8_t stat_idx)
@@ -3238,7 +3353,6 @@ rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
 						stat_idx, STAT_QMAP_TX));
 }
 
-
 int
 rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id,
 		uint8_t stat_idx)
@@ -3256,6 +3370,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (fw_version == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u FW version to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (fw_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u FW version to buffer with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
 							fw_version, fw_size));
@@ -3274,6 +3402,15 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (dev_info == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u info to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3281,9 +3418,6 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	dev = &rte_eth_devices[port_id];
-
 	dev_info->rx_desc_lim = lim;
 	dev_info->tx_desc_lim = lim;
 	dev_info->device = dev->device;
@@ -3323,6 +3457,21 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported packet types to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (num == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported packet types to array with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
@@ -3361,8 +3510,12 @@ rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	if (num > 0 && set_ptypes == NULL)
+	if (num > 0 && set_ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u set packet types to NULL when array size is non zero\n",
+			port_id);
 		return -EINVAL;
+	}
 
 	if (*dev->dev_ops->dev_supported_ptypes_get == NULL ||
 			*dev->dev_ops->dev_ptypes_set == NULL) {
@@ -3432,6 +3585,14 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (mac_addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
 
 	return 0;
@@ -3443,8 +3604,14 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (mtu == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u MTU to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	*mtu = dev->data->mtu;
 	return 0;
 }
@@ -3490,6 +3657,7 @@ rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	if (!(dev->data->dev_conf.rxmode.offloads &
 	      DEV_RX_OFFLOAD_VLAN_FILTER)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: vlan-filtering disabled\n",
@@ -3531,6 +3699,7 @@ rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid rx_queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
@@ -3551,8 +3720,8 @@ rte_eth_dev_set_vlan_ether_type(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
 
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type,
 							       tpid));
 }
@@ -3681,8 +3850,8 @@ rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP);
 
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on));
 }
 
@@ -3693,6 +3862,14 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u flow control config to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
 	memset(fc_conf, 0, sizeof(*fc_conf));
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf));
@@ -3704,12 +3881,20 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u flow control from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf));
 }
@@ -3721,12 +3906,20 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (pfc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u priority flow control from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	/* High water, low water validation are device specific */
 	if  (*dev->dev_ops->priority_flow_ctrl_set)
 		return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set)
@@ -3740,9 +3933,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3759,9 +3949,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3792,13 +3979,27 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u RSS RETA to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (reta_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u RSS RETA with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
-
 	/* Check entry value */
 	ret = eth_check_reta_entry(reta_conf, reta_size,
 				dev->data->nb_rx_queues);
@@ -3819,13 +4020,20 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot query ethdev port %u RSS RETA from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf,
 							    reta_size));
@@ -3840,14 +4048,20 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u RSS hash from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
 
 	rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
-
-	dev = &rte_eth_devices[port_id];
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3869,6 +4083,14 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u RSS hash config to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
 								   rss_conf));
@@ -3881,8 +4103,12 @@ rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
 	if (udp_tunnel == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n");
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot add ethdev port %u UDP tunnel port from NULL UDP tunnel\n",
+			port_id);
 		return -EINVAL;
 	}
 
@@ -3891,7 +4117,6 @@ rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_add)(dev,
 								udp_tunnel));
@@ -3907,7 +4132,9 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
 	dev = &rte_eth_devices[port_id];
 
 	if (udp_tunnel == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n");
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot delete ethdev port %u UDP tunnel port from NULL UDP tunnel\n",
+			port_id);
 		return -EINVAL;
 	}
 
@@ -3928,6 +4155,7 @@ rte_eth_led_on(uint16_t port_id)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_on, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->dev_led_on)(dev));
 }
@@ -3939,6 +4167,7 @@ rte_eth_led_off(uint16_t port_id)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_off, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev));
 }
@@ -3951,11 +4180,16 @@ rte_eth_fec_get_capability(uint16_t port_id,
 	struct rte_eth_dev *dev;
 	int ret;
 
-	if (speed_fec_capa == NULL && num > 0)
-		return -EINVAL;
-
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (speed_fec_capa == NULL && num > 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u FEC capability to NULL when array size is non zero\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get_capability, -ENOTSUP);
 	ret = (*dev->dev_ops->fec_get_capability)(dev, speed_fec_capa, num);
 
@@ -3967,11 +4201,16 @@ rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa)
 {
 	struct rte_eth_dev *dev;
 
-	if (fec_capa == NULL)
-		return -EINVAL;
-
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (fec_capa == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u current FEC mode to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fec_get)(dev, fec_capa));
 }
@@ -3983,6 +4222,7 @@ rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fec_set)(dev, fec_capa));
 }
@@ -4024,6 +4264,14 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot add ethdev port %u MAC address from NULL address\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
 	if (rte_is_zero_ether_addr(addr)) {
@@ -4074,6 +4322,14 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot remove ethdev port %u MAC address from NULL address\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
 
 	index = eth_dev_get_mac_addr_index(port_id, addr);
@@ -4104,11 +4360,18 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u default MAC address from NULL address\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	if (!rte_is_valid_assigned_ether_addr(addr))
 		return -EINVAL;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
 	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
@@ -4159,8 +4422,15 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u unicast hash table from NULL address\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rte_is_zero_ether_addr(addr)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
 			port_id);
@@ -4209,7 +4479,6 @@ rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_all_hash_table_set, -ENOTSUP);
@@ -4226,12 +4495,12 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
 	link = dev->data->dev_link;
 
 	if (queue_idx > dev_info.max_tx_queues) {
@@ -4261,6 +4530,15 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (mirror_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u mirror rule from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
 		return -EINVAL;
@@ -4287,7 +4565,6 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP);
 
 	return eth_err(port_id, (*dev->dev_ops->mirror_rule_set)(dev,
@@ -4300,12 +4577,10 @@ rte_eth_mirror_rule_reset(uint16_t port_id, uint8_t rule_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_reset, -ENOTSUP);
 
-	return eth_err(port_id, (*dev->dev_ops->mirror_rule_reset)(dev,
-								   rule_id));
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_reset, -ENOTSUP);
+	return eth_err(port_id, (*dev->dev_ops->mirror_rule_reset)(dev, rule_id));
 }
 
 RTE_INIT(eth_dev_init_cb_lists)
@@ -4326,8 +4601,12 @@ rte_eth_dev_callback_register(uint16_t port_id,
 	uint16_t next_port;
 	uint16_t last_port;
 
-	if (!cb_fn)
+	if (cb_fn == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot register ethdev port %u callback from NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
 	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
 		RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
@@ -4389,8 +4668,12 @@ rte_eth_dev_callback_unregister(uint16_t port_id,
 	uint16_t next_port;
 	uint16_t last_port;
 
-	if (!cb_fn)
+	if (cb_fn == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot unregister ethdev port %u callback from NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
 	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
 		RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
@@ -4483,7 +4766,6 @@ rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data)
 	int rc;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	if (!dev->intr_handle) {
@@ -4520,7 +4802,6 @@ rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id)
 	int fd;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
-
 	dev = &rte_eth_devices[port_id];
 
 	if (queue_id >= dev->data->nb_rx_queues) {
@@ -4707,8 +4988,8 @@ rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
 	int rc;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
 		return -EINVAL;
@@ -4745,7 +5026,6 @@ rte_eth_dev_rx_intr_enable(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	ret = eth_dev_validate_rx_queue(dev, queue_id);
@@ -4753,8 +5033,7 @@ rte_eth_dev_rx_intr_enable(uint16_t port_id,
 		return ret;
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_enable, -ENOTSUP);
-	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev,
-								queue_id));
+	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev, queue_id));
 }
 
 int
@@ -4765,7 +5044,6 @@ rte_eth_dev_rx_intr_disable(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	ret = eth_dev_validate_rx_queue(dev, queue_id);
@@ -4773,8 +5051,7 @@ rte_eth_dev_rx_intr_disable(uint16_t port_id,
 		return ret;
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_disable, -ENOTSUP);
-	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev,
-								queue_id));
+	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev, queue_id));
 }
 
 
@@ -5008,16 +5285,19 @@ rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-	if (qinfo == NULL)
-		return -EINVAL;
-
 	dev = &rte_eth_devices[port_id];
+
 	if (queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
 		return -EINVAL;
 	}
 
+	if (qinfo == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Rx queue %u info to NULL\n",
+			port_id, queue_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->rx_queues == NULL ||
 			dev->data->rx_queues[queue_id] == NULL) {
 		RTE_ETHDEV_LOG(ERR,
@@ -5050,16 +5330,19 @@ rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-	if (qinfo == NULL)
-		return -EINVAL;
-
 	dev = &rte_eth_devices[port_id];
+
 	if (queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
 		return -EINVAL;
 	}
 
+	if (qinfo == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Tx queue %u info to NULL\n",
+			port_id, queue_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->tx_queues == NULL ||
 			dev->data->tx_queues[queue_id] == NULL) {
 		RTE_ETHDEV_LOG(ERR,
@@ -5092,10 +5375,6 @@ rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-	if (mode == NULL)
-		return -EINVAL;
-
 	dev = &rte_eth_devices[port_id];
 
 	if (queue_id >= dev->data->nb_rx_queues) {
@@ -5103,6 +5382,13 @@ rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
+	if (mode == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u Rx queue %u burst mode to NULL\n",
+			port_id, queue_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_burst_mode_get, -ENOTSUP);
 	memset(mode, 0, sizeof(*mode));
 	return eth_err(port_id,
@@ -5116,10 +5402,6 @@ rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-	if (mode == NULL)
-		return -EINVAL;
-
 	dev = &rte_eth_devices[port_id];
 
 	if (queue_id >= dev->data->nb_tx_queues) {
@@ -5127,6 +5409,13 @@ rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
+	if (mode == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u Tx queue %u burst mode to NULL\n",
+			port_id, queue_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_burst_mode_get, -ENOTSUP);
 	memset(mode, 0, sizeof(*mode));
 	return eth_err(port_id,
@@ -5140,25 +5429,23 @@ rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_monitor_addr, -ENOTSUP);
-
 	if (queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id);
 		return -EINVAL;
 	}
 
 	if (pmc == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Invalid power monitor condition=%p\n",
-				pmc);
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u Rx queue %u power monitor condition to NULL\n",
+			port_id, queue_id);
 		return -EINVAL;
 	}
 
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_monitor_addr, -ENOTSUP);
 	return eth_err(port_id,
-		dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id],
-			pmc));
+		dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id], pmc));
 }
 
 int
@@ -5169,8 +5456,8 @@ rte_eth_dev_set_mc_addr_list(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP);
 	return eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev,
 						mc_addr_set, nb_mc_addr));
@@ -5209,6 +5496,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Rx timestamp to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp)
 				(dev, timestamp, flags));
@@ -5223,6 +5517,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Tx timestamp to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp)
 				(dev, timestamp));
@@ -5237,8 +5538,7 @@ rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta)
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_adjust_time, -ENOTSUP);
-	return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev,
-								      delta));
+	return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev, delta));
 }
 
 int
@@ -5249,6 +5549,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u timesync time to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev,
 								timestamp));
@@ -5262,6 +5569,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot write ethdev port %u timesync from NULL time\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev,
 								timestamp));
@@ -5275,6 +5589,12 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (clock == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot read ethdev port %u clock to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
 }
@@ -5285,10 +5605,15 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (info == NULL)
+	dev = &rte_eth_devices[port_id];
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u register info to NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
 }
@@ -5299,8 +5624,8 @@ rte_eth_dev_get_eeprom_length(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom_length, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->get_eeprom_length)(dev));
 }
@@ -5311,10 +5636,15 @@ rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (info == NULL)
+	dev = &rte_eth_devices[port_id];
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u EEPROM info to NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->get_eeprom)(dev, info));
 }
@@ -5325,10 +5655,15 @@ rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (info == NULL)
+	dev = &rte_eth_devices[port_id];
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u EEPROM from NULL info\n",
+			port_id);
 		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info));
 }
@@ -5340,10 +5675,15 @@ rte_eth_dev_get_module_info(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (modinfo == NULL)
+	dev = &rte_eth_devices[port_id];
+
+	if (modinfo == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u EEPROM module info to NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP);
 	return (*dev->dev_ops->get_module_info)(dev, modinfo);
 }
@@ -5355,10 +5695,29 @@ rte_eth_dev_get_module_eeprom(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (info == NULL || info->data == NULL || info->length == 0)
+	dev = &rte_eth_devices[port_id];
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u module EEPROM info to NULL\n",
+			port_id);
 		return -EINVAL;
+	}
+
+	if (info->data == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u module EEPROM data to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (info->length == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u module EEPROM to data with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP);
 	return (*dev->dev_ops->get_module_eeprom)(dev, info);
 }
@@ -5370,8 +5729,15 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (dcb_info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u DCB info to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP);
@@ -5421,8 +5787,15 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (cap == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin capability to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
 	memset(cap, 0, sizeof(*cap));
 	return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
@@ -5431,8 +5804,7 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 int
 rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	if (dev->data->rx_queue_state[queue_id] ==
-	    RTE_ETH_QUEUE_STATE_HAIRPIN)
+	if (dev->data->rx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN)
 		return 1;
 	return 0;
 }
@@ -5440,8 +5812,7 @@ rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 int
 rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	if (dev->data->tx_queue_state[queue_id] ==
-	    RTE_ETH_QUEUE_STATE_HAIRPIN)
+	if (dev->data->tx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN)
 		return 1;
 	return 0;
 }
@@ -5452,11 +5823,14 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
 
-	if (pool == NULL)
+	if (pool == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot test ethdev port %u mempool operation from NULL pool\n",
+			port_id);
 		return -EINVAL;
-
-	dev = &rte_eth_devices[port_id];
+	}
 
 	if (*dev->dev_ops->pool_ops_supported == NULL)
 		return 1; /* all pools are supported */
@@ -5928,8 +6302,7 @@ rte_eth_representor_info_get(uint16_t port_id,
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->representor_info_get, -ENOTSUP);
-	return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev,
-								      info));
+	return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev, info));
 }
 
 RTE_LOG_REGISTER(rte_eth_dev_logtype, lib.ethdev, INFO);
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index a0d01d26675f..faf3bd901d75 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2711,6 +2711,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2726,6 +2727,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2761,7 +2763,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2934,6 +2936,7 @@ int rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
  *    -ENODEV for invalid port_id,
  *    -EIO if device is removed,
  *    -EINVAL if the xstat_name doesn't exist in port_id
+ *    -ENOMEM if bad parameter.
  */
 int rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 		uint64_t *id);
@@ -3006,6 +3009,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3050,6 +3054,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3069,6 +3074,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3112,6 +3118,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3162,6 +3169,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3356,7 +3364,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3783,6 +3791,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3854,7 +3863,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4053,6 +4063,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4121,6 +4132,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4533,6 +4545,7 @@ rte_eth_dev_get_module_eeprom(uint16_t port_id,
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if PMD of *port_id* doesn't support multicast filtering.
  *   - (-ENOSPC) if *port_id* has not enough multicast filtering resources.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_set_mc_addr_list(uint16_t port_id,
 				 struct rte_ether_addr *mc_addr_set,
@@ -4637,6 +4650,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4703,6 +4717,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4806,6 +4821,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.30.2


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21  2:36   ` [dpdk-dev] [PATCH v9] " Ferruh Yigit
@ 2021-04-21 10:48     ` Thomas Monjalon
  2021-04-21 11:28     ` Andrew Rybchenko
  1 sibling, 0 replies; 65+ messages in thread
From: Thomas Monjalon @ 2021-04-21 10:48 UTC (permalink / raw)
  To: Ferruh Yigit, Min Hu (Connor)
  Cc: Andrew Rybchenko, Gaetan Rivet, Stephen Hemminger, dev, stable,
	Kevin Traynor

21/04/2021 04:36, Ferruh Yigit:
> From: "Min Hu (Connor)" <humin29@huawei.com>
> 
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Acked-by: Kevin Traynor <ktraynor@redhat.com>
> ---
> 
> It seems I underestimated finding good log messages ;), not sure if they
> are complete, please comment, we can have more versions until they are
> good.

They are probably good enough.
Thanks for all the work.

Acked-by: Thomas Monjalon <thomas@monjalon.net>



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21  2:36   ` [dpdk-dev] [PATCH v9] " Ferruh Yigit
  2021-04-21 10:48     ` Thomas Monjalon
@ 2021-04-21 11:28     ` Andrew Rybchenko
  2021-04-21 12:36       ` Min Hu (Connor)
                         ` (3 more replies)
  1 sibling, 4 replies; 65+ messages in thread
From: Andrew Rybchenko @ 2021-04-21 11:28 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon, Gaetan Rivet, Stephen Hemminger,
	Qi Zhang, Ali Alnubani, Yuanhan Liu, Matan Azrad,
	Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: dev, Min Hu (Connor), stable, Kevin Traynor

On 4/21/21 5:36 AM, Ferruh Yigit wrote:
> From: "Min Hu (Connor)" <humin29@huawei.com>
> 
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Acked-by: Kevin Traynor <ktraynor@redhat.com>

Few nits below.
Other than that I confirm my "Reviewed-by".

The patch is really long. It would be better to split it into
few:
 - relocate dev assignment
 - empty lines mangling (when it is unrelated to previous item)
 - ops check before usage (combined with related style checks)
 - error logs refinement

However, since the patch is already reviewed this way, may
be it is better to push as is after review notes processing.

> @@ -817,7 +859,12 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
>  	uint16_t pid;
>  
>  	if (name == NULL) {
> -		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
> +		RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
> +		return -EINVAL;
> +	}
> +
> +	if (port_id == NULL) {
> +		RTE_ETHDEV_LOG(ERR, "Cannot get port ID to NULL\n");

Since name is already checked above, I think it would be useful
to log 'name' here to provide context.

>  		return -EINVAL;
>  	}
>  

[snip]

> @@ -3256,6 +3370,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	dev = &rte_eth_devices[port_id];
>  
> +	if (fw_version == NULL) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u FW version to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
> +	if (fw_size == 0) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u FW version to buffer with zero size\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +

The only error condition is NULL fw_version with positive
fw_size. Othwerwise, it could be just a call to get required
size of buffer for FW version.

>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
>  	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
>  							fw_version, fw_size));

[snip]

> @@ -3323,6 +3457,21 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>  
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	dev = &rte_eth_devices[port_id];
> +
> +	if (ptypes == NULL) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u supported packet types to NULL\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
> +	if (num == 0) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u supported packet types to array with zero size\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +

The error condition is "ptypes == NULL && num > 0".
Otherwise, if num == 0 (regardless ptypes) it is just
a call to get size of required buffer. Same as below.

>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
>  	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
>  

[snip]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [dpdk-dev] [PATCH v10] ethdev: add sanity checks in control APIs
  2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
                   ` (7 preceding siblings ...)
  2021-04-17  7:39 ` [dpdk-dev] [PATCH v8] " Min Hu (Connor)
@ 2021-04-21 12:36 ` Min Hu (Connor)
  2021-04-21 14:19   ` Ferruh Yigit
  8 siblings, 1 reply; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-21 12:36 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, thomas, andrew.rybchenko, ktraynor

This patch adds more sanity checks in control path APIs.

Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
Fixes: 0366137722a0 ("ethdev: check for invalid device name")
Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
Fixes: f8244c6399d9 ("ethdev: increase port id range")
Cc: stable@dpdk.org

Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Kevin Traynor <ktraynor@redhat.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
v10:
* ajust check in 'rte_eth_dev_fw_version_get' and
'rte_eth_dev_get_supported_ptypes'.

v9:
* Updated more functions that were missing log messages
  - rte_eth_hairpin_get_peer_ports
  - rte_eth_tx_buffer_init
  - rte_eth_xstats_get_id_by_name
  - rte_eth_dev_set_ptypes
  - rte_eth_dev_udp_tunnel_port_add
  - rte_eth_fec_get_capability
  - rte_eth_fec_get
  - rte_eth_dev_get_reg_info

* Updated log messages

* Change order of verification for some functions to be sure
  verification order is parameter order

* Remove empty line between port_id check and ethdev assignment

* Joined some lines barely above 80 columns for code readability
v8:
* Change logging style.

v7:
* Use a natural sounding names instead of argument name.

v6:
* Change logging grammar.
* "Failed to" change to "Cannot".
* Break the message part to next line.
* Delete param check for internal function.

v5:
* Keep "RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV)"
  and "dev = &rte_eth_devices[port_id]" together.

v4:
* add error logging.
* delete check in control path API.

v3:
* set port_id checked first.
* add error logging.

v2:
* Removed unnecessary checks.
* Deleted checks in internal API.
* Added documentation in the header file.
---
 lib/librte_ethdev/rte_ethdev.c | 664 +++++++++++++++++++++++++++++++----------
 lib/librte_ethdev/rte_ethdev.h |  22 +-
 2 files changed, 531 insertions(+), 155 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index d5adf4f..3fc9949 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -195,6 +195,17 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 	char *cls_str = NULL;
 	int str_size;
 
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL iterator\n");
+		return -EINVAL;
+	}
+
+	if (devargs_str == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot initialize iterator from NULL device description string\n");
+		return -EINVAL;
+	}
+
 	memset(iter, 0, sizeof(*iter));
 	memset(&devargs, 0, sizeof(devargs));
 
@@ -289,6 +300,12 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str)
 uint16_t
 rte_eth_iterator_next(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get next device from NULL iterator\n");
+		return RTE_MAX_ETHPORTS;
+	}
+
 	if (iter->cls == NULL) /* invalid ethdev iterator */
 		return RTE_MAX_ETHPORTS;
 
@@ -318,6 +335,11 @@ rte_eth_iterator_next(struct rte_dev_iterator *iter)
 void
 rte_eth_iterator_cleanup(struct rte_dev_iterator *iter)
 {
+	if (iter == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot do clean up from NULL iterator\n");
+		return;
+	}
+
 	if (iter->bus_str == NULL)
 		return; /* nothing to free in pure class filter */
 	free(RTE_CAST_FIELD(iter, bus_str, char *)); /* workaround const */
@@ -618,6 +640,11 @@ rte_eth_find_next_owned_by(uint16_t port_id, const uint64_t owner_id)
 int
 rte_eth_dev_owner_new(uint64_t *owner_id)
 {
+	if (owner_id == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get new owner ID to NULL\n");
+		return -EINVAL;
+	}
+
 	eth_dev_shared_data_prepare();
 
 	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
@@ -641,6 +668,13 @@ eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 		return -ENODEV;
 	}
 
+	if (new_owner == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u owner from NULL owner\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (!eth_is_valid_owner_id(new_owner->id) &&
 	    !eth_is_valid_owner_id(old_owner_id)) {
 		RTE_ETHDEV_LOG(ERR,
@@ -734,23 +768,30 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
 int
 rte_eth_dev_owner_get(const uint16_t port_id, struct rte_eth_dev_owner *owner)
 {
-	int ret = 0;
-	struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
-
-	eth_dev_shared_data_prepare();
+	struct rte_eth_dev *ethdev;
 
-	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	ethdev = &rte_eth_devices[port_id];
 
-	if (port_id >= RTE_MAX_ETHPORTS || !eth_dev_is_allocated(ethdev)) {
+	if (!eth_dev_is_allocated(ethdev)) {
 		RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
 			port_id);
-		ret = -ENODEV;
-	} else {
-		rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
+		return -ENODEV;
+	}
+
+	if (owner == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u owner to NULL\n",
+			port_id);
+		return -EINVAL;
 	}
 
+	eth_dev_shared_data_prepare();
+
+	rte_spinlock_lock(&eth_dev_shared_data->ownership_lock);
+	rte_memcpy(owner, &ethdev->data->owner, sizeof(*owner));
 	rte_spinlock_unlock(&eth_dev_shared_data->ownership_lock);
-	return ret;
+
+	return 0;
 }
 
 int
@@ -800,7 +841,8 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	if (name == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u name to NULL\n",
+			port_id);
 		return -EINVAL;
 	}
 
@@ -817,7 +859,13 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
 	uint16_t pid;
 
 	if (name == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
+		RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
+		return -EINVAL;
+	}
+
+	if (port_id == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get port ID to NULL for %s\n", name);
 		return -EINVAL;
 	}
 
@@ -945,8 +993,8 @@ rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (!dev->data->dev_started) {
 		RTE_ETHDEV_LOG(ERR,
 			"Port %u must be started before start any queue\n",
@@ -974,9 +1022,7 @@ rte_eth_dev_rx_queue_start(uint16_t port_id, uint16_t rx_queue_id)
 		return 0;
 	}
 
-	return eth_err(port_id, dev->dev_ops->rx_queue_start(dev,
-							     rx_queue_id));
-
+	return eth_err(port_id, dev->dev_ops->rx_queue_start(dev, rx_queue_id));
 }
 
 int
@@ -986,7 +1032,6 @@ rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	ret = eth_dev_validate_rx_queue(dev, rx_queue_id);
@@ -1010,7 +1055,6 @@ rte_eth_dev_rx_queue_stop(uint16_t port_id, uint16_t rx_queue_id)
 	}
 
 	return eth_err(port_id, dev->dev_ops->rx_queue_stop(dev, rx_queue_id));
-
 }
 
 int
@@ -1020,8 +1064,8 @@ rte_eth_dev_tx_queue_start(uint16_t port_id, uint16_t tx_queue_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (!dev->data->dev_started) {
 		RTE_ETHDEV_LOG(ERR,
 			"Port %u must be started before start any queue\n",
@@ -1059,7 +1103,6 @@ rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	ret = eth_dev_validate_tx_queue(dev, tx_queue_id);
@@ -1083,7 +1126,6 @@ rte_eth_dev_tx_queue_stop(uint16_t port_id, uint16_t tx_queue_id)
 	}
 
 	return eth_err(port_id, dev->dev_ops->tx_queue_stop(dev, tx_queue_id));
-
 }
 
 static int
@@ -1294,9 +1336,15 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	uint16_t old_mtu;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
+	if (dev_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot configure ethdev port %u from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
 
 	if (dev->data->dev_started) {
@@ -1697,7 +1745,6 @@ rte_eth_dev_start(uint16_t port_id)
 	int ret, ret_stop;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
@@ -1778,7 +1825,6 @@ rte_eth_dev_set_link_up(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_up, -ENOTSUP);
@@ -1791,7 +1837,6 @@ rte_eth_dev_set_link_down(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_set_link_down, -ENOTSUP);
@@ -1848,7 +1893,6 @@ rte_eth_dev_is_removed(uint16_t port_id)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
-
 	dev = &rte_eth_devices[port_id];
 
 	if (dev->state == RTE_ETH_DEV_REMOVED)
@@ -1949,8 +1993,8 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	void **rxq;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
@@ -2134,12 +2178,20 @@ rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 	int count;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
 	}
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Rx hairpin queue from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
 	if (ret != 0)
 		return ret;
@@ -2205,8 +2257,8 @@ rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
 		return -EINVAL;
@@ -2307,10 +2359,19 @@ rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	if (tx_queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
 		return -EINVAL;
 	}
+
+	if (conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot setup ethdev port %u Tx hairpin queue from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
 	if (ret != 0)
 		return ret;
@@ -2372,6 +2433,7 @@ rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
 	dev = &rte_eth_devices[tx_port];
+
 	if (dev->data->dev_started == 0) {
 		RTE_ETHDEV_LOG(ERR, "Tx port %d is not started\n", tx_port);
 		return -EBUSY;
@@ -2395,6 +2457,7 @@ rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(tx_port, -ENODEV);
 	dev = &rte_eth_devices[tx_port];
+
 	if (dev->data->dev_started == 0) {
 		RTE_ETHDEV_LOG(ERR, "Tx port %d is already stopped\n", tx_port);
 		return -EBUSY;
@@ -2417,11 +2480,23 @@ rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
 	struct rte_eth_dev *dev;
 	int ret;
 
-	if (peer_ports == NULL || len == 0)
-		return -EINVAL;
-
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (peer_ports == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin peer ports to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (len == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin peer ports to array with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_get_peer_ports,
 				-ENOTSUP);
 
@@ -2455,6 +2530,12 @@ int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
 		buffer_tx_error_fn cbfn, void *userdata)
 {
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set Tx buffer error callback to NULL buffer\n");
+		return -EINVAL;
+	}
+
 	buffer->error_callback = cbfn;
 	buffer->error_userdata = userdata;
 	return 0;
@@ -2465,8 +2546,10 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
 {
 	int ret = 0;
 
-	if (buffer == NULL)
+	if (buffer == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot initialize NULL buffer\n");
 		return -EINVAL;
+	}
 
 	buffer->size = size;
 	if (buffer->error_callback == NULL) {
@@ -2480,11 +2563,12 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
 int
 rte_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id, uint32_t free_cnt)
 {
-	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	struct rte_eth_dev *dev;
 	int ret;
 
-	/* Validate Input Data. Bail if not valid or not supported. */
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
 
 	/* Call driver to free pending mbufs. */
@@ -2541,8 +2625,8 @@ rte_eth_promiscuous_get(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	return dev->data->promiscuous;
 }
 
@@ -2592,8 +2676,8 @@ rte_eth_allmulticast_get(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	return dev->data->all_multicast;
 }
 
@@ -2605,8 +2689,13 @@ rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	if (dev->data->dev_conf.intr_conf.lsc &&
-	    dev->data->dev_started)
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
 	else {
 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
@@ -2625,8 +2714,13 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	if (dev->data->dev_conf.intr_conf.lsc &&
-	    dev->data->dev_started)
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u link to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (dev->data->dev_conf.intr_conf.lsc && dev->data->dev_started)
 		rte_eth_linkstatus_get(dev, eth_link);
 	else {
 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
@@ -2663,6 +2757,22 @@ rte_eth_link_speed_to_str(uint32_t link_speed)
 int
 rte_eth_link_to_str(char *str, size_t len, const struct rte_eth_link *eth_link)
 {
+	if (str == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert link to NULL string\n");
+		return -EINVAL;
+	}
+
+	if (len == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot convert link to string with zero size\n");
+		return -EINVAL;
+	}
+
+	if (eth_link == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot convert to string from NULL link\n");
+		return -EINVAL;
+	}
+
 	if (eth_link->link_status == ETH_LINK_DOWN)
 		return snprintf(str, len, "Link down");
 	else
@@ -2680,8 +2790,14 @@ rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (stats == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u stats to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(stats, 0, sizeof(*stats));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
@@ -2761,13 +2877,17 @@ rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
-	if (!id) {
-		RTE_ETHDEV_LOG(ERR, "Id pointer is NULL\n");
+	if (xstat_name == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u xstats ID from NULL xstat name\n",
+			port_id);
 		return -ENOMEM;
 	}
 
-	if (!xstat_name) {
-		RTE_ETHDEV_LOG(ERR, "xstat_name pointer is NULL\n");
+	if (id == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u xstats ID to NULL\n",
+			port_id);
 		return -ENOMEM;
 	}
 
@@ -3055,12 +3175,13 @@ rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
 	ret = eth_dev_get_xstats_count(port_id);
 	if (ret < 0)
 		return ret;
 	expected_entries = (uint16_t)ret;
 	struct rte_eth_xstat xstats[expected_entries];
-	dev = &rte_eth_devices[port_id];
 	basic_count = eth_dev_get_xstats_basic_count(dev);
 
 	/* Return max number of stats if no ids given */
@@ -3144,7 +3265,6 @@ rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
@@ -3210,11 +3330,8 @@ eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP);
-
 	if (is_rx && (queue_id >= dev->data->nb_rx_queues))
 		return -EINVAL;
 
@@ -3224,11 +3341,10 @@ eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
 	if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
 		return -EINVAL;
 
-	return (*dev->dev_ops->queue_stats_mapping_set)
-			(dev, queue_id, stat_idx, is_rx);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP);
+	return (*dev->dev_ops->queue_stats_mapping_set) (dev, queue_id, stat_idx, is_rx);
 }
 
-
 int
 rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
 		uint8_t stat_idx)
@@ -3238,7 +3354,6 @@ rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
 						stat_idx, STAT_QMAP_TX));
 }
 
-
 int
 rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id,
 		uint8_t stat_idx)
@@ -3256,6 +3371,13 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (fw_version == NULL && fw_size > 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u FW version to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
 							fw_version, fw_size));
@@ -3274,6 +3396,15 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	};
 	int diag;
 
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (dev_info == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u info to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Init dev_info before port_id check since caller does not have
 	 * return status and does not know if get is successful or not.
@@ -3281,9 +3412,6 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
 	memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
 	dev_info->switch_info.domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	dev = &rte_eth_devices[port_id];
-
 	dev_info->rx_desc_lim = lim;
 	dev_info->tx_desc_lim = lim;
 	dev_info->device = dev->device;
@@ -3323,6 +3451,14 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (ptypes == NULL && num > 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u supported packet types to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
@@ -3361,8 +3497,12 @@ rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
-	if (num > 0 && set_ptypes == NULL)
+	if (num > 0 && set_ptypes == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u set packet types to NULL when array size is non zero\n",
+			port_id);
 		return -EINVAL;
+	}
 
 	if (*dev->dev_ops->dev_supported_ptypes_get == NULL ||
 			*dev->dev_ops->dev_ptypes_set == NULL) {
@@ -3432,6 +3572,14 @@ rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (mac_addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u MAC address to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
 
 	return 0;
@@ -3443,8 +3591,14 @@ rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (mtu == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u MTU to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	*mtu = dev->data->mtu;
 	return 0;
 }
@@ -3490,6 +3644,7 @@ rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	if (!(dev->data->dev_conf.rxmode.offloads &
 	      DEV_RX_OFFLOAD_VLAN_FILTER)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: vlan-filtering disabled\n",
@@ -3531,6 +3686,7 @@ rte_eth_dev_set_vlan_strip_on_queue(uint16_t port_id, uint16_t rx_queue_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	if (rx_queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid rx_queue_id=%u\n", rx_queue_id);
 		return -EINVAL;
@@ -3551,8 +3707,8 @@ rte_eth_dev_set_vlan_ether_type(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
 
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_tpid_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->vlan_tpid_set)(dev, vlan_type,
 							       tpid));
 }
@@ -3681,8 +3837,8 @@ rte_eth_dev_set_vlan_pvid(uint16_t port_id, uint16_t pvid, int on)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP);
 
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on));
 }
 
@@ -3693,6 +3849,14 @@ rte_eth_dev_flow_ctrl_get(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u flow control config to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
 	memset(fc_conf, 0, sizeof(*fc_conf));
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf));
@@ -3704,12 +3868,20 @@ rte_eth_dev_flow_ctrl_set(uint16_t port_id, struct rte_eth_fc_conf *fc_conf)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (fc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u flow control from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if ((fc_conf->send_xon != 0) && (fc_conf->send_xon != 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid send_xon, only 0/1 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->flow_ctrl_set)(dev, fc_conf));
 }
@@ -3721,12 +3893,20 @@ rte_eth_dev_priority_flow_ctrl_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (pfc_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u priority flow control from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (pfc_conf->priority > (ETH_DCB_NUM_USER_PRIORITIES - 1)) {
 		RTE_ETHDEV_LOG(ERR, "Invalid priority, only 0-7 allowed\n");
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	/* High water, low water validation are device specific */
 	if  (*dev->dev_ops->priority_flow_ctrl_set)
 		return eth_err(port_id, (*dev->dev_ops->priority_flow_ctrl_set)
@@ -3740,9 +3920,6 @@ eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, num;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
 	for (i = 0; i < num; i++) {
 		if (reta_conf[i].mask)
@@ -3759,9 +3936,6 @@ eth_check_reta_entry(struct rte_eth_rss_reta_entry64 *reta_conf,
 {
 	uint16_t i, idx, shift;
 
-	if (!reta_conf)
-		return -EINVAL;
-
 	if (max_rxq == 0) {
 		RTE_ETHDEV_LOG(ERR, "No receive queue is available\n");
 		return -EINVAL;
@@ -3792,13 +3966,27 @@ rte_eth_dev_rss_reta_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u RSS RETA to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (reta_size == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u RSS RETA with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
-
 	/* Check entry value */
 	ret = eth_check_reta_entry(reta_conf, reta_size,
 				dev->data->nb_rx_queues);
@@ -3819,13 +4007,20 @@ rte_eth_dev_rss_reta_query(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (reta_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot query ethdev port %u RSS RETA from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	/* Check mask bits */
 	ret = eth_check_reta_mask(reta_conf, reta_size);
 	if (ret < 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_query, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->reta_query)(dev, reta_conf,
 							    reta_size));
@@ -3840,14 +4035,20 @@ rte_eth_dev_rss_hash_update(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot update ethdev port %u RSS hash from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
 
 	rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
-
-	dev = &rte_eth_devices[port_id];
 	if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
 	    dev_info.flow_type_rss_offloads) {
 		RTE_ETHDEV_LOG(ERR,
@@ -3869,6 +4070,14 @@ rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (rss_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u RSS hash config to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->rss_hash_conf_get)(dev,
 								   rss_conf));
@@ -3881,8 +4090,12 @@ rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
 	if (udp_tunnel == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n");
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot add ethdev port %u UDP tunnel port from NULL UDP tunnel\n",
+			port_id);
 		return -EINVAL;
 	}
 
@@ -3891,7 +4104,6 @@ rte_eth_dev_udp_tunnel_port_add(uint16_t port_id,
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->udp_tunnel_port_add, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->udp_tunnel_port_add)(dev,
 								udp_tunnel));
@@ -3907,7 +4119,9 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
 	dev = &rte_eth_devices[port_id];
 
 	if (udp_tunnel == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Invalid udp_tunnel parameter\n");
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot delete ethdev port %u UDP tunnel port from NULL UDP tunnel\n",
+			port_id);
 		return -EINVAL;
 	}
 
@@ -3928,6 +4142,7 @@ rte_eth_led_on(uint16_t port_id)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_on, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->dev_led_on)(dev));
 }
@@ -3939,6 +4154,7 @@ rte_eth_led_off(uint16_t port_id)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_led_off, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev));
 }
@@ -3951,11 +4167,16 @@ rte_eth_fec_get_capability(uint16_t port_id,
 	struct rte_eth_dev *dev;
 	int ret;
 
-	if (speed_fec_capa == NULL && num > 0)
-		return -EINVAL;
-
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (speed_fec_capa == NULL && num > 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u FEC capability to NULL when array size is non zero\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get_capability, -ENOTSUP);
 	ret = (*dev->dev_ops->fec_get_capability)(dev, speed_fec_capa, num);
 
@@ -3967,11 +4188,16 @@ rte_eth_fec_get(uint16_t port_id, uint32_t *fec_capa)
 {
 	struct rte_eth_dev *dev;
 
-	if (fec_capa == NULL)
-		return -EINVAL;
-
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (fec_capa == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u current FEC mode to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fec_get)(dev, fec_capa));
 }
@@ -3983,6 +4209,7 @@ rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_set, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->fec_set)(dev, fec_capa));
 }
@@ -4024,6 +4251,14 @@ rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *addr,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot add ethdev port %u MAC address from NULL address\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_add, -ENOTSUP);
 
 	if (rte_is_zero_ether_addr(addr)) {
@@ -4074,6 +4309,14 @@ rte_eth_dev_mac_addr_remove(uint16_t port_id, struct rte_ether_addr *addr)
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot remove ethdev port %u MAC address from NULL address\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_remove, -ENOTSUP);
 
 	index = eth_dev_get_mac_addr_index(port_id, addr);
@@ -4104,11 +4347,18 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct rte_ether_addr *addr)
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u default MAC address from NULL address\n",
+			port_id);
+		return -EINVAL;
+	}
 
 	if (!rte_is_valid_assigned_ether_addr(addr))
 		return -EINVAL;
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
 	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
@@ -4159,8 +4409,15 @@ rte_eth_dev_uc_hash_table_set(uint16_t port_id, struct rte_ether_addr *addr,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (addr == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u unicast hash table from NULL address\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (rte_is_zero_ether_addr(addr)) {
 		RTE_ETHDEV_LOG(ERR, "Port %u: Cannot add NULL MAC address\n",
 			port_id);
@@ -4209,7 +4466,6 @@ rte_eth_dev_uc_all_hash_table_set(uint16_t port_id, uint8_t on)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->uc_all_hash_table_set, -ENOTSUP);
@@ -4226,12 +4482,12 @@ int rte_eth_set_queue_rate_limit(uint16_t port_id, uint16_t queue_idx,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
 
 	ret = rte_eth_dev_info_get(port_id, &dev_info);
 	if (ret != 0)
 		return ret;
 
-	dev = &rte_eth_devices[port_id];
 	link = dev->data->dev_link;
 
 	if (queue_idx > dev_info.max_tx_queues) {
@@ -4261,6 +4517,15 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (mirror_conf == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u mirror rule from NULL config\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (mirror_conf->rule_type == 0) {
 		RTE_ETHDEV_LOG(ERR, "Mirror rule type can not be 0\n");
 		return -EINVAL;
@@ -4287,7 +4552,6 @@ rte_eth_mirror_rule_set(uint16_t port_id,
 		return -EINVAL;
 	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_set, -ENOTSUP);
 
 	return eth_err(port_id, (*dev->dev_ops->mirror_rule_set)(dev,
@@ -4300,12 +4564,10 @@ rte_eth_mirror_rule_reset(uint16_t port_id, uint8_t rule_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_reset, -ENOTSUP);
 
-	return eth_err(port_id, (*dev->dev_ops->mirror_rule_reset)(dev,
-								   rule_id));
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mirror_rule_reset, -ENOTSUP);
+	return eth_err(port_id, (*dev->dev_ops->mirror_rule_reset)(dev, rule_id));
 }
 
 RTE_INIT(eth_dev_init_cb_lists)
@@ -4326,8 +4588,12 @@ rte_eth_dev_callback_register(uint16_t port_id,
 	uint16_t next_port;
 	uint16_t last_port;
 
-	if (!cb_fn)
+	if (cb_fn == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot register ethdev port %u callback from NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
 	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
 		RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
@@ -4389,8 +4655,12 @@ rte_eth_dev_callback_unregister(uint16_t port_id,
 	uint16_t next_port;
 	uint16_t last_port;
 
-	if (!cb_fn)
+	if (cb_fn == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot unregister ethdev port %u callback from NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
 	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
 		RTE_ETHDEV_LOG(ERR, "Invalid port_id=%d\n", port_id);
@@ -4483,7 +4753,6 @@ rte_eth_dev_rx_intr_ctl(uint16_t port_id, int epfd, int op, void *data)
 	int rc;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	if (!dev->intr_handle) {
@@ -4520,7 +4789,6 @@ rte_eth_dev_rx_intr_ctl_q_get_fd(uint16_t port_id, uint16_t queue_id)
 	int fd;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
-
 	dev = &rte_eth_devices[port_id];
 
 	if (queue_id >= dev->data->nb_rx_queues) {
@@ -4707,8 +4975,8 @@ rte_eth_dev_rx_intr_ctl_q(uint16_t port_id, uint16_t queue_id,
 	int rc;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	if (queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
 		return -EINVAL;
@@ -4745,7 +5013,6 @@ rte_eth_dev_rx_intr_enable(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	ret = eth_dev_validate_rx_queue(dev, queue_id);
@@ -4753,8 +5020,7 @@ rte_eth_dev_rx_intr_enable(uint16_t port_id,
 		return ret;
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_enable, -ENOTSUP);
-	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev,
-								queue_id));
+	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_enable)(dev, queue_id));
 }
 
 int
@@ -4765,7 +5031,6 @@ rte_eth_dev_rx_intr_disable(uint16_t port_id,
 	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
 	ret = eth_dev_validate_rx_queue(dev, queue_id);
@@ -4773,8 +5038,7 @@ rte_eth_dev_rx_intr_disable(uint16_t port_id,
 		return ret;
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_intr_disable, -ENOTSUP);
-	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev,
-								queue_id));
+	return eth_err(port_id, (*dev->dev_ops->rx_queue_intr_disable)(dev, queue_id));
 }
 
 
@@ -5008,16 +5272,19 @@ rte_eth_rx_queue_info_get(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-	if (qinfo == NULL)
-		return -EINVAL;
-
 	dev = &rte_eth_devices[port_id];
+
 	if (queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
 		return -EINVAL;
 	}
 
+	if (qinfo == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Rx queue %u info to NULL\n",
+			port_id, queue_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->rx_queues == NULL ||
 			dev->data->rx_queues[queue_id] == NULL) {
 		RTE_ETHDEV_LOG(ERR,
@@ -5050,16 +5317,19 @@ rte_eth_tx_queue_info_get(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-	if (qinfo == NULL)
-		return -EINVAL;
-
 	dev = &rte_eth_devices[port_id];
+
 	if (queue_id >= dev->data->nb_tx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
 		return -EINVAL;
 	}
 
+	if (qinfo == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot get ethdev port %u Tx queue %u info to NULL\n",
+			port_id, queue_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->tx_queues == NULL ||
 			dev->data->tx_queues[queue_id] == NULL) {
 		RTE_ETHDEV_LOG(ERR,
@@ -5092,10 +5362,6 @@ rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-	if (mode == NULL)
-		return -EINVAL;
-
 	dev = &rte_eth_devices[port_id];
 
 	if (queue_id >= dev->data->nb_rx_queues) {
@@ -5103,6 +5369,13 @@ rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
+	if (mode == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u Rx queue %u burst mode to NULL\n",
+			port_id, queue_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_burst_mode_get, -ENOTSUP);
 	memset(mode, 0, sizeof(*mode));
 	return eth_err(port_id,
@@ -5116,10 +5389,6 @@ rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-	if (mode == NULL)
-		return -EINVAL;
-
 	dev = &rte_eth_devices[port_id];
 
 	if (queue_id >= dev->data->nb_tx_queues) {
@@ -5127,6 +5396,13 @@ rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
+	if (mode == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u Tx queue %u burst mode to NULL\n",
+			port_id, queue_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_burst_mode_get, -ENOTSUP);
 	memset(mode, 0, sizeof(*mode));
 	return eth_err(port_id,
@@ -5140,25 +5416,23 @@ rte_eth_get_monitor_addr(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
 
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_monitor_addr, -ENOTSUP);
-
 	if (queue_id >= dev->data->nb_rx_queues) {
 		RTE_ETHDEV_LOG(ERR, "Invalid Rx queue_id=%u\n", queue_id);
 		return -EINVAL;
 	}
 
 	if (pmc == NULL) {
-		RTE_ETHDEV_LOG(ERR, "Invalid power monitor condition=%p\n",
-				pmc);
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u Rx queue %u power monitor condition to NULL\n",
+			port_id, queue_id);
 		return -EINVAL;
 	}
 
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_monitor_addr, -ENOTSUP);
 	return eth_err(port_id,
-		dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id],
-			pmc));
+		dev->dev_ops->get_monitor_addr(dev->data->rx_queues[queue_id], pmc));
 }
 
 int
@@ -5169,8 +5443,8 @@ rte_eth_dev_set_mc_addr_list(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_mc_addr_list, -ENOTSUP);
 	return eth_err(port_id, dev->dev_ops->set_mc_addr_list(dev,
 						mc_addr_set, nb_mc_addr));
@@ -5209,6 +5483,13 @@ rte_eth_timesync_read_rx_timestamp(uint16_t port_id, struct timespec *timestamp,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Rx timestamp to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_rx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_rx_timestamp)
 				(dev, timestamp, flags));
@@ -5223,6 +5504,13 @@ rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u Tx timestamp to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_tx_timestamp, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_tx_timestamp)
 				(dev, timestamp));
@@ -5237,8 +5525,7 @@ rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta)
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_adjust_time, -ENOTSUP);
-	return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev,
-								      delta));
+	return eth_err(port_id, (*dev->dev_ops->timesync_adjust_time)(dev, delta));
 }
 
 int
@@ -5249,6 +5536,13 @@ rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot read ethdev port %u timesync time to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_read_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_read_time)(dev,
 								timestamp));
@@ -5262,6 +5556,13 @@ rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *timestamp)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (timestamp == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot write ethdev port %u timesync from NULL time\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timesync_write_time, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->timesync_write_time)(dev,
 								timestamp));
@@ -5275,6 +5576,12 @@ rte_eth_read_clock(uint16_t port_id, uint64_t *clock)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
+	if (clock == NULL) {
+		RTE_ETHDEV_LOG(ERR, "Cannot read ethdev port %u clock to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->read_clock, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->read_clock)(dev, clock));
 }
@@ -5285,10 +5592,15 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (info == NULL)
+	dev = &rte_eth_devices[port_id];
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u register info to NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->get_reg)(dev, info));
 }
@@ -5299,8 +5611,8 @@ rte_eth_dev_get_eeprom_length(uint16_t port_id)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom_length, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->get_eeprom_length)(dev));
 }
@@ -5311,10 +5623,15 @@ rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (info == NULL)
+	dev = &rte_eth_devices[port_id];
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u EEPROM info to NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->get_eeprom)(dev, info));
 }
@@ -5325,10 +5642,15 @@ rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (info == NULL)
+	dev = &rte_eth_devices[port_id];
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot set ethdev port %u EEPROM from NULL info\n",
+			port_id);
 		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP);
 	return eth_err(port_id, (*dev->dev_ops->set_eeprom)(dev, info));
 }
@@ -5340,10 +5662,15 @@ rte_eth_dev_get_module_info(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (modinfo == NULL)
+	dev = &rte_eth_devices[port_id];
+
+	if (modinfo == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u EEPROM module info to NULL\n",
+			port_id);
 		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP);
 	return (*dev->dev_ops->get_module_info)(dev, modinfo);
 }
@@ -5355,10 +5682,29 @@ rte_eth_dev_get_module_eeprom(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	if (info == NULL || info->data == NULL || info->length == 0)
+	dev = &rte_eth_devices[port_id];
+
+	if (info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u module EEPROM info to NULL\n",
+			port_id);
 		return -EINVAL;
+	}
+
+	if (info->data == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u module EEPROM data to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
+	if (info->length == 0) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u module EEPROM to data with zero size\n",
+			port_id);
+		return -EINVAL;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP);
 	return (*dev->dev_ops->get_module_eeprom)(dev, info);
 }
@@ -5370,8 +5716,15 @@ rte_eth_dev_get_dcb_info(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (dcb_info == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u DCB info to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	memset(dcb_info, 0, sizeof(struct rte_eth_dcb_info));
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_dcb_info, -ENOTSUP);
@@ -5421,8 +5774,15 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
 	dev = &rte_eth_devices[port_id];
+
+	if (cap == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot get ethdev port %u hairpin capability to NULL\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_cap_get, -ENOTSUP);
 	memset(cap, 0, sizeof(*cap));
 	return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
@@ -5431,8 +5791,7 @@ rte_eth_dev_hairpin_capability_get(uint16_t port_id,
 int
 rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	if (dev->data->rx_queue_state[queue_id] ==
-	    RTE_ETH_QUEUE_STATE_HAIRPIN)
+	if (dev->data->rx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN)
 		return 1;
 	return 0;
 }
@@ -5440,8 +5799,7 @@ rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 int
 rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	if (dev->data->tx_queue_state[queue_id] ==
-	    RTE_ETH_QUEUE_STATE_HAIRPIN)
+	if (dev->data->tx_queue_state[queue_id] == RTE_ETH_QUEUE_STATE_HAIRPIN)
 		return 1;
 	return 0;
 }
@@ -5452,11 +5810,14 @@ rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
 	struct rte_eth_dev *dev;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
 
-	if (pool == NULL)
+	if (pool == NULL) {
+		RTE_ETHDEV_LOG(ERR,
+			"Cannot test ethdev port %u mempool operation from NULL pool\n",
+			port_id);
 		return -EINVAL;
-
-	dev = &rte_eth_devices[port_id];
+	}
 
 	if (*dev->dev_ops->pool_ops_supported == NULL)
 		return 1; /* all pools are supported */
@@ -5928,8 +6289,7 @@ rte_eth_representor_info_get(uint16_t port_id,
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->representor_info_get, -ENOTSUP);
-	return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev,
-								      info));
+	return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev, info));
 }
 
 RTE_LOG_REGISTER(rte_eth_dev_logtype, lib.ethdev, INFO);
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index a0d01d2..faf3bd9 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -2711,6 +2711,7 @@ int rte_eth_allmulticast_get(uint16_t port_id);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2726,6 +2727,7 @@ int rte_eth_link_get(uint16_t port_id, struct rte_eth_link *link);
  *   - (0) if successful.
  *   - (-ENOTSUP) if the function is not supported in PMD driver.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *link);
 
@@ -2761,7 +2763,7 @@ const char *rte_eth_link_speed_to_str(uint32_t link_speed);
  * @param eth_link
  *   Link status returned by rte_eth_link_get function
  * @return
- *   Number of bytes written to str array.
+ *   Number of bytes written to str array or -EINVAL if bad parameter.
  */
 __rte_experimental
 int rte_eth_link_to_str(char *str, size_t len,
@@ -2934,6 +2936,7 @@ int rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids,
  *    -ENODEV for invalid port_id,
  *    -EIO if device is removed,
  *    -EINVAL if the xstat_name doesn't exist in port_id
+ *    -ENOMEM if bad parameter.
  */
 int rte_eth_xstats_get_id_by_name(uint16_t port_id, const char *xstat_name,
 		uint64_t *id);
@@ -3006,6 +3009,7 @@ int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  * @return
  *   - (0) if successful
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
@@ -3050,6 +3054,7 @@ int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
  *   - (0) if successful.
  *   - (-ENOTSUP) if support for dev_infos_get() does not exist for the device.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
 
@@ -3069,6 +3074,7 @@ int rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info);
  *   - (-ENOTSUP) if operation is not supported.
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
+ *   - (-EINVAL) if bad parameter.
  *   - (>0) if *fw_size* is not enough to store firmware version, return
  *          the size of the non truncated string.
  */
@@ -3112,6 +3118,7 @@ int rte_eth_dev_fw_version_get(uint16_t port_id,
  *           only num entries will be filled into the ptypes array, but the full
  *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
 				     uint32_t *ptypes, int num);
@@ -3162,6 +3169,7 @@ int rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
  * @return
  *   - (0) if successful.
  *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu);
 
@@ -3356,7 +3364,7 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size);
  * @param userdata
  *   Arbitrary parameter to be passed to the callback function
  * @return
- *   0 on success, or -1 on error with rte_errno set appropriately
+ *   0 on success, or -EINVAL if bad parameter
  */
 int
 rte_eth_tx_buffer_set_err_callback(struct rte_eth_dev_tx_buffer *buffer,
@@ -3783,6 +3791,7 @@ int rte_eth_fec_set(uint16_t port_id, uint32_t fec_capa);
  *   - (-ENOTSUP) if hardware doesn't support flow control.
  *   - (-ENODEV)  if *port_id* invalid.
  *   - (-EIO)  if device is removed.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_flow_ctrl_get(uint16_t port_id,
 			      struct rte_eth_fc_conf *fc_conf);
@@ -3854,7 +3863,8 @@ int rte_eth_dev_mac_addr_add(uint16_t port_id, struct rte_ether_addr *mac_addr,
  *   - (0) if successful, or *mac_addr* didn't exist.
  *   - (-ENOTSUP) if hardware doesn't support.
  *   - (-ENODEV) if *port* invalid.
- *   - (-EADDRINUSE) if attempting to remove the default MAC address
+ *   - (-EADDRINUSE) if attempting to remove the default MAC address.
+ *   - (-EINVAL) if MAC address is invalid.
  */
 int rte_eth_dev_mac_addr_remove(uint16_t port_id,
 				struct rte_ether_addr *mac_addr);
@@ -4053,6 +4063,7 @@ int rte_eth_dev_rss_hash_update(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support RSS.
+ *   - (-EINVAL) if bad parameter.
  */
 int
 rte_eth_dev_rss_hash_conf_get(uint16_t port_id,
@@ -4121,6 +4132,7 @@ rte_eth_dev_udp_tunnel_port_delete(uint16_t port_id,
  *   - (-ENODEV) if port identifier is invalid.
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_get_dcb_info(uint16_t port_id,
 			     struct rte_eth_dcb_info *dcb_info);
@@ -4533,6 +4545,7 @@ rte_eth_dev_get_module_eeprom(uint16_t port_id,
  *   - (-EIO) if device is removed.
  *   - (-ENOTSUP) if PMD of *port_id* doesn't support multicast filtering.
  *   - (-ENOSPC) if *port_id* has not enough multicast filtering resources.
+ *   - (-EINVAL) if bad parameter.
  */
 int rte_eth_dev_set_mc_addr_list(uint16_t port_id,
 				 struct rte_ether_addr *mc_addr_set,
@@ -4637,6 +4650,7 @@ int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
  *
  * @return
  *   - 0: Success.
+ *   - -EINVAL: Bad parameter.
  */
 int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *time);
 
@@ -4703,6 +4717,7 @@ int rte_eth_timesync_write_time(uint16_t port_id, const struct timespec *time);
  *   - 0: Success.
  *   - -ENODEV: The port ID is invalid.
  *   - -ENOTSUP: The function is not supported by the Ethernet driver.
+ *   - -EINVAL: if bad parameter.
  */
 __rte_experimental
 int
@@ -4806,6 +4821,7 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  * @return
  *   - (0) if successful.
  *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-EINVAL) if bad parameter.
  */
 __rte_experimental
 int rte_eth_dev_hairpin_capability_get(uint16_t port_id,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21 11:28     ` Andrew Rybchenko
@ 2021-04-21 12:36       ` Min Hu (Connor)
  2021-04-21 12:38       ` Kevin Traynor
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 65+ messages in thread
From: Min Hu (Connor) @ 2021-04-21 12:36 UTC (permalink / raw)
  To: Andrew Rybchenko, Ferruh Yigit, Thomas Monjalon, Gaetan Rivet,
	Stephen Hemminger, Qi Zhang, Ali Alnubani, Yuanhan Liu,
	Matan Azrad, Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: dev, stable, Kevin Traynor

Hi, fixed in v10, thanks.

在 2021/4/21 19:28, Andrew Rybchenko 写道:
> On 4/21/21 5:36 AM, Ferruh Yigit wrote:
>> From: "Min Hu (Connor)" <humin29@huawei.com>
>>
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Acked-by: Kevin Traynor <ktraynor@redhat.com>
> 
> Few nits below.
> Other than that I confirm my "Reviewed-by".
> 
> The patch is really long. It would be better to split it into
> few:
>   - relocate dev assignment
>   - empty lines mangling (when it is unrelated to previous item)
>   - ops check before usage (combined with related style checks)
>   - error logs refinement
> 
> However, since the patch is already reviewed this way, may
> be it is better to push as is after review notes processing.
> 
>> @@ -817,7 +859,12 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
>>   	uint16_t pid;
>>   
>>   	if (name == NULL) {
>> -		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
>> +		RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (port_id == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot get port ID to NULL\n");
> 
> Since name is already checked above, I think it would be useful
> to log 'name' here to provide context.
> 
>>   		return -EINVAL;
>>   	}
>>   
> 
> [snip]
> 
>> @@ -3256,6 +3370,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	dev = &rte_eth_devices[port_id];
>>   
>> +	if (fw_version == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u FW version to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (fw_size == 0) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u FW version to buffer with zero size\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
> 
> The only error condition is NULL fw_version with positive
> fw_size. Othwerwise, it could be just a call to get required
> size of buffer for FW version.
> 
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
>>   	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
>>   							fw_version, fw_size));
> 
> [snip]
> 
>> @@ -3323,6 +3457,21 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	dev = &rte_eth_devices[port_id];
>> +
>> +	if (ptypes == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u supported packet types to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (num == 0) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u supported packet types to array with zero size\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
> 
> The error condition is "ptypes == NULL && num > 0".
> Otherwise, if num == 0 (regardless ptypes) it is just
> a call to get size of required buffer. Same as below.
> 
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
>>   	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
>>   
> 
> [snip]
> .
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21 11:28     ` Andrew Rybchenko
  2021-04-21 12:36       ` Min Hu (Connor)
@ 2021-04-21 12:38       ` Kevin Traynor
  2021-04-21 13:19       ` Ferruh Yigit
  2021-04-21 14:17       ` Ferruh Yigit
  3 siblings, 0 replies; 65+ messages in thread
From: Kevin Traynor @ 2021-04-21 12:38 UTC (permalink / raw)
  To: Andrew Rybchenko, Ferruh Yigit, Thomas Monjalon, Gaetan Rivet,
	Stephen Hemminger, Qi Zhang, Ali Alnubani, Yuanhan Liu,
	Matan Azrad, Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: dev, Min Hu (Connor), stable

On 21/04/2021 12:28, Andrew Rybchenko wrote:
> On 4/21/21 5:36 AM, Ferruh Yigit wrote:
>> From: "Min Hu (Connor)" <humin29@huawei.com>
>>
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Acked-by: Kevin Traynor <ktraynor@redhat.com>
> 
> Few nits below.
> Other than that I confirm my "Reviewed-by".
> 
> The patch is really long. It would be better to split it into
> few:
>  - relocate dev assignment
>  - empty lines mangling (when it is unrelated to previous item)
>  - ops check before usage (combined with related style checks)
>  - error logs refinement
> 

+1

> However, since the patch is already reviewed this way, may
> be it is better to push as is after review notes processing.
> 
>> @@ -817,7 +859,12 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
>>  	uint16_t pid;
>>  
>>  	if (name == NULL) {
>> -		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
>> +		RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (port_id == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot get port ID to NULL\n");
> 
> Since name is already checked above, I think it would be useful
> to log 'name' here to provide context.
> 
>>  		return -EINVAL;
>>  	}
>>  
> 
> [snip]
> 
>> @@ -3256,6 +3370,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
>>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>  	dev = &rte_eth_devices[port_id];
>>  
>> +	if (fw_version == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u FW version to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (fw_size == 0) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u FW version to buffer with zero size\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
> 
> The only error condition is NULL fw_version with positive
> fw_size. Othwerwise, it could be just a call to get required
> size of buffer for FW version.
> 
>>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
>>  	return eth_err(port_id, (*dev->dev_ops->fw_version_get)(dev,
>>  							fw_version, fw_size));
> 
> [snip]
> 
>> @@ -3323,6 +3457,21 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>>  
>>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>  	dev = &rte_eth_devices[port_id];
>> +
>> +	if (ptypes == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u supported packet types to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (num == 0) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u supported packet types to array with zero size\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
> 
> The error condition is "ptypes == NULL && num > 0".
> Otherwise, if num == 0 (regardless ptypes) it is just
> a call to get size of required buffer. Same as below.
> 
>>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
>>  	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
>>  
> 

nice catch for these.

> [snip]
>






^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21 11:28     ` Andrew Rybchenko
  2021-04-21 12:36       ` Min Hu (Connor)
  2021-04-21 12:38       ` Kevin Traynor
@ 2021-04-21 13:19       ` Ferruh Yigit
  2021-04-21 13:40         ` Ferruh Yigit
  2021-04-21 13:50         ` Andrew Rybchenko
  2021-04-21 14:17       ` Ferruh Yigit
  3 siblings, 2 replies; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-21 13:19 UTC (permalink / raw)
  To: Andrew Rybchenko, Thomas Monjalon, Gaetan Rivet,
	Stephen Hemminger, Qi Zhang, Ali Alnubani, Yuanhan Liu,
	Matan Azrad, Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: dev, Min Hu (Connor), stable, Kevin Traynor

On 4/21/2021 12:28 PM, Andrew Rybchenko wrote:
> On 4/21/21 5:36 AM, Ferruh Yigit wrote:
>> From: "Min Hu (Connor)" <humin29@huawei.com>
>>
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Acked-by: Kevin Traynor <ktraynor@redhat.com>
> 
> Few nits below.
> Other than that I confirm my "Reviewed-by".
> 
> The patch is really long. It would be better to split it into
> few:
>   - relocate dev assignment
>   - empty lines mangling (when it is unrelated to previous item)
>   - ops check before usage (combined with related style checks)
>   - error logs refinement
> 
> However, since the patch is already reviewed this way, may
> be it is better to push as is after review notes processing.
> 
>> @@ -817,7 +859,12 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
>>   	uint16_t pid;
>>   
>>   	if (name == NULL) {
>> -		RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
>> +		RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (port_id == NULL) {
>> +		RTE_ETHDEV_LOG(ERR, "Cannot get port ID to NULL\n");
> 
> Since name is already checked above, I think it would be useful
> to log 'name' here to provide context.
> 
>>   		return -EINVAL;
>>   	}
>>   
> 
> [snip]
> 
>> @@ -3256,6 +3370,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	dev = &rte_eth_devices[port_id];
>>   
>> +	if (fw_version == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u FW version to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (fw_size == 0) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u FW version to buffer with zero size\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
> 
> The only error condition is NULL fw_version with positive
> fw_size. Othwerwise, it could be just a call to get required
> size of buffer for FW version.
> 

Right, above is wrong.

Agree that "fw_version == NULL && fw_size > 0" is error condition,
but is it clear if how this API should behave on
"fw_version == NULL && fw_size == 0"?

Like sfc has following,
  if ((fw_version == NULL) || (fw_size == 0))
  	return -EINVAL;

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21 13:19       ` Ferruh Yigit
@ 2021-04-21 13:40         ` Ferruh Yigit
  2021-04-21 13:50           ` Andrew Rybchenko
  2021-04-21 13:50         ` Andrew Rybchenko
  1 sibling, 1 reply; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-21 13:40 UTC (permalink / raw)
  To: Andrew Rybchenko, Thomas Monjalon, Gaetan Rivet,
	Stephen Hemminger, Qi Zhang, Ali Alnubani, Yuanhan Liu,
	Matan Azrad, Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: dev, Min Hu (Connor), stable, Kevin Traynor

On 4/21/2021 2:19 PM, Ferruh Yigit wrote:
> On 4/21/2021 12:28 PM, Andrew Rybchenko wrote:
>> On 4/21/21 5:36 AM, Ferruh Yigit wrote:
>>> From: "Min Hu (Connor)" <humin29@huawei.com>
>>>
>>> This patch adds more sanity checks in control path APIs.
>>>
>>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process 
>>> model")
>>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>>> Cc: stable@dpdk.org
>>>
>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>> Acked-by: Kevin Traynor <ktraynor@redhat.com>
>>
>> Few nits below.
>> Other than that I confirm my "Reviewed-by".
>>
>> The patch is really long. It would be better to split it into
>> few:
>>   - relocate dev assignment
>>   - empty lines mangling (when it is unrelated to previous item)
>>   - ops check before usage (combined with related style checks)
>>   - error logs refinement
>>
>> However, since the patch is already reviewed this way, may
>> be it is better to push as is after review notes processing.
>>
>>> @@ -817,7 +859,12 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t 
>>> *port_id)
>>>       uint16_t pid;
>>>       if (name == NULL) {
>>> -        RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
>>> +        RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    if (port_id == NULL) {
>>> +        RTE_ETHDEV_LOG(ERR, "Cannot get port ID to NULL\n");
>>
>> Since name is already checked above, I think it would be useful
>> to log 'name' here to provide context.
>>
>>>           return -EINVAL;
>>>       }
>>
>> [snip]
>>
>>> @@ -3256,6 +3370,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char 
>>> *fw_version, size_t fw_size)
>>>       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>       dev = &rte_eth_devices[port_id];
>>> +    if (fw_version == NULL) {
>>> +        RTE_ETHDEV_LOG(ERR,
>>> +            "Cannot get ethdev port %u FW version to NULL\n",
>>> +            port_id);
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    if (fw_size == 0) {
>>> +        RTE_ETHDEV_LOG(ERR,
>>> +            "Cannot get ethdev port %u FW version to buffer with zero size\n",
>>> +            port_id);
>>> +        return -EINVAL;
>>> +    }
>>> +
>>
>> The only error condition is NULL fw_version with positive
>> fw_size. Othwerwise, it could be just a call to get required
>> size of buffer for FW version.
>>
> 
> Right, above is wrong.
> 
> Agree that "fw_version == NULL && fw_size > 0" is error condition,
> but is it clear if how this API should behave on
> "fw_version == NULL && fw_size == 0"?
> 
> Like sfc has following,
> if ((fw_version == NULL) || (fw_size == 0))
>      return -EINVAL;

axgbe, qede also returns error when fw_version is NULL, independent from fw_size.

But I think taking "fw_version == NULL && fw_size > 0" as only error condition 
is reasonable, although some PMDs will be behaving wrong.
I can send a separate patch to unify the behavior.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21 13:19       ` Ferruh Yigit
  2021-04-21 13:40         ` Ferruh Yigit
@ 2021-04-21 13:50         ` Andrew Rybchenko
  1 sibling, 0 replies; 65+ messages in thread
From: Andrew Rybchenko @ 2021-04-21 13:50 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon, Gaetan Rivet, Stephen Hemminger,
	Qi Zhang, Ali Alnubani, Yuanhan Liu, Matan Azrad,
	Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: dev, Min Hu (Connor), stable, Kevin Traynor

On 4/21/21 4:19 PM, Ferruh Yigit wrote:
> On 4/21/2021 12:28 PM, Andrew Rybchenko wrote:
>> On 4/21/21 5:36 AM, Ferruh Yigit wrote:
>>> From: "Min Hu (Connor)" <humin29@huawei.com>
>>>
>>> This patch adds more sanity checks in control path APIs.
>>>
>>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and
>>> variables")
>>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple
>>> process model")
>>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>>> Cc: stable@dpdk.org
>>>
>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>> Acked-by: Kevin Traynor <ktraynor@redhat.com>
>>
>> Few nits below.
>> Other than that I confirm my "Reviewed-by".
>>
>> The patch is really long. It would be better to split it into
>> few:
>>   - relocate dev assignment
>>   - empty lines mangling (when it is unrelated to previous item)
>>   - ops check before usage (combined with related style checks)
>>   - error logs refinement
>>
>> However, since the patch is already reviewed this way, may
>> be it is better to push as is after review notes processing.
>>
>>> @@ -817,7 +859,12 @@ rte_eth_dev_get_port_by_name(const char *name,
>>> uint16_t *port_id)
>>>       uint16_t pid;
>>>         if (name == NULL) {
>>> -        RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
>>> +        RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    if (port_id == NULL) {
>>> +        RTE_ETHDEV_LOG(ERR, "Cannot get port ID to NULL\n");
>>
>> Since name is already checked above, I think it would be useful
>> to log 'name' here to provide context.
>>
>>>           return -EINVAL;
>>>       }
>>>   
>>
>> [snip]
>>
>>> @@ -3256,6 +3370,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id,
>>> char *fw_version, size_t fw_size)
>>>       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>       dev = &rte_eth_devices[port_id];
>>>   +    if (fw_version == NULL) {
>>> +        RTE_ETHDEV_LOG(ERR,
>>> +            "Cannot get ethdev port %u FW version to NULL\n",
>>> +            port_id);
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    if (fw_size == 0) {
>>> +        RTE_ETHDEV_LOG(ERR,
>>> +            "Cannot get ethdev port %u FW version to buffer with
>>> zero size\n",
>>> +            port_id);
>>> +        return -EINVAL;
>>> +    }
>>> +
>>
>> The only error condition is NULL fw_version with positive
>> fw_size. Othwerwise, it could be just a call to get required
>> size of buffer for FW version.
>>
>
> Right, above is wrong.
>
> Agree that "fw_version == NULL && fw_size > 0" is error condition,
> but is it clear if how this API should behave on
> "fw_version == NULL && fw_size == 0"?
>
> Like sfc has following,
> if ((fw_version == NULL) || (fw_size == 0))
>     return -EINVAL;

It looks like net/sfc is buggy here. My review notes are based on
rte_eth_dev_fw_version_get() return values description.


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21 13:40         ` Ferruh Yigit
@ 2021-04-21 13:50           ` Andrew Rybchenko
  0 siblings, 0 replies; 65+ messages in thread
From: Andrew Rybchenko @ 2021-04-21 13:50 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon, Gaetan Rivet, Stephen Hemminger,
	Qi Zhang, Ali Alnubani, Yuanhan Liu, Matan Azrad,
	Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: dev, Min Hu (Connor), stable, Kevin Traynor

On 4/21/21 4:40 PM, Ferruh Yigit wrote:
> On 4/21/2021 2:19 PM, Ferruh Yigit wrote:
>> On 4/21/2021 12:28 PM, Andrew Rybchenko wrote:
>>> On 4/21/21 5:36 AM, Ferruh Yigit wrote:
>>>> From: "Min Hu (Connor)" <humin29@huawei.com>
>>>>
>>>> This patch adds more sanity checks in control path APIs.
>>>>
>>>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>>>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and
>>>> variables")
>>>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>>>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple
>>>> process model")
>>>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>>>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>>>> Cc: stable@dpdk.org
>>>>
>>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>>>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>> Acked-by: Kevin Traynor <ktraynor@redhat.com>
>>>
>>> Few nits below.
>>> Other than that I confirm my "Reviewed-by".
>>>
>>> The patch is really long. It would be better to split it into
>>> few:
>>>   - relocate dev assignment
>>>   - empty lines mangling (when it is unrelated to previous item)
>>>   - ops check before usage (combined with related style checks)
>>>   - error logs refinement
>>>
>>> However, since the patch is already reviewed this way, may
>>> be it is better to push as is after review notes processing.
>>>
>>>> @@ -817,7 +859,12 @@ rte_eth_dev_get_port_by_name(const char *name,
>>>> uint16_t *port_id)
>>>>       uint16_t pid;
>>>>       if (name == NULL) {
>>>> -        RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n");
>>>> +        RTE_ETHDEV_LOG(ERR, "Cannot get port ID from NULL name");
>>>> +        return -EINVAL;
>>>> +    }
>>>> +
>>>> +    if (port_id == NULL) {
>>>> +        RTE_ETHDEV_LOG(ERR, "Cannot get port ID to NULL\n");
>>>
>>> Since name is already checked above, I think it would be useful
>>> to log 'name' here to provide context.
>>>
>>>>           return -EINVAL;
>>>>       }
>>>
>>> [snip]
>>>
>>>> @@ -3256,6 +3370,20 @@ rte_eth_dev_fw_version_get(uint16_t port_id,
>>>> char *fw_version, size_t fw_size)
>>>>       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>>       dev = &rte_eth_devices[port_id];
>>>> +    if (fw_version == NULL) {
>>>> +        RTE_ETHDEV_LOG(ERR,
>>>> +            "Cannot get ethdev port %u FW version to NULL\n",
>>>> +            port_id);
>>>> +        return -EINVAL;
>>>> +    }
>>>> +
>>>> +    if (fw_size == 0) {
>>>> +        RTE_ETHDEV_LOG(ERR,
>>>> +            "Cannot get ethdev port %u FW version to buffer with
>>>> zero size\n",
>>>> +            port_id);
>>>> +        return -EINVAL;
>>>> +    }
>>>> +
>>>
>>> The only error condition is NULL fw_version with positive
>>> fw_size. Othwerwise, it could be just a call to get required
>>> size of buffer for FW version.
>>>
>>
>> Right, above is wrong.
>>
>> Agree that "fw_version == NULL && fw_size > 0" is error condition,
>> but is it clear if how this API should behave on
>> "fw_version == NULL && fw_size == 0"?
>>
>> Like sfc has following,
>> if ((fw_version == NULL) || (fw_size == 0))
>>      return -EINVAL;
> 
> axgbe, qede also returns error when fw_version is NULL, independent from
> fw_size.
> 
> But I think taking "fw_version == NULL && fw_size > 0" as only error
> condition is reasonable, although some PMDs will be behaving wrong.
> I can send a separate patch to unify the behavior.

Many thanks, please, let me know if you need help with net/sfc.


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v9] ethdev: add sanity checks in control APIs
  2021-04-21 11:28     ` Andrew Rybchenko
                         ` (2 preceding siblings ...)
  2021-04-21 13:19       ` Ferruh Yigit
@ 2021-04-21 14:17       ` Ferruh Yigit
  3 siblings, 0 replies; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-21 14:17 UTC (permalink / raw)
  To: Andrew Rybchenko, Thomas Monjalon, Gaetan Rivet,
	Stephen Hemminger, Qi Zhang, Ali Alnubani, Yuanhan Liu,
	Matan Azrad, Konstantin Ananyev, Zhiyong Yang, Adrien Mazarguil
  Cc: dev, Min Hu (Connor), stable, Kevin Traynor

On 4/21/2021 12:28 PM, Andrew Rybchenko wrote:
> On 4/21/21 5:36 AM, Ferruh Yigit wrote:
>> From: "Min Hu (Connor)" <humin29@huawei.com>
>>
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Acked-by: Kevin Traynor <ktraynor@redhat.com>

<...>

>> @@ -3323,6 +3457,21 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>>   
>>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>   	dev = &rte_eth_devices[port_id];
>> +
>> +	if (ptypes == NULL) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u supported packet types to NULL\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	if (num == 0) {
>> +		RTE_ETHDEV_LOG(ERR,
>> +			"Cannot get ethdev port %u supported packet types to array with zero size\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
> 
> The error condition is "ptypes == NULL && num > 0".
> Otherwise, if num == 0 (regardless ptypes) it is just
> a call to get size of required buffer. Same as below.
> 
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
>>   	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
>>   
> 

Ack. Thanks for catching these issues.


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v10] ethdev: add sanity checks in control APIs
  2021-04-21 12:36 ` [dpdk-dev] [PATCH v10] " Min Hu (Connor)
@ 2021-04-21 14:19   ` Ferruh Yigit
  2021-04-21 16:22     ` Ferruh Yigit
  0 siblings, 1 reply; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-21 14:19 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: thomas, andrew.rybchenko, ktraynor

On 4/21/2021 1:36 PM, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Acked-by: Kevin Traynor <ktraynor@redhat.com>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

<...>

> @@ -3256,6 +3371,13 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>   	dev = &rte_eth_devices[port_id];
>   
> +	if (fw_version == NULL && fw_size > 0) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u FW version to NULL\n",

In the log problem seems like only 'fw_version' to be NULL but that is not 
exactly corret, what do you think to extend it as we did a few other places in 
this patch

"Cannot get ethdev port %u FW version to NULL when string size is non zero\n"

<...>

> @@ -3323,6 +3451,14 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, uint32_t ptype_mask,
>   
>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>   	dev = &rte_eth_devices[port_id];
> +
> +	if (ptypes == NULL && num > 0) {
> +		RTE_ETHDEV_LOG(ERR,
> +			"Cannot get ethdev port %u supported packet types to NULL\n",
> +			port_id);

Ditto. What about:

"Cannot get ethdev port %u supported packet types to NULL when array size is non 
zero\n

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v10] ethdev: add sanity checks in control APIs
  2021-04-21 14:19   ` Ferruh Yigit
@ 2021-04-21 16:22     ` Ferruh Yigit
  2021-04-21 17:16       ` Ferruh Yigit
  0 siblings, 1 reply; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-21 16:22 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: thomas, andrew.rybchenko, ktraynor

On 4/21/2021 3:19 PM, Ferruh Yigit wrote:
> On 4/21/2021 1:36 PM, Min Hu (Connor) wrote:
>> This patch adds more sanity checks in control path APIs.
>>
>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process 
>> model")
>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Acked-by: Kevin Traynor <ktraynor@redhat.com>
>> Acked-by: Thomas Monjalon <thomas@monjalon.net>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> 
> <...>
> 
>> @@ -3256,6 +3371,13 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char 
>> *fw_version, size_t fw_size)
>>       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>       dev = &rte_eth_devices[port_id];
>> +    if (fw_version == NULL && fw_size > 0) {
>> +        RTE_ETHDEV_LOG(ERR,
>> +            "Cannot get ethdev port %u FW version to NULL\n",
> 
> In the log problem seems like only 'fw_version' to be NULL but that is not 
> exactly corret, what do you think to extend it as we did a few other places in 
> this patch
> 
> "Cannot get ethdev port %u FW version to NULL when string size is non zero\n"
> 
> <...>
> 
>> @@ -3323,6 +3451,14 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, 
>> uint32_t ptype_mask,
>>       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>       dev = &rte_eth_devices[port_id];
>> +
>> +    if (ptypes == NULL && num > 0) {
>> +        RTE_ETHDEV_LOG(ERR,
>> +            "Cannot get ethdev port %u supported packet types to NULL\n",
>> +            port_id);
> 
> Ditto. What about:
> 
> "Cannot get ethdev port %u supported packet types to NULL when array size is non 
> zero\n

I can fix these in the next-net if there is no objection.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v10] ethdev: add sanity checks in control APIs
  2021-04-21 16:22     ` Ferruh Yigit
@ 2021-04-21 17:16       ` Ferruh Yigit
  0 siblings, 0 replies; 65+ messages in thread
From: Ferruh Yigit @ 2021-04-21 17:16 UTC (permalink / raw)
  To: Min Hu (Connor), dev; +Cc: thomas, andrew.rybchenko, ktraynor

On 4/21/2021 5:22 PM, Ferruh Yigit wrote:
> On 4/21/2021 3:19 PM, Ferruh Yigit wrote:
>> On 4/21/2021 1:36 PM, Min Hu (Connor) wrote:
>>> This patch adds more sanity checks in control path APIs.
>>>
>>> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
>>> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
>>> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
>>> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process 
>>> model")
>>> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
>>> Fixes: f8244c6399d9 ("ethdev: increase port id range")
>>> Cc: stable@dpdk.org
>>>
>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>> Acked-by: Kevin Traynor <ktraynor@redhat.com>
>>> Acked-by: Thomas Monjalon <thomas@monjalon.net>
>>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>
>> <...>
>>
>>> @@ -3256,6 +3371,13 @@ rte_eth_dev_fw_version_get(uint16_t port_id, char 
>>> *fw_version, size_t fw_size)
>>>       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>       dev = &rte_eth_devices[port_id];
>>> +    if (fw_version == NULL && fw_size > 0) {
>>> +        RTE_ETHDEV_LOG(ERR,
>>> +            "Cannot get ethdev port %u FW version to NULL\n",
>>
>> In the log problem seems like only 'fw_version' to be NULL but that is not 
>> exactly corret, what do you think to extend it as we did a few other places in 
>> this patch
>>
>> "Cannot get ethdev port %u FW version to NULL when string size is non zero\n"
>>
>> <...>
>>
>>> @@ -3323,6 +3451,14 @@ rte_eth_dev_get_supported_ptypes(uint16_t port_id, 
>>> uint32_t ptype_mask,
>>>       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>       dev = &rte_eth_devices[port_id];
>>> +
>>> +    if (ptypes == NULL && num > 0) {
>>> +        RTE_ETHDEV_LOG(ERR,
>>> +            "Cannot get ethdev port %u supported packet types to NULL\n",
>>> +            port_id);
>>
>> Ditto. What about:
>>
>> "Cannot get ethdev port %u supported packet types to NULL when array size is 
>> non zero\n
> 
> I can fix these in the next-net if there is no objection.

Applied to dpdk-next-net/main, thanks.

Above two logs updated while merging.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: add sanity checks in control APIs
  2021-04-13  3:22 ` [dpdk-dev] [PATCH v2] " Min Hu (Connor)
  2021-04-13  8:44   ` Andrew Rybchenko
@ 2021-04-29 17:48   ` Tyler Retzlaff
  2021-04-29 18:18     ` Stephen Hemminger
  1 sibling, 1 reply; 65+ messages in thread
From: Tyler Retzlaff @ 2021-04-29 17:48 UTC (permalink / raw)
  To: Min Hu (Connor); +Cc: dev, ferruh.yigit, thomas, andrew.rybchenko

On Tue, Apr 13, 2021 at 11:22:14AM +0800, Min Hu (Connor) wrote:
> This patch adds more sanity checks in control path APIs.
> 
> Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> Fixes: f8244c6399d9 ("ethdev: increase port id range")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---

this whole patch breaks abi since it returns new errno that were not
previously documented or returned. even if it is accepted it probably
should not be backported to stable.

it is entirely conceivable that you can have code that was calling these
functions and checking for specific return values where the new return
values will not be handled at all or improperly handled.

you can't just start emitting brand new errors or different errors for
the same input parameters.

thanks.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: add sanity checks in control APIs
  2021-04-29 17:48   ` Tyler Retzlaff
@ 2021-04-29 18:18     ` Stephen Hemminger
  0 siblings, 0 replies; 65+ messages in thread
From: Stephen Hemminger @ 2021-04-29 18:18 UTC (permalink / raw)
  To: Tyler Retzlaff
  Cc: Min Hu (Connor), dev, ferruh.yigit, thomas, andrew.rybchenko

On Thu, 29 Apr 2021 10:48:34 -0700
Tyler Retzlaff <roretzla@linux.microsoft.com> wrote:

> On Tue, Apr 13, 2021 at 11:22:14AM +0800, Min Hu (Connor) wrote:
> > This patch adds more sanity checks in control path APIs.
> > 
> > Fixes: 214ed1acd125 ("ethdev: add iterator to match devargs input")
> > Fixes: 3d98f921fbe9 ("ethdev: unify prefix for static functions and variables")
> > Fixes: 0366137722a0 ("ethdev: check for invalid device name")
> > Fixes: d948f596fee2 ("ethdev: fix port data mismatched in multiple process model")
> > Fixes: 5b7ba31148a8 ("ethdev: add port ownership")
> > Fixes: f8244c6399d9 ("ethdev: increase port id range")
> > Cc: stable@dpdk.org
> > 
> > Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> > ---  
> 
> this whole patch breaks abi since it returns new errno that were not
> previously documented or returned. even if it is accepted it probably
> should not be backported to stable.
> 
> it is entirely conceivable that you can have code that was calling these
> functions and checking for specific return values where the new return
> values will not be handled at all or improperly handled.
> 
> you can't just start emitting brand new errors or different errors for
> the same input parameters.

In practice, checking for passing a NULL doesn't add a lot of value.
No program should ever do that, and if it did the crash that happens
when it dereferenced is as good as an assert() or an error return.


^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2021-04-29 18:18 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-10  9:18 [dpdk-dev] [PATCH] ethdev: add sanity checks in control APIs Min Hu (Connor)
2021-04-12 23:08 ` Ferruh Yigit
2021-04-13  3:23   ` Min Hu (Connor)
2021-04-13  3:22 ` [dpdk-dev] [PATCH v2] " Min Hu (Connor)
2021-04-13  8:44   ` Andrew Rybchenko
2021-04-13  8:58     ` Thomas Monjalon
2021-04-13  9:24       ` Ferruh Yigit
2021-04-14 11:12     ` Min Hu (Connor)
2021-04-29 17:48   ` Tyler Retzlaff
2021-04-29 18:18     ` Stephen Hemminger
2021-04-14 11:11 ` [dpdk-dev] [PATCH v3] " Min Hu (Connor)
2021-04-14 12:00   ` Andrew Rybchenko
2021-04-15  0:52     ` Min Hu (Connor)
2021-04-15  0:52 ` [dpdk-dev] [PATCH v4] " Min Hu (Connor)
2021-04-15  8:15   ` Andrew Rybchenko
2021-04-15 11:09     ` Min Hu (Connor)
2021-04-15 11:57     ` Thomas Monjalon
2021-04-15 12:03       ` Andrew Rybchenko
2021-04-15 12:20         ` Thomas Monjalon
2021-04-15 12:43           ` Andrew Rybchenko
2021-04-15 12:04   ` Kevin Traynor
2021-04-15 12:15     ` Thomas Monjalon
2021-04-16  7:01       ` Min Hu (Connor)
2021-04-16  7:00     ` Min Hu (Connor)
2021-04-16 10:09       ` Kevin Traynor
2021-04-16 10:44         ` Min Hu (Connor)
2021-04-15 11:09 ` [dpdk-dev] [PATCH v5] " Min Hu (Connor)
2021-04-15 15:38   ` Ferruh Yigit
2021-04-16  7:02     ` Min Hu (Connor)
2021-04-16 16:19     ` Stephen Hemminger
2021-04-15 15:45   ` Ferruh Yigit
2021-04-15 16:21     ` Thomas Monjalon
2021-04-16  7:04       ` Min Hu (Connor)
2021-04-16 16:25   ` Stephen Hemminger
2021-04-16  6:52 ` [dpdk-dev] [PATCH v6] " Min Hu (Connor)
2021-04-16 10:22   ` Kevin Traynor
2021-04-16 11:00     ` Min Hu (Connor)
2021-04-16 16:28     ` Stephen Hemminger
2021-04-17  0:28       ` Min Hu (Connor)
2021-04-17 21:37         ` Thomas Monjalon
2021-04-19  0:34           ` Min Hu (Connor)
2021-04-17  7:42       ` Min Hu (Connor)
2021-04-16 11:00 ` [dpdk-dev] [PATCH v7] " Min Hu (Connor)
2021-04-16 11:31   ` Ferruh Yigit
2021-04-16 12:02   ` Thomas Monjalon
2021-04-17  7:39     ` Min Hu (Connor)
2021-04-17  7:39 ` [dpdk-dev] [PATCH v8] " Min Hu (Connor)
2021-04-20 10:04   ` Thomas Monjalon
2021-04-20 13:59     ` Ferruh Yigit
2021-04-20 14:20     ` Kevin Traynor
2021-04-20 14:33       ` Thomas Monjalon
2021-04-21  2:36   ` [dpdk-dev] [PATCH v9] " Ferruh Yigit
2021-04-21 10:48     ` Thomas Monjalon
2021-04-21 11:28     ` Andrew Rybchenko
2021-04-21 12:36       ` Min Hu (Connor)
2021-04-21 12:38       ` Kevin Traynor
2021-04-21 13:19       ` Ferruh Yigit
2021-04-21 13:40         ` Ferruh Yigit
2021-04-21 13:50           ` Andrew Rybchenko
2021-04-21 13:50         ` Andrew Rybchenko
2021-04-21 14:17       ` Ferruh Yigit
2021-04-21 12:36 ` [dpdk-dev] [PATCH v10] " Min Hu (Connor)
2021-04-21 14:19   ` Ferruh Yigit
2021-04-21 16:22     ` Ferruh Yigit
2021-04-21 17:16       ` Ferruh Yigit

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git