[v4,5/7] ethdev: add API to retrieve multiple ethernet addresses

Message ID 20211004135603.20593-6-konstantin.ananyev@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series hide eth dev related structures |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Ananyev, Konstantin Oct. 4, 2021, 1:56 p.m. UTC
  Introduce rte_eth_macaddrs_get() to allow user to retrieve all ethernet
addresses assigned to given port.
Change testpmd to use this new function and avoid referencing directly
rte_eth_devices[].

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 app/test-pmd/config.c                  | 23 +++++++++++------------
 doc/guides/rel_notes/release_21_11.rst |  5 +++++
 lib/ethdev/rte_ethdev.c                | 25 +++++++++++++++++++++++++
 lib/ethdev/rte_ethdev.h                | 19 +++++++++++++++++++
 lib/ethdev/version.map                 |  3 +++
 5 files changed, 63 insertions(+), 12 deletions(-)
  

Comments

Thomas Monjalon Oct. 5, 2021, 1:13 p.m. UTC | #1
04/10/2021 15:56, Konstantin Ananyev:
> Introduce rte_eth_macaddrs_get() to allow user to retrieve all ethernet
> addresses assigned to given port.

We already have functions to get MAC addresses.
Please explain the difference.

[...]
> +* **Add new function into ethdev lib.**
> +
> +  * Added ``rte_eth_macaddrs_get`` to allow user to retrieve all Ethernet
> +    addresses aasigned to given ethernet port.

typo above

> +/**
> + * Retrieve the Ethernet addresses of an Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param ma
> + *   A pointer to an array of structures of type *ether_addr* to be filled with
> + *   the Ethernet addresses of the Ethernet device.
> + * @param num
> + *   Number of elements in the *ma* array.
> + * @return
> + *   - number of retrieved addresses if successful
> + *   - (-ENODEV) if *port_id* invalid.
> + *   - (-EINVAL) if bad parameter.

Which error if the array is too small?

> + */
> +__rte_experimental
> +int rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr ma[],

Please don't use array syntax in parameters, it should be a pointer.
How do we get the number of returned addresses?

> +	uint32_t num);

Another approach would be to get addresses one by one by passing an index.
  
Ananyev, Konstantin Oct. 5, 2021, 4:35 p.m. UTC | #2
> 
> 04/10/2021 15:56, Konstantin Ananyev:
> > Introduce rte_eth_macaddrs_get() to allow user to retrieve all ethernet
> > addresses assigned to given port.
> 
> We already have functions to get MAC addresses.
> Please explain the difference.

rte_eth_macaddr_get() returns just first (primary) MAC address
assigned to the port.
That one allow user to retrieve all addresses assigned to the port.  
> 
> [...]
> > +* **Add new function into ethdev lib.**
> > +
> > +  * Added ``rte_eth_macaddrs_get`` to allow user to retrieve all Ethernet
> > +    addresses aasigned to given ethernet port.
> 
> typo above
> 
> > +/**
> > + * Retrieve the Ethernet addresses of an Ethernet device.
> > + *
> > + * @param port_id
> > + *   The port identifier of the Ethernet device.
> > + * @param ma
> > + *   A pointer to an array of structures of type *ether_addr* to be filled with
> > + *   the Ethernet addresses of the Ethernet device.
> > + * @param num
> > + *   Number of elements in the *ma* array.
> > + * @return
> > + *   - number of retrieved addresses if successful
> > + *   - (-ENODEV) if *port_id* invalid.
> > + *   - (-EINVAL) if bad parameter.
> 
> Which error if the array is too small?

None, we just return up to *num* addresses, that's it.
 
> > + */
> > +__rte_experimental
> > +int rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr ma[],
> 
> Please don't use array syntax in parameters, it should be a pointer.
> How do we get the number of returned addresses?
> 
> > +	uint32_t num);

From above:
 * @return
 *   - number of retrieved addresses if successful
 
> Another approach would be to get addresses one by one by passing an index.
> 

Yes, it is another possible way.
Though current one seems a bit more convenient to me.
  
Thomas Monjalon Oct. 5, 2021, 4:45 p.m. UTC | #3
05/10/2021 18:35, Ananyev, Konstantin:
> > 04/10/2021 15:56, Konstantin Ananyev:
> > > Introduce rte_eth_macaddrs_get() to allow user to retrieve all ethernet
> > > addresses assigned to given port.
> > 
> > We already have functions to get MAC addresses.
> > Please explain the difference.
> 
> rte_eth_macaddr_get() returns just first (primary) MAC address
> assigned to the port.
> That one allow user to retrieve all addresses assigned to the port.

I was sure we had other function.
Anyway, would be good to reference rte_eth_macaddr_get in the commit.


> > > +/**
> > > + * Retrieve the Ethernet addresses of an Ethernet device.
> > > + *
> > > + * @param port_id
> > > + *   The port identifier of the Ethernet device.
> > > + * @param ma
> > > + *   A pointer to an array of structures of type *ether_addr* to be filled with
> > > + *   the Ethernet addresses of the Ethernet device.
> > > + * @param num
> > > + *   Number of elements in the *ma* array.
> > > + * @return
> > > + *   - number of retrieved addresses if successful
> > > + *   - (-ENODEV) if *port_id* invalid.
> > > + *   - (-EINVAL) if bad parameter.
> > 
> > Which error if the array is too small?
> 
> None, we just return up to *num* addresses, that's it.

So we don't know know whether there are more.

> > > + */
> > > +__rte_experimental
> > > +int rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr ma[],
> > 
> > Please don't use array syntax in parameters, it should be a pointer.
> > How do we get the number of returned addresses?
> > 
> > > +	uint32_t num);
> 
> From above:
>  * @return
>  *   - number of retrieved addresses if successful
>  
> > Another approach would be to get addresses one by one by passing an index.
> > 
> 
> Yes, it is another possible way.
> Though current one seems a bit more convenient to me. 

It misses a way to get the number of addresses.
  
Ananyev, Konstantin Oct. 5, 2021, 5:12 p.m. UTC | #4
> 05/10/2021 18:35, Ananyev, Konstantin:
> > > 04/10/2021 15:56, Konstantin Ananyev:
> > > > Introduce rte_eth_macaddrs_get() to allow user to retrieve all ethernet
> > > > addresses assigned to given port.
> > >
> > > We already have functions to get MAC addresses.
> > > Please explain the difference.
> >
> > rte_eth_macaddr_get() returns just first (primary) MAC address
> > assigned to the port.
> > That one allow user to retrieve all addresses assigned to the port.
> 
> I was sure we had other function.

I didn't find one.
If we do, I am ok to drop that change and rework testpmd code to use
existing one instead.

> Anyway, would be good to reference rte_eth_macaddr_get in the commit.
> 
> 
> > > > +/**
> > > > + * Retrieve the Ethernet addresses of an Ethernet device.
> > > > + *
> > > > + * @param port_id
> > > > + *   The port identifier of the Ethernet device.
> > > > + * @param ma
> > > > + *   A pointer to an array of structures of type *ether_addr* to be filled with
> > > > + *   the Ethernet addresses of the Ethernet device.
> > > > + * @param num
> > > > + *   Number of elements in the *ma* array.
> > > > + * @return
> > > > + *   - number of retrieved addresses if successful
> > > > + *   - (-ENODEV) if *port_id* invalid.
> > > > + *   - (-EINVAL) if bad parameter.
> > >
> > > Which error if the array is too small?
> >
> > None, we just return up to *num* addresses, that's it.
> 
> So we don't know know whether there are more.

rte_eth_dev_info. max_mac_addrs tells max number of MACs for this port.

> 
> > > > + */
> > > > +__rte_experimental
> > > > +int rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr ma[],
> > >
> > > Please don't use array syntax in parameters, it should be a pointer.
> > > How do we get the number of returned addresses?
> > >
> > > > +	uint32_t num);
> >
> > From above:
> >  * @return
> >  *   - number of retrieved addresses if successful
> >
> > > Another approach would be to get addresses one by one by passing an index.
> > >
> >
> > Yes, it is another possible way.
> > Though current one seems a bit more convenient to me.
> 
> It misses a way to get the number of addresses.
>
  
Thomas Monjalon Oct. 5, 2021, 5:41 p.m. UTC | #5
05/10/2021 19:12, Ananyev, Konstantin:
> > 05/10/2021 18:35, Ananyev, Konstantin:
> > > > 04/10/2021 15:56, Konstantin Ananyev:
> > > > > Introduce rte_eth_macaddrs_get() to allow user to retrieve all ethernet
> > > > > addresses assigned to given port.
> > > >
> > > > We already have functions to get MAC addresses.
> > > > Please explain the difference.
> > >
> > > rte_eth_macaddr_get() returns just first (primary) MAC address
> > > assigned to the port.
> > > That one allow user to retrieve all addresses assigned to the port.
> > 
> > I was sure we had other function.
> 
> I didn't find one.
> If we do, I am ok to drop that change and rework testpmd code to use
> existing one instead.

No there is no alternative, so your patch is welcome.

> > Anyway, would be good to reference rte_eth_macaddr_get in the commit.
> > 
> > 
> > > > > +/**
> > > > > + * Retrieve the Ethernet addresses of an Ethernet device.
> > > > > + *
> > > > > + * @param port_id
> > > > > + *   The port identifier of the Ethernet device.
> > > > > + * @param ma
> > > > > + *   A pointer to an array of structures of type *ether_addr* to be filled with
> > > > > + *   the Ethernet addresses of the Ethernet device.
> > > > > + * @param num
> > > > > + *   Number of elements in the *ma* array.
> > > > > + * @return
> > > > > + *   - number of retrieved addresses if successful
> > > > > + *   - (-ENODEV) if *port_id* invalid.
> > > > > + *   - (-EINVAL) if bad parameter.
> > > >
> > > > Which error if the array is too small?
> > >
> > > None, we just return up to *num* addresses, that's it.
> > 
> > So we don't know know whether there are more.
> 
> rte_eth_dev_info. max_mac_addrs tells max number of MACs for this port.

Right. Please mention it in the comment of this function.
  

Patch

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 9c66329e96..7221644230 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -5215,20 +5215,20 @@  show_macs(portid_t port_id)
 {
 	char buf[RTE_ETHER_ADDR_FMT_SIZE];
 	struct rte_eth_dev_info dev_info;
-	struct rte_ether_addr *addr;
-	uint32_t i, num_macs = 0;
-	struct rte_eth_dev *dev;
-
-	dev = &rte_eth_devices[port_id];
+	int32_t i, rc, num_macs = 0;
 
 	if (eth_dev_info_get_print_err(port_id, &dev_info))
 		return;
 
-	for (i = 0; i < dev_info.max_mac_addrs; i++) {
-		addr = &dev->data->mac_addrs[i];
+	struct rte_ether_addr addr[dev_info.max_mac_addrs];
+	rc = rte_eth_macaddrs_get(port_id, addr, dev_info.max_mac_addrs);
+	if (rc < 0)
+		return;
+
+	for (i = 0; i < rc; i++) {
 
 		/* skip zero address */
-		if (rte_is_zero_ether_addr(addr))
+		if (rte_is_zero_ether_addr(&addr[i]))
 			continue;
 
 		num_macs++;
@@ -5236,14 +5236,13 @@  show_macs(portid_t port_id)
 
 	printf("Number of MAC address added: %d\n", num_macs);
 
-	for (i = 0; i < dev_info.max_mac_addrs; i++) {
-		addr = &dev->data->mac_addrs[i];
+	for (i = 0; i < rc; i++) {
 
 		/* skip zero address */
-		if (rte_is_zero_ether_addr(addr))
+		if (rte_is_zero_ether_addr(&addr[i]))
 			continue;
 
-		rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, addr);
+		rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, &addr[i]);
 		printf("  %s\n", buf);
 	}
 }
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index fd80538b6c..91c392c14e 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -125,6 +125,11 @@  New Features
   * Added tests to validate packets hard expiry.
   * Added tests to verify tunnel header verification in IPsec inbound.
 
+* **Add new function into ethdev lib.**
+
+  * Added ``rte_eth_macaddrs_get`` to allow user to retrieve all Ethernet
+    addresses aasigned to given ethernet port.
+
 
 Removed Items
 -------------
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 036c82cbfb..b051eff70e 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -3574,6 +3574,31 @@  rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
 	return ret;
 }
 
+int
+rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr ma[], uint32_t num)
+{
+	int32_t ret;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	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;
+
+	if (ma == NULL) {
+		RTE_ETHDEV_LOG(ERR, "%s: invalid parameters\n", __func__);
+		return -EINVAL;
+	}
+
+	num = RTE_MIN(dev_info.max_mac_addrs, num);
+	memcpy(ma, dev->data->mac_addrs, num * sizeof(ma[0]));
+
+	return num;
+}
+
 int
 rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
 {
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 7f68be406e..047f7c9c5a 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -3037,6 +3037,25 @@  int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
  */
 int rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr);
 
+/**
+ * Retrieve the Ethernet addresses of an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ma
+ *   A pointer to an array of structures of type *ether_addr* to be filled with
+ *   the Ethernet addresses of the Ethernet device.
+ * @param num
+ *   Number of elements in the *ma* array.
+ * @return
+ *   - number of retrieved addresses if successful
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+__rte_experimental
+int rte_eth_macaddrs_get(uint16_t port_id, struct rte_ether_addr ma[],
+	uint32_t num);
+
 /**
  * Retrieve the contextual information of an Ethernet device.
  *
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 2348ec3c3c..0881202381 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -252,6 +252,9 @@  EXPERIMENTAL {
 	rte_mtr_meter_policy_delete;
 	rte_mtr_meter_policy_update;
 	rte_mtr_meter_policy_validate;
+
+	# added in 21.11
+	rte_eth_macaddrs_get;
 };
 
 INTERNAL {