DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations
@ 2019-05-16 18:04 Stephen Hemminger
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 1/7] ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
                   ` (13 more replies)
  0 siblings, 14 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 18:04 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of patches around the ethernet address
manipulation routines in librte_net/rte_ether.

This does not include the prefixing of the ether_address
which is still under review.

v2 incorporates feedback and Bruce's alignement patch

Bruce Richardson (1):
  ether: mark ethernet addresses as being 2-byte aligned

Stephen Hemminger (6):
  ether: do not mark ethernet address and header as packed
  ether: deinline non-critical functions
  ether: add eth_unformat_addr
  ethdev: use eth_unformat_addr
  ether: use bitops to speedup comparison
  cmdline: use ether_unformat_addr

 lib/Makefile                                 |  3 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 69 ++----------------
 lib/librte_cmdline/meson.build               |  3 +
 lib/librte_ethdev/Makefile                   |  2 +-
 lib/librte_ethdev/meson.build                |  2 +-
 lib/librte_ethdev/rte_class_eth.c            |  9 +--
 lib/librte_net/Makefile                      |  1 +
 lib/librte_net/rte_ether.c                   | 76 ++++++++++++++++++++
 lib/librte_net/rte_ether.h                   | 70 +++++++++---------
 lib/librte_net/rte_net_version.map           |  8 +++
 11 files changed, 134 insertions(+), 112 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 1/7] ether: mark ethernet addresses as being 2-byte aligned
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
@ 2019-05-16 18:04 ` Stephen Hemminger
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 2/7] ether: do not mark ethernet address and header as packed Stephen Hemminger
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 18:04 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Stephen Hemminger

From: Bruce Richardson <bruce.richardson@intel.com>

When including the rte_ether.h header in applications with warnings
enabled, a warning was given because of the assumption of 2-byte alignment
of ethernet addresses when processing them.

.../include/rte_ether.h:149:2: warning: converting a packed ‘const
  struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
  {aka ‘const short unsigned int’} pointer (alignment 2) may result in
  an unaligned pointer value [-Waddress-of-packed-member]
149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
    |  ^~~~~

Since ethernet addresses should always be aligned on a two-byte boundary,
we can just inform the compiler of this assumption to remove the warnings
and allow us to always access the addresses using 16-bit operations.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_net/rte_ether.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 3a87ff184900..ac8897681aca 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -55,7 +55,8 @@ extern "C" {
  * See http://standards.ieee.org/regauth/groupmac/tutorial.html
  */
 struct ether_addr {
-	uint8_t addr_bytes[ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+	/** Addr bytes in tx order */
+	uint8_t addr_bytes[ETHER_ADDR_LEN] __rte_aligned(2);
 } __attribute__((__packed__));
 
 #define ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
@@ -146,7 +147,7 @@ static inline int is_multicast_ether_addr(const struct ether_addr *ea)
  */
 static inline int is_broadcast_ether_addr(const struct ether_addr *ea)
 {
-	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
+	const uint16_t *ea_words = (const uint16_t *)ea;
 
 	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
 		ea_words[2] == 0xFFFF);
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 2/7] ether: do not mark ethernet address and header as packed
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 1/7] ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-05-16 18:04 ` Stephen Hemminger
  2019-05-16 20:40   ` Bruce Richardson
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 3/7] ether: deinline non-critical functions Stephen Hemminger
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 18:04 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Bruce Richardson

Since the Ethernet address and header are naturally aligned
correctly on all architectures, there is no need to mark them
as packed. This results in faster code, and also gets rid of
warnings with gcc-9 about getting address of packed structure.

Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_net/rte_ether.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index ac8897681aca..0954d183cca7 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -57,7 +57,7 @@ extern "C" {
 struct ether_addr {
 	/** Addr bytes in tx order */
 	uint8_t addr_bytes[ETHER_ADDR_LEN] __rte_aligned(2);
-} __attribute__((__packed__));
+};
 
 #define ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
 #define ETHER_GROUP_ADDR       0x01 /**< Multicast or broadcast Eth. address. */
@@ -273,7 +273,7 @@ struct ether_hdr {
 	struct ether_addr d_addr; /**< Destination address. */
 	struct ether_addr s_addr; /**< Source address. */
 	uint16_t ether_type;      /**< Frame type. */
-} __attribute__((__packed__));
+};
 
 /**
  * Ethernet VLAN Header.
@@ -283,7 +283,7 @@ struct ether_hdr {
 struct vlan_hdr {
 	uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */
 	uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */
-} __attribute__((__packed__));
+};
 
 /**
  * VXLAN protocol header.
@@ -293,7 +293,7 @@ struct vlan_hdr {
 struct vxlan_hdr {
 	uint32_t vx_flags; /**< flag (8) + Reserved (24). */
 	uint32_t vx_vni;   /**< VNI (24) + Reserved (8). */
-} __attribute__((__packed__));
+};
 
 /* Ethernet frame types */
 #define ETHER_TYPE_IPv4 0x0800 /**< IPv4 Protocol. */
@@ -325,7 +325,7 @@ struct vxlan_gpe_hdr {
 	uint8_t reserved[2]; /**< Reserved (16). */
 	uint8_t proto;       /**< next-protocol (8). */
 	uint32_t vx_vni;     /**< VNI (24) + Reserved (8). */
-} __attribute__((__packed__));
+};
 
 /* VXLAN-GPE next protocol types */
 #define VXLAN_GPE_TYPE_IPV4 1 /**< IPv4 Protocol. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 3/7] ether: deinline non-critical functions
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 1/7] ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 2/7] ether: do not mark ethernet address and header as packed Stephen Hemminger
@ 2019-05-16 18:04 ` Stephen Hemminger
  2019-05-16 18:29   ` Rami Rosen
  2019-05-17  7:08   ` David Marchand
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 4/7] ether: add eth_unformat_addr Stephen Hemminger
                   ` (10 subsequent siblings)
  13 siblings, 2 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 18:04 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Formatting ethernet address and getting a random value are
not in critical path so they should not be inlined.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_net/Makefile            |  1 +
 lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 24 ++++--------------------
 lib/librte_net/rte_net_version.map |  8 ++++++++
 4 files changed, 42 insertions(+), 20 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index c3082069ab50..b4900b44f4d0 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -15,6 +15,7 @@ LIBABIVER := 1
 SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
+SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
 
 # install includes
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h rte_udp.h rte_esp.h
diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
new file mode 100644
index 000000000000..d4b41f122a16
--- /dev/null
+++ b/lib/librte_net/rte_ether.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_ether.h>
+
+void
+eth_random_addr(uint8_t *addr)
+{
+	uint64_t rand = rte_rand();
+	uint8_t *p = (uint8_t *)&rand;
+
+	rte_memcpy(addr, p, ETHER_ADDR_LEN);
+	addr[0] &= (uint8_t)~ETHER_GROUP_ADDR;	/* clear multicast bit */
+	addr[0] |= ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
+}
+
+void
+ether_format_addr(char *buf, uint16_t size,
+		  const struct ether_addr *eth_addr)
+{
+	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
+		 eth_addr->addr_bytes[0],
+		 eth_addr->addr_bytes[1],
+		 eth_addr->addr_bytes[2],
+		 eth_addr->addr_bytes[3],
+		 eth_addr->addr_bytes[4],
+		 eth_addr->addr_bytes[5]);
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 0954d183cca7..ed178a1f1736 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -205,15 +205,8 @@ static inline int is_valid_assigned_ether_addr(const struct ether_addr *ea)
  * @param addr
  *   A pointer to Ethernet address.
  */
-static inline void eth_random_addr(uint8_t *addr)
-{
-	uint64_t rand = rte_rand();
-	uint8_t *p = (uint8_t *)&rand;
-
-	rte_memcpy(addr, p, ETHER_ADDR_LEN);
-	addr[0] &= (uint8_t)~ETHER_GROUP_ADDR;       /* clear multicast bit */
-	addr[0] |= ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
-}
+void
+eth_random_addr(uint8_t *addr);
 
 /**
  * Fast copy an Ethernet address.
@@ -252,18 +245,9 @@ static inline void ether_addr_copy(const struct ether_addr *ea_from,
  * @param eth_addr
  *   A pointer to a ether_addr structure.
  */
-static inline void
+void
 ether_format_addr(char *buf, uint16_t size,
-		  const struct ether_addr *eth_addr)
-{
-	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 eth_addr->addr_bytes[0],
-		 eth_addr->addr_bytes[1],
-		 eth_addr->addr_bytes[2],
-		 eth_addr->addr_bytes[3],
-		 eth_addr->addr_bytes[4],
-		 eth_addr->addr_bytes[5]);
-}
+		  const struct ether_addr *eth_addr);
 
 /**
  * Ethernet header: Contains the destination address, source address
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 26c06e7c7ae7..49d34093781c 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -13,6 +13,14 @@ DPDK_17.05 {
 
 } DPDK_16.11;
 
+DPDK_19.08 {
+	global:
+
+	eth_random_addr;
+	eth_format_addr;
+} DPDK_17.05;
+
+
 EXPERIMENTAL {
 	global:
 
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 4/7] ether: add eth_unformat_addr
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (2 preceding siblings ...)
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 3/7] ether: deinline non-critical functions Stephen Hemminger
@ 2019-05-16 18:04 ` Stephen Hemminger
  2019-05-17  7:08   ` David Marchand
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 5/7] ethdev: use eth_unformat_addr Stephen Hemminger
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 18:04 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Make a function that coresponds with eth_aton_r which can
be used to convert string to ether_addr.

This also allows rte_ethdev to no longer depend on the
cmdline library.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 14 +++++++++
 lib/librte_net/rte_net_version.map |  2 +-
 3 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
index d4b41f122a16..12d9af58b5c3 100644
--- a/lib/librte_net/rte_ether.c
+++ b/lib/librte_net/rte_ether.c
@@ -27,3 +27,50 @@ ether_format_addr(char *buf, uint16_t size,
 		 eth_addr->addr_bytes[4],
 		 eth_addr->addr_bytes[5]);
 }
+
+/*
+ * Like ether_aton_r but can handle either
+ * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
+ */
+int
+ether_unformat_addr(const char *s, struct ether_addr *ea)
+{
+	unsigned int o0, o1, o2, o3, o4, o5;
+	int n;
+
+	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
+		    &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (n == 6) {
+		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
+		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0;
+		ea->addr_bytes[1] = o1;
+		ea->addr_bytes[2] = o2;
+		ea->addr_bytes[3] = o3;
+		ea->addr_bytes[4] = o4;
+		ea->addr_bytes[5] = o5;
+
+		return 0;
+	}
+
+	/* Support the format XXXX:XXXX:XXXX */
+	n = sscanf(s, "%x:%x:%x", &o0, &o1, &o2);
+	if (n == 3) {
+		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0 >> 8;
+		ea->addr_bytes[1] = o0 & 0xff;
+		ea->addr_bytes[2] = o1 >> 8;
+		ea->addr_bytes[3] = o1 & 0xff;
+		ea->addr_bytes[4] = o2 >> 8;
+		ea->addr_bytes[5] = o2 & 0xff;
+		return 0;
+	}
+	/* unknown format */
+
+	return -1;
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index ed178a1f1736..0fa4481d266b 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -249,6 +249,20 @@ void
 ether_format_addr(char *buf, uint16_t size,
 		  const struct ether_addr *eth_addr);
 
+/**
+ * Convert string with Ethernet address to an ether_addr.
+ *
+ * @param str
+ *   A pointer to buffer contains the formatted MAC address.
+ * @param eth_addr
+ *   A pointer to a ether_addr structure.
+ * @return
+ *   0 if successful
+ *   -1 and sets rte_errno if invalid string
+ */
+int __rte_experimental
+ether_unformat_addr(const char *str, struct ether_addr *eth_addr);
+
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 49d34093781c..41d6a5943515 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -20,10 +20,10 @@ DPDK_19.08 {
 	eth_format_addr;
 } DPDK_17.05;
 
-
 EXPERIMENTAL {
 	global:
 
 	rte_net_make_rarp_packet;
 	rte_net_skip_ip6_ext;
+	eth_unformat_addr;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 5/7] ethdev: use eth_unformat_addr
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (3 preceding siblings ...)
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 4/7] ether: add eth_unformat_addr Stephen Hemminger
@ 2019-05-16 18:04 ` Stephen Hemminger
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 6/7] ether: use bitops to speedup comparison Stephen Hemminger
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 18:04 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use eth_unformat_addr, so that ethdev can be built and work
without the cmdline library. The dependency on cmdline was
an arrangement of convenience anyway.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                      | 1 -
 lib/librte_ethdev/Makefile        | 2 +-
 lib/librte_ethdev/meson.build     | 2 +-
 lib/librte_ethdev/rte_class_eth.c | 9 +--------
 4 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 791e0d9911d6..82b2c4bfa8ea 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
 DEPDIRS-librte_ethdev += librte_kvargs
-DEPDIRS-librte_ethdev += librte_cmdline
 DEPDIRS-librte_ethdev += librte_meter
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 8d4a02630c4f..60bcc2227878 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_cmdline -lrte_meter
+LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_meter
 
 EXPORT_MAP := rte_ethdev_version.map
 
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 8d6165b2a7dd..f75d428c96d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -26,4 +26,4 @@ headers = files('rte_ethdev.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
 
-deps += ['net', 'kvargs', 'cmdline', 'meter']
+deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index cb99c92ece93..40ca936230c6 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -4,7 +4,6 @@
 
 #include <string.h>
 
-#include <cmdline_parse_etheraddr.h>
 #include <rte_class.h>
 #include <rte_compat.h>
 #include <rte_errno.h>
@@ -43,19 +42,13 @@ static int
 eth_mac_cmp(const char *key __rte_unused,
 		const char *value, void *opaque)
 {
-	int ret;
 	struct ether_addr mac;
 	const struct rte_eth_dev_data *data = opaque;
 	struct rte_eth_dev_info dev_info;
 	uint32_t index;
 
 	/* Parse devargs MAC address. */
-	/*
-	 * cannot use ether_aton_r(value, &mac)
-	 * because of include conflict with rte_ether.h
-	 */
-	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
-	if (ret < 0)
+	if (ether_unformat_addr(value, &mac) < 0)
 		return -1; /* invalid devargs value */
 
 	/* Return 0 if devargs MAC is matching one of the device MACs. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 6/7] ether: use bitops to speedup comparison
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (4 preceding siblings ...)
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 5/7] ethdev: use eth_unformat_addr Stephen Hemminger
@ 2019-05-16 18:04 ` Stephen Hemminger
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 7/7] cmdline: use ether_unformat_addr Stephen Hemminger
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 18:04 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_net/rte_ether.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 0fa4481d266b..799996dc7e1b 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -79,11 +79,10 @@ struct ether_addr {
 static inline int is_same_ether_addr(const struct ether_addr *ea1,
 				     const struct ether_addr *ea2)
 {
-	int i;
-	for (i = 0; i < ETHER_ADDR_LEN; i++)
-		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-			return 0;
-	return 1;
+	const uint16_t *w1 = (const uint16_t *)ea1;
+	const uint16_t *w2 = (const uint16_t *)ea2;
+
+	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -98,11 +97,9 @@ static inline int is_same_ether_addr(const struct ether_addr *ea1,
  */
 static inline int is_zero_ether_addr(const struct ether_addr *ea)
 {
-	int i;
-	for (i = 0; i < ETHER_ADDR_LEN; i++)
-		if (ea->addr_bytes[i] != 0x00)
-			return 0;
-	return 1;
+	const uint16_t *w = (const uint16_t *)ea;
+
+	return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**
-- 
2.20.1


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

* [dpdk-dev] [PATCH v2 7/7] cmdline: use ether_unformat_addr
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (5 preceding siblings ...)
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 6/7] ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-05-16 18:04 ` Stephen Hemminger
  2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 18:04 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Now that there is a version of ether_aton in rte_ether, it can
be used by the cmdline ethernet address parser.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                                 |  2 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 69 ++------------------
 lib/librte_cmdline/meson.build               |  3 +
 4 files changed, 13 insertions(+), 64 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 82b2c4bfa8ea..cc36fe7591f0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,7 +20,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
-DEPDIRS-librte_cmdline := librte_eal
+DEPDIRS-librte_cmdline := librte_eal librte_net
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index c64142b8d5a0..04057d7c671f 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cmdline.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_cmdline_version.map
 
@@ -25,7 +26,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_net -lrte_eal
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_parse_etheraddr.c b/lib/librte_cmdline/cmdline_parse_etheraddr.c
index 24e04755cd9e..f9ba31b49447 100644
--- a/lib/librte_cmdline/cmdline_parse_etheraddr.c
+++ b/lib/librte_cmdline/cmdline_parse_etheraddr.c
@@ -12,9 +12,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
 
 #include <rte_string_fns.h>
+#include <rte_ether.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -26,67 +26,13 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 	.get_help = cmdline_get_help_etheraddr,
 };
 
-/* the format can be either XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX */
-#define ETHER_ADDRSTRLENLONG 18
-#define ETHER_ADDRSTRLENSHORT 15
-
-#ifdef __linux__
-#define ea_oct ether_addr_octet
-#else
-#define ea_oct octet
-#endif
-
-
-static struct ether_addr *
-my_ether_aton(const char *a)
-{
-	int i;
-	char *end;
-	unsigned long o[ETHER_ADDR_LEN];
-	static struct ether_addr ether_addr;
-
-	i = 0;
-	do {
-		errno = 0;
-		o[i] = strtoul(a, &end, 16);
-		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
-			return NULL;
-		a = end + 1;
-	} while (++i != sizeof (o) / sizeof (o[0]) && end[0] != 0);
-
-	/* Junk at the end of line */
-	if (end[0] != 0)
-		return NULL;
-
-	/* Support the format XX:XX:XX:XX:XX:XX */
-	if (i == ETHER_ADDR_LEN) {
-		while (i-- != 0) {
-			if (o[i] > UINT8_MAX)
-				return NULL;
-			ether_addr.ea_oct[i] = (uint8_t)o[i];
-		}
-	/* Support the format XXXX:XXXX:XXXX */
-	} else if (i == ETHER_ADDR_LEN / 2) {
-		while (i-- != 0) {
-			if (o[i] > UINT16_MAX)
-				return NULL;
-			ether_addr.ea_oct[i * 2] = (uint8_t)(o[i] >> 8);
-			ether_addr.ea_oct[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
-		}
-	/* unknown format */
-	} else
-		return NULL;
-
-	return (struct ether_addr *)&ether_addr;
-}
-
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 	const char *buf, void *res, unsigned ressize)
 {
 	unsigned int token_len = 0;
-	char ether_str[ETHER_ADDRSTRLENLONG+1];
-	struct ether_addr *tmp;
+	char ether_str[ETHER_ADDR_FMT_SIZE];
+	struct ether_addr tmp;
 
 	if (res && ressize < sizeof(struct ether_addr))
 		return -1;
@@ -98,17 +44,16 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 		token_len++;
 
 	/* if token doesn't match possible string lengths... */
-	if ((token_len != ETHER_ADDRSTRLENLONG - 1) &&
-			(token_len != ETHER_ADDRSTRLENSHORT - 1))
+	if (token_len >= ETHER_ADDR_FMT_SIZE) 
 		return -1;
 
 	strlcpy(ether_str, buf, token_len + 1);
 
-	tmp = my_ether_aton(ether_str);
-	if (tmp == NULL)
+	if (ether_unformat_addr(ether_str, &tmp) < 0)
 		return -1;
+
 	if (res)
-		memcpy(res, tmp, sizeof(struct ether_addr));
+		memcpy(res, &tmp, sizeof(struct ether_addr));
 	return token_len;
 }
 
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 0fa61385fccf..c01033fd796f 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -4,6 +4,8 @@
 # This library is processed before EAL
 includes = [global_inc]
 
+cflags  += '-DALLOW_EXPERIMENTAL_API'
+
 version = 2
 sources = files('cmdline.c',
 	'cmdline_cirbuf.c',
@@ -28,3 +30,4 @@ headers = files('cmdline.h',
 	'cmdline_socket.h',
 	'cmdline_cirbuf.h',
 	'cmdline_parse_portlist.h')
+deps += ['net']
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v2 3/7] ether: deinline non-critical functions
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 3/7] ether: deinline non-critical functions Stephen Hemminger
@ 2019-05-16 18:29   ` Rami Rosen
  2019-05-17  7:08   ` David Marchand
  1 sibling, 0 replies; 127+ messages in thread
From: Rami Rosen @ 2019-05-16 18:29 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

Acked-by: Rami Rosen <ramirose@gmail.com>

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

* Re: [dpdk-dev] [PATCH v2 2/7] ether: do not mark ethernet address and header as packed
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 2/7] ether: do not mark ethernet address and header as packed Stephen Hemminger
@ 2019-05-16 20:40   ` Bruce Richardson
  2019-05-16 23:17     ` Stephen Hemminger
  0 siblings, 1 reply; 127+ messages in thread
From: Bruce Richardson @ 2019-05-16 20:40 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Thu, May 16, 2019 at 11:04:22AM -0700, Stephen Hemminger wrote:
> Since the Ethernet address and header are naturally aligned
> correctly on all architectures, there is no need to mark them
> as packed. This results in faster code, and also gets rid of
> warnings with gcc-9 about getting address of packed structure.
> 
> Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  lib/librte_net/rte_ether.h | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index ac8897681aca..0954d183cca7 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -57,7 +57,7 @@ extern "C" {
>  struct ether_addr {
>  	/** Addr bytes in tx order */
>  	uint8_t addr_bytes[ETHER_ADDR_LEN] __rte_aligned(2);
> -} __attribute__((__packed__));
> +};
>  
>  #define ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
>  #define ETHER_GROUP_ADDR       0x01 /**< Multicast or broadcast Eth. address. */
> @@ -273,7 +273,7 @@ struct ether_hdr {
>  	struct ether_addr d_addr; /**< Destination address. */
>  	struct ether_addr s_addr; /**< Source address. */
>  	uint16_t ether_type;      /**< Frame type. */
> -} __attribute__((__packed__));
> +};
>  
>  /**
>   * Ethernet VLAN Header.
> @@ -283,7 +283,7 @@ struct ether_hdr {
>  struct vlan_hdr {
>  	uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */
>  	uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */
> -} __attribute__((__packed__));
> +};
>  
>  /**
>   * VXLAN protocol header.
> @@ -293,7 +293,7 @@ struct vlan_hdr {
>  struct vxlan_hdr {
>  	uint32_t vx_flags; /**< flag (8) + Reserved (24). */
>  	uint32_t vx_vni;   /**< VNI (24) + Reserved (8). */
> -} __attribute__((__packed__));
> +};
>  
>  /* Ethernet frame types */
>  #define ETHER_TYPE_IPv4 0x0800 /**< IPv4 Protocol. */
> @@ -325,7 +325,7 @@ struct vxlan_gpe_hdr {
>  	uint8_t reserved[2]; /**< Reserved (16). */
>  	uint8_t proto;       /**< next-protocol (8). */
>  	uint32_t vx_vni;     /**< VNI (24) + Reserved (8). */
> -} __attribute__((__packed__));
> +};
>  

Are we sure that these last two structures are always 4-byte aligned in
packets?

>  /* VXLAN-GPE next protocol types */
>  #define VXLAN_GPE_TYPE_IPV4 1 /**< IPv4 Protocol. */
> -- 
> 2.20.1
> 

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

* Re: [dpdk-dev] [PATCH v2 2/7] ether: do not mark ethernet address and header as packed
  2019-05-16 20:40   ` Bruce Richardson
@ 2019-05-16 23:17     ` Stephen Hemminger
  0 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-05-16 23:17 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev

On Thu, 16 May 2019 21:40:05 +0100
Bruce Richardson <bruce.richardson@intel.com> wrote:

> On Thu, May 16, 2019 at 11:04:22AM -0700, Stephen Hemminger wrote:
> > Since the Ethernet address and header are naturally aligned
> > correctly on all architectures, there is no need to mark them
> > as packed. This results in faster code, and also gets rid of
> > warnings with gcc-9 about getting address of packed structure.
> > 
> > Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > ---
> >  lib/librte_net/rte_ether.h | 10 +++++-----
> >  1 file changed, 5 insertions(+), 5 deletions(-)
> > 
> > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > index ac8897681aca..0954d183cca7 100644
> > --- a/lib/librte_net/rte_ether.h
> > +++ b/lib/librte_net/rte_ether.h
> > @@ -57,7 +57,7 @@ extern "C" {
> >  struct ether_addr {
> >  	/** Addr bytes in tx order */
> >  	uint8_t addr_bytes[ETHER_ADDR_LEN] __rte_aligned(2);
> > -} __attribute__((__packed__));
> > +};
> >  
> >  #define ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
> >  #define ETHER_GROUP_ADDR       0x01 /**< Multicast or broadcast Eth. address. */
> > @@ -273,7 +273,7 @@ struct ether_hdr {
> >  	struct ether_addr d_addr; /**< Destination address. */
> >  	struct ether_addr s_addr; /**< Source address. */
> >  	uint16_t ether_type;      /**< Frame type. */
> > -} __attribute__((__packed__));
> > +};
> >  
> >  /**
> >   * Ethernet VLAN Header.
> > @@ -283,7 +283,7 @@ struct ether_hdr {
> >  struct vlan_hdr {
> >  	uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */
> >  	uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */
> > -} __attribute__((__packed__));
> > +};
> >  
> >  /**
> >   * VXLAN protocol header.
> > @@ -293,7 +293,7 @@ struct vlan_hdr {
> >  struct vxlan_hdr {
> >  	uint32_t vx_flags; /**< flag (8) + Reserved (24). */
> >  	uint32_t vx_vni;   /**< VNI (24) + Reserved (8). */
> > -} __attribute__((__packed__));
> > +};
> >  
> >  /* Ethernet frame types */
> >  #define ETHER_TYPE_IPv4 0x0800 /**< IPv4 Protocol. */
> > @@ -325,7 +325,7 @@ struct vxlan_gpe_hdr {
> >  	uint8_t reserved[2]; /**< Reserved (16). */
> >  	uint8_t proto;       /**< next-protocol (8). */
> >  	uint32_t vx_vni;     /**< VNI (24) + Reserved (8). */
> > -} __attribute__((__packed__));
> > +};
> >    
> 
> Are we sure that these last two structures are always 4-byte aligned in
> packets?

That is a general issue of unaligned IP header problem.
Really we should be doing a combination of packed and 2 byte alignment.

I will drop the Vxlan and NVGre ones


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

* Re: [dpdk-dev] [PATCH v2 4/7] ether: add eth_unformat_addr
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 4/7] ether: add eth_unformat_addr Stephen Hemminger
@ 2019-05-17  7:08   ` David Marchand
  0 siblings, 0 replies; 127+ messages in thread
From: David Marchand @ 2019-05-17  7:08 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Thu, May 16, 2019 at 8:05 PM Stephen Hemminger <
stephen@networkplumber.org> wrote:

> Make a function that coresponds with eth_aton_r which can
>

corresponds

be used to convert string to ether_addr.
>
> This also allows rte_ethdev to no longer depend on the
> cmdline library.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
>  lib/librte_net/rte_ether.h         | 14 +++++++++
>  lib/librte_net/rte_net_version.map |  2 +-
>  3 files changed, 62 insertions(+), 1 deletion(-)
>
> diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
> index d4b41f122a16..12d9af58b5c3 100644
> --- a/lib/librte_net/rte_ether.c
> +++ b/lib/librte_net/rte_ether.c
> @@ -27,3 +27,50 @@ ether_format_addr(char *buf, uint16_t size,
>                  eth_addr->addr_bytes[4],
>                  eth_addr->addr_bytes[5]);
>  }
> +
> +/*
> + * Like ether_aton_r but can handle either
> + * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
> + */
> +int
> +ether_unformat_addr(const char *s, struct ether_addr *ea)
> +{
> +       unsigned int o0, o1, o2, o3, o4, o5;
> +       int n;
> +
> +       n = sscanf(s, "%x:%x:%x:%x:%x:%x",
> +                   &o0, &o1, &o2, &o3, &o4, &o5);
> +
>

Still weak to trailing characters.


+       if (n == 6) {
> +               if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
> +                   o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX)
> +                       return -1;
> +
> +               ea->addr_bytes[0] = o0;
> +               ea->addr_bytes[1] = o1;
> +               ea->addr_bytes[2] = o2;
> +               ea->addr_bytes[3] = o3;
> +               ea->addr_bytes[4] = o4;
> +               ea->addr_bytes[5] = o5;
> +
> +               return 0;
> +       }
> +
> +       /* Support the format XXXX:XXXX:XXXX */
> +       n = sscanf(s, "%x:%x:%x", &o0, &o1, &o2);
>

Idem trailing characters.


+       if (n == 3) {
> +               if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX)
> +                       return -1;
> +
> +               ea->addr_bytes[0] = o0 >> 8;
> +               ea->addr_bytes[1] = o0 & 0xff;
> +               ea->addr_bytes[2] = o1 >> 8;
> +               ea->addr_bytes[3] = o1 & 0xff;
> +               ea->addr_bytes[4] = o2 >> 8;
> +               ea->addr_bytes[5] = o2 & 0xff;
> +               return 0;
> +       }
> +       /* unknown format */
> +
> +       return -1;
> +}
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index ed178a1f1736..0fa4481d266b 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -249,6 +249,20 @@ void
>  ether_format_addr(char *buf, uint16_t size,
>                   const struct ether_addr *eth_addr);
>
> +/**
> + * Convert string with Ethernet address to an ether_addr.
> + *
> + * @param str
> + *   A pointer to buffer contains the formatted MAC address.
> + * @param eth_addr
> + *   A pointer to a ether_addr structure.
> + * @return
> + *   0 if successful
> + *   -1 and sets rte_errno if invalid string
> + */
> +int __rte_experimental
> +ether_unformat_addr(const char *str, struct ether_addr *eth_addr);
> +
>  /**
>   * Ethernet header: Contains the destination address, source address
>   * and frame type.
> diff --git a/lib/librte_net/rte_net_version.map
> b/lib/librte_net/rte_net_version.map
> index 49d34093781c..41d6a5943515 100644
> --- a/lib/librte_net/rte_net_version.map
> +++ b/lib/librte_net/rte_net_version.map
> @@ -20,10 +20,10 @@ DPDK_19.08 {
>         eth_format_addr;
>  } DPDK_17.05;
>
> -
>

And same comment on the function name than in the rfc patch.


 EXPERIMENTAL {
>         global:
>
>         rte_net_make_rarp_packet;
>         rte_net_skip_ip6_ext;
> +       eth_unformat_addr;
>  };
> --
> 2.20.1
>
>

-- 
David Marchand

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

* Re: [dpdk-dev] [PATCH v2 3/7] ether: deinline non-critical functions
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 3/7] ether: deinline non-critical functions Stephen Hemminger
  2019-05-16 18:29   ` Rami Rosen
@ 2019-05-17  7:08   ` David Marchand
  1 sibling, 0 replies; 127+ messages in thread
From: David Marchand @ 2019-05-17  7:08 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Thu, May 16, 2019 at 8:05 PM Stephen Hemminger <
stephen@networkplumber.org> wrote:

> Formatting ethernet address and getting a random value are
> not in critical path so they should not be inlined.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>

Same comments as on the rfc patch.
Please have a look.
Thanks.

-- 
David Marchand

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

* [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (6 preceding siblings ...)
  2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 7/7] cmdline: use ether_unformat_addr Stephen Hemminger
@ 2019-06-05  1:08 ` Stephen Hemminger
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 1/6] net/rte_ether: deinline non-critical functions Stephen Hemminger
                     ` (5 more replies)
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                   ` (5 subsequent siblings)
  13 siblings, 6 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05  1:08 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of patches around the ethernet address
manipulation routines in librte_net/rte_ether.

v3 
   rebase to use rte_ether prefix
   drop aligning ethernet headers for now.

Bruce Richardson (1):
  net/ether: mark ethernet addresses as being 2-byte aligned

Stephen Hemminger (5):
  net/rte_ether: deinline non-critical functions
  net/ether: add rte_eth_unformat_addr
  ethdev: use rte_eth_unformat_addr
  net/ether: use bitops to speedup comparison
  cmdline: use rte_ether_unformat_addr

 lib/Makefile                                 |  3 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++---------------
 lib/librte_cmdline/meson.build               |  3 +
 lib/librte_ethdev/Makefile                   |  2 +-
 lib/librte_ethdev/meson.build                |  2 +-
 lib/librte_ethdev/rte_class_eth.c            |  9 +--
 lib/librte_net/Makefile                      |  1 +
 lib/librte_net/rte_ether.c                   | 76 ++++++++++++++++++++
 lib/librte_net/rte_ether.h                   | 59 +++++++--------
 lib/librte_net/rte_net_version.map           |  8 +++
 11 files changed, 129 insertions(+), 108 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 1/6] net/rte_ether: deinline non-critical functions
  2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
@ 2019-06-05  1:08   ` Stephen Hemminger
  2019-06-05  8:44     ` Andrew Rybchenko
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 2/6] net/ether: add rte_eth_unformat_addr Stephen Hemminger
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05  1:08 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Rami Rosen

Formatting ethernet address and getting a random value are
not in critical path so they should not be inlined.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Rami Rosen <ramirose@gmail.com>
---
 lib/librte_net/Makefile            |  1 +
 lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 25 ++++---------------------
 lib/librte_net/rte_net_version.map |  7 +++++++
 4 files changed, 41 insertions(+), 21 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index c3082069ab50..1244c9fd54c9 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -14,6 +14,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
+SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 
 # install includes
diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
new file mode 100644
index 000000000000..974fe815b335
--- /dev/null
+++ b/lib/librte_net/rte_ether.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_ether.h>
+
+void
+rte_eth_random_addr(uint8_t *addr)
+{
+	uint64_t rand = rte_rand();
+	uint8_t *p = (uint8_t *)&rand;
+
+	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
+	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;	/* clear multicast bit */
+	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
+}
+
+void
+rte_ether_format_addr(char *buf, uint16_t size,
+		      const struct rte_ether_addr *eth_addr)
+{
+	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
+		 eth_addr->addr_bytes[0],
+		 eth_addr->addr_bytes[1],
+		 eth_addr->addr_bytes[2],
+		 eth_addr->addr_bytes[3],
+		 eth_addr->addr_bytes[4],
+		 eth_addr->addr_bytes[5]);
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 7be9b4890af7..3caae0d98f6d 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -207,15 +207,8 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *
  * @param addr
  *   A pointer to Ethernet address.
  */
-static inline void rte_eth_random_addr(uint8_t *addr)
-{
-	uint64_t rand = rte_rand();
-	uint8_t *p = (uint8_t *)&rand;
-
-	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
-	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;  /* clear multicast bit */
-	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
-}
+void
+rte_eth_random_addr(uint8_t *addr);
 
 /**
  * Fast copy an Ethernet address.
@@ -254,19 +247,9 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
  * @param eth_addr
  *   A pointer to a ether_addr structure.
  */
-static inline void
+void
 rte_ether_format_addr(char *buf, uint16_t size,
-		  const struct rte_ether_addr *eth_addr)
-{
-	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 eth_addr->addr_bytes[0],
-		 eth_addr->addr_bytes[1],
-		 eth_addr->addr_bytes[2],
-		 eth_addr->addr_bytes[3],
-		 eth_addr->addr_bytes[4],
-		 eth_addr->addr_bytes[5]);
-}
-
+		      const struct rte_ether_addr *eth_addr);
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 26c06e7c7ae7..dae6e420cded 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -13,6 +13,13 @@ DPDK_17.05 {
 
 } DPDK_16.11;
 
+DPDK_19.08 {
+	global:
+
+	eth_random_addr;
+	eth_format_addr;
+} DPDK_17.05;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 2/6] net/ether: add rte_eth_unformat_addr
  2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 1/6] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-06-05  1:08   ` Stephen Hemminger
  2019-06-05  8:55     ` Andrew Rybchenko
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 3/6] ethdev: use rte_eth_unformat_addr Stephen Hemminger
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05  1:08 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Make a function that coresponds with eth_aton_r which can
be used to convert string to rte_ether_addr.

This also allows rte_ethdev to no longer depend on the
cmdline library.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 14 +++++++++
 lib/librte_net/rte_net_version.map |  1 +
 3 files changed, 62 insertions(+)

diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
index 974fe815b335..acc8a0e938c5 100644
--- a/lib/librte_net/rte_ether.c
+++ b/lib/librte_net/rte_ether.c
@@ -27,3 +27,50 @@ rte_ether_format_addr(char *buf, uint16_t size,
 		 eth_addr->addr_bytes[4],
 		 eth_addr->addr_bytes[5]);
 }
+
+/*
+ * Like ether_aton_r but can handle either
+ * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
+ */
+int
+rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
+{
+	unsigned int o0, o1, o2, o3, o4, o5;
+	int n;
+
+	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
+		    &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (n == 6) {
+		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
+		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0;
+		ea->addr_bytes[1] = o1;
+		ea->addr_bytes[2] = o2;
+		ea->addr_bytes[3] = o3;
+		ea->addr_bytes[4] = o4;
+		ea->addr_bytes[5] = o5;
+
+		return 0;
+	}
+
+	/* Support the format XXXX:XXXX:XXXX */
+	n = sscanf(s, "%x:%x:%x", &o0, &o1, &o2);
+	if (n == 3) {
+		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0 >> 8;
+		ea->addr_bytes[1] = o0 & 0xff;
+		ea->addr_bytes[2] = o1 >> 8;
+		ea->addr_bytes[3] = o1 & 0xff;
+		ea->addr_bytes[4] = o2 >> 8;
+		ea->addr_bytes[5] = o2 & 0xff;
+		return 0;
+	}
+	/* unknown format */
+
+	return -1;
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 3caae0d98f6d..8edc7e217b25 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -250,6 +250,20 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
 void
 rte_ether_format_addr(char *buf, uint16_t size,
 		      const struct rte_ether_addr *eth_addr);
+/**
+ * Convert string with Ethernet address to an ether_addr.
+ *
+ * @param str
+ *   A pointer to buffer contains the formatted MAC address.
+ * @param eth_addr
+ *   A pointer to a ether_addr structure.
+ * @return
+ *   0 if successful
+ *   -1 and sets rte_errno if invalid string
+ */
+int __rte_experimental
+rte_ether_unformat_addr(const char *str, struct rte_ether_addr *eth_addr);
+
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index dae6e420cded..8776534b731d 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -25,4 +25,5 @@ EXPERIMENTAL {
 
 	rte_net_make_rarp_packet;
 	rte_net_skip_ip6_ext;
+	rte_eth_unformat_addr;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 3/6] ethdev: use rte_eth_unformat_addr
  2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 1/6] net/rte_ether: deinline non-critical functions Stephen Hemminger
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 2/6] net/ether: add rte_eth_unformat_addr Stephen Hemminger
@ 2019-06-05  1:08   ` Stephen Hemminger
  2019-06-05  8:59     ` Andrew Rybchenko
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 4/6] net/ether: use bitops to speedup comparison Stephen Hemminger
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05  1:08 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_eth_unformat_addr, so that ethdev can be built and work
without the cmdline library. The dependency on cmdline was
an arrangement of convenience anyway.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                      | 1 -
 lib/librte_ethdev/Makefile        | 2 +-
 lib/librte_ethdev/meson.build     | 2 +-
 lib/librte_ethdev/rte_class_eth.c | 9 +--------
 4 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 791e0d9911d6..82b2c4bfa8ea 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
 DEPDIRS-librte_ethdev += librte_kvargs
-DEPDIRS-librte_ethdev += librte_cmdline
 DEPDIRS-librte_ethdev += librte_meter
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 8d4a02630c4f..60bcc2227878 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_cmdline -lrte_meter
+LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_meter
 
 EXPORT_MAP := rte_ethdev_version.map
 
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 8d6165b2a7dd..f75d428c96d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -26,4 +26,4 @@ headers = files('rte_ethdev.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
 
-deps += ['net', 'kvargs', 'cmdline', 'meter']
+deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 873a653532ad..6338355e2557 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -4,7 +4,6 @@
 
 #include <string.h>
 
-#include <cmdline_parse_etheraddr.h>
 #include <rte_class.h>
 #include <rte_compat.h>
 #include <rte_errno.h>
@@ -43,19 +42,13 @@ static int
 eth_mac_cmp(const char *key __rte_unused,
 		const char *value, void *opaque)
 {
-	int ret;
 	struct rte_ether_addr mac;
 	const struct rte_eth_dev_data *data = opaque;
 	struct rte_eth_dev_info dev_info;
 	uint32_t index;
 
 	/* Parse devargs MAC address. */
-	/*
-	 * cannot use ether_aton_r(value, &mac)
-	 * because of include conflict with rte_ether.h
-	 */
-	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
-	if (ret < 0)
+	if (rte_ether_unformat_addr(value, &mac) < 0)
 		return -1; /* invalid devargs value */
 
 	/* Return 0 if devargs MAC is matching one of the device MACs. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 4/6] net/ether: use bitops to speedup comparison
  2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
                     ` (2 preceding siblings ...)
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 3/6] ethdev: use rte_eth_unformat_addr Stephen Hemminger
@ 2019-06-05  1:08   ` Stephen Hemminger
  2019-06-05  9:02     ` Andrew Rybchenko
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 5/6] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 6/6] cmdline: use rte_ether_unformat_addr Stephen Hemminger
  5 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05  1:08 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_net/rte_ether.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 8edc7e217b25..feb35a33c94b 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -81,11 +81,10 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
+	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+
+	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea->addr_bytes[i] != 0x00)
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w = (const uint16_t *)ea;
+
+	return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 5/6] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
                     ` (3 preceding siblings ...)
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 4/6] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-06-05  1:08   ` Stephen Hemminger
  2019-06-05  9:04     ` Andrew Rybchenko
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 6/6] cmdline: use rte_ether_unformat_addr Stephen Hemminger
  5 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05  1:08 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Stephen Hemminger

From: Bruce Richardson <bruce.richardson@intel.com>

When including the rte_ether.h header in applications with warnings
enabled, a warning was given because of the assumption of 2-byte alignment
of ethernet addresses when processing them.

.../include/rte_ether.h:149:2: warning: converting a packed ‘const
  struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
  {aka ‘const short unsigned int’} pointer (alignment 2) may result in
  an unaligned pointer value [-Waddress-of-packed-member]
149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
    |  ^~~~~

Since ethernet addresses should always be aligned on a two-byte boundary,
we can just inform the compiler of this assumption to remove the warnings
and allow us to always access the addresses using 16-bit operations.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_net/rte_ether.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index feb35a33c94b..d7b76ddf63eb 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -58,7 +58,8 @@ extern "C" {
  * See http://standards.ieee.org/regauth/groupmac/tutorial.html
  */
 struct rte_ether_addr {
-	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
+	/**< Addr bytes in tx order */
 } __attribute__((__packed__));
 
 #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
@@ -81,8 +82,8 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
-	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+	const uint16_t *w1 = (const uint16_t *)ea1;
+	const uint16_t *w2 = (const uint16_t *)ea2;
 
 	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
@@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *w = (const uint16_t *)ea;
+	const uint16_t *w = (const uint16_t *)ea;
 
 	return (w[0] | w[1] | w[2]) == 0;
 }
@@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
  */
 static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
+	const uint16_t *ea_words = (const uint16_t *)ea;
 
 	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
 		ea_words[2] == 0xFFFF);
-- 
2.20.1


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

* [dpdk-dev] [PATCH v3 6/6] cmdline: use rte_ether_unformat_addr
  2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
                     ` (4 preceding siblings ...)
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 5/6] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-06-05  1:08   ` Stephen Hemminger
  5 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05  1:08 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Now that there is a version of ether_aton in rte_ether, it can
be used by the cmdline ethernet address parser.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                                 |  2 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++-----------------
 lib/librte_cmdline/meson.build               |  3 +
 4 files changed, 14 insertions(+), 65 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 82b2c4bfa8ea..cc36fe7591f0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,7 +20,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
-DEPDIRS-librte_cmdline := librte_eal
+DEPDIRS-librte_cmdline := librte_eal librte_net
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index c64142b8d5a0..04057d7c671f 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cmdline.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_cmdline_version.map
 
@@ -25,7 +26,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_net -lrte_eal
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_parse_etheraddr.c b/lib/librte_cmdline/cmdline_parse_etheraddr.c
index 24e04755cd9e..2cb8dd2a1267 100644
--- a/lib/librte_cmdline/cmdline_parse_etheraddr.c
+++ b/lib/librte_cmdline/cmdline_parse_etheraddr.c
@@ -12,9 +12,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
 
 #include <rte_string_fns.h>
+#include <rte_ether.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -26,69 +26,15 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 	.get_help = cmdline_get_help_etheraddr,
 };
 
-/* the format can be either XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX */
-#define ETHER_ADDRSTRLENLONG 18
-#define ETHER_ADDRSTRLENSHORT 15
-
-#ifdef __linux__
-#define ea_oct ether_addr_octet
-#else
-#define ea_oct octet
-#endif
-
-
-static struct ether_addr *
-my_ether_aton(const char *a)
-{
-	int i;
-	char *end;
-	unsigned long o[ETHER_ADDR_LEN];
-	static struct ether_addr ether_addr;
-
-	i = 0;
-	do {
-		errno = 0;
-		o[i] = strtoul(a, &end, 16);
-		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
-			return NULL;
-		a = end + 1;
-	} while (++i != sizeof (o) / sizeof (o[0]) && end[0] != 0);
-
-	/* Junk at the end of line */
-	if (end[0] != 0)
-		return NULL;
-
-	/* Support the format XX:XX:XX:XX:XX:XX */
-	if (i == ETHER_ADDR_LEN) {
-		while (i-- != 0) {
-			if (o[i] > UINT8_MAX)
-				return NULL;
-			ether_addr.ea_oct[i] = (uint8_t)o[i];
-		}
-	/* Support the format XXXX:XXXX:XXXX */
-	} else if (i == ETHER_ADDR_LEN / 2) {
-		while (i-- != 0) {
-			if (o[i] > UINT16_MAX)
-				return NULL;
-			ether_addr.ea_oct[i * 2] = (uint8_t)(o[i] >> 8);
-			ether_addr.ea_oct[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
-		}
-	/* unknown format */
-	} else
-		return NULL;
-
-	return (struct ether_addr *)&ether_addr;
-}
-
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 	const char *buf, void *res, unsigned ressize)
 {
 	unsigned int token_len = 0;
-	char ether_str[ETHER_ADDRSTRLENLONG+1];
-	struct ether_addr *tmp;
+	char ether_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr tmp;
 
-	if (res && ressize < sizeof(struct ether_addr))
+	if (res && ressize < sizeof(tmp))
 		return -1;
 
 	if (!buf || ! *buf)
@@ -98,17 +44,16 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 		token_len++;
 
 	/* if token doesn't match possible string lengths... */
-	if ((token_len != ETHER_ADDRSTRLENLONG - 1) &&
-			(token_len != ETHER_ADDRSTRLENSHORT - 1))
+	if (token_len >= RTE_ETHER_ADDR_FMT_SIZE)
 		return -1;
 
 	strlcpy(ether_str, buf, token_len + 1);
 
-	tmp = my_ether_aton(ether_str);
-	if (tmp == NULL)
+	if (rte_ether_unformat_addr(ether_str, &tmp) < 0)
 		return -1;
+
 	if (res)
-		memcpy(res, tmp, sizeof(struct ether_addr));
+		memcpy(res, &tmp, sizeof(tmp));
 	return token_len;
 }
 
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 0fa61385fccf..c01033fd796f 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -4,6 +4,8 @@
 # This library is processed before EAL
 includes = [global_inc]
 
+cflags  += '-DALLOW_EXPERIMENTAL_API'
+
 version = 2
 sources = files('cmdline.c',
 	'cmdline_cirbuf.c',
@@ -28,3 +30,4 @@ headers = files('cmdline.h',
 	'cmdline_socket.h',
 	'cmdline_cirbuf.h',
 	'cmdline_parse_portlist.h')
+deps += ['net']
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v3 1/6] net/rte_ether: deinline non-critical functions
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 1/6] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-06-05  8:44     ` Andrew Rybchenko
  2019-06-05 16:29       ` Stephen Hemminger
  0 siblings, 1 reply; 127+ messages in thread
From: Andrew Rybchenko @ 2019-06-05  8:44 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Rami Rosen

On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> Formatting ethernet address and getting a random value are
> not in critical path so they should not be inlined.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Acked-by: Rami Rosen <ramirose@gmail.com>

Meson build is lost plus one nit below.
Other than that:

Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

[...]

> diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
> index 26c06e7c7ae7..dae6e420cded 100644
> --- a/lib/librte_net/rte_net_version.map
> +++ b/lib/librte_net/rte_net_version.map
> @@ -13,6 +13,13 @@ DPDK_17.05 {
>   
>   } DPDK_16.11;
>   
> +DPDK_19.08 {
> +	global:
> +
> +	eth_random_addr;
> +	eth_format_addr;

rte_ prefix is lost

> +} DPDK_17.05;
> +
>   EXPERIMENTAL {
>   	global:
>   


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

* Re: [dpdk-dev] [PATCH v3 2/6] net/ether: add rte_eth_unformat_addr
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 2/6] net/ether: add rte_eth_unformat_addr Stephen Hemminger
@ 2019-06-05  8:55     ` Andrew Rybchenko
  2019-06-05 16:31       ` Stephen Hemminger
  0 siblings, 1 reply; 127+ messages in thread
From: Andrew Rybchenko @ 2019-06-05  8:55 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> Make a function that coresponds with eth_aton_r which can

I guess ether_aton_r

> be used to convert string to rte_ether_addr.
>
> This also allows rte_ethdev to no longer depend on the
> cmdline library.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>   lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
>   lib/librte_net/rte_ether.h         | 14 +++++++++
>   lib/librte_net/rte_net_version.map |  1 +
>   3 files changed, 62 insertions(+)
>
> diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
> index 974fe815b335..acc8a0e938c5 100644
> --- a/lib/librte_net/rte_ether.c
> +++ b/lib/librte_net/rte_ether.c
> @@ -27,3 +27,50 @@ rte_ether_format_addr(char *buf, uint16_t size,
>   		 eth_addr->addr_bytes[4],
>   		 eth_addr->addr_bytes[5]);
>   }
> +
> +/*
> + * Like ether_aton_r but can handle either
> + * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
> + */
> +int
> +rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
> +{
> +	unsigned int o0, o1, o2, o3, o4, o5;
> +	int n;
> +
> +	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
> +		    &o0, &o1, &o2, &o3, &o4, &o5);

Is it intended that the following input will pass?
  "af:bb:03:65:dc:ddobar" or  "af:bb:03:65:dc:dd foobar"

I guess yes since ether_aton() accepts it. If so,
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>


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

* Re: [dpdk-dev] [PATCH v3 3/6] ethdev: use rte_eth_unformat_addr
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 3/6] ethdev: use rte_eth_unformat_addr Stephen Hemminger
@ 2019-06-05  8:59     ` Andrew Rybchenko
  2019-06-05 15:02       ` Stephen Hemminger
  2019-06-05 16:33       ` Stephen Hemminger
  0 siblings, 2 replies; 127+ messages in thread
From: Andrew Rybchenko @ 2019-06-05  8:59 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> Use rte_eth_unformat_addr, so that ethdev can be built and work
> without the cmdline library. The dependency on cmdline was
> an arrangement of convenience anyway.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

[...]

> diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
> index 873a653532ad..6338355e2557 100644
> --- a/lib/librte_ethdev/rte_class_eth.c
> +++ b/lib/librte_ethdev/rte_class_eth.c
> @@ -4,7 +4,6 @@
>   
>   #include <string.h>
>   
> -#include <cmdline_parse_etheraddr.h>
>   #include <rte_class.h>
>   #include <rte_compat.h>
>   #include <rte_errno.h>
> @@ -43,19 +42,13 @@ static int
>   eth_mac_cmp(const char *key __rte_unused,
>   		const char *value, void *opaque)
>   {
> -	int ret;
>   	struct rte_ether_addr mac;
>   	const struct rte_eth_dev_data *data = opaque;
>   	struct rte_eth_dev_info dev_info;
>   	uint32_t index;
>   
>   	/* Parse devargs MAC address. */
> -	/*
> -	 * cannot use ether_aton_r(value, &mac)
> -	 * because of include conflict with rte_ether.h

Why not ether_aton_r()? Isn't conflict resolved now after patch series 
from Olivier?
I think it would be nice to explain it in the changeset description.

> -	 */
> -	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
> -	if (ret < 0)
> +	if (rte_ether_unformat_addr(value, &mac) < 0)
>   		return -1; /* invalid devargs value */
>   
>   	/* Return 0 if devargs MAC is matching one of the device MACs. */


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

* Re: [dpdk-dev] [PATCH v3 4/6] net/ether: use bitops to speedup comparison
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 4/6] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-06-05  9:02     ` Andrew Rybchenko
  0 siblings, 0 replies; 127+ messages in thread
From: Andrew Rybchenko @ 2019-06-05  9:02 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> Using bit operations like or and xor is faster than a loop
> on all architectures. Really just explicit unrolling.
>
> Similar cast to uint16 unaligned is already done in
> other functions here.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>


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

* Re: [dpdk-dev] [PATCH v3 5/6] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 5/6] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-06-05  9:04     ` Andrew Rybchenko
  0 siblings, 0 replies; 127+ messages in thread
From: Andrew Rybchenko @ 2019-06-05  9:04 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Bruce Richardson

On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> From: Bruce Richardson <bruce.richardson@intel.com>
>
> When including the rte_ether.h header in applications with warnings
> enabled, a warning was given because of the assumption of 2-byte alignment
> of ethernet addresses when processing them.
>
> .../include/rte_ether.h:149:2: warning: converting a packed ‘const
>    struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
>    {aka ‘const short unsigned int’} pointer (alignment 2) may result in
>    an unaligned pointer value [-Waddress-of-packed-member]
> 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
>      |  ^~~~~
>
> Since ethernet addresses should always be aligned on a two-byte boundary,
> we can just inform the compiler of this assumption to remove the warnings
> and allow us to always access the addresses using 16-bit operations.
>
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>


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

* Re: [dpdk-dev] [PATCH v3 3/6] ethdev: use rte_eth_unformat_addr
  2019-06-05  8:59     ` Andrew Rybchenko
@ 2019-06-05 15:02       ` Stephen Hemminger
  2019-06-05 16:33       ` Stephen Hemminger
  1 sibling, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 15:02 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev

On Wed, 5 Jun 2019 11:59:52 +0300
Andrew Rybchenko <arybchenko@solarflare.com> wrote:

> On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> > Use rte_eth_unformat_addr, so that ethdev can be built and work
> > without the cmdline library. The dependency on cmdline was
> > an arrangement of convenience anyway.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>  
> 
> [...]
> 
> > diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
> > index 873a653532ad..6338355e2557 100644
> > --- a/lib/librte_ethdev/rte_class_eth.c
> > +++ b/lib/librte_ethdev/rte_class_eth.c
> > @@ -4,7 +4,6 @@
> >   
> >   #include <string.h>
> >   
> > -#include <cmdline_parse_etheraddr.h>
> >   #include <rte_class.h>
> >   #include <rte_compat.h>
> >   #include <rte_errno.h>
> > @@ -43,19 +42,13 @@ static int
> >   eth_mac_cmp(const char *key __rte_unused,
> >   		const char *value, void *opaque)
> >   {
> > -	int ret;
> >   	struct rte_ether_addr mac;
> >   	const struct rte_eth_dev_data *data = opaque;
> >   	struct rte_eth_dev_info dev_info;
> >   	uint32_t index;
> >   
> >   	/* Parse devargs MAC address. */
> > -	/*
> > -	 * cannot use ether_aton_r(value, &mac)
> > -	 * because of include conflict with rte_ether.h  
> 
> Why not ether_aton_r()? Isn't conflict resolved now after patch series 
> from Olivier?
> I think it would be nice to explain it in the changeset description.

ether_aton_r won;t work for 3 three ushorts model.

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

* Re: [dpdk-dev] [PATCH v3 1/6] net/rte_ether: deinline non-critical functions
  2019-06-05  8:44     ` Andrew Rybchenko
@ 2019-06-05 16:29       ` Stephen Hemminger
  0 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 16:29 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, Rami Rosen

On Wed, 5 Jun 2019 11:44:42 +0300
Andrew Rybchenko <arybchenko@solarflare.com> wrote:

> On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> > Formatting ethernet address and getting a random value are
> > not in critical path so they should not be inlined.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > Acked-by: Rami Rosen <ramirose@gmail.com>  
> 
> Meson build is lost plus one nit below.
> Other than that:
> 
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> 
> [...]
> 
> > diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
> > index 26c06e7c7ae7..dae6e420cded 100644
> > --- a/lib/librte_net/rte_net_version.map
> > +++ b/lib/librte_net/rte_net_version.map
> > @@ -13,6 +13,13 @@ DPDK_17.05 {
> >   
> >   } DPDK_16.11;
> >   
> > +DPDK_19.08 {
> > +	global:
> > +
> > +	eth_random_addr;
> > +	eth_format_addr;  
> 
> rte_ prefix is lost
> 
> > +} DPDK_17.05;
> > +
> >   EXPERIMENTAL {
> >   	global:
> >     
> 

Fixing those now for v4

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

* Re: [dpdk-dev] [PATCH v3 2/6] net/ether: add rte_eth_unformat_addr
  2019-06-05  8:55     ` Andrew Rybchenko
@ 2019-06-05 16:31       ` Stephen Hemminger
  0 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 16:31 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev

On Wed, 5 Jun 2019 11:55:21 +0300
Andrew Rybchenko <arybchenko@solarflare.com> wrote:

> On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> > Make a function that coresponds with eth_aton_r which can  
> 
> I guess ether_aton_r
> 
> > be used to convert string to rte_ether_addr.
> >
> > This also allows rte_ethdev to no longer depend on the
> > cmdline library.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > ---
> >   lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
> >   lib/librte_net/rte_ether.h         | 14 +++++++++
> >   lib/librte_net/rte_net_version.map |  1 +
> >   3 files changed, 62 insertions(+)
> >
> > diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
> > index 974fe815b335..acc8a0e938c5 100644
> > --- a/lib/librte_net/rte_ether.c
> > +++ b/lib/librte_net/rte_ether.c
> > @@ -27,3 +27,50 @@ rte_ether_format_addr(char *buf, uint16_t size,
> >   		 eth_addr->addr_bytes[4],
> >   		 eth_addr->addr_bytes[5]);
> >   }
> > +
> > +/*
> > + * Like ether_aton_r but can handle either
> > + * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
> > + */
> > +int
> > +rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
> > +{
> > +	unsigned int o0, o1, o2, o3, o4, o5;
> > +	int n;
> > +
> > +	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
> > +		    &o0, &o1, &o2, &o3, &o4, &o5);  
> 
> Is it intended that the following input will pass?
>   "af:bb:03:65:dc:ddobar" or  "af:bb:03:65:dc:dd foobar"
> 
> I guess yes since ether_aton() accepts it. If so,
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

you are right ether_aton has same logic.
doing something more complex is possible but not really needed.

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

* Re: [dpdk-dev] [PATCH v3 3/6] ethdev: use rte_eth_unformat_addr
  2019-06-05  8:59     ` Andrew Rybchenko
  2019-06-05 15:02       ` Stephen Hemminger
@ 2019-06-05 16:33       ` Stephen Hemminger
  1 sibling, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 16:33 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev

On Wed, 5 Jun 2019 11:59:52 +0300
Andrew Rybchenko <arybchenko@solarflare.com> wrote:

> On 6/5/19 4:08 AM, Stephen Hemminger wrote:
> > Use rte_eth_unformat_addr, so that ethdev can be built and work
> > without the cmdline library. The dependency on cmdline was
> > an arrangement of convenience anyway.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>  
> 
> [...]
> 
> > diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
> > index 873a653532ad..6338355e2557 100644
> > --- a/lib/librte_ethdev/rte_class_eth.c
> > +++ b/lib/librte_ethdev/rte_class_eth.c
> > @@ -4,7 +4,6 @@
> >   
> >   #include <string.h>
> >   
> > -#include <cmdline_parse_etheraddr.h>
> >   #include <rte_class.h>
> >   #include <rte_compat.h>
> >   #include <rte_errno.h>
> > @@ -43,19 +42,13 @@ static int
> >   eth_mac_cmp(const char *key __rte_unused,
> >   		const char *value, void *opaque)
> >   {
> > -	int ret;
> >   	struct rte_ether_addr mac;
> >   	const struct rte_eth_dev_data *data = opaque;
> >   	struct rte_eth_dev_info dev_info;
> >   	uint32_t index;
> >   
> >   	/* Parse devargs MAC address. */
> > -	/*
> > -	 * cannot use ether_aton_r(value, &mac)
> > -	 * because of include conflict with rte_ether.h  
> 
> Why not ether_aton_r()? Isn't conflict resolved now after patch series 
> from Olivier?
> I think it would be nice to explain it in the changeset description.

The problem with using ether_aton_r is that it does not accept the same
input formats as old code.

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

* [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (7 preceding siblings ...)
  2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
@ 2019-06-05 18:09 ` Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
                     ` (7 more replies)
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                   ` (4 subsequent siblings)
  13 siblings, 8 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of patches around the ethernet address
manipulation routines in librte_net/rte_ether.

v4
   fix meson build
   reword commit messages
   add bonding and tespmd patches
v3 
   rebase to use rte_ether prefix
   drop aligning ethernet headers for now.

Bruce Richardson (1):
  net/ether: mark ethernet addresses as being 2-byte aligned

Stephen Hemminger (7):
  net/rte_ether: deinline non-critical functions
  net/ether: add rte_eth_unformat_addr
  ethdev: use rte_eth_unformat_addr
  net/ether: use bitops to speedup comparison
  cmdline: use rte_ether_unformat_addr
  net/bonding: use rte_ether_unformat_addr rather than cmdline_parse
  app/testpmd: use rte_ether_unformat_addr

 app/test-pmd/cmdline_flow.c                  |  5 +-
 app/test-pmd/config.c                        | 10 +--
 app/test-pmd/parameters.c                    | 15 +---
 drivers/net/bonding/Makefile                 |  2 +-
 drivers/net/bonding/meson.build              |  2 +-
 drivers/net/bonding/rte_eth_bond_args.c      |  6 +-
 lib/Makefile                                 |  3 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++---------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/librte_ethdev/Makefile                   |  2 +-
 lib/librte_ethdev/meson.build                |  2 +-
 lib/librte_ethdev/rte_class_eth.c            |  9 +--
 lib/librte_net/Makefile                      |  1 +
 lib/librte_net/meson.build                   |  2 +-
 lib/librte_net/rte_ether.c                   | 76 ++++++++++++++++++++
 lib/librte_net/rte_ether.h                   | 59 +++++++--------
 lib/librte_net/rte_net_version.map           |  8 +++
 lib/meson.build                              |  2 +-
 19 files changed, 142 insertions(+), 142 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 1/8] net/rte_ether: deinline non-critical functions
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
@ 2019-06-05 18:09   ` Stephen Hemminger
  2019-06-06  8:06     ` Maxime Coquelin
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 2/8] net/ether: add rte_eth_unformat_addr Stephen Hemminger
                     ` (6 subsequent siblings)
  7 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Rami Rosen, Andrew Rybchenko

Formatting Ethernet address and getting a random value are
not in critical path so they should not be inlined.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Rami Rosen <ramirose@gmail.com>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/Makefile            |  1 +
 lib/librte_net/meson.build         |  2 +-
 lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 25 ++++---------------------
 lib/librte_net/rte_net_version.map |  7 +++++++
 5 files changed, 42 insertions(+), 22 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index c3082069ab50..1244c9fd54c9 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -14,6 +14,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
+SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 
 # install includes
diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build
index 7d66f693cbf3..868a93fd6b6b 100644
--- a/lib/librte_net/meson.build
+++ b/lib/librte_net/meson.build
@@ -16,5 +16,5 @@ headers = files('rte_ip.h',
 	'rte_net_crc.h',
 	'rte_mpls.h')
 
-sources = files('rte_arp.c', 'rte_net.c', 'rte_net_crc.c')
+sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c')
 deps += ['mbuf']
diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
new file mode 100644
index 000000000000..974fe815b335
--- /dev/null
+++ b/lib/librte_net/rte_ether.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_ether.h>
+
+void
+rte_eth_random_addr(uint8_t *addr)
+{
+	uint64_t rand = rte_rand();
+	uint8_t *p = (uint8_t *)&rand;
+
+	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
+	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;	/* clear multicast bit */
+	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
+}
+
+void
+rte_ether_format_addr(char *buf, uint16_t size,
+		      const struct rte_ether_addr *eth_addr)
+{
+	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
+		 eth_addr->addr_bytes[0],
+		 eth_addr->addr_bytes[1],
+		 eth_addr->addr_bytes[2],
+		 eth_addr->addr_bytes[3],
+		 eth_addr->addr_bytes[4],
+		 eth_addr->addr_bytes[5]);
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 7be9b4890af7..3caae0d98f6d 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -207,15 +207,8 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *
  * @param addr
  *   A pointer to Ethernet address.
  */
-static inline void rte_eth_random_addr(uint8_t *addr)
-{
-	uint64_t rand = rte_rand();
-	uint8_t *p = (uint8_t *)&rand;
-
-	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
-	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;  /* clear multicast bit */
-	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
-}
+void
+rte_eth_random_addr(uint8_t *addr);
 
 /**
  * Fast copy an Ethernet address.
@@ -254,19 +247,9 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
  * @param eth_addr
  *   A pointer to a ether_addr structure.
  */
-static inline void
+void
 rte_ether_format_addr(char *buf, uint16_t size,
-		  const struct rte_ether_addr *eth_addr)
-{
-	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 eth_addr->addr_bytes[0],
-		 eth_addr->addr_bytes[1],
-		 eth_addr->addr_bytes[2],
-		 eth_addr->addr_bytes[3],
-		 eth_addr->addr_bytes[4],
-		 eth_addr->addr_bytes[5]);
-}
-
+		      const struct rte_ether_addr *eth_addr);
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 26c06e7c7ae7..f1e1b84ab491 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -13,6 +13,13 @@ DPDK_17.05 {
 
 } DPDK_16.11;
 
+DPDK_19.08 {
+	global:
+
+	rte_eth_random_addr;
+	rte_ether_format_addr;
+} DPDK_17.05;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 2/8] net/ether: add rte_eth_unformat_addr
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-06-05 18:09   ` Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 3/8] ethdev: use rte_eth_unformat_addr Stephen Hemminger
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Make a function that can be used in place of eth_aton_r
to convert a string to rte_ether_addr. This function
allows both byte (xx:xx:xx:xx:xx:xx) and word (XXXX:XXXX:XXXX)
format and has the same lack of error handling as the original.

This also allows ethdev to no longer have a hard dependency
on the cmdline library.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 14 +++++++++
 lib/librte_net/rte_net_version.map |  1 +
 3 files changed, 62 insertions(+)

diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
index 974fe815b335..acc8a0e938c5 100644
--- a/lib/librte_net/rte_ether.c
+++ b/lib/librte_net/rte_ether.c
@@ -27,3 +27,50 @@ rte_ether_format_addr(char *buf, uint16_t size,
 		 eth_addr->addr_bytes[4],
 		 eth_addr->addr_bytes[5]);
 }
+
+/*
+ * Like ether_aton_r but can handle either
+ * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
+ */
+int
+rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
+{
+	unsigned int o0, o1, o2, o3, o4, o5;
+	int n;
+
+	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
+		    &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (n == 6) {
+		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
+		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0;
+		ea->addr_bytes[1] = o1;
+		ea->addr_bytes[2] = o2;
+		ea->addr_bytes[3] = o3;
+		ea->addr_bytes[4] = o4;
+		ea->addr_bytes[5] = o5;
+
+		return 0;
+	}
+
+	/* Support the format XXXX:XXXX:XXXX */
+	n = sscanf(s, "%x:%x:%x", &o0, &o1, &o2);
+	if (n == 3) {
+		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0 >> 8;
+		ea->addr_bytes[1] = o0 & 0xff;
+		ea->addr_bytes[2] = o1 >> 8;
+		ea->addr_bytes[3] = o1 & 0xff;
+		ea->addr_bytes[4] = o2 >> 8;
+		ea->addr_bytes[5] = o2 & 0xff;
+		return 0;
+	}
+	/* unknown format */
+
+	return -1;
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 3caae0d98f6d..8edc7e217b25 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -250,6 +250,20 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
 void
 rte_ether_format_addr(char *buf, uint16_t size,
 		      const struct rte_ether_addr *eth_addr);
+/**
+ * Convert string with Ethernet address to an ether_addr.
+ *
+ * @param str
+ *   A pointer to buffer contains the formatted MAC address.
+ * @param eth_addr
+ *   A pointer to a ether_addr structure.
+ * @return
+ *   0 if successful
+ *   -1 and sets rte_errno if invalid string
+ */
+int __rte_experimental
+rte_ether_unformat_addr(const char *str, struct rte_ether_addr *eth_addr);
+
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index f1e1b84ab491..f4c915069d57 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -25,4 +25,5 @@ EXPERIMENTAL {
 
 	rte_net_make_rarp_packet;
 	rte_net_skip_ip6_ext;
+	rte_ether_unformat_addr;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 3/8] ethdev: use rte_eth_unformat_addr
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 2/8] net/ether: add rte_eth_unformat_addr Stephen Hemminger
@ 2019-06-05 18:09   ` Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_eth_unformat_addr, so that ethdev can be built and work
without the cmdline library. The dependency on cmdline was
an arrangement of convenience anyway.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                      | 1 -
 lib/librte_ethdev/Makefile        | 2 +-
 lib/librte_ethdev/meson.build     | 2 +-
 lib/librte_ethdev/rte_class_eth.c | 9 +--------
 4 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 791e0d9911d6..82b2c4bfa8ea 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
 DEPDIRS-librte_ethdev += librte_kvargs
-DEPDIRS-librte_ethdev += librte_cmdline
 DEPDIRS-librte_ethdev += librte_meter
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 8d4a02630c4f..60bcc2227878 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_cmdline -lrte_meter
+LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_meter
 
 EXPORT_MAP := rte_ethdev_version.map
 
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 8d6165b2a7dd..f75d428c96d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -26,4 +26,4 @@ headers = files('rte_ethdev.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
 
-deps += ['net', 'kvargs', 'cmdline', 'meter']
+deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 873a653532ad..6338355e2557 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -4,7 +4,6 @@
 
 #include <string.h>
 
-#include <cmdline_parse_etheraddr.h>
 #include <rte_class.h>
 #include <rte_compat.h>
 #include <rte_errno.h>
@@ -43,19 +42,13 @@ static int
 eth_mac_cmp(const char *key __rte_unused,
 		const char *value, void *opaque)
 {
-	int ret;
 	struct rte_ether_addr mac;
 	const struct rte_eth_dev_data *data = opaque;
 	struct rte_eth_dev_info dev_info;
 	uint32_t index;
 
 	/* Parse devargs MAC address. */
-	/*
-	 * cannot use ether_aton_r(value, &mac)
-	 * because of include conflict with rte_ether.h
-	 */
-	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
-	if (ret < 0)
+	if (rte_ether_unformat_addr(value, &mac) < 0)
 		return -1; /* invalid devargs value */
 
 	/* Return 0 if devargs MAC is matching one of the device MACs. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 4/8] net/ether: use bitops to speedup comparison
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (2 preceding siblings ...)
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 3/8] ethdev: use rte_eth_unformat_addr Stephen Hemminger
@ 2019-06-05 18:09   ` Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 8edc7e217b25..feb35a33c94b 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -81,11 +81,10 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
+	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+
+	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea->addr_bytes[i] != 0x00)
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w = (const uint16_t *)ea;
+
+	return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (3 preceding siblings ...)
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-06-05 18:09   ` Stephen Hemminger
  2019-06-07 16:59     ` Ananyev, Konstantin
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 6/8] cmdline: use rte_ether_unformat_addr Stephen Hemminger
                     ` (2 subsequent siblings)
  7 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Stephen Hemminger, Andrew Rybchenko

From: Bruce Richardson <bruce.richardson@intel.com>

When including the rte_ether.h header in applications with warnings
enabled, a warning was given because of the assumption of 2-byte alignment
of ethernet addresses when processing them.

.../include/rte_ether.h:149:2: warning: converting a packed ‘const
  struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
  {aka ‘const short unsigned int’} pointer (alignment 2) may result in
  an unaligned pointer value [-Waddress-of-packed-member]
149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
    |  ^~~~~

Since ethernet addresses should always be aligned on a two-byte boundary,
we can just inform the compiler of this assumption to remove the warnings
and allow us to always access the addresses using 16-bit operations.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index feb35a33c94b..d7b76ddf63eb 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -58,7 +58,8 @@ extern "C" {
  * See http://standards.ieee.org/regauth/groupmac/tutorial.html
  */
 struct rte_ether_addr {
-	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
+	/**< Addr bytes in tx order */
 } __attribute__((__packed__));
 
 #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
@@ -81,8 +82,8 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
-	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+	const uint16_t *w1 = (const uint16_t *)ea1;
+	const uint16_t *w2 = (const uint16_t *)ea2;
 
 	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
@@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *w = (const uint16_t *)ea;
+	const uint16_t *w = (const uint16_t *)ea;
 
 	return (w[0] | w[1] | w[2]) == 0;
 }
@@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
  */
 static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
+	const uint16_t *ea_words = (const uint16_t *)ea;
 
 	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
 		ea_words[2] == 0xFFFF);
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 6/8] cmdline: use rte_ether_unformat_addr
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (4 preceding siblings ...)
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-06-05 18:09   ` Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 7/8] net/bonding: use rte_ether_unformat_addr rather than cmdline_parse Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 8/8] app/testpmd: use rte_ether_unformat_addr Stephen Hemminger
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Now that there is a version of ether_aton in rte_ether, it can
be used by the cmdline ethernet address parser.

Note: ether_aton_r can not be used in cmdline because
the old code would accept either bytes XX:XX:XX:XX:XX:XX
or words XXXX:XXXX:XXXX and we need to keep compatiablity.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                                 |  2 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++-----------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/meson.build                              |  2 +-
 5 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 82b2c4bfa8ea..cc36fe7591f0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,7 +20,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
-DEPDIRS-librte_cmdline := librte_eal
+DEPDIRS-librte_cmdline := librte_eal librte_net
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index c64142b8d5a0..04057d7c671f 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cmdline.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_cmdline_version.map
 
@@ -25,7 +26,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_net -lrte_eal
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_parse_etheraddr.c b/lib/librte_cmdline/cmdline_parse_etheraddr.c
index 24e04755cd9e..2cb8dd2a1267 100644
--- a/lib/librte_cmdline/cmdline_parse_etheraddr.c
+++ b/lib/librte_cmdline/cmdline_parse_etheraddr.c
@@ -12,9 +12,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
 
 #include <rte_string_fns.h>
+#include <rte_ether.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -26,69 +26,15 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 	.get_help = cmdline_get_help_etheraddr,
 };
 
-/* the format can be either XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX */
-#define ETHER_ADDRSTRLENLONG 18
-#define ETHER_ADDRSTRLENSHORT 15
-
-#ifdef __linux__
-#define ea_oct ether_addr_octet
-#else
-#define ea_oct octet
-#endif
-
-
-static struct ether_addr *
-my_ether_aton(const char *a)
-{
-	int i;
-	char *end;
-	unsigned long o[ETHER_ADDR_LEN];
-	static struct ether_addr ether_addr;
-
-	i = 0;
-	do {
-		errno = 0;
-		o[i] = strtoul(a, &end, 16);
-		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
-			return NULL;
-		a = end + 1;
-	} while (++i != sizeof (o) / sizeof (o[0]) && end[0] != 0);
-
-	/* Junk at the end of line */
-	if (end[0] != 0)
-		return NULL;
-
-	/* Support the format XX:XX:XX:XX:XX:XX */
-	if (i == ETHER_ADDR_LEN) {
-		while (i-- != 0) {
-			if (o[i] > UINT8_MAX)
-				return NULL;
-			ether_addr.ea_oct[i] = (uint8_t)o[i];
-		}
-	/* Support the format XXXX:XXXX:XXXX */
-	} else if (i == ETHER_ADDR_LEN / 2) {
-		while (i-- != 0) {
-			if (o[i] > UINT16_MAX)
-				return NULL;
-			ether_addr.ea_oct[i * 2] = (uint8_t)(o[i] >> 8);
-			ether_addr.ea_oct[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
-		}
-	/* unknown format */
-	} else
-		return NULL;
-
-	return (struct ether_addr *)&ether_addr;
-}
-
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 	const char *buf, void *res, unsigned ressize)
 {
 	unsigned int token_len = 0;
-	char ether_str[ETHER_ADDRSTRLENLONG+1];
-	struct ether_addr *tmp;
+	char ether_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr tmp;
 
-	if (res && ressize < sizeof(struct ether_addr))
+	if (res && ressize < sizeof(tmp))
 		return -1;
 
 	if (!buf || ! *buf)
@@ -98,17 +44,16 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 		token_len++;
 
 	/* if token doesn't match possible string lengths... */
-	if ((token_len != ETHER_ADDRSTRLENLONG - 1) &&
-			(token_len != ETHER_ADDRSTRLENSHORT - 1))
+	if (token_len >= RTE_ETHER_ADDR_FMT_SIZE)
 		return -1;
 
 	strlcpy(ether_str, buf, token_len + 1);
 
-	tmp = my_ether_aton(ether_str);
-	if (tmp == NULL)
+	if (rte_ether_unformat_addr(ether_str, &tmp) < 0)
 		return -1;
+
 	if (res)
-		memcpy(res, tmp, sizeof(struct ether_addr));
+		memcpy(res, &tmp, sizeof(tmp));
 	return token_len;
 }
 
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 0fa61385fccf..07334c1b0956 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -1,10 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
-# This library is processed before EAL
-includes = [global_inc]
-
 version = 2
+allow_experimental_apis = true
 sources = files('cmdline.c',
 	'cmdline_cirbuf.c',
 	'cmdline_parse.c',
@@ -28,3 +26,5 @@ headers = files('cmdline.h',
 	'cmdline_socket.h',
 	'cmdline_cirbuf.h',
 	'cmdline_parse_portlist.h')
+
+deps += ['net']
diff --git a/lib/meson.build b/lib/meson.build
index e067ce5ea349..fc57fec1908a 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -11,8 +11,8 @@
 libraries = [
 	'kvargs', # eal depends on kvargs
 	'eal', # everything depends on eal
-	'cmdline', # ethdev depends on cmdline for parsing functions
 	'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
+	'cmdline',
 	'metrics', # bitrate/latency stats depends on this
 	'hash',    # efd depends on this
 	'timer',   # eventdev depends on this
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 7/8] net/bonding: use rte_ether_unformat_addr rather than cmdline_parse
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (5 preceding siblings ...)
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 6/8] cmdline: use rte_ether_unformat_addr Stephen Hemminger
@ 2019-06-05 18:09   ` Stephen Hemminger
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 8/8] app/testpmd: use rte_ether_unformat_addr Stephen Hemminger
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline library used to be the only way to parse a
mac address. Now there is rte_ether_unformat_addr.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bonding/Makefile            | 2 +-
 drivers/net/bonding/meson.build         | 2 +-
 drivers/net/bonding/rte_eth_bond_args.c | 6 +-----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 1893e3cad313..26c1782554cd 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
-LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_pci -lrte_bus_pci
 LDLIBS += -lrte_bus_vdev
 
diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build
index 00374edb2a9d..6267210adf5f 100644
--- a/drivers/net/bonding/meson.build
+++ b/drivers/net/bonding/meson.build
@@ -8,6 +8,6 @@ sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', 'rte_eth_bond_flow.c
 	'rte_eth_bond_args.c', 'rte_eth_bond_8023ad.c', 'rte_eth_bond_alb.c')
 
 deps += 'sched' # needed for rte_bitmap.h
-deps += ['ip_frag', 'cmdline']
+deps += ['ip_frag']
 
 install_headers('rte_eth_bond.h', 'rte_eth_bond_8023ad.h')
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index 01bbb06c1a84..936440fb8491 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -7,9 +7,6 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
 #include "rte_eth_bond.h"
 #include "rte_eth_bond_private.h"
 
@@ -281,8 +278,7 @@ bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
 		return -1;
 
 	/* Parse MAC */
-	return cmdline_parse_etheraddr(NULL, value, extra_args,
-		sizeof(struct rte_ether_addr));
+	return rte_ether_unformat_addr(value, extra_args);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v4 8/8] app/testpmd: use rte_ether_unformat_addr
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (6 preceding siblings ...)
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 7/8] net/bonding: use rte_ether_unformat_addr rather than cmdline_parse Stephen Hemminger
@ 2019-06-05 18:09   ` Stephen Hemminger
  2019-06-20 14:18     ` Iremonger, Bernard
  7 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-05 18:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline_parse_ether_addr does not need to be used everywhere
in testpmd. Can use rte_ether_unformat_addr instead.
As an added bonus it eliminates some code for copying.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline_flow.c |  5 ++---
 app/test-pmd/config.c       | 10 +++-------
 app/test-pmd/parameters.c   | 15 +++------------
 3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 201bd9de56e0..2b02ca29b7ac 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -18,7 +18,6 @@
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_flow.h>
 
 #include "testpmd.h"
@@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct token *token,
 	/* Only network endian is supported. */
 	if (!arg->hton)
 		goto error;
-	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
-	if (ret < 0 || (unsigned int)ret != len)
+	ret = rte_ether_unformat_addr(str, &tmp);
+	if (ret < 0)
 		goto error;
 	if (!ctx->object)
 		return len;
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index ab458c8d2837..1d804705d96c 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -49,7 +49,6 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include <rte_gro.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_config.h>
 
 #include "testpmd.h"
@@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 void
 set_fwd_eth_peer(portid_t port_id, char *peer_addr)
 {
-	uint8_t c, new_peer_addr[6];
+	struct rte_ether_addr new_peer_addr;
 	if (!rte_eth_dev_is_valid_port(port_id)) {
 		printf("Error: Invalid port number %i\n", port_id);
 		return;
 	}
-	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
-					sizeof(new_peer_addr)) < 0) {
+	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
 		printf("Error: Invalid ethernet address: %s\n", peer_addr);
 		return;
 	}
-	for (c = 0; c < 6; c++)
-		peer_eth_addrs[port_id].addr_bytes[c] =
-			new_peer_addr[c];
+	peer_eth_addrs[port_id] = new_peer_addr;
 }
 
 int
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 245b610641ee..975a97807009 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -39,10 +39,6 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_CMDLINE
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-#endif
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
@@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
 		if (fgets(buf, sizeof(buf), config_file) == NULL)
 			break;
 
-		if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i],
-				sizeof(peer_eth_addrs[i])) < 0) {
+		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
 			printf("Bad MAC address format on line %d\n", i+1);
 			fclose(config_file);
 			return -1;
@@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
 			}
 			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
 				char *port_end;
-				uint8_t c, peer_addr[6];
 
 				errno = 0;
 				n = strtoul(optarg, &port_end, 10);
@@ -739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
 						 "eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
 						 n, RTE_MAX_ETHPORTS);
 
-				if (cmdline_parse_etheraddr(NULL, port_end,
-						&peer_addr, sizeof(peer_addr)) < 0)
+				if (rte_ether_unformat_addr(port_end,
+							    &peer_eth_addrs[n]) < 0)
 					rte_exit(EXIT_FAILURE,
 						 "Invalid ethernet address: %s\n",
 						 port_end);
-				for (c = 0; c < 6; c++)
-					peer_eth_addrs[n].addr_bytes[c] =
-						peer_addr[c];
 				nb_peer_eth_addrs++;
 			}
 #endif
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v4 1/8] net/rte_ether: deinline non-critical functions
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-06-06  8:06     ` Maxime Coquelin
  0 siblings, 0 replies; 127+ messages in thread
From: Maxime Coquelin @ 2019-06-06  8:06 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Rami Rosen, Andrew Rybchenko



On 6/5/19 8:09 PM, Stephen Hemminger wrote:
> Formatting Ethernet address and getting a random value are
> not in critical path so they should not be inlined.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Acked-by: Rami Rosen <ramirose@gmail.com>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>   lib/librte_net/Makefile            |  1 +
>   lib/librte_net/meson.build         |  2 +-
>   lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
>   lib/librte_net/rte_ether.h         | 25 ++++---------------------
>   lib/librte_net/rte_net_version.map |  7 +++++++
>   5 files changed, 42 insertions(+), 22 deletions(-)
>   create mode 100644 lib/librte_net/rte_ether.c
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>


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

* Re: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-06-07 16:59     ` Ananyev, Konstantin
  2019-06-07 18:35       ` Stephen Hemminger
  2019-06-07 20:39       ` Richardson, Bruce
  0 siblings, 2 replies; 127+ messages in thread
From: Ananyev, Konstantin @ 2019-06-07 16:59 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Richardson, Bruce, Andrew Rybchenko



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen Hemminger
> Sent: Wednesday, June 5, 2019 7:10 PM
> To: dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Stephen Hemminger <stephen@networkplumber.org>; Andrew Rybchenko
> <arybchenko@solarflare.com>
> Subject: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
> 
> From: Bruce Richardson <bruce.richardson@intel.com>
> 
> When including the rte_ether.h header in applications with warnings
> enabled, a warning was given because of the assumption of 2-byte alignment
> of ethernet addresses when processing them.
> 
> .../include/rte_ether.h:149:2: warning: converting a packed ‘const
>   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
>   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
>   an unaligned pointer value [-Waddress-of-packed-member]
> 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
>     |  ^~~~~
> 
> Since ethernet addresses should always be aligned on a two-byte boundary,
> we can just inform the compiler of this assumption to remove the warnings
> and allow us to always access the addresses using 16-bit operations.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>  lib/librte_net/rte_ether.h | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index feb35a33c94b..d7b76ddf63eb 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -58,7 +58,8 @@ extern "C" {
>   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
>   */
>  struct rte_ether_addr {
> -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
> +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> +	/**< Addr bytes in tx order */
>  } __attribute__((__packed__));

Hmm, that would change layout of any struct/union that has struct rte_ether_addr inside.
So seems like implicit ABI breakage to me.
Konstantin


> 
>  #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
> @@ -81,8 +82,8 @@ struct rte_ether_addr {
>  static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
>  				     const struct rte_ether_addr *ea2)
>  {
> -	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
> -	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
> +	const uint16_t *w1 = (const uint16_t *)ea1;
> +	const uint16_t *w2 = (const uint16_t *)ea2;
> 
>  	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
>  }
> @@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
>   */
>  static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
>  {
> -	const unaligned_uint16_t *w = (const uint16_t *)ea;
> +	const uint16_t *w = (const uint16_t *)ea;
> 
>  	return (w[0] | w[1] | w[2]) == 0;
>  }
> @@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
>   */
>  static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
>  {
> -	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
> +	const uint16_t *ea_words = (const uint16_t *)ea;
> 
>  	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
>  		ea_words[2] == 0xFFFF);
> --
> 2.20.1


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

* Re: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-07 16:59     ` Ananyev, Konstantin
@ 2019-06-07 18:35       ` Stephen Hemminger
  2019-06-07 20:40         ` Richardson, Bruce
  2019-06-08 11:51         ` Ananyev, Konstantin
  2019-06-07 20:39       ` Richardson, Bruce
  1 sibling, 2 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-07 18:35 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev, Richardson, Bruce, Andrew Rybchenko

On Fri, 7 Jun 2019 16:59:32 +0000
"Ananyev, Konstantin" <konstantin.ananyev@intel.com> wrote:

> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen Hemminger
> > Sent: Wednesday, June 5, 2019 7:10 PM
> > To: dev@dpdk.org
> > Cc: Richardson, Bruce <bruce.richardson@intel.com>; Stephen Hemminger <stephen@networkplumber.org>; Andrew Rybchenko
> > <arybchenko@solarflare.com>
> > Subject: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
> > 
> > From: Bruce Richardson <bruce.richardson@intel.com>
> > 
> > When including the rte_ether.h header in applications with warnings
> > enabled, a warning was given because of the assumption of 2-byte alignment
> > of ethernet addresses when processing them.
> > 
> > .../include/rte_ether.h:149:2: warning: converting a packed ‘const
> >   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
> >   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
> >   an unaligned pointer value [-Waddress-of-packed-member]
> > 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
> >     |  ^~~~~
> > 
> > Since ethernet addresses should always be aligned on a two-byte boundary,
> > we can just inform the compiler of this assumption to remove the warnings
> > and allow us to always access the addresses using 16-bit operations.
> > 
> > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > ---
> >  lib/librte_net/rte_ether.h | 11 ++++++-----
> >  1 file changed, 6 insertions(+), 5 deletions(-)
> > 
> > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > index feb35a33c94b..d7b76ddf63eb 100644
> > --- a/lib/librte_net/rte_ether.h
> > +++ b/lib/librte_net/rte_ether.h
> > @@ -58,7 +58,8 @@ extern "C" {
> >   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
> >   */
> >  struct rte_ether_addr {
> > -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
> > +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> > +	/**< Addr bytes in tx order */
> >  } __attribute__((__packed__));  
> 
> Hmm, that would change layout of any struct/union that has struct rte_ether_addr inside.
> So seems like implicit ABI breakage to me.
> Konstantin

There was no rte_ether_addr in previous releases.


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

* Re: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-07 16:59     ` Ananyev, Konstantin
  2019-06-07 18:35       ` Stephen Hemminger
@ 2019-06-07 20:39       ` Richardson, Bruce
  2019-06-08 12:15         ` Ananyev, Konstantin
  1 sibling, 1 reply; 127+ messages in thread
From: Richardson, Bruce @ 2019-06-07 20:39 UTC (permalink / raw)
  To: Ananyev, Konstantin, Stephen Hemminger, dev; +Cc: Andrew Rybchenko



> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Friday, June 7, 2019 6:00 PM
> To: Stephen Hemminger <stephen@networkplumber.org>; dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Andrew Rybchenko
> <arybchenko@solarflare.com>
> Subject: RE: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses
> as being 2-byte aligned
> 
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen Hemminger
> > Sent: Wednesday, June 5, 2019 7:10 PM
> > To: dev@dpdk.org
> > Cc: Richardson, Bruce <bruce.richardson@intel.com>; Stephen Hemminger
> > <stephen@networkplumber.org>; Andrew Rybchenko
> > <arybchenko@solarflare.com>
> > Subject: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses
> > as being 2-byte aligned
> >
> > From: Bruce Richardson <bruce.richardson@intel.com>
> >
> > When including the rte_ether.h header in applications with warnings
> > enabled, a warning was given because of the assumption of 2-byte
> > alignment of ethernet addresses when processing them.
> >
> > .../include/rte_ether.h:149:2: warning: converting a packed ‘const
> >   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
> >   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
> >   an unaligned pointer value [-Waddress-of-packed-member]
> > 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t
> *)ea;
> >     |  ^~~~~
> >
> > Since ethernet addresses should always be aligned on a two-byte
> > boundary, we can just inform the compiler of this assumption to remove
> > the warnings and allow us to always access the addresses using 16-bit
> operations.
> >
> > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > ---
> >  lib/librte_net/rte_ether.h | 11 ++++++-----
> >  1 file changed, 6 insertions(+), 5 deletions(-)
> >
> > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > index feb35a33c94b..d7b76ddf63eb 100644
> > --- a/lib/librte_net/rte_ether.h
> > +++ b/lib/librte_net/rte_ether.h
> > @@ -58,7 +58,8 @@ extern "C" {
> >   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
> >   */
> >  struct rte_ether_addr {
> > -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order
> */
> > +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> > +	/**< Addr bytes in tx order */
> >  } __attribute__((__packed__));
> 
> Hmm, that would change layout of any struct/union that has struct
> rte_ether_addr inside.
> So seems like implicit ABI breakage to me.
> Konstantin
> 

I suppose it could, though only if you had the structure starting at an odd byte
inside the larger structure. Personally, I'd think it should be ok in just about
all cases, as I'd find it hard to imagine when you wouldn't have this, but 
technically I suppose it's a break. For real packet heads the fields will always be
two-byte aligned so there is no issue.

/Bruce

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

* Re: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-07 18:35       ` Stephen Hemminger
@ 2019-06-07 20:40         ` Richardson, Bruce
  2019-06-08 11:51         ` Ananyev, Konstantin
  1 sibling, 0 replies; 127+ messages in thread
From: Richardson, Bruce @ 2019-06-07 20:40 UTC (permalink / raw)
  To: Stephen Hemminger, Ananyev, Konstantin; +Cc: dev, Andrew Rybchenko



> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, June 7, 2019 7:35 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: dev@dpdk.org; Richardson, Bruce <bruce.richardson@intel.com>; Andrew
> Rybchenko <arybchenko@solarflare.com>
> Subject: Re: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses
> as being 2-byte aligned
> 
> On Fri, 7 Jun 2019 16:59:32 +0000
> "Ananyev, Konstantin" <konstantin.ananyev@intel.com> wrote:
> 
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen
> > > Hemminger
> > > Sent: Wednesday, June 5, 2019 7:10 PM
> > > To: dev@dpdk.org
> > > Cc: Richardson, Bruce <bruce.richardson@intel.com>; Stephen
> > > Hemminger <stephen@networkplumber.org>; Andrew Rybchenko
> > > <arybchenko@solarflare.com>
> > > Subject: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet
> > > addresses as being 2-byte aligned
> > >
> > > From: Bruce Richardson <bruce.richardson@intel.com>
> > >
> > > When including the rte_ether.h header in applications with warnings
> > > enabled, a warning was given because of the assumption of 2-byte
> > > alignment of ethernet addresses when processing them.
> > >
> > > .../include/rte_ether.h:149:2: warning: converting a packed ‘const
> > >   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
> > >   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
> > >   an unaligned pointer value [-Waddress-of-packed-member]
> > > 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t
> *)ea;
> > >     |  ^~~~~
> > >
> > > Since ethernet addresses should always be aligned on a two-byte
> > > boundary, we can just inform the compiler of this assumption to
> > > remove the warnings and allow us to always access the addresses using
> 16-bit operations.
> > >
> > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > > ---
> > >  lib/librte_net/rte_ether.h | 11 ++++++-----
> > >  1 file changed, 6 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > > index feb35a33c94b..d7b76ddf63eb 100644
> > > --- a/lib/librte_net/rte_ether.h
> > > +++ b/lib/librte_net/rte_ether.h
> > > @@ -58,7 +58,8 @@ extern "C" {
> > >   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
> > >   */
> > >  struct rte_ether_addr {
> > > -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order
> */
> > > +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> > > +	/**< Addr bytes in tx order */
> > >  } __attribute__((__packed__));
> >
> > Hmm, that would change layout of any struct/union that has struct
> rte_ether_addr inside.
> > So seems like implicit ABI breakage to me.
> > Konstantin
> 
> There was no rte_ether_addr in previous releases.

Good point. Thanks for remembering...

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

* Re: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-07 18:35       ` Stephen Hemminger
  2019-06-07 20:40         ` Richardson, Bruce
@ 2019-06-08 11:51         ` Ananyev, Konstantin
  1 sibling, 0 replies; 127+ messages in thread
From: Ananyev, Konstantin @ 2019-06-08 11:51 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, Richardson, Bruce, Andrew Rybchenko,
	Olivier Matz (olivier.matz@6wind.com)


> > >
> > > When including the rte_ether.h header in applications with warnings
> > > enabled, a warning was given because of the assumption of 2-byte alignment
> > > of ethernet addresses when processing them.
> > >
> > > .../include/rte_ether.h:149:2: warning: converting a packed ‘const
> > >   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
> > >   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
> > >   an unaligned pointer value [-Waddress-of-packed-member]
> > > 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
> > >     |  ^~~~~
> > >
> > > Since ethernet addresses should always be aligned on a two-byte boundary,
> > > we can just inform the compiler of this assumption to remove the warnings
> > > and allow us to always access the addresses using 16-bit operations.
> > >
> > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > > ---
> > >  lib/librte_net/rte_ether.h | 11 ++++++-----
> > >  1 file changed, 6 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > > index feb35a33c94b..d7b76ddf63eb 100644
> > > --- a/lib/librte_net/rte_ether.h
> > > +++ b/lib/librte_net/rte_ether.h
> > > @@ -58,7 +58,8 @@ extern "C" {
> > >   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
> > >   */
> > >  struct rte_ether_addr {
> > > -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
> > > +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> > > +	/**< Addr bytes in tx order */
> > >  } __attribute__((__packed__));
> >
> > Hmm, that would change layout of any struct/union that has struct rte_ether_addr inside.
> > So seems like implicit ABI breakage to me.
> > Konstantin
> 
> There was no rte_ether_addr in previous releases.

I suppose you refer to the fact that struct ether_addr was renamed to rte_ether_addr by:
https://git.dpdk.org/dpdk/commit/?id=6d13ea8e8e49ab957deae2bba5ecf4a4bfe747d1 
As I understand, Olivier patches in that rework introduce API change only,  keeping ABI unchanged.
While your patch makes ABI breakage possible.
Konstantin 



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

* Re: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-07 20:39       ` Richardson, Bruce
@ 2019-06-08 12:15         ` Ananyev, Konstantin
  0 siblings, 0 replies; 127+ messages in thread
From: Ananyev, Konstantin @ 2019-06-08 12:15 UTC (permalink / raw)
  To: Richardson, Bruce, Stephen Hemminger, dev; +Cc: Andrew Rybchenko


> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen Hemminger
> > > Sent: Wednesday, June 5, 2019 7:10 PM
> > > To: dev@dpdk.org
> > > Cc: Richardson, Bruce <bruce.richardson@intel.com>; Stephen Hemminger
> > > <stephen@networkplumber.org>; Andrew Rybchenko
> > > <arybchenko@solarflare.com>
> > > Subject: [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses
> > > as being 2-byte aligned
> > >
> > > From: Bruce Richardson <bruce.richardson@intel.com>
> > >
> > > When including the rte_ether.h header in applications with warnings
> > > enabled, a warning was given because of the assumption of 2-byte
> > > alignment of ethernet addresses when processing them.
> > >
> > > .../include/rte_ether.h:149:2: warning: converting a packed ‘const
> > >   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
> > >   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
> > >   an unaligned pointer value [-Waddress-of-packed-member]
> > > 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t
> > *)ea;
> > >     |  ^~~~~
> > >
> > > Since ethernet addresses should always be aligned on a two-byte
> > > boundary, we can just inform the compiler of this assumption to remove
> > > the warnings and allow us to always access the addresses using 16-bit
> > operations.
> > >
> > > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > > ---
> > >  lib/librte_net/rte_ether.h | 11 ++++++-----
> > >  1 file changed, 6 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > > index feb35a33c94b..d7b76ddf63eb 100644
> > > --- a/lib/librte_net/rte_ether.h
> > > +++ b/lib/librte_net/rte_ether.h
> > > @@ -58,7 +58,8 @@ extern "C" {
> > >   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
> > >   */
> > >  struct rte_ether_addr {
> > > -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order
> > */
> > > +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> > > +	/**< Addr bytes in tx order */
> > >  } __attribute__((__packed__));
> >
> > Hmm, that would change layout of any struct/union that has struct
> > rte_ether_addr inside.
> > So seems like implicit ABI breakage to me.
> > Konstantin
> >
> 
> I suppose it could, though only if you had the structure starting at an odd byte
> inside the larger structure.

Yes.

>  Personally, I'd think it should be ok in just about
> all cases, as I'd find it hard to imagine when you wouldn't have this, but
> technically I suppose it's a break.

I also don't expect it to be a common case, but it is not totally impossible.
So I still think it qualifies as ABI change and we need to follow our own ABI
breakage policy here. 

> For real packet heads the fields will always be
> two-byte aligned so there is no issue.
> 


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

* Re: [dpdk-dev] [PATCH v4 8/8] app/testpmd: use rte_ether_unformat_addr
  2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 8/8] app/testpmd: use rte_ether_unformat_addr Stephen Hemminger
@ 2019-06-20 14:18     ` Iremonger, Bernard
  2019-06-20 16:12       ` Stephen Hemminger
  0 siblings, 1 reply; 127+ messages in thread
From: Iremonger, Bernard @ 2019-06-20 14:18 UTC (permalink / raw)
  To: Stephen Hemminger, dev

Hi Stephen,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen
> Hemminger
> Sent: Wednesday, June 5, 2019 7:10 PM
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>
> Subject: [dpdk-dev] [PATCH v4 8/8] app/testpmd: use
> rte_ether_unformat_addr
> 
> The cmdline_parse_ether_addr does not need to be used everywhere in
> testpmd. Can use rte_ether_unformat_addr instead.
> As an added bonus it eliminates some code for copying.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  app/test-pmd/cmdline_flow.c |  5 ++---
>  app/test-pmd/config.c       | 10 +++-------
>  app/test-pmd/parameters.c   | 15 +++------------
>  3 files changed, 8 insertions(+), 22 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 201bd9de56e0..2b02ca29b7ac 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -18,7 +18,6 @@
>  #include <rte_ethdev.h>
>  #include <rte_byteorder.h>
>  #include <cmdline_parse.h>
> -#include <cmdline_parse_etheraddr.h>
>  #include <rte_flow.h>
> 
>  #include "testpmd.h"
> @@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct
> token *token,
>  	/* Only network endian is supported. */
>  	if (!arg->hton)
>  		goto error;
> -	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
> -	if (ret < 0 || (unsigned int)ret != len)
> +	ret = rte_ether_unformat_addr(str, &tmp);
> +	if (ret < 0)
>  		goto error;
>  	if (!ctx->object)
>  		return len;
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> ab458c8d2837..1d804705d96c 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -49,7 +49,6 @@
>  #include <rte_pmd_bnxt.h>
>  #endif
>  #include <rte_gro.h>
> -#include <cmdline_parse_etheraddr.h>
>  #include <rte_config.h>
> 
>  #include "testpmd.h"
> @@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
> void  set_fwd_eth_peer(portid_t port_id, char *peer_addr)  {
> -	uint8_t c, new_peer_addr[6];
> +	struct rte_ether_addr new_peer_addr;
>  	if (!rte_eth_dev_is_valid_port(port_id)) {
>  		printf("Error: Invalid port number %i\n", port_id);
>  		return;
>  	}
> -	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
> -					sizeof(new_peer_addr)) < 0) {
> +	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
>  		printf("Error: Invalid ethernet address: %s\n", peer_addr);
>  		return;
>  	}
> -	for (c = 0; c < 6; c++)
> -		peer_eth_addrs[port_id].addr_bytes[c] =
> -			new_peer_addr[c];
> +	peer_eth_addrs[port_id] = new_peer_addr;
>  }
> 
>  int
> diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index
> 245b610641ee..975a97807009 100644
> --- a/app/test-pmd/parameters.c
> +++ b/app/test-pmd/parameters.c
> @@ -39,10 +39,6 @@
>  #include <rte_ether.h>
>  #include <rte_ethdev.h>
>  #include <rte_string_fns.h>
> -#ifdef RTE_LIBRTE_CMDLINE
> -#include <cmdline_parse.h>
> -#include <cmdline_parse_etheraddr.h>
> -#endif
>  #ifdef RTE_LIBRTE_PMD_BOND
>  #include <rte_eth_bond.h>
>  #endif
> @@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
>  		if (fgets(buf, sizeof(buf), config_file) == NULL)
>  			break;
> 
> -		if (cmdline_parse_etheraddr(NULL, buf,
> &peer_eth_addrs[i],
> -				sizeof(peer_eth_addrs[i])) < 0) {
> +		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
>  			printf("Bad MAC address format on line %d\n", i+1);
>  			fclose(config_file);
>  			return -1;
> @@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
>  			}
>  			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
>  				char *port_end;
> -				uint8_t c, peer_addr[6];
> 
>  				errno = 0;
>  				n = strtoul(optarg, &port_end, 10); @@ -
> 739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
>  						 "eth-peer: port %d >=
> RTE_MAX_ETHPORTS(%d)\n",
>  						 n, RTE_MAX_ETHPORTS);
> 
> -				if (cmdline_parse_etheraddr(NULL,
> port_end,
> -						&peer_addr,
> sizeof(peer_addr)) < 0)
> +				if (rte_ether_unformat_addr(port_end,
> +
> &peer_eth_addrs[n]) < 0)
>  					rte_exit(EXIT_FAILURE,
>  						 "Invalid ethernet address:
> %s\n",
>  						 port_end);
> -				for (c = 0; c < 6; c++)
> -					peer_eth_addrs[n].addr_bytes[c] =
> -						peer_addr[c];
>  				nb_peer_eth_addrs++;
>  			}
>  #endif
> --
> 2.20.1

./devtools/check-git-log.sh -1
Wrong headline format:
        app/testpmd: use rte_ether_unformat_addr

Does not like the "_" in the commit message.
This also affects four of the other patches in the set.


/devtools/checkpatches.sh  v4-8-8-app-testpmd-use-rte_ether_unformat_addr.patch

WARNING:LONG_LINE: line over 80 characters
#125: FILE: app/test-pmd/parameters.c:737:
+                                                           &peer_eth_addrs[n]) < 0)

total: 0 errors, 1 warnings, 88 lines checked

Long line should probably be fixed.

Regards,

Bernard

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

* Re: [dpdk-dev] [PATCH v4 8/8] app/testpmd: use rte_ether_unformat_addr
  2019-06-20 14:18     ` Iremonger, Bernard
@ 2019-06-20 16:12       ` Stephen Hemminger
  0 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-20 16:12 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: dev

On Thu, 20 Jun 2019 14:18:18 +0000
"Iremonger, Bernard" <bernard.iremonger@intel.com> wrote:

> Hi Stephen,
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen
> > Hemminger
> > Sent: Wednesday, June 5, 2019 7:10 PM
> > To: dev@dpdk.org
> > Cc: Stephen Hemminger <stephen@networkplumber.org>
> > Subject: [dpdk-dev] [PATCH v4 8/8] app/testpmd: use
> > rte_ether_unformat_addr
> > 
> > The cmdline_parse_ether_addr does not need to be used everywhere in
> > testpmd. Can use rte_ether_unformat_addr instead.
> > As an added bonus it eliminates some code for copying.
> > 
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > ---
> >  app/test-pmd/cmdline_flow.c |  5 ++---
> >  app/test-pmd/config.c       | 10 +++-------
> >  app/test-pmd/parameters.c   | 15 +++------------
> >  3 files changed, 8 insertions(+), 22 deletions(-)
> > 
> > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> > index 201bd9de56e0..2b02ca29b7ac 100644
> > --- a/app/test-pmd/cmdline_flow.c
> > +++ b/app/test-pmd/cmdline_flow.c
> > @@ -18,7 +18,6 @@
> >  #include <rte_ethdev.h>
> >  #include <rte_byteorder.h>
> >  #include <cmdline_parse.h>
> > -#include <cmdline_parse_etheraddr.h>
> >  #include <rte_flow.h>
> > 
> >  #include "testpmd.h"
> > @@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct
> > token *token,
> >  	/* Only network endian is supported. */
> >  	if (!arg->hton)
> >  		goto error;
> > -	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
> > -	if (ret < 0 || (unsigned int)ret != len)
> > +	ret = rte_ether_unformat_addr(str, &tmp);
> > +	if (ret < 0)
> >  		goto error;
> >  	if (!ctx->object)
> >  		return len;
> > diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> > ab458c8d2837..1d804705d96c 100644
> > --- a/app/test-pmd/config.c
> > +++ b/app/test-pmd/config.c
> > @@ -49,7 +49,6 @@
> >  #include <rte_pmd_bnxt.h>
> >  #endif
> >  #include <rte_gro.h>
> > -#include <cmdline_parse_etheraddr.h>
> >  #include <rte_config.h>
> > 
> >  #include "testpmd.h"
> > @@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
> > void  set_fwd_eth_peer(portid_t port_id, char *peer_addr)  {
> > -	uint8_t c, new_peer_addr[6];
> > +	struct rte_ether_addr new_peer_addr;
> >  	if (!rte_eth_dev_is_valid_port(port_id)) {
> >  		printf("Error: Invalid port number %i\n", port_id);
> >  		return;
> >  	}
> > -	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
> > -					sizeof(new_peer_addr)) < 0) {
> > +	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
> >  		printf("Error: Invalid ethernet address: %s\n", peer_addr);
> >  		return;
> >  	}
> > -	for (c = 0; c < 6; c++)
> > -		peer_eth_addrs[port_id].addr_bytes[c] =
> > -			new_peer_addr[c];
> > +	peer_eth_addrs[port_id] = new_peer_addr;
> >  }
> > 
> >  int
> > diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index
> > 245b610641ee..975a97807009 100644
> > --- a/app/test-pmd/parameters.c
> > +++ b/app/test-pmd/parameters.c
> > @@ -39,10 +39,6 @@
> >  #include <rte_ether.h>
> >  #include <rte_ethdev.h>
> >  #include <rte_string_fns.h>
> > -#ifdef RTE_LIBRTE_CMDLINE
> > -#include <cmdline_parse.h>
> > -#include <cmdline_parse_etheraddr.h>
> > -#endif
> >  #ifdef RTE_LIBRTE_PMD_BOND
> >  #include <rte_eth_bond.h>
> >  #endif
> > @@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
> >  		if (fgets(buf, sizeof(buf), config_file) == NULL)
> >  			break;
> > 
> > -		if (cmdline_parse_etheraddr(NULL, buf,
> > &peer_eth_addrs[i],
> > -				sizeof(peer_eth_addrs[i])) < 0) {
> > +		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
> >  			printf("Bad MAC address format on line %d\n", i+1);
> >  			fclose(config_file);
> >  			return -1;
> > @@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
> >  			}
> >  			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
> >  				char *port_end;
> > -				uint8_t c, peer_addr[6];
> > 
> >  				errno = 0;
> >  				n = strtoul(optarg, &port_end, 10); @@ -
> > 739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
> >  						 "eth-peer: port %d >=
> > RTE_MAX_ETHPORTS(%d)\n",
> >  						 n, RTE_MAX_ETHPORTS);
> > 
> > -				if (cmdline_parse_etheraddr(NULL,
> > port_end,
> > -						&peer_addr,
> > sizeof(peer_addr)) < 0)
> > +				if (rte_ether_unformat_addr(port_end,
> > +
> > &peer_eth_addrs[n]) < 0)
> >  					rte_exit(EXIT_FAILURE,
> >  						 "Invalid ethernet address:
> > %s\n",
> >  						 port_end);
> > -				for (c = 0; c < 6; c++)
> > -					peer_eth_addrs[n].addr_bytes[c] =
> > -						peer_addr[c];
> >  				nb_peer_eth_addrs++;
> >  			}
> >  #endif
> > --
> > 2.20.1  
> 
> ./devtools/check-git-log.sh -1
> Wrong headline format:
>         app/testpmd: use rte_ether_unformat_addr
> 
> Does not like the "_" in the commit message.
> This also affects four of the other patches in the set.

The tool is broken, not the patch.
This is not a restriction in other projects.

> /devtools/checkpatches.sh  v4-8-8-app-testpmd-use-rte_ether_unformat_addr.patch
> 
> WARNING:LONG_LINE: line over 80 characters
> #125: FILE: app/test-pmd/parameters.c:737:
> +                                                           &peer_eth_addrs[n]) < 0)
> 
> total: 0 errors, 1 warnings, 88 lines checked
> 
> Long line should probably be fixed.

The pre-existing code had a long line already.

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

* [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (8 preceding siblings ...)
  2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
@ 2019-06-24 20:44 ` Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
                     ` (7 more replies)
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                   ` (3 subsequent siblings)
  13 siblings, 8 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of patches around the ethernet address
manipulation routines in librte_net/rte_ether.

v5
   reword commit messages to workaround check-log complaints
v4
   fix meson build
   reword commit messages
   add bonding and tespmd patches
v3 
   rebase to use rte_ether prefix
   drop aligning ethernet headers for now.

Bruce Richardson (1):
  net/ether: mark ethernet addresses as being 2-byte aligned

Stephen Hemminger (7):
  net/rte_ether: deinline non-critical functions
  net/ether: add function to convert string to ethernet address
  ethdev: use new ethernet parsing function
  net/ether: use bitops to speedup comparison
  cmdline: use new ethernet address parser
  net/bonding: use new ethernet address parser
  app/testpmd: use new ethernet address parser

 app/test-pmd/cmdline_flow.c                  |  5 +-
 app/test-pmd/config.c                        | 10 +--
 app/test-pmd/parameters.c                    | 15 +---
 drivers/net/bonding/Makefile                 |  2 +-
 drivers/net/bonding/meson.build              |  2 +-
 drivers/net/bonding/rte_eth_bond_args.c      |  6 +-
 lib/Makefile                                 |  3 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++---------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/librte_ethdev/Makefile                   |  2 +-
 lib/librte_ethdev/meson.build                |  2 +-
 lib/librte_ethdev/rte_class_eth.c            |  9 +--
 lib/librte_net/Makefile                      |  1 +
 lib/librte_net/meson.build                   |  2 +-
 lib/librte_net/rte_ether.c                   | 76 ++++++++++++++++++++
 lib/librte_net/rte_ether.h                   | 59 +++++++--------
 lib/librte_net/rte_net_version.map           |  8 +++
 lib/meson.build                              |  2 +-
 19 files changed, 142 insertions(+), 142 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

-- 
2.20.1


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

* [dpdk-dev] [PATCH v5 1/8] net/rte_ether: deinline non-critical functions
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
@ 2019-06-24 20:44   ` Stephen Hemminger
  2019-07-02  7:56     ` Olivier Matz
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 2/8] net/ether: add function to convert string to ethernet address Stephen Hemminger
                     ` (6 subsequent siblings)
  7 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Rami Rosen, Andrew Rybchenko

Formatting Ethernet address and getting a random value are
not in critical path so they should not be inlined.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Rami Rosen <ramirose@gmail.com>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/Makefile            |  1 +
 lib/librte_net/meson.build         |  2 +-
 lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 25 ++++---------------------
 lib/librte_net/rte_net_version.map |  7 +++++++
 5 files changed, 42 insertions(+), 22 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index c3082069ab50..1244c9fd54c9 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -14,6 +14,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
+SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 
 # install includes
diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build
index 7d66f693cbf3..868a93fd6b6b 100644
--- a/lib/librte_net/meson.build
+++ b/lib/librte_net/meson.build
@@ -16,5 +16,5 @@ headers = files('rte_ip.h',
 	'rte_net_crc.h',
 	'rte_mpls.h')
 
-sources = files('rte_arp.c', 'rte_net.c', 'rte_net_crc.c')
+sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c')
 deps += ['mbuf']
diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
new file mode 100644
index 000000000000..974fe815b335
--- /dev/null
+++ b/lib/librte_net/rte_ether.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_ether.h>
+
+void
+rte_eth_random_addr(uint8_t *addr)
+{
+	uint64_t rand = rte_rand();
+	uint8_t *p = (uint8_t *)&rand;
+
+	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
+	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;	/* clear multicast bit */
+	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
+}
+
+void
+rte_ether_format_addr(char *buf, uint16_t size,
+		      const struct rte_ether_addr *eth_addr)
+{
+	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
+		 eth_addr->addr_bytes[0],
+		 eth_addr->addr_bytes[1],
+		 eth_addr->addr_bytes[2],
+		 eth_addr->addr_bytes[3],
+		 eth_addr->addr_bytes[4],
+		 eth_addr->addr_bytes[5]);
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 7be9b4890af7..3caae0d98f6d 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -207,15 +207,8 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *
  * @param addr
  *   A pointer to Ethernet address.
  */
-static inline void rte_eth_random_addr(uint8_t *addr)
-{
-	uint64_t rand = rte_rand();
-	uint8_t *p = (uint8_t *)&rand;
-
-	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
-	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;  /* clear multicast bit */
-	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
-}
+void
+rte_eth_random_addr(uint8_t *addr);
 
 /**
  * Fast copy an Ethernet address.
@@ -254,19 +247,9 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
  * @param eth_addr
  *   A pointer to a ether_addr structure.
  */
-static inline void
+void
 rte_ether_format_addr(char *buf, uint16_t size,
-		  const struct rte_ether_addr *eth_addr)
-{
-	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 eth_addr->addr_bytes[0],
-		 eth_addr->addr_bytes[1],
-		 eth_addr->addr_bytes[2],
-		 eth_addr->addr_bytes[3],
-		 eth_addr->addr_bytes[4],
-		 eth_addr->addr_bytes[5]);
-}
-
+		      const struct rte_ether_addr *eth_addr);
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 26c06e7c7ae7..f1e1b84ab491 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -13,6 +13,13 @@ DPDK_17.05 {
 
 } DPDK_16.11;
 
+DPDK_19.08 {
+	global:
+
+	rte_eth_random_addr;
+	rte_ether_format_addr;
+} DPDK_17.05;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.20.1


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

* [dpdk-dev] [PATCH v5 2/8] net/ether: add function to convert string to ethernet address
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-06-24 20:44   ` Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 3/8] ethdev: use new ethernet parsing function Stephen Hemminger
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Make a function that can be used in place of eth_aton_r
to convert a string to rte_ether_addr. This function
allows both byte (xx:xx:xx:xx:xx:xx) and word (XXXX:XXXX:XXXX)
format and has the same lack of error handling as the original.

This also allows ethdev to no longer have a hard dependency
on the cmdline library.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 14 +++++++++
 lib/librte_net/rte_net_version.map |  1 +
 3 files changed, 62 insertions(+)

diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
index 974fe815b335..acc8a0e938c5 100644
--- a/lib/librte_net/rte_ether.c
+++ b/lib/librte_net/rte_ether.c
@@ -27,3 +27,50 @@ rte_ether_format_addr(char *buf, uint16_t size,
 		 eth_addr->addr_bytes[4],
 		 eth_addr->addr_bytes[5]);
 }
+
+/*
+ * Like ether_aton_r but can handle either
+ * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
+ */
+int
+rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
+{
+	unsigned int o0, o1, o2, o3, o4, o5;
+	int n;
+
+	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
+		    &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (n == 6) {
+		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
+		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0;
+		ea->addr_bytes[1] = o1;
+		ea->addr_bytes[2] = o2;
+		ea->addr_bytes[3] = o3;
+		ea->addr_bytes[4] = o4;
+		ea->addr_bytes[5] = o5;
+
+		return 0;
+	}
+
+	/* Support the format XXXX:XXXX:XXXX */
+	n = sscanf(s, "%x:%x:%x", &o0, &o1, &o2);
+	if (n == 3) {
+		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0 >> 8;
+		ea->addr_bytes[1] = o0 & 0xff;
+		ea->addr_bytes[2] = o1 >> 8;
+		ea->addr_bytes[3] = o1 & 0xff;
+		ea->addr_bytes[4] = o2 >> 8;
+		ea->addr_bytes[5] = o2 & 0xff;
+		return 0;
+	}
+	/* unknown format */
+
+	return -1;
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 3caae0d98f6d..8edc7e217b25 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -250,6 +250,20 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
 void
 rte_ether_format_addr(char *buf, uint16_t size,
 		      const struct rte_ether_addr *eth_addr);
+/**
+ * Convert string with Ethernet address to an ether_addr.
+ *
+ * @param str
+ *   A pointer to buffer contains the formatted MAC address.
+ * @param eth_addr
+ *   A pointer to a ether_addr structure.
+ * @return
+ *   0 if successful
+ *   -1 and sets rte_errno if invalid string
+ */
+int __rte_experimental
+rte_ether_unformat_addr(const char *str, struct rte_ether_addr *eth_addr);
+
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index f1e1b84ab491..f4c915069d57 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -25,4 +25,5 @@ EXPERIMENTAL {
 
 	rte_net_make_rarp_packet;
 	rte_net_skip_ip6_ext;
+	rte_ether_unformat_addr;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v5 3/8] ethdev: use new ethernet parsing function
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 2/8] net/ether: add function to convert string to ethernet address Stephen Hemminger
@ 2019-06-24 20:44   ` Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_eth_unformat_addr, so that ethdev can be built and work
without the cmdline library. The dependency on cmdline was
an arrangement of convenience anyway.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                      | 1 -
 lib/librte_ethdev/Makefile        | 2 +-
 lib/librte_ethdev/meson.build     | 2 +-
 lib/librte_ethdev/rte_class_eth.c | 9 +--------
 4 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 791e0d9911d6..82b2c4bfa8ea 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
 DEPDIRS-librte_ethdev += librte_kvargs
-DEPDIRS-librte_ethdev += librte_cmdline
 DEPDIRS-librte_ethdev += librte_meter
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 8d4a02630c4f..60bcc2227878 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_cmdline -lrte_meter
+LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_meter
 
 EXPORT_MAP := rte_ethdev_version.map
 
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 8d6165b2a7dd..f75d428c96d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -26,4 +26,4 @@ headers = files('rte_ethdev.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
 
-deps += ['net', 'kvargs', 'cmdline', 'meter']
+deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 873a653532ad..6338355e2557 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -4,7 +4,6 @@
 
 #include <string.h>
 
-#include <cmdline_parse_etheraddr.h>
 #include <rte_class.h>
 #include <rte_compat.h>
 #include <rte_errno.h>
@@ -43,19 +42,13 @@ static int
 eth_mac_cmp(const char *key __rte_unused,
 		const char *value, void *opaque)
 {
-	int ret;
 	struct rte_ether_addr mac;
 	const struct rte_eth_dev_data *data = opaque;
 	struct rte_eth_dev_info dev_info;
 	uint32_t index;
 
 	/* Parse devargs MAC address. */
-	/*
-	 * cannot use ether_aton_r(value, &mac)
-	 * because of include conflict with rte_ether.h
-	 */
-	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
-	if (ret < 0)
+	if (rte_ether_unformat_addr(value, &mac) < 0)
 		return -1; /* invalid devargs value */
 
 	/* Return 0 if devargs MAC is matching one of the device MACs. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v5 4/8] net/ether: use bitops to speedup comparison
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (2 preceding siblings ...)
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 3/8] ethdev: use new ethernet parsing function Stephen Hemminger
@ 2019-06-24 20:44   ` Stephen Hemminger
  2019-07-02  7:53     ` Olivier Matz
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
                     ` (3 subsequent siblings)
  7 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 8edc7e217b25..feb35a33c94b 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -81,11 +81,10 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
+	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+
+	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea->addr_bytes[i] != 0x00)
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w = (const uint16_t *)ea;
+
+	return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**
-- 
2.20.1


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

* [dpdk-dev] [PATCH v5 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (3 preceding siblings ...)
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-06-24 20:44   ` Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 6/8] cmdline: use new ethernet address parser Stephen Hemminger
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Stephen Hemminger, Andrew Rybchenko

From: Bruce Richardson <bruce.richardson@intel.com>

When including the rte_ether.h header in applications with warnings
enabled, a warning was given because of the assumption of 2-byte alignment
of ethernet addresses when processing them.

.../include/rte_ether.h:149:2: warning: converting a packed ‘const
  struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
  {aka ‘const short unsigned int’} pointer (alignment 2) may result in
  an unaligned pointer value [-Waddress-of-packed-member]
149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
    |  ^~~~~

Since ethernet addresses should always be aligned on a two-byte boundary,
we can just inform the compiler of this assumption to remove the warnings
and allow us to always access the addresses using 16-bit operations.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index feb35a33c94b..d7b76ddf63eb 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -58,7 +58,8 @@ extern "C" {
  * See http://standards.ieee.org/regauth/groupmac/tutorial.html
  */
 struct rte_ether_addr {
-	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
+	/**< Addr bytes in tx order */
 } __attribute__((__packed__));
 
 #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
@@ -81,8 +82,8 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
-	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+	const uint16_t *w1 = (const uint16_t *)ea1;
+	const uint16_t *w2 = (const uint16_t *)ea2;
 
 	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
@@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *w = (const uint16_t *)ea;
+	const uint16_t *w = (const uint16_t *)ea;
 
 	return (w[0] | w[1] | w[2]) == 0;
 }
@@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
  */
 static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
+	const uint16_t *ea_words = (const uint16_t *)ea;
 
 	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
 		ea_words[2] == 0xFFFF);
-- 
2.20.1


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

* [dpdk-dev] [PATCH v5 6/8] cmdline: use new ethernet address parser
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (4 preceding siblings ...)
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-06-24 20:44   ` Stephen Hemminger
       [not found]     ` <8688172CD5C0B74590FAE19D9579F94B53742875@SHSMSX103.ccr.corp.intel.com>
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 7/8] net/bonding: " Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 8/8] app/testpmd: " Stephen Hemminger
  7 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Now that there is a version of ether_aton in rte_ether, it can
be used by the cmdline ethernet address parser.

Note: ether_aton_r can not be used in cmdline because
the old code would accept either bytes XX:XX:XX:XX:XX:XX
or words XXXX:XXXX:XXXX and we need to keep compatiablity.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                                 |  2 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++-----------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/meson.build                              |  2 +-
 5 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 82b2c4bfa8ea..cc36fe7591f0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,7 +20,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
-DEPDIRS-librte_cmdline := librte_eal
+DEPDIRS-librte_cmdline := librte_eal librte_net
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index c64142b8d5a0..04057d7c671f 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cmdline.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_cmdline_version.map
 
@@ -25,7 +26,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_net -lrte_eal
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_parse_etheraddr.c b/lib/librte_cmdline/cmdline_parse_etheraddr.c
index 24e04755cd9e..2cb8dd2a1267 100644
--- a/lib/librte_cmdline/cmdline_parse_etheraddr.c
+++ b/lib/librte_cmdline/cmdline_parse_etheraddr.c
@@ -12,9 +12,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
 
 #include <rte_string_fns.h>
+#include <rte_ether.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -26,69 +26,15 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 	.get_help = cmdline_get_help_etheraddr,
 };
 
-/* the format can be either XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX */
-#define ETHER_ADDRSTRLENLONG 18
-#define ETHER_ADDRSTRLENSHORT 15
-
-#ifdef __linux__
-#define ea_oct ether_addr_octet
-#else
-#define ea_oct octet
-#endif
-
-
-static struct ether_addr *
-my_ether_aton(const char *a)
-{
-	int i;
-	char *end;
-	unsigned long o[ETHER_ADDR_LEN];
-	static struct ether_addr ether_addr;
-
-	i = 0;
-	do {
-		errno = 0;
-		o[i] = strtoul(a, &end, 16);
-		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
-			return NULL;
-		a = end + 1;
-	} while (++i != sizeof (o) / sizeof (o[0]) && end[0] != 0);
-
-	/* Junk at the end of line */
-	if (end[0] != 0)
-		return NULL;
-
-	/* Support the format XX:XX:XX:XX:XX:XX */
-	if (i == ETHER_ADDR_LEN) {
-		while (i-- != 0) {
-			if (o[i] > UINT8_MAX)
-				return NULL;
-			ether_addr.ea_oct[i] = (uint8_t)o[i];
-		}
-	/* Support the format XXXX:XXXX:XXXX */
-	} else if (i == ETHER_ADDR_LEN / 2) {
-		while (i-- != 0) {
-			if (o[i] > UINT16_MAX)
-				return NULL;
-			ether_addr.ea_oct[i * 2] = (uint8_t)(o[i] >> 8);
-			ether_addr.ea_oct[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
-		}
-	/* unknown format */
-	} else
-		return NULL;
-
-	return (struct ether_addr *)&ether_addr;
-}
-
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 	const char *buf, void *res, unsigned ressize)
 {
 	unsigned int token_len = 0;
-	char ether_str[ETHER_ADDRSTRLENLONG+1];
-	struct ether_addr *tmp;
+	char ether_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr tmp;
 
-	if (res && ressize < sizeof(struct ether_addr))
+	if (res && ressize < sizeof(tmp))
 		return -1;
 
 	if (!buf || ! *buf)
@@ -98,17 +44,16 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 		token_len++;
 
 	/* if token doesn't match possible string lengths... */
-	if ((token_len != ETHER_ADDRSTRLENLONG - 1) &&
-			(token_len != ETHER_ADDRSTRLENSHORT - 1))
+	if (token_len >= RTE_ETHER_ADDR_FMT_SIZE)
 		return -1;
 
 	strlcpy(ether_str, buf, token_len + 1);
 
-	tmp = my_ether_aton(ether_str);
-	if (tmp == NULL)
+	if (rte_ether_unformat_addr(ether_str, &tmp) < 0)
 		return -1;
+
 	if (res)
-		memcpy(res, tmp, sizeof(struct ether_addr));
+		memcpy(res, &tmp, sizeof(tmp));
 	return token_len;
 }
 
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 0fa61385fccf..07334c1b0956 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -1,10 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
-# This library is processed before EAL
-includes = [global_inc]
-
 version = 2
+allow_experimental_apis = true
 sources = files('cmdline.c',
 	'cmdline_cirbuf.c',
 	'cmdline_parse.c',
@@ -28,3 +26,5 @@ headers = files('cmdline.h',
 	'cmdline_socket.h',
 	'cmdline_cirbuf.h',
 	'cmdline_parse_portlist.h')
+
+deps += ['net']
diff --git a/lib/meson.build b/lib/meson.build
index 992091a9407e..5c892404e706 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -11,8 +11,8 @@
 libraries = [
 	'kvargs', # eal depends on kvargs
 	'eal', # everything depends on eal
-	'cmdline', # ethdev depends on cmdline for parsing functions
 	'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
+	'cmdline',
 	'metrics', # bitrate/latency stats depends on this
 	'hash',    # efd depends on this
 	'timer',   # eventdev depends on this
-- 
2.20.1


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

* [dpdk-dev] [PATCH v5 7/8] net/bonding: use new ethernet address parser
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (5 preceding siblings ...)
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 6/8] cmdline: use new ethernet address parser Stephen Hemminger
@ 2019-06-24 20:44   ` Stephen Hemminger
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 8/8] app/testpmd: " Stephen Hemminger
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline library used to be the only way to parse a
mac address. Now there is rte_ether_unformat_addr.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bonding/Makefile            | 2 +-
 drivers/net/bonding/meson.build         | 2 +-
 drivers/net/bonding/rte_eth_bond_args.c | 6 +-----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 1893e3cad313..26c1782554cd 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
-LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_pci -lrte_bus_pci
 LDLIBS += -lrte_bus_vdev
 
diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build
index 00374edb2a9d..6267210adf5f 100644
--- a/drivers/net/bonding/meson.build
+++ b/drivers/net/bonding/meson.build
@@ -8,6 +8,6 @@ sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', 'rte_eth_bond_flow.c
 	'rte_eth_bond_args.c', 'rte_eth_bond_8023ad.c', 'rte_eth_bond_alb.c')
 
 deps += 'sched' # needed for rte_bitmap.h
-deps += ['ip_frag', 'cmdline']
+deps += ['ip_frag']
 
 install_headers('rte_eth_bond.h', 'rte_eth_bond_8023ad.h')
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index 01bbb06c1a84..936440fb8491 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -7,9 +7,6 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
 #include "rte_eth_bond.h"
 #include "rte_eth_bond_private.h"
 
@@ -281,8 +278,7 @@ bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
 		return -1;
 
 	/* Parse MAC */
-	return cmdline_parse_etheraddr(NULL, value, extra_args,
-		sizeof(struct rte_ether_addr));
+	return rte_ether_unformat_addr(value, extra_args);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v5 8/8] app/testpmd: use new ethernet address parser
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (6 preceding siblings ...)
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 7/8] net/bonding: " Stephen Hemminger
@ 2019-06-24 20:44   ` Stephen Hemminger
  7 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-06-24 20:44 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline_parse_ether_addr does not need to be used everywhere
in testpmd. Can use rte_ether_unformat_addr instead.
As an added bonus it eliminates some code for copying.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline_flow.c |  5 ++---
 app/test-pmd/config.c       | 10 +++-------
 app/test-pmd/parameters.c   | 15 +++------------
 3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 201bd9de56e0..2b02ca29b7ac 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -18,7 +18,6 @@
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_flow.h>
 
 #include "testpmd.h"
@@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct token *token,
 	/* Only network endian is supported. */
 	if (!arg->hton)
 		goto error;
-	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
-	if (ret < 0 || (unsigned int)ret != len)
+	ret = rte_ether_unformat_addr(str, &tmp);
+	if (ret < 0)
 		goto error;
 	if (!ctx->object)
 		return len;
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index ab458c8d2837..1d804705d96c 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -49,7 +49,6 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include <rte_gro.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_config.h>
 
 #include "testpmd.h"
@@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 void
 set_fwd_eth_peer(portid_t port_id, char *peer_addr)
 {
-	uint8_t c, new_peer_addr[6];
+	struct rte_ether_addr new_peer_addr;
 	if (!rte_eth_dev_is_valid_port(port_id)) {
 		printf("Error: Invalid port number %i\n", port_id);
 		return;
 	}
-	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
-					sizeof(new_peer_addr)) < 0) {
+	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
 		printf("Error: Invalid ethernet address: %s\n", peer_addr);
 		return;
 	}
-	for (c = 0; c < 6; c++)
-		peer_eth_addrs[port_id].addr_bytes[c] =
-			new_peer_addr[c];
+	peer_eth_addrs[port_id] = new_peer_addr;
 }
 
 int
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 245b610641ee..975a97807009 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -39,10 +39,6 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_CMDLINE
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-#endif
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
@@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
 		if (fgets(buf, sizeof(buf), config_file) == NULL)
 			break;
 
-		if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i],
-				sizeof(peer_eth_addrs[i])) < 0) {
+		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
 			printf("Bad MAC address format on line %d\n", i+1);
 			fclose(config_file);
 			return -1;
@@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
 			}
 			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
 				char *port_end;
-				uint8_t c, peer_addr[6];
 
 				errno = 0;
 				n = strtoul(optarg, &port_end, 10);
@@ -739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
 						 "eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
 						 n, RTE_MAX_ETHPORTS);
 
-				if (cmdline_parse_etheraddr(NULL, port_end,
-						&peer_addr, sizeof(peer_addr)) < 0)
+				if (rte_ether_unformat_addr(port_end,
+							    &peer_eth_addrs[n]) < 0)
 					rte_exit(EXIT_FAILURE,
 						 "Invalid ethernet address: %s\n",
 						 port_end);
-				for (c = 0; c < 6; c++)
-					peer_eth_addrs[n].addr_bytes[c] =
-						peer_addr[c];
 				nb_peer_eth_addrs++;
 			}
 #endif
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v5 4/8] net/ether: use bitops to speedup comparison
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-07-02  7:53     ` Olivier Matz
  2019-07-02  9:26       ` Olivier Matz
  0 siblings, 1 reply; 127+ messages in thread
From: Olivier Matz @ 2019-07-02  7:53 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Andrew Rybchenko

Hi,

On Mon, Jun 24, 2019 at 01:44:31PM -0700, Stephen Hemminger wrote:
> Using bit operations like or and xor is faster than a loop
> on all architectures. Really just explicit unrolling.
> 
> Similar cast to uint16 unaligned is already done in
> other functions here.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>  lib/librte_net/rte_ether.h | 17 +++++++----------
>  1 file changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index 8edc7e217b25..feb35a33c94b 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -81,11 +81,10 @@ struct rte_ether_addr {
>  static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
>  				     const struct rte_ether_addr *ea2)
>  {
> -	int i;
> -	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
> -		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
> -			return 0;
> -	return 1;
> +	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
> +	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
> +
> +	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
>  }
>  
>  /**
> @@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
>   */
>  static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
>  {
> -	int i;
> -	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
> -		if (ea->addr_bytes[i] != 0x00)
> -			return 0;
> -	return 1;
> +	const unaligned_uint16_t *w = (const uint16_t *)ea;
> +
> +	return (w[0] | w[1] | w[2]) == 0;
>  }
>  
>  /**

I wonder if using memcmp() isn't faster with recent compilers (gcc >= 7).
I tried it quickly, and it seems the generated code is good (no call):
https://godbolt.org/z/9MOL7g

It would avoid the use of unaligned_uint16_t, and the next patch that
adds the alignment constraint.

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

* Re: [dpdk-dev] [PATCH v5 1/8] net/rte_ether: deinline non-critical functions
  2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-07-02  7:56     ` Olivier Matz
  0 siblings, 0 replies; 127+ messages in thread
From: Olivier Matz @ 2019-07-02  7:56 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Rami Rosen, Andrew Rybchenko

Hi Stephen,

On Mon, Jun 24, 2019 at 01:44:28PM -0700, Stephen Hemminger wrote:
> Formatting Ethernet address and getting a random value are
> not in critical path so they should not be inlined.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Acked-by: Rami Rosen <ramirose@gmail.com>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>  lib/librte_net/Makefile            |  1 +
>  lib/librte_net/meson.build         |  2 +-
>  lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
>  lib/librte_net/rte_ether.h         | 25 ++++---------------------
>  lib/librte_net/rte_net_version.map |  7 +++++++
>  5 files changed, 42 insertions(+), 22 deletions(-)
>  create mode 100644 lib/librte_net/rte_ether.c
> 
> diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
> index c3082069ab50..1244c9fd54c9 100644
> --- a/lib/librte_net/Makefile
> +++ b/lib/librte_net/Makefile
> @@ -14,6 +14,7 @@ LIBABIVER := 1
>  
>  SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
>  SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
> +SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
>  SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
>  
>  # install includes
> diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build
> index 7d66f693cbf3..868a93fd6b6b 100644
> --- a/lib/librte_net/meson.build
> +++ b/lib/librte_net/meson.build
> @@ -16,5 +16,5 @@ headers = files('rte_ip.h',
>  	'rte_net_crc.h',
>  	'rte_mpls.h')
>  
> -sources = files('rte_arp.c', 'rte_net.c', 'rte_net_crc.c')
> +sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c')
>  deps += ['mbuf']
> diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
> new file mode 100644
> index 000000000000..974fe815b335
> --- /dev/null
> +++ b/lib/librte_net/rte_ether.c
> @@ -0,0 +1,29 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2010-2014 Intel Corporation
> + */
> +
> +#include <rte_ether.h>
> +
> +void
> +rte_eth_random_addr(uint8_t *addr)
> +{
> +	uint64_t rand = rte_rand();
> +	uint8_t *p = (uint8_t *)&rand;
> +
> +	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
> +	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;	/* clear multicast bit */
> +	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
> +}
> +
> +void
> +rte_ether_format_addr(char *buf, uint16_t size,
> +		      const struct rte_ether_addr *eth_addr)
> +{
> +	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
> +		 eth_addr->addr_bytes[0],
> +		 eth_addr->addr_bytes[1],
> +		 eth_addr->addr_bytes[2],
> +		 eth_addr->addr_bytes[3],
> +		 eth_addr->addr_bytes[4],
> +		 eth_addr->addr_bytes[5]);
> +}
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index 7be9b4890af7..3caae0d98f6d 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -207,15 +207,8 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *
>   * @param addr
>   *   A pointer to Ethernet address.
>   */
> -static inline void rte_eth_random_addr(uint8_t *addr)
> -{
> -	uint64_t rand = rte_rand();
> -	uint8_t *p = (uint8_t *)&rand;
> -
> -	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
> -	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;  /* clear multicast bit */
> -	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
> -}
> +void
> +rte_eth_random_addr(uint8_t *addr);
>  
>  /**
>   * Fast copy an Ethernet address.
> @@ -254,19 +247,9 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
>   * @param eth_addr
>   *   A pointer to a ether_addr structure.
>   */
> -static inline void
> +void
>  rte_ether_format_addr(char *buf, uint16_t size,
> -		  const struct rte_ether_addr *eth_addr)
> -{
> -	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
> -		 eth_addr->addr_bytes[0],
> -		 eth_addr->addr_bytes[1],
> -		 eth_addr->addr_bytes[2],
> -		 eth_addr->addr_bytes[3],
> -		 eth_addr->addr_bytes[4],
> -		 eth_addr->addr_bytes[5]);
> -}
> -
> +		      const struct rte_ether_addr *eth_addr);
>  /**
>   * Ethernet header: Contains the destination address, source address
>   * and frame type.
> diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
> index 26c06e7c7ae7..f1e1b84ab491 100644
> --- a/lib/librte_net/rte_net_version.map
> +++ b/lib/librte_net/rte_net_version.map
> @@ -13,6 +13,13 @@ DPDK_17.05 {
>  
>  } DPDK_16.11;
>  
> +DPDK_19.08 {
> +	global:
> +
> +	rte_eth_random_addr;
> +	rte_ether_format_addr;
> +} DPDK_17.05;
> +
>  EXPERIMENTAL {
>  	global:
>  
> -- 
> 2.20.1
> 

In drivers/net/memif and drivers/net/axgbe, rte_ether_format_addr() is
used, but -lrte_net is not passed to LDLIBS in the Makefile. This was
probably ok before because it was an inline function, but I wonder if
it shouldn't be added in this patch.

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

* Re: [dpdk-dev] [PATCH v5 4/8] net/ether: use bitops to speedup comparison
  2019-07-02  7:53     ` Olivier Matz
@ 2019-07-02  9:26       ` Olivier Matz
  2019-07-02 15:28         ` Stephen Hemminger
  0 siblings, 1 reply; 127+ messages in thread
From: Olivier Matz @ 2019-07-02  9:26 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Andrew Rybchenko

On Tue, Jul 02, 2019 at 09:53:14AM +0200, Olivier Matz wrote:
> Hi,
> 
> On Mon, Jun 24, 2019 at 01:44:31PM -0700, Stephen Hemminger wrote:
> > Using bit operations like or and xor is faster than a loop
> > on all architectures. Really just explicit unrolling.
> > 
> > Similar cast to uint16 unaligned is already done in
> > other functions here.
> > 
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > ---
> >  lib/librte_net/rte_ether.h | 17 +++++++----------
> >  1 file changed, 7 insertions(+), 10 deletions(-)
> > 
> > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > index 8edc7e217b25..feb35a33c94b 100644
> > --- a/lib/librte_net/rte_ether.h
> > +++ b/lib/librte_net/rte_ether.h
> > @@ -81,11 +81,10 @@ struct rte_ether_addr {
> >  static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
> >  				     const struct rte_ether_addr *ea2)
> >  {
> > -	int i;
> > -	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
> > -		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
> > -			return 0;
> > -	return 1;
> > +	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
> > +	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
> > +
> > +	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
> >  }
> >  
> >  /**
> > @@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
> >   */
> >  static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
> >  {
> > -	int i;
> > -	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
> > -		if (ea->addr_bytes[i] != 0x00)
> > -			return 0;
> > -	return 1;
> > +	const unaligned_uint16_t *w = (const uint16_t *)ea;
> > +
> > +	return (w[0] | w[1] | w[2]) == 0;
> >  }
> >  
> >  /**
> 
> I wonder if using memcmp() isn't faster with recent compilers (gcc >= 7).
> I tried it quickly, and it seems the generated code is good (no call):
> https://godbolt.org/z/9MOL7g
> 
> It would avoid the use of unaligned_uint16_t, and the next patch that
> adds the alignment constraint.

As pointed out by Konstantin privately (I guess he wanted to do a
reply-all), the size of addr_bytes is wrong in my previous link (8
instead of 6). Thanks for catching it.

With 6, the gcc code is not as good: there is still no call to memcmp(),
but there are some jumps. With the latest clang, the generated code is
nice: https://godbolt.org/z/nfptnY

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

* Re: [dpdk-dev] [PATCH v5 4/8] net/ether: use bitops to speedup comparison
  2019-07-02  9:26       ` Olivier Matz
@ 2019-07-02 15:28         ` Stephen Hemminger
  0 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 15:28 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev, Andrew Rybchenko

On Tue, 2 Jul 2019 11:26:15 +0200
Olivier Matz <olivier.matz@6wind.com> wrote:

> On Tue, Jul 02, 2019 at 09:53:14AM +0200, Olivier Matz wrote:
> > Hi,
> > 
> > On Mon, Jun 24, 2019 at 01:44:31PM -0700, Stephen Hemminger wrote:  
> > > Using bit operations like or and xor is faster than a loop
> > > on all architectures. Really just explicit unrolling.
> > > 
> > > Similar cast to uint16 unaligned is already done in
> > > other functions here.
> > > 
> > > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > > ---
> > >  lib/librte_net/rte_ether.h | 17 +++++++----------
> > >  1 file changed, 7 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > > index 8edc7e217b25..feb35a33c94b 100644
> > > --- a/lib/librte_net/rte_ether.h
> > > +++ b/lib/librte_net/rte_ether.h
> > > @@ -81,11 +81,10 @@ struct rte_ether_addr {
> > >  static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
> > >  				     const struct rte_ether_addr *ea2)
> > >  {
> > > -	int i;
> > > -	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
> > > -		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
> > > -			return 0;
> > > -	return 1;
> > > +	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
> > > +	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
> > > +
> > > +	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
> > >  }
> > >  
> > >  /**
> > > @@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
> > >   */
> > >  static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
> > >  {
> > > -	int i;
> > > -	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
> > > -		if (ea->addr_bytes[i] != 0x00)
> > > -			return 0;
> > > -	return 1;
> > > +	const unaligned_uint16_t *w = (const uint16_t *)ea;
> > > +
> > > +	return (w[0] | w[1] | w[2]) == 0;
> > >  }
> > >  
> > >  /**  
> > 
> > I wonder if using memcmp() isn't faster with recent compilers (gcc >= 7).
> > I tried it quickly, and it seems the generated code is good (no call):
> > https://godbolt.org/z/9MOL7g
> > 
> > It would avoid the use of unaligned_uint16_t, and the next patch that
> > adds the alignment constraint.  
> 
> As pointed out by Konstantin privately (I guess he wanted to do a
> reply-all), the size of addr_bytes is wrong in my previous link (8
> instead of 6). Thanks for catching it.
> 
> With 6, the gcc code is not as good: there is still no call to memcmp(),
> but there are some jumps. With the latest clang, the generated code is
> nice: https://godbolt.org/z/nfptnY

gcc matters most for current DPDK users.

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

* [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (9 preceding siblings ...)
  2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
@ 2019-07-02 16:50 ` Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
                     ` (8 more replies)
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                   ` (2 subsequent siblings)
  13 siblings, 9 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of patches around the ethernet address
manipulation routines in librte_net/rte_ether.

v6
   add librte_net to axgbe and memif Makefile
v5
   reword commit messages to workaround check-log complaints
v4
   fix meson build
   reword commit messages
   add bonding and tespmd patches
v3 
   rebase to use rte_ether prefix
   drop aligning ethernet headers for now.

Bruce Richardson (1):
  net/ether: mark ethernet addresses as being 2-byte aligned

Stephen Hemminger (7):
  net/rte_ether: deinline non-critical functions
  net/ether: add function to convert string to ethernet address
  ethdev: use new ethernet parsing function
  net/ether: use bitops to speedup comparison
  cmdline: use new ethernet address parser
  net/bonding: use new ethernet address parser
  app/testpmd: use new ethernet address parser

 app/test-pmd/cmdline_flow.c                  |  5 +-
 app/test-pmd/config.c                        | 10 +--
 app/test-pmd/parameters.c                    | 15 +---
 drivers/net/axgbe/Makefile                   |  2 +-
 drivers/net/bonding/Makefile                 |  2 +-
 drivers/net/bonding/meson.build              |  2 +-
 drivers/net/bonding/rte_eth_bond_args.c      |  6 +-
 drivers/net/memif/Makefile                   |  2 +-
 lib/Makefile                                 |  3 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++---------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/librte_ethdev/Makefile                   |  2 +-
 lib/librte_ethdev/meson.build                |  2 +-
 lib/librte_ethdev/rte_class_eth.c            |  9 +--
 lib/librte_net/Makefile                      |  1 +
 lib/librte_net/meson.build                   |  2 +-
 lib/librte_net/rte_ether.c                   | 76 ++++++++++++++++++++
 lib/librte_net/rte_ether.h                   | 59 +++++++--------
 lib/librte_net/rte_net_version.map           |  8 +++
 lib/meson.build                              |  2 +-
 21 files changed, 144 insertions(+), 144 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

-- 
2.20.1


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

* [dpdk-dev] [PATCH v6 1/8] net/rte_ether: deinline non-critical functions
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
@ 2019-07-02 16:50   ` Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 2/8] net/ether: add function to convert string to ethernet address Stephen Hemminger
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Rami Rosen, Andrew Rybchenko

Formatting Ethernet address and getting a random value are
not in critical path so they should not be inlined.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Rami Rosen <ramirose@gmail.com>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/axgbe/Makefile         |  2 +-
 drivers/net/memif/Makefile         |  2 +-
 lib/librte_net/Makefile            |  1 +
 lib/librte_net/meson.build         |  2 +-
 lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 25 ++++---------------------
 lib/librte_net/rte_net_version.map |  7 +++++++
 7 files changed, 44 insertions(+), 24 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

diff --git a/drivers/net/axgbe/Makefile b/drivers/net/axgbe/Makefile
index 72215aedaf55..c2d4336800c0 100644
--- a/drivers/net/axgbe/Makefile
+++ b/drivers/net/axgbe/Makefile
@@ -17,7 +17,7 @@ LIBABIVER := 1
 
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_pci -lrte_bus_pci
-LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_ethdev -lrte_net
 
 #
 # all source are stored in SRCS-y
diff --git a/drivers/net/memif/Makefile b/drivers/net/memif/Makefile
index fdbdf3378019..3d92b08f259b 100644
--- a/drivers/net/memif/Makefile
+++ b/drivers/net/memif/Makefile
@@ -21,7 +21,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 # - rte_mp_reply
 # - rte_mp_request_sync
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
-LDLIBS += -lrte_ethdev -lrte_kvargs
+LDLIBS += -lrte_ethdev -lrte_kvargs -lrte_net
 LDLIBS += -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index c3082069ab50..1244c9fd54c9 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -14,6 +14,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
+SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 
 # install includes
diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build
index 7d66f693cbf3..868a93fd6b6b 100644
--- a/lib/librte_net/meson.build
+++ b/lib/librte_net/meson.build
@@ -16,5 +16,5 @@ headers = files('rte_ip.h',
 	'rte_net_crc.h',
 	'rte_mpls.h')
 
-sources = files('rte_arp.c', 'rte_net.c', 'rte_net_crc.c')
+sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c')
 deps += ['mbuf']
diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
new file mode 100644
index 000000000000..974fe815b335
--- /dev/null
+++ b/lib/librte_net/rte_ether.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_ether.h>
+
+void
+rte_eth_random_addr(uint8_t *addr)
+{
+	uint64_t rand = rte_rand();
+	uint8_t *p = (uint8_t *)&rand;
+
+	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
+	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;	/* clear multicast bit */
+	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
+}
+
+void
+rte_ether_format_addr(char *buf, uint16_t size,
+		      const struct rte_ether_addr *eth_addr)
+{
+	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
+		 eth_addr->addr_bytes[0],
+		 eth_addr->addr_bytes[1],
+		 eth_addr->addr_bytes[2],
+		 eth_addr->addr_bytes[3],
+		 eth_addr->addr_bytes[4],
+		 eth_addr->addr_bytes[5]);
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 7be9b4890af7..3caae0d98f6d 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -207,15 +207,8 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *
  * @param addr
  *   A pointer to Ethernet address.
  */
-static inline void rte_eth_random_addr(uint8_t *addr)
-{
-	uint64_t rand = rte_rand();
-	uint8_t *p = (uint8_t *)&rand;
-
-	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
-	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;  /* clear multicast bit */
-	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
-}
+void
+rte_eth_random_addr(uint8_t *addr);
 
 /**
  * Fast copy an Ethernet address.
@@ -254,19 +247,9 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
  * @param eth_addr
  *   A pointer to a ether_addr structure.
  */
-static inline void
+void
 rte_ether_format_addr(char *buf, uint16_t size,
-		  const struct rte_ether_addr *eth_addr)
-{
-	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 eth_addr->addr_bytes[0],
-		 eth_addr->addr_bytes[1],
-		 eth_addr->addr_bytes[2],
-		 eth_addr->addr_bytes[3],
-		 eth_addr->addr_bytes[4],
-		 eth_addr->addr_bytes[5]);
-}
-
+		      const struct rte_ether_addr *eth_addr);
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 26c06e7c7ae7..f1e1b84ab491 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -13,6 +13,13 @@ DPDK_17.05 {
 
 } DPDK_16.11;
 
+DPDK_19.08 {
+	global:
+
+	rte_eth_random_addr;
+	rte_ether_format_addr;
+} DPDK_17.05;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.20.1


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

* [dpdk-dev] [PATCH v6 2/8] net/ether: add function to convert string to ethernet address
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-07-02 16:50   ` Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 3/8] ethdev: use new ethernet parsing function Stephen Hemminger
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Make a function that can be used in place of eth_aton_r
to convert a string to rte_ether_addr. This function
allows both byte (xx:xx:xx:xx:xx:xx) and word (XXXX:XXXX:XXXX)
format and has the same lack of error handling as the original.

This also allows ethdev to no longer have a hard dependency
on the cmdline library.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 14 +++++++++
 lib/librte_net/rte_net_version.map |  1 +
 3 files changed, 62 insertions(+)

diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
index 974fe815b335..acc8a0e938c5 100644
--- a/lib/librte_net/rte_ether.c
+++ b/lib/librte_net/rte_ether.c
@@ -27,3 +27,50 @@ rte_ether_format_addr(char *buf, uint16_t size,
 		 eth_addr->addr_bytes[4],
 		 eth_addr->addr_bytes[5]);
 }
+
+/*
+ * Like ether_aton_r but can handle either
+ * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
+ */
+int
+rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
+{
+	unsigned int o0, o1, o2, o3, o4, o5;
+	int n;
+
+	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
+		    &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (n == 6) {
+		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
+		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0;
+		ea->addr_bytes[1] = o1;
+		ea->addr_bytes[2] = o2;
+		ea->addr_bytes[3] = o3;
+		ea->addr_bytes[4] = o4;
+		ea->addr_bytes[5] = o5;
+
+		return 0;
+	}
+
+	/* Support the format XXXX:XXXX:XXXX */
+	n = sscanf(s, "%x:%x:%x", &o0, &o1, &o2);
+	if (n == 3) {
+		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0 >> 8;
+		ea->addr_bytes[1] = o0 & 0xff;
+		ea->addr_bytes[2] = o1 >> 8;
+		ea->addr_bytes[3] = o1 & 0xff;
+		ea->addr_bytes[4] = o2 >> 8;
+		ea->addr_bytes[5] = o2 & 0xff;
+		return 0;
+	}
+	/* unknown format */
+
+	return -1;
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 3caae0d98f6d..8edc7e217b25 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -250,6 +250,20 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
 void
 rte_ether_format_addr(char *buf, uint16_t size,
 		      const struct rte_ether_addr *eth_addr);
+/**
+ * Convert string with Ethernet address to an ether_addr.
+ *
+ * @param str
+ *   A pointer to buffer contains the formatted MAC address.
+ * @param eth_addr
+ *   A pointer to a ether_addr structure.
+ * @return
+ *   0 if successful
+ *   -1 and sets rte_errno if invalid string
+ */
+int __rte_experimental
+rte_ether_unformat_addr(const char *str, struct rte_ether_addr *eth_addr);
+
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index f1e1b84ab491..f4c915069d57 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -25,4 +25,5 @@ EXPERIMENTAL {
 
 	rte_net_make_rarp_packet;
 	rte_net_skip_ip6_ext;
+	rte_ether_unformat_addr;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v6 3/8] ethdev: use new ethernet parsing function
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 2/8] net/ether: add function to convert string to ethernet address Stephen Hemminger
@ 2019-07-02 16:50   ` Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_eth_unformat_addr, so that ethdev can be built and work
without the cmdline library. The dependency on cmdline was
an arrangement of convenience anyway.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                      | 1 -
 lib/librte_ethdev/Makefile        | 2 +-
 lib/librte_ethdev/meson.build     | 2 +-
 lib/librte_ethdev/rte_class_eth.c | 9 +--------
 4 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 791e0d9911d6..82b2c4bfa8ea 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
 DEPDIRS-librte_ethdev += librte_kvargs
-DEPDIRS-librte_ethdev += librte_cmdline
 DEPDIRS-librte_ethdev += librte_meter
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 8d4a02630c4f..60bcc2227878 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_cmdline -lrte_meter
+LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_meter
 
 EXPORT_MAP := rte_ethdev_version.map
 
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 8d6165b2a7dd..f75d428c96d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -26,4 +26,4 @@ headers = files('rte_ethdev.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
 
-deps += ['net', 'kvargs', 'cmdline', 'meter']
+deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 873a653532ad..6338355e2557 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -4,7 +4,6 @@
 
 #include <string.h>
 
-#include <cmdline_parse_etheraddr.h>
 #include <rte_class.h>
 #include <rte_compat.h>
 #include <rte_errno.h>
@@ -43,19 +42,13 @@ static int
 eth_mac_cmp(const char *key __rte_unused,
 		const char *value, void *opaque)
 {
-	int ret;
 	struct rte_ether_addr mac;
 	const struct rte_eth_dev_data *data = opaque;
 	struct rte_eth_dev_info dev_info;
 	uint32_t index;
 
 	/* Parse devargs MAC address. */
-	/*
-	 * cannot use ether_aton_r(value, &mac)
-	 * because of include conflict with rte_ether.h
-	 */
-	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
-	if (ret < 0)
+	if (rte_ether_unformat_addr(value, &mac) < 0)
 		return -1; /* invalid devargs value */
 
 	/* Return 0 if devargs MAC is matching one of the device MACs. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v6 4/8] net/ether: use bitops to speedup comparison
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (2 preceding siblings ...)
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 3/8] ethdev: use new ethernet parsing function Stephen Hemminger
@ 2019-07-02 16:50   ` Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 8edc7e217b25..feb35a33c94b 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -81,11 +81,10 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
+	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+
+	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea->addr_bytes[i] != 0x00)
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w = (const uint16_t *)ea;
+
+	return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**
-- 
2.20.1


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

* [dpdk-dev] [PATCH v6 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (3 preceding siblings ...)
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-07-02 16:50   ` Stephen Hemminger
  2019-07-02 21:46     ` Ananyev, Konstantin
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 6/8] cmdline: use new ethernet address parser Stephen Hemminger
                     ` (3 subsequent siblings)
  8 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Stephen Hemminger, Andrew Rybchenko

From: Bruce Richardson <bruce.richardson@intel.com>

When including the rte_ether.h header in applications with warnings
enabled, a warning was given because of the assumption of 2-byte alignment
of ethernet addresses when processing them.

.../include/rte_ether.h:149:2: warning: converting a packed ‘const
  struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
  {aka ‘const short unsigned int’} pointer (alignment 2) may result in
  an unaligned pointer value [-Waddress-of-packed-member]
149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
    |  ^~~~~

Since ethernet addresses should always be aligned on a two-byte boundary,
we can just inform the compiler of this assumption to remove the warnings
and allow us to always access the addresses using 16-bit operations.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index feb35a33c94b..d7b76ddf63eb 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -58,7 +58,8 @@ extern "C" {
  * See http://standards.ieee.org/regauth/groupmac/tutorial.html
  */
 struct rte_ether_addr {
-	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
+	/**< Addr bytes in tx order */
 } __attribute__((__packed__));
 
 #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
@@ -81,8 +82,8 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
-	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+	const uint16_t *w1 = (const uint16_t *)ea1;
+	const uint16_t *w2 = (const uint16_t *)ea2;
 
 	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
@@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *w = (const uint16_t *)ea;
+	const uint16_t *w = (const uint16_t *)ea;
 
 	return (w[0] | w[1] | w[2]) == 0;
 }
@@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
  */
 static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
+	const uint16_t *ea_words = (const uint16_t *)ea;
 
 	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
 		ea_words[2] == 0xFFFF);
-- 
2.20.1


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

* [dpdk-dev] [PATCH v6 6/8] cmdline: use new ethernet address parser
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (4 preceding siblings ...)
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-07-02 16:50   ` Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 7/8] net/bonding: " Stephen Hemminger
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Now that there is a version of ether_aton in rte_ether, it can
be used by the cmdline ethernet address parser.

Note: ether_aton_r can not be used in cmdline because
the old code would accept either bytes XX:XX:XX:XX:XX:XX
or words XXXX:XXXX:XXXX and we need to keep compatiablity.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                                 |  2 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++-----------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/meson.build                              |  2 +-
 5 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 82b2c4bfa8ea..cc36fe7591f0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,7 +20,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
-DEPDIRS-librte_cmdline := librte_eal
+DEPDIRS-librte_cmdline := librte_eal librte_net
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index c64142b8d5a0..04057d7c671f 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cmdline.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_cmdline_version.map
 
@@ -25,7 +26,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_net -lrte_eal
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_parse_etheraddr.c b/lib/librte_cmdline/cmdline_parse_etheraddr.c
index 24e04755cd9e..2cb8dd2a1267 100644
--- a/lib/librte_cmdline/cmdline_parse_etheraddr.c
+++ b/lib/librte_cmdline/cmdline_parse_etheraddr.c
@@ -12,9 +12,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
 
 #include <rte_string_fns.h>
+#include <rte_ether.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -26,69 +26,15 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 	.get_help = cmdline_get_help_etheraddr,
 };
 
-/* the format can be either XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX */
-#define ETHER_ADDRSTRLENLONG 18
-#define ETHER_ADDRSTRLENSHORT 15
-
-#ifdef __linux__
-#define ea_oct ether_addr_octet
-#else
-#define ea_oct octet
-#endif
-
-
-static struct ether_addr *
-my_ether_aton(const char *a)
-{
-	int i;
-	char *end;
-	unsigned long o[ETHER_ADDR_LEN];
-	static struct ether_addr ether_addr;
-
-	i = 0;
-	do {
-		errno = 0;
-		o[i] = strtoul(a, &end, 16);
-		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
-			return NULL;
-		a = end + 1;
-	} while (++i != sizeof (o) / sizeof (o[0]) && end[0] != 0);
-
-	/* Junk at the end of line */
-	if (end[0] != 0)
-		return NULL;
-
-	/* Support the format XX:XX:XX:XX:XX:XX */
-	if (i == ETHER_ADDR_LEN) {
-		while (i-- != 0) {
-			if (o[i] > UINT8_MAX)
-				return NULL;
-			ether_addr.ea_oct[i] = (uint8_t)o[i];
-		}
-	/* Support the format XXXX:XXXX:XXXX */
-	} else if (i == ETHER_ADDR_LEN / 2) {
-		while (i-- != 0) {
-			if (o[i] > UINT16_MAX)
-				return NULL;
-			ether_addr.ea_oct[i * 2] = (uint8_t)(o[i] >> 8);
-			ether_addr.ea_oct[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
-		}
-	/* unknown format */
-	} else
-		return NULL;
-
-	return (struct ether_addr *)&ether_addr;
-}
-
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 	const char *buf, void *res, unsigned ressize)
 {
 	unsigned int token_len = 0;
-	char ether_str[ETHER_ADDRSTRLENLONG+1];
-	struct ether_addr *tmp;
+	char ether_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr tmp;
 
-	if (res && ressize < sizeof(struct ether_addr))
+	if (res && ressize < sizeof(tmp))
 		return -1;
 
 	if (!buf || ! *buf)
@@ -98,17 +44,16 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 		token_len++;
 
 	/* if token doesn't match possible string lengths... */
-	if ((token_len != ETHER_ADDRSTRLENLONG - 1) &&
-			(token_len != ETHER_ADDRSTRLENSHORT - 1))
+	if (token_len >= RTE_ETHER_ADDR_FMT_SIZE)
 		return -1;
 
 	strlcpy(ether_str, buf, token_len + 1);
 
-	tmp = my_ether_aton(ether_str);
-	if (tmp == NULL)
+	if (rte_ether_unformat_addr(ether_str, &tmp) < 0)
 		return -1;
+
 	if (res)
-		memcpy(res, tmp, sizeof(struct ether_addr));
+		memcpy(res, &tmp, sizeof(tmp));
 	return token_len;
 }
 
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 0fa61385fccf..07334c1b0956 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -1,10 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
-# This library is processed before EAL
-includes = [global_inc]
-
 version = 2
+allow_experimental_apis = true
 sources = files('cmdline.c',
 	'cmdline_cirbuf.c',
 	'cmdline_parse.c',
@@ -28,3 +26,5 @@ headers = files('cmdline.h',
 	'cmdline_socket.h',
 	'cmdline_cirbuf.h',
 	'cmdline_parse_portlist.h')
+
+deps += ['net']
diff --git a/lib/meson.build b/lib/meson.build
index 9398a3ac04e3..c133f2f35ff3 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -11,8 +11,8 @@
 libraries = [
 	'kvargs', # eal depends on kvargs
 	'eal', # everything depends on eal
-	'cmdline', # ethdev depends on cmdline for parsing functions
 	'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
+	'cmdline',
 	'metrics', # bitrate/latency stats depends on this
 	'hash',    # efd depends on this
 	'timer',   # eventdev depends on this
-- 
2.20.1


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

* [dpdk-dev] [PATCH v6 7/8] net/bonding: use new ethernet address parser
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (5 preceding siblings ...)
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 6/8] cmdline: use new ethernet address parser Stephen Hemminger
@ 2019-07-02 16:50   ` Stephen Hemminger
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 8/8] app/testpmd: " Stephen Hemminger
  2019-07-02 21:37   ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Thomas Monjalon
  8 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline library used to be the only way to parse a
mac address. Now there is rte_ether_unformat_addr.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bonding/Makefile            | 2 +-
 drivers/net/bonding/meson.build         | 2 +-
 drivers/net/bonding/rte_eth_bond_args.c | 6 +-----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 1893e3cad313..26c1782554cd 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
-LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_pci -lrte_bus_pci
 LDLIBS += -lrte_bus_vdev
 
diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build
index 00374edb2a9d..6267210adf5f 100644
--- a/drivers/net/bonding/meson.build
+++ b/drivers/net/bonding/meson.build
@@ -8,6 +8,6 @@ sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', 'rte_eth_bond_flow.c
 	'rte_eth_bond_args.c', 'rte_eth_bond_8023ad.c', 'rte_eth_bond_alb.c')
 
 deps += 'sched' # needed for rte_bitmap.h
-deps += ['ip_frag', 'cmdline']
+deps += ['ip_frag']
 
 install_headers('rte_eth_bond.h', 'rte_eth_bond_8023ad.h')
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index 01bbb06c1a84..936440fb8491 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -7,9 +7,6 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
 #include "rte_eth_bond.h"
 #include "rte_eth_bond_private.h"
 
@@ -281,8 +278,7 @@ bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
 		return -1;
 
 	/* Parse MAC */
-	return cmdline_parse_etheraddr(NULL, value, extra_args,
-		sizeof(struct rte_ether_addr));
+	return rte_ether_unformat_addr(value, extra_args);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v6 8/8] app/testpmd: use new ethernet address parser
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (6 preceding siblings ...)
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 7/8] net/bonding: " Stephen Hemminger
@ 2019-07-02 16:50   ` Stephen Hemminger
  2019-07-02 21:37   ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Thomas Monjalon
  8 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 16:50 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline_parse_ether_addr does not need to be used everywhere
in testpmd. Can use rte_ether_unformat_addr instead.
As an added bonus it eliminates some code for copying.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline_flow.c |  5 ++---
 app/test-pmd/config.c       | 10 +++-------
 app/test-pmd/parameters.c   | 15 +++------------
 3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 201bd9de56e0..2b02ca29b7ac 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -18,7 +18,6 @@
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_flow.h>
 
 #include "testpmd.h"
@@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct token *token,
 	/* Only network endian is supported. */
 	if (!arg->hton)
 		goto error;
-	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
-	if (ret < 0 || (unsigned int)ret != len)
+	ret = rte_ether_unformat_addr(str, &tmp);
+	if (ret < 0)
 		goto error;
 	if (!ctx->object)
 		return len;
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index ab458c8d2837..1d804705d96c 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -49,7 +49,6 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include <rte_gro.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_config.h>
 
 #include "testpmd.h"
@@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 void
 set_fwd_eth_peer(portid_t port_id, char *peer_addr)
 {
-	uint8_t c, new_peer_addr[6];
+	struct rte_ether_addr new_peer_addr;
 	if (!rte_eth_dev_is_valid_port(port_id)) {
 		printf("Error: Invalid port number %i\n", port_id);
 		return;
 	}
-	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
-					sizeof(new_peer_addr)) < 0) {
+	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
 		printf("Error: Invalid ethernet address: %s\n", peer_addr);
 		return;
 	}
-	for (c = 0; c < 6; c++)
-		peer_eth_addrs[port_id].addr_bytes[c] =
-			new_peer_addr[c];
+	peer_eth_addrs[port_id] = new_peer_addr;
 }
 
 int
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 245b610641ee..975a97807009 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -39,10 +39,6 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_CMDLINE
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-#endif
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
@@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
 		if (fgets(buf, sizeof(buf), config_file) == NULL)
 			break;
 
-		if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i],
-				sizeof(peer_eth_addrs[i])) < 0) {
+		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
 			printf("Bad MAC address format on line %d\n", i+1);
 			fclose(config_file);
 			return -1;
@@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
 			}
 			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
 				char *port_end;
-				uint8_t c, peer_addr[6];
 
 				errno = 0;
 				n = strtoul(optarg, &port_end, 10);
@@ -739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
 						 "eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
 						 n, RTE_MAX_ETHPORTS);
 
-				if (cmdline_parse_etheraddr(NULL, port_end,
-						&peer_addr, sizeof(peer_addr)) < 0)
+				if (rte_ether_unformat_addr(port_end,
+							    &peer_eth_addrs[n]) < 0)
 					rte_exit(EXIT_FAILURE,
 						 "Invalid ethernet address: %s\n",
 						 port_end);
-				for (c = 0; c < 6; c++)
-					peer_eth_addrs[n].addr_bytes[c] =
-						peer_addr[c];
 				nb_peer_eth_addrs++;
 			}
 #endif
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
                     ` (7 preceding siblings ...)
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 8/8] app/testpmd: " Stephen Hemminger
@ 2019-07-02 21:37   ` Thomas Monjalon
  2019-07-02 22:03     ` Stephen Hemminger
  8 siblings, 1 reply; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-02 21:37 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, gaetan.rivet, Matan Azrad, Jakub Grajciar

> Stephen Hemminger (7):
>   net/rte_ether: deinline non-critical functions
>   net/ether: add function to convert string to ethernet address
>   ethdev: use new ethernet parsing function
>   net/ether: use bitops to speedup comparison
>   cmdline: use new ethernet address parser
>   net/bonding: use new ethernet address parser
>   app/testpmd: use new ethernet address parser

There are other MAC parsing code:
	drivers/net/failsafe/failsafe_args.c - fs_get_mac_addr_arg()
	drivers/net/memif/rte_eth_memif.c - memif_set_mac()
	drivers/net/vdev_netvsc/vdev_netvsc.c - vdev_netvsc_netvsc_probe()
	drivers/net/virtio/virtio_user/virtio_user_dev.c - parse_mac()
Should they be replaced?



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

* Re: [dpdk-dev] [PATCH v6 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-07-02 21:46     ` Ananyev, Konstantin
  0 siblings, 0 replies; 127+ messages in thread
From: Ananyev, Konstantin @ 2019-07-02 21:46 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Richardson, Bruce, Andrew Rybchenko



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen Hemminger
> Sent: Tuesday, July 2, 2019 5:50 PM
> To: dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Stephen Hemminger <stephen@networkplumber.org>; Andrew Rybchenko
> <arybchenko@solarflare.com>
> Subject: [dpdk-dev] [PATCH v6 5/8] net/ether: mark ethernet addresses as being 2-byte aligned
> 
> From: Bruce Richardson <bruce.richardson@intel.com>
> 
> When including the rte_ether.h header in applications with warnings
> enabled, a warning was given because of the assumption of 2-byte alignment
> of ethernet addresses when processing them.
> 
> .../include/rte_ether.h:149:2: warning: converting a packed ‘const
>   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
>   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
>   an unaligned pointer value [-Waddress-of-packed-member]
> 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
>     |  ^~~~~
> 
> Since ethernet addresses should always be aligned on a two-byte boundary,
> we can just inform the compiler of this assumption to remove the warnings
> and allow us to always access the addresses using 16-bit operations.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

Seems like you forgot to remove that patch from the seies.
Konstantin


> ---
>  lib/librte_net/rte_ether.h | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index feb35a33c94b..d7b76ddf63eb 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -58,7 +58,8 @@ extern "C" {
>   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
>   */
>  struct rte_ether_addr {
> -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
> +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> +	/**< Addr bytes in tx order */
>  } __attribute__((__packed__));
> 
>  #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
> @@ -81,8 +82,8 @@ struct rte_ether_addr {
>  static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
>  				     const struct rte_ether_addr *ea2)
>  {
> -	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
> -	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
> +	const uint16_t *w1 = (const uint16_t *)ea1;
> +	const uint16_t *w2 = (const uint16_t *)ea2;
> 
>  	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
>  }
> @@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
>   */
>  static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
>  {
> -	const unaligned_uint16_t *w = (const uint16_t *)ea;
> +	const uint16_t *w = (const uint16_t *)ea;
> 
>  	return (w[0] | w[1] | w[2]) == 0;
>  }
> @@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
>   */
>  static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
>  {
> -	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
> +	const uint16_t *ea_words = (const uint16_t *)ea;
> 
>  	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
>  		ea_words[2] == 0xFFFF);
> --
> 2.20.1


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

* Re: [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations
  2019-07-02 21:37   ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Thomas Monjalon
@ 2019-07-02 22:03     ` Stephen Hemminger
  0 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:03 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, gaetan.rivet, Matan Azrad, Jakub Grajciar

On Tue, 02 Jul 2019 23:37:29 +0200
Thomas Monjalon <thomas@monjalon.net> wrote:

> > Stephen Hemminger (7):
> >   net/rte_ether: deinline non-critical functions
> >   net/ether: add function to convert string to ethernet address
> >   ethdev: use new ethernet parsing function
> >   net/ether: use bitops to speedup comparison
> >   cmdline: use new ethernet address parser
> >   net/bonding: use new ethernet address parser
> >   app/testpmd: use new ethernet address parser  
> 
> There are other MAC parsing code:
> 	drivers/net/failsafe/failsafe_args.c - fs_get_mac_addr_arg()
> 	drivers/net/memif/rte_eth_memif.c - memif_set_mac()
> 	drivers/net/vdev_netvsc/vdev_netvsc.c - vdev_netvsc_netvsc_probe()
> 	drivers/net/virtio/virtio_user/virtio_user_dev.c - parse_mac()
> Should they be replaced?
> 
> 

Sure, I can add these to v7

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

* [dpdk-dev] [PATCH v7 00/12] ether: improvements and optimizations
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (10 preceding siblings ...)
  2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
@ 2019-07-02 22:12 ` Stephen Hemminger
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 01/12] net/rte_ether: deinline non-critical functions Stephen Hemminger
                     ` (11 more replies)
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
  13 siblings, 12 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of patches around the ethernet address
manipulation routines in librte_net/rte_ether.

v7
   use rte_ether_unformat_addr in more drivers
v6
   add librte_net to axgbe and memif Makefile
v5
   reword commit messages to workaround check-log complaints
v4
   fix meson build
   reword commit messages
   add bonding and tespmd patches
v3 
   rebase to use rte_ether prefix
   drop aligning ethernet headers for now.

Bruce Richardson (1):
  net/ether: mark ethernet addresses as being 2-byte aligned

Stephen Hemminger (11):
  net/rte_ether: deinline non-critical functions
  net/ether: add function to convert string to ethernet address
  ethdev: use new ethernet parsing function
  net/ether: use bitops to speedup comparison
  cmdline: use new ethernet address parser
  net/bonding: use new ethernet address parser
  app/testpmd: use new ethernet address parser
  net/virtio: use new ether addr parsing
  net/failsafe: use common ether address parsing routine
  net/vdev_netvsc: use common ethernet address parsing
  net/memif: use common ethernet address parsing routine

 app/test-pmd/cmdline_flow.c                   |  5 +-
 app/test-pmd/config.c                         | 10 +--
 app/test-pmd/parameters.c                     | 15 +---
 drivers/net/axgbe/Makefile                    |  2 +-
 drivers/net/bonding/Makefile                  |  2 +-
 drivers/net/bonding/meson.build               |  2 +-
 drivers/net/bonding/rte_eth_bond_args.c       |  6 +-
 drivers/net/failsafe/failsafe_args.c          |  8 +-
 drivers/net/memif/Makefile                    |  2 +-
 drivers/net/memif/rte_eth_memif.c             |  7 +-
 drivers/net/vdev_netvsc/vdev_netvsc.c         | 10 +--
 .../net/virtio/virtio_user/virtio_user_dev.c  | 10 +--
 lib/Makefile                                  |  3 +-
 lib/librte_cmdline/Makefile                   |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c  | 71 ++---------------
 lib/librte_cmdline/meson.build                |  6 +-
 lib/librte_ethdev/Makefile                    |  2 +-
 lib/librte_ethdev/meson.build                 |  2 +-
 lib/librte_ethdev/rte_class_eth.c             |  9 +--
 lib/librte_net/Makefile                       |  1 +
 lib/librte_net/meson.build                    |  2 +-
 lib/librte_net/rte_ether.c                    | 76 +++++++++++++++++++
 lib/librte_net/rte_ether.h                    | 59 +++++++-------
 lib/librte_net/rte_net_version.map            |  8 ++
 lib/meson.build                               |  2 +-
 25 files changed, 151 insertions(+), 172 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 01/12] net/rte_ether: deinline non-critical functions
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-05 14:25     ` Olivier Matz
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 02/12] net/ether: add function to convert string to ethernet address Stephen Hemminger
                     ` (10 subsequent siblings)
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Rami Rosen, Andrew Rybchenko

Formatting Ethernet address and getting a random value are
not in critical path so they should not be inlined.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Rami Rosen <ramirose@gmail.com>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/axgbe/Makefile         |  2 +-
 drivers/net/memif/Makefile         |  2 +-
 lib/librte_net/Makefile            |  1 +
 lib/librte_net/meson.build         |  2 +-
 lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 25 ++++---------------------
 lib/librte_net/rte_net_version.map |  7 +++++++
 7 files changed, 44 insertions(+), 24 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

diff --git a/drivers/net/axgbe/Makefile b/drivers/net/axgbe/Makefile
index 72215aedaf55..c2d4336800c0 100644
--- a/drivers/net/axgbe/Makefile
+++ b/drivers/net/axgbe/Makefile
@@ -17,7 +17,7 @@ LIBABIVER := 1
 
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_pci -lrte_bus_pci
-LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_ethdev -lrte_net
 
 #
 # all source are stored in SRCS-y
diff --git a/drivers/net/memif/Makefile b/drivers/net/memif/Makefile
index fdbdf3378019..3d92b08f259b 100644
--- a/drivers/net/memif/Makefile
+++ b/drivers/net/memif/Makefile
@@ -21,7 +21,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 # - rte_mp_reply
 # - rte_mp_request_sync
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
-LDLIBS += -lrte_ethdev -lrte_kvargs
+LDLIBS += -lrte_ethdev -lrte_kvargs -lrte_net
 LDLIBS += -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index c3082069ab50..1244c9fd54c9 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -14,6 +14,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
+SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 
 # install includes
diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build
index 7d66f693cbf3..868a93fd6b6b 100644
--- a/lib/librte_net/meson.build
+++ b/lib/librte_net/meson.build
@@ -16,5 +16,5 @@ headers = files('rte_ip.h',
 	'rte_net_crc.h',
 	'rte_mpls.h')
 
-sources = files('rte_arp.c', 'rte_net.c', 'rte_net_crc.c')
+sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c')
 deps += ['mbuf']
diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
new file mode 100644
index 000000000000..974fe815b335
--- /dev/null
+++ b/lib/librte_net/rte_ether.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_ether.h>
+
+void
+rte_eth_random_addr(uint8_t *addr)
+{
+	uint64_t rand = rte_rand();
+	uint8_t *p = (uint8_t *)&rand;
+
+	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
+	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;	/* clear multicast bit */
+	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
+}
+
+void
+rte_ether_format_addr(char *buf, uint16_t size,
+		      const struct rte_ether_addr *eth_addr)
+{
+	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
+		 eth_addr->addr_bytes[0],
+		 eth_addr->addr_bytes[1],
+		 eth_addr->addr_bytes[2],
+		 eth_addr->addr_bytes[3],
+		 eth_addr->addr_bytes[4],
+		 eth_addr->addr_bytes[5]);
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 7be9b4890af7..3caae0d98f6d 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -207,15 +207,8 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *
  * @param addr
  *   A pointer to Ethernet address.
  */
-static inline void rte_eth_random_addr(uint8_t *addr)
-{
-	uint64_t rand = rte_rand();
-	uint8_t *p = (uint8_t *)&rand;
-
-	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
-	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;  /* clear multicast bit */
-	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
-}
+void
+rte_eth_random_addr(uint8_t *addr);
 
 /**
  * Fast copy an Ethernet address.
@@ -254,19 +247,9 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
  * @param eth_addr
  *   A pointer to a ether_addr structure.
  */
-static inline void
+void
 rte_ether_format_addr(char *buf, uint16_t size,
-		  const struct rte_ether_addr *eth_addr)
-{
-	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 eth_addr->addr_bytes[0],
-		 eth_addr->addr_bytes[1],
-		 eth_addr->addr_bytes[2],
-		 eth_addr->addr_bytes[3],
-		 eth_addr->addr_bytes[4],
-		 eth_addr->addr_bytes[5]);
-}
-
+		      const struct rte_ether_addr *eth_addr);
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 26c06e7c7ae7..f1e1b84ab491 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -13,6 +13,13 @@ DPDK_17.05 {
 
 } DPDK_16.11;
 
+DPDK_19.08 {
+	global:
+
+	rte_eth_random_addr;
+	rte_ether_format_addr;
+} DPDK_17.05;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 02/12] net/ether: add function to convert string to ethernet address
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 01/12] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-05 14:25     ` Olivier Matz
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 03/12] ethdev: use new ethernet parsing function Stephen Hemminger
                     ` (9 subsequent siblings)
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Make a function that can be used in place of eth_aton_r
to convert a string to rte_ether_addr. This function
allows both byte (xx:xx:xx:xx:xx:xx) and word (XXXX:XXXX:XXXX)
format and has the same lack of error handling as the original.

This also allows ethdev to no longer have a hard dependency
on the cmdline library.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 14 +++++++++
 lib/librte_net/rte_net_version.map |  1 +
 3 files changed, 62 insertions(+)

diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
index 974fe815b335..acc8a0e938c5 100644
--- a/lib/librte_net/rte_ether.c
+++ b/lib/librte_net/rte_ether.c
@@ -27,3 +27,50 @@ rte_ether_format_addr(char *buf, uint16_t size,
 		 eth_addr->addr_bytes[4],
 		 eth_addr->addr_bytes[5]);
 }
+
+/*
+ * Like ether_aton_r but can handle either
+ * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
+ */
+int
+rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
+{
+	unsigned int o0, o1, o2, o3, o4, o5;
+	int n;
+
+	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
+		    &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (n == 6) {
+		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
+		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0;
+		ea->addr_bytes[1] = o1;
+		ea->addr_bytes[2] = o2;
+		ea->addr_bytes[3] = o3;
+		ea->addr_bytes[4] = o4;
+		ea->addr_bytes[5] = o5;
+
+		return 0;
+	}
+
+	/* Support the format XXXX:XXXX:XXXX */
+	n = sscanf(s, "%x:%x:%x", &o0, &o1, &o2);
+	if (n == 3) {
+		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX)
+			return -1;
+
+		ea->addr_bytes[0] = o0 >> 8;
+		ea->addr_bytes[1] = o0 & 0xff;
+		ea->addr_bytes[2] = o1 >> 8;
+		ea->addr_bytes[3] = o1 & 0xff;
+		ea->addr_bytes[4] = o2 >> 8;
+		ea->addr_bytes[5] = o2 & 0xff;
+		return 0;
+	}
+	/* unknown format */
+
+	return -1;
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 3caae0d98f6d..8edc7e217b25 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -250,6 +250,20 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
 void
 rte_ether_format_addr(char *buf, uint16_t size,
 		      const struct rte_ether_addr *eth_addr);
+/**
+ * Convert string with Ethernet address to an ether_addr.
+ *
+ * @param str
+ *   A pointer to buffer contains the formatted MAC address.
+ * @param eth_addr
+ *   A pointer to a ether_addr structure.
+ * @return
+ *   0 if successful
+ *   -1 and sets rte_errno if invalid string
+ */
+int __rte_experimental
+rte_ether_unformat_addr(const char *str, struct rte_ether_addr *eth_addr);
+
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index f1e1b84ab491..f4c915069d57 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -25,4 +25,5 @@ EXPERIMENTAL {
 
 	rte_net_make_rarp_packet;
 	rte_net_skip_ip6_ext;
+	rte_ether_unformat_addr;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 03/12] ethdev: use new ethernet parsing function
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 01/12] net/rte_ether: deinline non-critical functions Stephen Hemminger
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 02/12] net/ether: add function to convert string to ethernet address Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 04/12] net/ether: use bitops to speedup comparison Stephen Hemminger
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_eth_unformat_addr, so that ethdev can be built and work
without the cmdline library. The dependency on cmdline was
an arrangement of convenience anyway.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                      | 1 -
 lib/librte_ethdev/Makefile        | 2 +-
 lib/librte_ethdev/meson.build     | 2 +-
 lib/librte_ethdev/rte_class_eth.c | 9 +--------
 4 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 791e0d9911d6..82b2c4bfa8ea 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
 DEPDIRS-librte_ethdev += librte_kvargs
-DEPDIRS-librte_ethdev += librte_cmdline
 DEPDIRS-librte_ethdev += librte_meter
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 8d4a02630c4f..60bcc2227878 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_cmdline -lrte_meter
+LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_meter
 
 EXPORT_MAP := rte_ethdev_version.map
 
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 8d6165b2a7dd..f75d428c96d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -26,4 +26,4 @@ headers = files('rte_ethdev.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
 
-deps += ['net', 'kvargs', 'cmdline', 'meter']
+deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 873a653532ad..6338355e2557 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -4,7 +4,6 @@
 
 #include <string.h>
 
-#include <cmdline_parse_etheraddr.h>
 #include <rte_class.h>
 #include <rte_compat.h>
 #include <rte_errno.h>
@@ -43,19 +42,13 @@ static int
 eth_mac_cmp(const char *key __rte_unused,
 		const char *value, void *opaque)
 {
-	int ret;
 	struct rte_ether_addr mac;
 	const struct rte_eth_dev_data *data = opaque;
 	struct rte_eth_dev_info dev_info;
 	uint32_t index;
 
 	/* Parse devargs MAC address. */
-	/*
-	 * cannot use ether_aton_r(value, &mac)
-	 * because of include conflict with rte_ether.h
-	 */
-	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
-	if (ret < 0)
+	if (rte_ether_unformat_addr(value, &mac) < 0)
 		return -1; /* invalid devargs value */
 
 	/* Return 0 if devargs MAC is matching one of the device MACs. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 04/12] net/ether: use bitops to speedup comparison
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (2 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 03/12] ethdev: use new ethernet parsing function Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-05 14:34     ` Olivier Matz
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 05/12] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
                     ` (7 subsequent siblings)
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 8edc7e217b25..feb35a33c94b 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -81,11 +81,10 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
+	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+
+	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea->addr_bytes[i] != 0x00)
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w = (const uint16_t *)ea;
+
+	return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 05/12] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (3 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 04/12] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-05 14:34     ` Olivier Matz
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 06/12] cmdline: use new ethernet address parser Stephen Hemminger
                     ` (6 subsequent siblings)
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Stephen Hemminger, Andrew Rybchenko

From: Bruce Richardson <bruce.richardson@intel.com>

When including the rte_ether.h header in applications with warnings
enabled, a warning was given because of the assumption of 2-byte alignment
of ethernet addresses when processing them.

.../include/rte_ether.h:149:2: warning: converting a packed ‘const
  struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
  {aka ‘const short unsigned int’} pointer (alignment 2) may result in
  an unaligned pointer value [-Waddress-of-packed-member]
149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
    |  ^~~~~

Since ethernet addresses should always be aligned on a two-byte boundary,
we can just inform the compiler of this assumption to remove the warnings
and allow us to always access the addresses using 16-bit operations.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index feb35a33c94b..d7b76ddf63eb 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -58,7 +58,8 @@ extern "C" {
  * See http://standards.ieee.org/regauth/groupmac/tutorial.html
  */
 struct rte_ether_addr {
-	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
+	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
+	/**< Addr bytes in tx order */
 } __attribute__((__packed__));
 
 #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
@@ -81,8 +82,8 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
-	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+	const uint16_t *w1 = (const uint16_t *)ea1;
+	const uint16_t *w2 = (const uint16_t *)ea2;
 
 	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
@@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *w = (const uint16_t *)ea;
+	const uint16_t *w = (const uint16_t *)ea;
 
 	return (w[0] | w[1] | w[2]) == 0;
 }
@@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
  */
 static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
 {
-	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
+	const uint16_t *ea_words = (const uint16_t *)ea;
 
 	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
 		ea_words[2] == 0xFFFF);
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 06/12] cmdline: use new ethernet address parser
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (4 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 05/12] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-05 14:46     ` Olivier Matz
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 07/12] net/bonding: " Stephen Hemminger
                     ` (5 subsequent siblings)
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Now that there is a version of ether_aton in rte_ether, it can
be used by the cmdline ethernet address parser.

Note: ether_aton_r can not be used in cmdline because
the old code would accept either bytes XX:XX:XX:XX:XX:XX
or words XXXX:XXXX:XXXX and we need to keep compatiablity.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                                 |  2 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++-----------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/meson.build                              |  2 +-
 5 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 82b2c4bfa8ea..cc36fe7591f0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,7 +20,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
-DEPDIRS-librte_cmdline := librte_eal
+DEPDIRS-librte_cmdline := librte_eal librte_net
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index c64142b8d5a0..04057d7c671f 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cmdline.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_cmdline_version.map
 
@@ -25,7 +26,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_net -lrte_eal
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_parse_etheraddr.c b/lib/librte_cmdline/cmdline_parse_etheraddr.c
index 24e04755cd9e..2cb8dd2a1267 100644
--- a/lib/librte_cmdline/cmdline_parse_etheraddr.c
+++ b/lib/librte_cmdline/cmdline_parse_etheraddr.c
@@ -12,9 +12,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
 
 #include <rte_string_fns.h>
+#include <rte_ether.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -26,69 +26,15 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 	.get_help = cmdline_get_help_etheraddr,
 };
 
-/* the format can be either XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX */
-#define ETHER_ADDRSTRLENLONG 18
-#define ETHER_ADDRSTRLENSHORT 15
-
-#ifdef __linux__
-#define ea_oct ether_addr_octet
-#else
-#define ea_oct octet
-#endif
-
-
-static struct ether_addr *
-my_ether_aton(const char *a)
-{
-	int i;
-	char *end;
-	unsigned long o[ETHER_ADDR_LEN];
-	static struct ether_addr ether_addr;
-
-	i = 0;
-	do {
-		errno = 0;
-		o[i] = strtoul(a, &end, 16);
-		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
-			return NULL;
-		a = end + 1;
-	} while (++i != sizeof (o) / sizeof (o[0]) && end[0] != 0);
-
-	/* Junk at the end of line */
-	if (end[0] != 0)
-		return NULL;
-
-	/* Support the format XX:XX:XX:XX:XX:XX */
-	if (i == ETHER_ADDR_LEN) {
-		while (i-- != 0) {
-			if (o[i] > UINT8_MAX)
-				return NULL;
-			ether_addr.ea_oct[i] = (uint8_t)o[i];
-		}
-	/* Support the format XXXX:XXXX:XXXX */
-	} else if (i == ETHER_ADDR_LEN / 2) {
-		while (i-- != 0) {
-			if (o[i] > UINT16_MAX)
-				return NULL;
-			ether_addr.ea_oct[i * 2] = (uint8_t)(o[i] >> 8);
-			ether_addr.ea_oct[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
-		}
-	/* unknown format */
-	} else
-		return NULL;
-
-	return (struct ether_addr *)&ether_addr;
-}
-
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 	const char *buf, void *res, unsigned ressize)
 {
 	unsigned int token_len = 0;
-	char ether_str[ETHER_ADDRSTRLENLONG+1];
-	struct ether_addr *tmp;
+	char ether_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr tmp;
 
-	if (res && ressize < sizeof(struct ether_addr))
+	if (res && ressize < sizeof(tmp))
 		return -1;
 
 	if (!buf || ! *buf)
@@ -98,17 +44,16 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 		token_len++;
 
 	/* if token doesn't match possible string lengths... */
-	if ((token_len != ETHER_ADDRSTRLENLONG - 1) &&
-			(token_len != ETHER_ADDRSTRLENSHORT - 1))
+	if (token_len >= RTE_ETHER_ADDR_FMT_SIZE)
 		return -1;
 
 	strlcpy(ether_str, buf, token_len + 1);
 
-	tmp = my_ether_aton(ether_str);
-	if (tmp == NULL)
+	if (rte_ether_unformat_addr(ether_str, &tmp) < 0)
 		return -1;
+
 	if (res)
-		memcpy(res, tmp, sizeof(struct ether_addr));
+		memcpy(res, &tmp, sizeof(tmp));
 	return token_len;
 }
 
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 0fa61385fccf..07334c1b0956 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -1,10 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
-# This library is processed before EAL
-includes = [global_inc]
-
 version = 2
+allow_experimental_apis = true
 sources = files('cmdline.c',
 	'cmdline_cirbuf.c',
 	'cmdline_parse.c',
@@ -28,3 +26,5 @@ headers = files('cmdline.h',
 	'cmdline_socket.h',
 	'cmdline_cirbuf.h',
 	'cmdline_parse_portlist.h')
+
+deps += ['net']
diff --git a/lib/meson.build b/lib/meson.build
index 9398a3ac04e3..c133f2f35ff3 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -11,8 +11,8 @@
 libraries = [
 	'kvargs', # eal depends on kvargs
 	'eal', # everything depends on eal
-	'cmdline', # ethdev depends on cmdline for parsing functions
 	'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
+	'cmdline',
 	'metrics', # bitrate/latency stats depends on this
 	'hash',    # efd depends on this
 	'timer',   # eventdev depends on this
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 07/12] net/bonding: use new ethernet address parser
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (5 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 06/12] cmdline: use new ethernet address parser Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 08/12] app/testpmd: " Stephen Hemminger
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline library used to be the only way to parse a
mac address. Now there is rte_ether_unformat_addr.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bonding/Makefile            | 2 +-
 drivers/net/bonding/meson.build         | 2 +-
 drivers/net/bonding/rte_eth_bond_args.c | 6 +-----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 1893e3cad313..26c1782554cd 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
-LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_pci -lrte_bus_pci
 LDLIBS += -lrte_bus_vdev
 
diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build
index 00374edb2a9d..6267210adf5f 100644
--- a/drivers/net/bonding/meson.build
+++ b/drivers/net/bonding/meson.build
@@ -8,6 +8,6 @@ sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', 'rte_eth_bond_flow.c
 	'rte_eth_bond_args.c', 'rte_eth_bond_8023ad.c', 'rte_eth_bond_alb.c')
 
 deps += 'sched' # needed for rte_bitmap.h
-deps += ['ip_frag', 'cmdline']
+deps += ['ip_frag']
 
 install_headers('rte_eth_bond.h', 'rte_eth_bond_8023ad.h')
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index 01bbb06c1a84..936440fb8491 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -7,9 +7,6 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
 #include "rte_eth_bond.h"
 #include "rte_eth_bond_private.h"
 
@@ -281,8 +278,7 @@ bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
 		return -1;
 
 	/* Parse MAC */
-	return cmdline_parse_etheraddr(NULL, value, extra_args,
-		sizeof(struct rte_ether_addr));
+	return rte_ether_unformat_addr(value, extra_args);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 08/12] app/testpmd: use new ethernet address parser
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (6 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 07/12] net/bonding: " Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-03 13:30     ` Iremonger, Bernard
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 09/12] net/virtio: use new ether addr parsing Stephen Hemminger
                     ` (3 subsequent siblings)
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline_parse_ether_addr does not need to be used everywhere
in testpmd. Can use rte_ether_unformat_addr instead.
As an added bonus it eliminates some code for copying.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline_flow.c |  5 ++---
 app/test-pmd/config.c       | 10 +++-------
 app/test-pmd/parameters.c   | 15 +++------------
 3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 201bd9de56e0..2b02ca29b7ac 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -18,7 +18,6 @@
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_flow.h>
 
 #include "testpmd.h"
@@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct token *token,
 	/* Only network endian is supported. */
 	if (!arg->hton)
 		goto error;
-	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
-	if (ret < 0 || (unsigned int)ret != len)
+	ret = rte_ether_unformat_addr(str, &tmp);
+	if (ret < 0)
 		goto error;
 	if (!ctx->object)
 		return len;
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index ab458c8d2837..1d804705d96c 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -49,7 +49,6 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include <rte_gro.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_config.h>
 
 #include "testpmd.h"
@@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 void
 set_fwd_eth_peer(portid_t port_id, char *peer_addr)
 {
-	uint8_t c, new_peer_addr[6];
+	struct rte_ether_addr new_peer_addr;
 	if (!rte_eth_dev_is_valid_port(port_id)) {
 		printf("Error: Invalid port number %i\n", port_id);
 		return;
 	}
-	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
-					sizeof(new_peer_addr)) < 0) {
+	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
 		printf("Error: Invalid ethernet address: %s\n", peer_addr);
 		return;
 	}
-	for (c = 0; c < 6; c++)
-		peer_eth_addrs[port_id].addr_bytes[c] =
-			new_peer_addr[c];
+	peer_eth_addrs[port_id] = new_peer_addr;
 }
 
 int
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 245b610641ee..975a97807009 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -39,10 +39,6 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_CMDLINE
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-#endif
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
@@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
 		if (fgets(buf, sizeof(buf), config_file) == NULL)
 			break;
 
-		if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i],
-				sizeof(peer_eth_addrs[i])) < 0) {
+		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
 			printf("Bad MAC address format on line %d\n", i+1);
 			fclose(config_file);
 			return -1;
@@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
 			}
 			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
 				char *port_end;
-				uint8_t c, peer_addr[6];
 
 				errno = 0;
 				n = strtoul(optarg, &port_end, 10);
@@ -739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
 						 "eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
 						 n, RTE_MAX_ETHPORTS);
 
-				if (cmdline_parse_etheraddr(NULL, port_end,
-						&peer_addr, sizeof(peer_addr)) < 0)
+				if (rte_ether_unformat_addr(port_end,
+							    &peer_eth_addrs[n]) < 0)
 					rte_exit(EXIT_FAILURE,
 						 "Invalid ethernet address: %s\n",
 						 port_end);
-				for (c = 0; c < 6; c++)
-					peer_eth_addrs[n].addr_bytes[c] =
-						peer_addr[c];
 				nb_peer_eth_addrs++;
 			}
 #endif
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 09/12] net/virtio: use new ether addr parsing
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (7 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 08/12] app/testpmd: " Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 10/12] net/failsafe: use common ether address parsing routine Stephen Hemminger
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/virtio/virtio_user/virtio_user_dev.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index e743695e4510..0bac725e7cdd 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -225,17 +225,13 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
 static inline void
 parse_mac(struct virtio_user_dev *dev, const char *mac)
 {
-	int i, r;
-	uint32_t tmp[RTE_ETHER_ADDR_LEN];
+	struct rte_ether_addr tmp;
 
 	if (!mac)
 		return;
 
-	r = sscanf(mac, "%x:%x:%x:%x:%x:%x", &tmp[0],
-			&tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
-	if (r == RTE_ETHER_ADDR_LEN) {
-		for (i = 0; i < RTE_ETHER_ADDR_LEN; ++i)
-			dev->mac_addr[i] = (uint8_t)tmp[i];
+	if (rte_ether_unformat_addr(mac, &tmp) == 0) {
+		memcpy(dev->mac_addr, &tmp, RTE_ETHER_ADDR_LEN);
 		dev->mac_specified = 1;
 	} else {
 		/* ignore the wrong mac, use random mac */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 10/12] net/failsafe: use common ether address parsing routine
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (8 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 09/12] net/virtio: use new ether addr parsing Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-03  9:10     ` Gaëtan Rivet
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 11/12] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 12/12] net/memif: use common ethernet address parsing routine Stephen Hemminger
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/failsafe/failsafe_args.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/net/failsafe/failsafe_args.c b/drivers/net/failsafe/failsafe_args.c
index d2e725bcea13..707490b94c4e 100644
--- a/drivers/net/failsafe/failsafe_args.c
+++ b/drivers/net/failsafe/failsafe_args.c
@@ -368,15 +368,11 @@ fs_get_mac_addr_arg(const char *key __rte_unused,
 		const char *value, void *out)
 {
 	struct rte_ether_addr *ea = out;
-	int ret;
 
 	if ((value == NULL) || (out == NULL))
 		return -EINVAL;
-	ret = sscanf(value, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-		&ea->addr_bytes[0], &ea->addr_bytes[1],
-		&ea->addr_bytes[2], &ea->addr_bytes[3],
-		&ea->addr_bytes[4], &ea->addr_bytes[5]);
-	return ret != RTE_ETHER_ADDR_LEN;
+
+	return rte_ether_unformat_addr(value, ea);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 11/12] net/vdev_netvsc: use common ethernet address parsing
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (9 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 10/12] net/failsafe: use common ether address parsing routine Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  2019-07-03  8:12     ` Matan Azrad
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 12/12] net/memif: use common ethernet address parsing routine Stephen Hemminger
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/vdev_netvsc/vdev_netvsc.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/net/vdev_netvsc/vdev_netvsc.c b/drivers/net/vdev_netvsc/vdev_netvsc.c
index 1fcf90d7bc02..be8f19c0c63e 100644
--- a/drivers/net/vdev_netvsc/vdev_netvsc.c
+++ b/drivers/net/vdev_netvsc/vdev_netvsc.c
@@ -529,15 +529,7 @@ vdev_netvsc_netvsc_probe(const struct if_nameindex *iface,
 			} else if (!strcmp(pair->key, VDEV_NETVSC_ARG_MAC)) {
 				struct rte_ether_addr tmp;
 
-				if (sscanf(pair->value,
-					   "%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":"
-					   "%" SCNx8 ":%" SCNx8 ":%" SCNx8,
-					   &tmp.addr_bytes[0],
-					   &tmp.addr_bytes[1],
-					   &tmp.addr_bytes[2],
-					   &tmp.addr_bytes[3],
-					   &tmp.addr_bytes[4],
-					   &tmp.addr_bytes[5]) != 6) {
+				if (rte_ether_unformat_addr(pair->value, &tmp) != 0) {
 					DRV_LOG(ERR,
 						"invalid MAC address format"
 						" \"%s\"",
-- 
2.20.1


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

* [dpdk-dev] [PATCH v7 12/12] net/memif: use common ethernet address parsing routine
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
                     ` (10 preceding siblings ...)
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 11/12] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
@ 2019-07-02 22:12   ` Stephen Hemminger
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-02 22:12 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/memif/rte_eth_memif.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/memif/rte_eth_memif.c b/drivers/net/memif/rte_eth_memif.c
index e9ddf6413597..00c9b396ab85 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -1224,13 +1224,8 @@ static int
 memif_set_mac(const char *key __rte_unused, const char *value, void *extra_args)
 {
 	struct rte_ether_addr *ether_addr = (struct rte_ether_addr *)extra_args;
-	int ret = 0;
 
-	ret = sscanf(value, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-	       &ether_addr->addr_bytes[0], &ether_addr->addr_bytes[1],
-	       &ether_addr->addr_bytes[2], &ether_addr->addr_bytes[3],
-	       &ether_addr->addr_bytes[4], &ether_addr->addr_bytes[5]);
-	if (ret != 6)
+	if (rte_ether_unformat_addr(value, ether_addr) < 0)
 		MIF_LOG(WARNING, "Failed to parse mac '%s'.", value);
 	return 0;
 }
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v7 11/12] net/vdev_netvsc: use common ethernet address parsing
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 11/12] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
@ 2019-07-03  8:12     ` Matan Azrad
  0 siblings, 0 replies; 127+ messages in thread
From: Matan Azrad @ 2019-07-03  8:12 UTC (permalink / raw)
  To: Stephen Hemminger, dev



From: Stephen Hemminger
> Use rte_ether_unformat_addr rather than sscanf.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Matan Azrad <matan@mellanox.com>

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

* Re: [dpdk-dev] [PATCH v7 10/12] net/failsafe: use common ether address parsing routine
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 10/12] net/failsafe: use common ether address parsing routine Stephen Hemminger
@ 2019-07-03  9:10     ` Gaëtan Rivet
  0 siblings, 0 replies; 127+ messages in thread
From: Gaëtan Rivet @ 2019-07-03  9:10 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Tue, Jul 02, 2019 at 03:12:45PM -0700, Stephen Hemminger wrote:
> Use rte_ether_unformat_addr rather than sscanf.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>


-- 
Gaëtan Rivet
6WIND

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

* Re: [dpdk-dev] [PATCH v7 08/12] app/testpmd: use new ethernet address parser
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 08/12] app/testpmd: " Stephen Hemminger
@ 2019-07-03 13:30     ` Iremonger, Bernard
  2019-07-05 17:12       ` Stephen Hemminger
  0 siblings, 1 reply; 127+ messages in thread
From: Iremonger, Bernard @ 2019-07-03 13:30 UTC (permalink / raw)
  To: Stephen Hemminger, dev

Hi Stephen,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen
> Hemminger
> Sent: Tuesday, July 2, 2019 11:13 PM
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>
> Subject: [dpdk-dev] [PATCH v7 08/12] app/testpmd: use new ethernet
> address parser
> 
> The cmdline_parse_ether_addr does not need to be used everywhere in
> testpmd. Can use rte_ether_unformat_addr instead.
> As an added bonus it eliminates some code for copying.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  app/test-pmd/cmdline_flow.c |  5 ++---
>  app/test-pmd/config.c       | 10 +++-------
>  app/test-pmd/parameters.c   | 15 +++------------
>  3 files changed, 8 insertions(+), 22 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 201bd9de56e0..2b02ca29b7ac 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -18,7 +18,6 @@
>  #include <rte_ethdev.h>
>  #include <rte_byteorder.h>
>  #include <cmdline_parse.h>
> -#include <cmdline_parse_etheraddr.h>
>  #include <rte_flow.h>
> 
>  #include "testpmd.h"
> @@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct
> token *token,
>  	/* Only network endian is supported. */
>  	if (!arg->hton)
>  		goto error;
> -	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
> -	if (ret < 0 || (unsigned int)ret != len)
> +	ret = rte_ether_unformat_addr(str, &tmp);
> +	if (ret < 0)
>  		goto error;
>  	if (!ctx->object)
>  		return len;
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> ab458c8d2837..1d804705d96c 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -49,7 +49,6 @@
>  #include <rte_pmd_bnxt.h>
>  #endif
>  #include <rte_gro.h>
> -#include <cmdline_parse_etheraddr.h>
>  #include <rte_config.h>
> 
>  #include "testpmd.h"
> @@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
> void  set_fwd_eth_peer(portid_t port_id, char *peer_addr)  {
> -	uint8_t c, new_peer_addr[6];
> +	struct rte_ether_addr new_peer_addr;
>  	if (!rte_eth_dev_is_valid_port(port_id)) {
>  		printf("Error: Invalid port number %i\n", port_id);
>  		return;
>  	}
> -	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
> -					sizeof(new_peer_addr)) < 0) {
> +	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
>  		printf("Error: Invalid ethernet address: %s\n", peer_addr);
>  		return;
>  	}
> -	for (c = 0; c < 6; c++)
> -		peer_eth_addrs[port_id].addr_bytes[c] =
> -			new_peer_addr[c];
> +	peer_eth_addrs[port_id] = new_peer_addr;
>  }
> 
>  int
> diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index
> 245b610641ee..975a97807009 100644
> --- a/app/test-pmd/parameters.c
> +++ b/app/test-pmd/parameters.c
> @@ -39,10 +39,6 @@
>  #include <rte_ether.h>
>  #include <rte_ethdev.h>
>  #include <rte_string_fns.h>
> -#ifdef RTE_LIBRTE_CMDLINE
> -#include <cmdline_parse.h>
> -#include <cmdline_parse_etheraddr.h>
> -#endif
>  #ifdef RTE_LIBRTE_PMD_BOND
>  #include <rte_eth_bond.h>
>  #endif
> @@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
>  		if (fgets(buf, sizeof(buf), config_file) == NULL)
>  			break;
> 
> -		if (cmdline_parse_etheraddr(NULL, buf,
> &peer_eth_addrs[i],
> -				sizeof(peer_eth_addrs[i])) < 0) {
> +		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
>  			printf("Bad MAC address format on line %d\n", i+1);
>  			fclose(config_file);
>  			return -1;
> @@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
>  			}
>  			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
>  				char *port_end;
> -				uint8_t c, peer_addr[6];
> 
>  				errno = 0;
>  				n = strtoul(optarg, &port_end, 10); @@ -
> 739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
>  						 "eth-peer: port %d >=
> RTE_MAX_ETHPORTS(%d)\n",
>  						 n, RTE_MAX_ETHPORTS);
> 
> -				if (cmdline_parse_etheraddr(NULL,
> port_end,
> -						&peer_addr,
> sizeof(peer_addr)) < 0)
> +				if (rte_ether_unformat_addr(port_end,
> +
> &peer_eth_addrs[n]) < 0)
>  					rte_exit(EXIT_FAILURE,
>  						 "Invalid ethernet address:
> %s\n",
>  						 port_end);
> -				for (c = 0; c < 6; c++)
> -					peer_eth_addrs[n].addr_bytes[c] =
> -						peer_addr[c];
>  				nb_peer_eth_addrs++;
>  			}
>  #endif
> --
> 2.20.1

./devtools/checkpatches.sh v7-08-12-app-testpmd-use-new-ethernet-address-parser.patch

WARNING:LONG_LINE: line over 80 characters
#126: FILE: app/test-pmd/parameters.c:737:
+                                                           &peer_eth_addrs[n]) < 0)

No harm to fix this, otherwise

Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>

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

* Re: [dpdk-dev] [PATCH v7 02/12] net/ether: add function to convert string to ethernet address
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 02/12] net/ether: add function to convert string to ethernet address Stephen Hemminger
@ 2019-07-05 14:25     ` Olivier Matz
  0 siblings, 0 replies; 127+ messages in thread
From: Olivier Matz @ 2019-07-05 14:25 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Andrew Rybchenko

Hi,

On Tue, Jul 02, 2019 at 03:12:37PM -0700, Stephen Hemminger wrote:
> Make a function that can be used in place of eth_aton_r
> to convert a string to rte_ether_addr. This function
> allows both byte (xx:xx:xx:xx:xx:xx) and word (XXXX:XXXX:XXXX)
> format and has the same lack of error handling as the original.
> 
> This also allows ethdev to no longer have a hard dependency
> on the cmdline library.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>  lib/librte_net/rte_ether.c         | 47 ++++++++++++++++++++++++++++++
>  lib/librte_net/rte_ether.h         | 14 +++++++++
>  lib/librte_net/rte_net_version.map |  1 +
>  3 files changed, 62 insertions(+)
> 
> diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
> index 974fe815b335..acc8a0e938c5 100644
> --- a/lib/librte_net/rte_ether.c
> +++ b/lib/librte_net/rte_ether.c
> @@ -27,3 +27,50 @@ rte_ether_format_addr(char *buf, uint16_t size,
>  		 eth_addr->addr_bytes[4],
>  		 eth_addr->addr_bytes[5]);
>  }
> +
> +/*
> + * Like ether_aton_r but can handle either
> + * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
> + */
> +int
> +rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
> +{
> +	unsigned int o0, o1, o2, o3, o4, o5;
> +	int n;
> +
> +	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
> +		    &o0, &o1, &o2, &o3, &o4, &o5);
> +
> +	if (n == 6) {
> +		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
> +		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX)
> +			return -1;
> +
> +		ea->addr_bytes[0] = o0;
> +		ea->addr_bytes[1] = o1;
> +		ea->addr_bytes[2] = o2;
> +		ea->addr_bytes[3] = o3;
> +		ea->addr_bytes[4] = o4;
> +		ea->addr_bytes[5] = o5;
> +
> +		return 0;
> +	}
> +
> +	/* Support the format XXXX:XXXX:XXXX */
> +	n = sscanf(s, "%x:%x:%x", &o0, &o1, &o2);
> +	if (n == 3) {
> +		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX)
> +			return -1;
> +
> +		ea->addr_bytes[0] = o0 >> 8;
> +		ea->addr_bytes[1] = o0 & 0xff;
> +		ea->addr_bytes[2] = o1 >> 8;
> +		ea->addr_bytes[3] = o1 & 0xff;
> +		ea->addr_bytes[4] = o2 >> 8;
> +		ea->addr_bytes[5] = o2 & 0xff;
> +		return 0;
> +	}
> +	/* unknown format */
> +
> +	return -1;
> +}
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index 3caae0d98f6d..8edc7e217b25 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -250,6 +250,20 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
>  void
>  rte_ether_format_addr(char *buf, uint16_t size,
>  		      const struct rte_ether_addr *eth_addr);
> +/**
> + * Convert string with Ethernet address to an ether_addr.
> + *
> + * @param str
> + *   A pointer to buffer contains the formatted MAC address.
> + * @param eth_addr
> + *   A pointer to a ether_addr structure.
> + * @return
> + *   0 if successful
> + *   -1 and sets rte_errno if invalid string

Is rte_errno really set?


> + */
> +int __rte_experimental
> +rte_ether_unformat_addr(const char *str, struct rte_ether_addr *eth_addr);
> +
>  /**
>   * Ethernet header: Contains the destination address, source address
>   * and frame type.
> diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
> index f1e1b84ab491..f4c915069d57 100644
> --- a/lib/librte_net/rte_net_version.map
> +++ b/lib/librte_net/rte_net_version.map
> @@ -25,4 +25,5 @@ EXPERIMENTAL {
>  
>  	rte_net_make_rarp_packet;
>  	rte_net_skip_ip6_ext;
> +	rte_ether_unformat_addr;
>  };
> -- 
> 2.20.1
> 

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

* Re: [dpdk-dev] [PATCH v7 01/12] net/rte_ether: deinline non-critical functions
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 01/12] net/rte_ether: deinline non-critical functions Stephen Hemminger
@ 2019-07-05 14:25     ` Olivier Matz
  0 siblings, 0 replies; 127+ messages in thread
From: Olivier Matz @ 2019-07-05 14:25 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Rami Rosen, Andrew Rybchenko

On Tue, Jul 02, 2019 at 03:12:36PM -0700, Stephen Hemminger wrote:
> Formatting Ethernet address and getting a random value are
> not in critical path so they should not be inlined.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Acked-by: Rami Rosen <ramirose@gmail.com>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

just a nit in the title: net/ether instead of net/rte_ether for
consistency with other patches

Acked-by: Olivier Matz <olivier.matz@6wind.com>

Thanks

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

* Re: [dpdk-dev] [PATCH v7 05/12] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 05/12] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
@ 2019-07-05 14:34     ` Olivier Matz
  2019-07-05 15:45       ` Richardson, Bruce
  0 siblings, 1 reply; 127+ messages in thread
From: Olivier Matz @ 2019-07-05 14:34 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Bruce Richardson, Andrew Rybchenko

On Tue, Jul 02, 2019 at 03:12:40PM -0700, Stephen Hemminger wrote:
> From: Bruce Richardson <bruce.richardson@intel.com>
> 
> When including the rte_ether.h header in applications with warnings
> enabled, a warning was given because of the assumption of 2-byte alignment
> of ethernet addresses when processing them.
> 
> .../include/rte_ether.h:149:2: warning: converting a packed ‘const
>   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
>   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
>   an unaligned pointer value [-Waddress-of-packed-member]
> 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
>     |  ^~~~~
> 
> Since ethernet addresses should always be aligned on a two-byte boundary,
> we can just inform the compiler of this assumption to remove the warnings
> and allow us to always access the addresses using 16-bit operations.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>  lib/librte_net/rte_ether.h | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index feb35a33c94b..d7b76ddf63eb 100644
> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -58,7 +58,8 @@ extern "C" {
>   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
>   */
>  struct rte_ether_addr {
> -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
> +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> +	/**< Addr bytes in tx order */
>  } __attribute__((__packed__));
>  
>  #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
> @@ -81,8 +82,8 @@ struct rte_ether_addr {
>  static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
>  				     const struct rte_ether_addr *ea2)
>  {
> -	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
> -	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
> +	const uint16_t *w1 = (const uint16_t *)ea1;
> +	const uint16_t *w2 = (const uint16_t *)ea2;
>  
>  	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
>  }
> @@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
>   */
>  static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
>  {
> -	const unaligned_uint16_t *w = (const uint16_t *)ea;
> +	const uint16_t *w = (const uint16_t *)ea;
>  
>  	return (w[0] | w[1] | w[2]) == 0;
>  }
> @@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
>   */
>  static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
>  {
> -	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
> +	const uint16_t *ea_words = (const uint16_t *)ea;
>  
>  	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
>  		ea_words[2] == 0xFFFF);
> -- 
> 2.20.1
> 

Following this discussion:
https://mails.dpdk.org/archives/dev/2019-July/136590.html

I still think that changing the ABI without deprecation notice
is not a good idea.

The warning issued by the compiler makes me think that the definition of
unaligned_uint16_t is wrong on intel arch. I made a quick test, and it
seems that in this particular case, the generated code is the same with
or without __attribute__((aligned(1))). See: https://godbolt.org/z/NjBNQk

But changing the definition of unaligned_uint16_t without a deprecation
notice is not an option either.

What do you think about using a specific typedef similar to
unaligned_uint16_t in rte_ether, that has the __attribute__((aligned(1))) ?
It would avoid to change the alignment of struct rte_ether_addr.

In parallel, we can talk about changing unaligned_uint16_t for intel
in another patchset.

Olivier

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

* Re: [dpdk-dev] [PATCH v7 04/12] net/ether: use bitops to speedup comparison
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 04/12] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-07-05 14:34     ` Olivier Matz
  0 siblings, 0 replies; 127+ messages in thread
From: Olivier Matz @ 2019-07-05 14:34 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Andrew Rybchenko

On Tue, Jul 02, 2019 at 03:12:39PM -0700, Stephen Hemminger wrote:
> Using bit operations like or and xor is faster than a loop
> on all architectures. Really just explicit unrolling.
> 
> Similar cast to uint16 unaligned is already done in
> other functions here.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

Acked-by: Olivier Matz <olivier.matz@6wind.com>

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

* Re: [dpdk-dev] [PATCH v7 06/12] cmdline: use new ethernet address parser
  2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 06/12] cmdline: use new ethernet address parser Stephen Hemminger
@ 2019-07-05 14:46     ` Olivier Matz
  0 siblings, 0 replies; 127+ messages in thread
From: Olivier Matz @ 2019-07-05 14:46 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Tue, Jul 02, 2019 at 03:12:41PM -0700, Stephen Hemminger wrote:
> Now that there is a version of ether_aton in rte_ether, it can
> be used by the cmdline ethernet address parser.
> 
> Note: ether_aton_r can not be used in cmdline because
> the old code would accept either bytes XX:XX:XX:XX:XX:XX
> or words XXXX:XXXX:XXXX and we need to keep compatiablity.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Acked-by: Olivier Matz <olivier.matz@6wind.com>

Thanks!

BTW, I noticed that it also fixes a more serious bug: the previous
commandline parser was using a static buffer, making it thread-unsafe.
I didn't see any places that could have been impacted.

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

* Re: [dpdk-dev] [PATCH v7 05/12] net/ether: mark ethernet addresses as being 2-byte aligned
  2019-07-05 14:34     ` Olivier Matz
@ 2019-07-05 15:45       ` Richardson, Bruce
  0 siblings, 0 replies; 127+ messages in thread
From: Richardson, Bruce @ 2019-07-05 15:45 UTC (permalink / raw)
  To: Olivier Matz, Stephen Hemminger; +Cc: dev, Andrew Rybchenko



> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Friday, July 5, 2019 3:34 PM
> To: Stephen Hemminger <stephen@networkplumber.org>
> Cc: dev@dpdk.org; Richardson, Bruce <bruce.richardson@intel.com>; Andrew
> Rybchenko <arybchenko@solarflare.com>
> Subject: Re: [dpdk-dev] [PATCH v7 05/12] net/ether: mark ethernet
> addresses as being 2-byte aligned
> 
> On Tue, Jul 02, 2019 at 03:12:40PM -0700, Stephen Hemminger wrote:
> > From: Bruce Richardson <bruce.richardson@intel.com>
> >
> > When including the rte_ether.h header in applications with warnings
> > enabled, a warning was given because of the assumption of 2-byte
> > alignment of ethernet addresses when processing them.
> >
> > .../include/rte_ether.h:149:2: warning: converting a packed ‘const
> >   struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’
> >   {aka ‘const short unsigned int’} pointer (alignment 2) may result in
> >   an unaligned pointer value [-Waddress-of-packed-member]
> > 149 |  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t
> *)ea;
> >     |  ^~~~~
> >
> > Since ethernet addresses should always be aligned on a two-byte
> > boundary, we can just inform the compiler of this assumption to remove
> > the warnings and allow us to always access the addresses using 16-bit
> operations.
> >
> > Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > ---
> >  lib/librte_net/rte_ether.h | 11 ++++++-----
> >  1 file changed, 6 insertions(+), 5 deletions(-)
> >
> > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > index feb35a33c94b..d7b76ddf63eb 100644
> > --- a/lib/librte_net/rte_ether.h
> > +++ b/lib/librte_net/rte_ether.h
> > @@ -58,7 +58,8 @@ extern "C" {
> >   * See http://standards.ieee.org/regauth/groupmac/tutorial.html
> >   */
> >  struct rte_ether_addr {
> > -	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order
> */
> > +	uint8_t addr_bytes[RTE_ETHER_ADDR_LEN] __rte_aligned(2);
> > +	/**< Addr bytes in tx order */
> >  } __attribute__((__packed__));
> >
> >  #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth.
> > address. */ @@ -81,8 +82,8 @@ struct rte_ether_addr {  static inline
> > int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
> >  				     const struct rte_ether_addr *ea2)  {
> > -	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
> > -	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
> > +	const uint16_t *w1 = (const uint16_t *)ea1;
> > +	const uint16_t *w2 = (const uint16_t *)ea2;
> >
> >  	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
> > } @@ -99,7 +100,7 @@ static inline int rte_is_same_ether_addr(const
> > struct rte_ether_addr *ea1,
> >   */
> >  static inline int rte_is_zero_ether_addr(const struct rte_ether_addr
> > *ea)  {
> > -	const unaligned_uint16_t *w = (const uint16_t *)ea;
> > +	const uint16_t *w = (const uint16_t *)ea;
> >
> >  	return (w[0] | w[1] | w[2]) == 0;
> >  }
> > @@ -146,7 +147,7 @@ static inline int rte_is_multicast_ether_addr(const
> struct rte_ether_addr *ea)
> >   */
> >  static inline int rte_is_broadcast_ether_addr(const struct
> > rte_ether_addr *ea)  {
> > -	const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
> > +	const uint16_t *ea_words = (const uint16_t *)ea;
> >
> >  	return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
> >  		ea_words[2] == 0xFFFF);
> > --
> > 2.20.1
> >
> 
> Following this discussion:
> https://mails.dpdk.org/archives/dev/2019-July/136590.html
> 
> I still think that changing the ABI without deprecation notice
> is not a good idea.
> 
I'm ok with that. Let's put in a deprecation notice and take this
patch in 19.11.

> The warning issued by the compiler makes me think that the definition of
> unaligned_uint16_t is wrong on intel arch. I made a quick test, and it
> seems that in this particular case, the generated code is the same with
> or without __attribute__((aligned(1))). See: https://godbolt.org/z/NjBNQk
> 
> But changing the definition of unaligned_uint16_t without a deprecation
> notice is not an option either.
> 
> What do you think about using a specific typedef similar to
> unaligned_uint16_t in rte_ether, that has the __attribute__((aligned(1)))
> ?
> It would avoid to change the alignment of struct rte_ether_addr.
> 

I'd like the alignment changed. Since the existing warnings about alignment don’t
seem to be causing anyone any real problems, I suggest we just leave them for
now and fix them by changing the alignment setting for 19.11.

> In parallel, we can talk about changing unaligned_uint16_t for intel
> in another patchset.
> 

Yes, let's fix the broken unaligned definition as a separate issue.

/Bruce

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

* Re: [dpdk-dev] [PATCH v7 08/12] app/testpmd: use new ethernet address parser
  2019-07-03 13:30     ` Iremonger, Bernard
@ 2019-07-05 17:12       ` Stephen Hemminger
  0 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:12 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: dev

On Wed, 3 Jul 2019 13:30:35 +0000
"Iremonger, Bernard" <bernard.iremonger@intel.com> wrote:

> Hi Stephen,
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Stephen
> > Hemminger
> > Sent: Tuesday, July 2, 2019 11:13 PM
> > To: dev@dpdk.org
> > Cc: Stephen Hemminger <stephen@networkplumber.org>
> > Subject: [dpdk-dev] [PATCH v7 08/12] app/testpmd: use new ethernet
> > address parser
> > 
> > The cmdline_parse_ether_addr does not need to be used everywhere in
> > testpmd. Can use rte_ether_unformat_addr instead.
> > As an added bonus it eliminates some code for copying.
> > 
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > ---
> >  app/test-pmd/cmdline_flow.c |  5 ++---
> >  app/test-pmd/config.c       | 10 +++-------
> >  app/test-pmd/parameters.c   | 15 +++------------
> >  3 files changed, 8 insertions(+), 22 deletions(-)
> > 
> > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> > index 201bd9de56e0..2b02ca29b7ac 100644
> > --- a/app/test-pmd/cmdline_flow.c
> > +++ b/app/test-pmd/cmdline_flow.c
> > @@ -18,7 +18,6 @@
> >  #include <rte_ethdev.h>
> >  #include <rte_byteorder.h>
> >  #include <cmdline_parse.h>
> > -#include <cmdline_parse_etheraddr.h>
> >  #include <rte_flow.h>
> > 
> >  #include "testpmd.h"
> > @@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct
> > token *token,
> >  	/* Only network endian is supported. */
> >  	if (!arg->hton)
> >  		goto error;
> > -	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
> > -	if (ret < 0 || (unsigned int)ret != len)
> > +	ret = rte_ether_unformat_addr(str, &tmp);
> > +	if (ret < 0)
> >  		goto error;
> >  	if (!ctx->object)
> >  		return len;
> > diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> > ab458c8d2837..1d804705d96c 100644
> > --- a/app/test-pmd/config.c
> > +++ b/app/test-pmd/config.c
> > @@ -49,7 +49,6 @@
> >  #include <rte_pmd_bnxt.h>
> >  #endif
> >  #include <rte_gro.h>
> > -#include <cmdline_parse_etheraddr.h>
> >  #include <rte_config.h>
> > 
> >  #include "testpmd.h"
> > @@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
> > void  set_fwd_eth_peer(portid_t port_id, char *peer_addr)  {
> > -	uint8_t c, new_peer_addr[6];
> > +	struct rte_ether_addr new_peer_addr;
> >  	if (!rte_eth_dev_is_valid_port(port_id)) {
> >  		printf("Error: Invalid port number %i\n", port_id);
> >  		return;
> >  	}
> > -	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
> > -					sizeof(new_peer_addr)) < 0) {
> > +	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
> >  		printf("Error: Invalid ethernet address: %s\n", peer_addr);
> >  		return;
> >  	}
> > -	for (c = 0; c < 6; c++)
> > -		peer_eth_addrs[port_id].addr_bytes[c] =
> > -			new_peer_addr[c];
> > +	peer_eth_addrs[port_id] = new_peer_addr;
> >  }
> > 
> >  int
> > diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index
> > 245b610641ee..975a97807009 100644
> > --- a/app/test-pmd/parameters.c
> > +++ b/app/test-pmd/parameters.c
> > @@ -39,10 +39,6 @@
> >  #include <rte_ether.h>
> >  #include <rte_ethdev.h>
> >  #include <rte_string_fns.h>
> > -#ifdef RTE_LIBRTE_CMDLINE
> > -#include <cmdline_parse.h>
> > -#include <cmdline_parse_etheraddr.h>
> > -#endif
> >  #ifdef RTE_LIBRTE_PMD_BOND
> >  #include <rte_eth_bond.h>
> >  #endif
> > @@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
> >  		if (fgets(buf, sizeof(buf), config_file) == NULL)
> >  			break;
> > 
> > -		if (cmdline_parse_etheraddr(NULL, buf,
> > &peer_eth_addrs[i],
> > -				sizeof(peer_eth_addrs[i])) < 0) {
> > +		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
> >  			printf("Bad MAC address format on line %d\n", i+1);
> >  			fclose(config_file);
> >  			return -1;
> > @@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
> >  			}
> >  			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
> >  				char *port_end;
> > -				uint8_t c, peer_addr[6];
> > 
> >  				errno = 0;
> >  				n = strtoul(optarg, &port_end, 10); @@ -
> > 739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
> >  						 "eth-peer: port %d >=
> > RTE_MAX_ETHPORTS(%d)\n",
> >  						 n, RTE_MAX_ETHPORTS);
> > 
> > -				if (cmdline_parse_etheraddr(NULL,
> > port_end,
> > -						&peer_addr,
> > sizeof(peer_addr)) < 0)
> > +				if (rte_ether_unformat_addr(port_end,
> > +
> > &peer_eth_addrs[n]) < 0)
> >  					rte_exit(EXIT_FAILURE,
> >  						 "Invalid ethernet address:
> > %s\n",
> >  						 port_end);
> > -				for (c = 0; c < 6; c++)
> > -					peer_eth_addrs[n].addr_bytes[c] =
> > -						peer_addr[c];
> >  				nb_peer_eth_addrs++;
> >  			}
> >  #endif
> > --
> > 2.20.1  
> 
> ./devtools/checkpatches.sh v7-08-12-app-testpmd-use-new-ethernet-address-parser.patch
> 
> WARNING:LONG_LINE: line over 80 characters
> #126: FILE: app/test-pmd/parameters.c:737:
> +                                                           &peer_eth_addrs[n]) < 0)
> 
> No harm to fix this, otherwise

Fixing the long lines (the right way) would require refactoring testpmd here.
Not something I want to do.

> 
> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>


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

* [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (11 preceding siblings ...)
  2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
@ 2019-07-05 17:16 ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 01/11] net/ether: deinline non-critical functions Stephen Hemminger
                     ` (10 more replies)
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
  13 siblings, 11 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of patches around the ethernet address
manipulation routines in librte_net/rte_ether.

v8
   set rte_errno in rte_eth_unformat_addr
   drop ether_address alignment patch. Bruce can handle deprecation
   and sending the patches later
v7
   use rte_ether_unformat_addr in more drivers
v6
   add librte_net to axgbe and memif Makefile
v5
   reword commit messages to workaround check-log complaints
v4
   fix meson build
   reword commit messages
   add bonding and tespmd patches
v3 
   rebase to use rte_ether prefix
   drop aligning ethernet headers for now.

Stephen Hemminger (11):
  net/ether: deinline non-critical functions
  net/ether: add function to convert string to ethernet address
  ethdev: use new ethernet parsing function
  net/ether: use bitops to speedup comparison
  cmdline: use new ethernet address parser
  net/bonding: use new ethernet address parser
  app/testpmd: use new ethernet address parser
  net/virtio: use new ether addr parsing
  net/failsafe: use common ether address parsing routine
  net/vdev_netvsc: use common ethernet address parsing
  net/memif: use common ethernet address parsing routine

 app/test-pmd/cmdline_flow.c                   |  5 +-
 app/test-pmd/config.c                         | 10 +--
 app/test-pmd/parameters.c                     | 15 +---
 drivers/net/axgbe/Makefile                    |  2 +-
 drivers/net/bonding/Makefile                  |  2 +-
 drivers/net/bonding/meson.build               |  2 +-
 drivers/net/bonding/rte_eth_bond_args.c       |  6 +-
 drivers/net/failsafe/failsafe_args.c          |  8 +-
 drivers/net/memif/Makefile                    |  2 +-
 drivers/net/memif/rte_eth_memif.c             |  7 +-
 drivers/net/vdev_netvsc/vdev_netvsc.c         | 10 +--
 .../net/virtio/virtio_user/virtio_user_dev.c  | 10 +--
 lib/Makefile                                  |  3 +-
 lib/librte_cmdline/Makefile                   |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c  | 71 ++---------------
 lib/librte_cmdline/meson.build                |  6 +-
 lib/librte_ethdev/Makefile                    |  2 +-
 lib/librte_ethdev/meson.build                 |  2 +-
 lib/librte_ethdev/rte_class_eth.c             |  9 +--
 lib/librte_net/Makefile                       |  1 +
 lib/librte_net/meson.build                    |  2 +-
 lib/librte_net/rte_ether.c                    | 78 +++++++++++++++++++
 lib/librte_net/rte_ether.h                    | 54 ++++++-------
 lib/librte_net/rte_net_version.map            |  8 ++
 lib/meson.build                               |  2 +-
 25 files changed, 150 insertions(+), 170 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 01/11] net/ether: deinline non-critical functions
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 02/11] net/ether: add function to convert string to ethernet address Stephen Hemminger
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Rami Rosen, Andrew Rybchenko, Olivier Matz

Formatting Ethernet address and getting a random value are
not in critical path so they should not be inlined.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Rami Rosen <ramirose@gmail.com>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/axgbe/Makefile         |  2 +-
 drivers/net/memif/Makefile         |  2 +-
 lib/librte_net/Makefile            |  1 +
 lib/librte_net/meson.build         |  2 +-
 lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 25 ++++---------------------
 lib/librte_net/rte_net_version.map |  7 +++++++
 7 files changed, 44 insertions(+), 24 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

diff --git a/drivers/net/axgbe/Makefile b/drivers/net/axgbe/Makefile
index 72215aedaf55..c2d4336800c0 100644
--- a/drivers/net/axgbe/Makefile
+++ b/drivers/net/axgbe/Makefile
@@ -17,7 +17,7 @@ LIBABIVER := 1
 
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_pci -lrte_bus_pci
-LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_ethdev -lrte_net
 
 #
 # all source are stored in SRCS-y
diff --git a/drivers/net/memif/Makefile b/drivers/net/memif/Makefile
index fdbdf3378019..3d92b08f259b 100644
--- a/drivers/net/memif/Makefile
+++ b/drivers/net/memif/Makefile
@@ -21,7 +21,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 # - rte_mp_reply
 # - rte_mp_request_sync
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
-LDLIBS += -lrte_ethdev -lrte_kvargs
+LDLIBS += -lrte_ethdev -lrte_kvargs -lrte_net
 LDLIBS += -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index c3082069ab50..1244c9fd54c9 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -14,6 +14,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
+SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 
 # install includes
diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build
index 7d66f693cbf3..868a93fd6b6b 100644
--- a/lib/librte_net/meson.build
+++ b/lib/librte_net/meson.build
@@ -16,5 +16,5 @@ headers = files('rte_ip.h',
 	'rte_net_crc.h',
 	'rte_mpls.h')
 
-sources = files('rte_arp.c', 'rte_net.c', 'rte_net_crc.c')
+sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c')
 deps += ['mbuf']
diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
new file mode 100644
index 000000000000..974fe815b335
--- /dev/null
+++ b/lib/librte_net/rte_ether.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_ether.h>
+
+void
+rte_eth_random_addr(uint8_t *addr)
+{
+	uint64_t rand = rte_rand();
+	uint8_t *p = (uint8_t *)&rand;
+
+	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
+	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;	/* clear multicast bit */
+	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
+}
+
+void
+rte_ether_format_addr(char *buf, uint16_t size,
+		      const struct rte_ether_addr *eth_addr)
+{
+	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
+		 eth_addr->addr_bytes[0],
+		 eth_addr->addr_bytes[1],
+		 eth_addr->addr_bytes[2],
+		 eth_addr->addr_bytes[3],
+		 eth_addr->addr_bytes[4],
+		 eth_addr->addr_bytes[5]);
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 1868cb7077d2..df1a51462a37 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -207,15 +207,8 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *
  * @param addr
  *   A pointer to Ethernet address.
  */
-static inline void rte_eth_random_addr(uint8_t *addr)
-{
-	uint64_t rand = rte_rand();
-	uint8_t *p = (uint8_t *)&rand;
-
-	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
-	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;  /* clear multicast bit */
-	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
-}
+void
+rte_eth_random_addr(uint8_t *addr);
 
 /**
  * Fast copy an Ethernet address.
@@ -254,19 +247,9 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
  * @param eth_addr
  *   A pointer to a ether_addr structure.
  */
-static inline void
+void
 rte_ether_format_addr(char *buf, uint16_t size,
-		  const struct rte_ether_addr *eth_addr)
-{
-	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 eth_addr->addr_bytes[0],
-		 eth_addr->addr_bytes[1],
-		 eth_addr->addr_bytes[2],
-		 eth_addr->addr_bytes[3],
-		 eth_addr->addr_bytes[4],
-		 eth_addr->addr_bytes[5]);
-}
-
+		      const struct rte_ether_addr *eth_addr);
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 26c06e7c7ae7..f1e1b84ab491 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -13,6 +13,13 @@ DPDK_17.05 {
 
 } DPDK_16.11;
 
+DPDK_19.08 {
+	global:
+
+	rte_eth_random_addr;
+	rte_ether_format_addr;
+} DPDK_17.05;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 02/11] net/ether: add function to convert string to ethernet address
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 01/11] net/ether: deinline non-critical functions Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 03/11] ethdev: use new ethernet parsing function Stephen Hemminger
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Make a function that can be used in place of eth_aton_r
to convert a string to rte_ether_addr. This function
allows both byte (xx:xx:xx:xx:xx:xx) and word (XXXX:XXXX:XXXX)
format and has the same lack of error handling as the original.

This also allows ethdev to no longer have a hard dependency
on the cmdline library.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.c         | 49 ++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 14 +++++++++
 lib/librte_net/rte_net_version.map |  1 +
 3 files changed, 64 insertions(+)

diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
index 974fe815b335..8d040173cfc6 100644
--- a/lib/librte_net/rte_ether.c
+++ b/lib/librte_net/rte_ether.c
@@ -3,6 +3,7 @@
  */
 
 #include <rte_ether.h>
+#include <rte_errno.h>
 
 void
 rte_eth_random_addr(uint8_t *addr)
@@ -27,3 +28,51 @@ rte_ether_format_addr(char *buf, uint16_t size,
 		 eth_addr->addr_bytes[4],
 		 eth_addr->addr_bytes[5]);
 }
+
+/*
+ * Like ether_aton_r but can handle either
+ * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
+ */
+int
+rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
+{
+	unsigned int o0, o1, o2, o3, o4, o5;
+	int n;
+
+	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
+		    &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (n == 6) {
+		/* Standard format XX:XX:XX:XX:XX:XX */
+		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
+		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX) {
+			rte_errno = ERANGE;
+			return -1;
+		}
+
+		ea->addr_bytes[0] = o0;
+		ea->addr_bytes[1] = o1;
+		ea->addr_bytes[2] = o2;
+		ea->addr_bytes[3] = o3;
+		ea->addr_bytes[4] = o4;
+		ea->addr_bytes[5] = o5;
+	} else if (n == 3) {
+		/* Support the format XXXX:XXXX:XXXX */
+		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX) {
+			rte_errno = ERANGE;
+			return -1;
+		}
+
+		ea->addr_bytes[0] = o0 >> 8;
+		ea->addr_bytes[1] = o0 & 0xff;
+		ea->addr_bytes[2] = o1 >> 8;
+		ea->addr_bytes[3] = o1 & 0xff;
+		ea->addr_bytes[4] = o2 >> 8;
+		ea->addr_bytes[5] = o2 & 0xff;
+	} else {
+		/* unknown format */
+		rte_errno = EINVAL;
+		return -1;
+	}
+	return 0;
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index df1a51462a37..77b4569b1ad4 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -250,6 +250,20 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
 void
 rte_ether_format_addr(char *buf, uint16_t size,
 		      const struct rte_ether_addr *eth_addr);
+/**
+ * Convert string with Ethernet address to an ether_addr.
+ *
+ * @param str
+ *   A pointer to buffer contains the formatted MAC address.
+ * @param eth_addr
+ *   A pointer to a ether_addr structure.
+ * @return
+ *   0 if successful
+ *   -1 and sets rte_errno if invalid string
+ */
+int __rte_experimental
+rte_ether_unformat_addr(const char *str, struct rte_ether_addr *eth_addr);
+
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index f1e1b84ab491..f4c915069d57 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -25,4 +25,5 @@ EXPERIMENTAL {
 
 	rte_net_make_rarp_packet;
 	rte_net_skip_ip6_ext;
+	rte_ether_unformat_addr;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 03/11] ethdev: use new ethernet parsing function
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 01/11] net/ether: deinline non-critical functions Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 02/11] net/ether: add function to convert string to ethernet address Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 04/11] net/ether: use bitops to speedup comparison Stephen Hemminger
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_eth_unformat_addr, so that ethdev can be built and work
without the cmdline library. The dependency on cmdline was
an arrangement of convenience anyway.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                      | 1 -
 lib/librte_ethdev/Makefile        | 2 +-
 lib/librte_ethdev/meson.build     | 2 +-
 lib/librte_ethdev/rte_class_eth.c | 9 +--------
 4 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 791e0d9911d6..82b2c4bfa8ea 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
 DEPDIRS-librte_ethdev += librte_kvargs
-DEPDIRS-librte_ethdev += librte_cmdline
 DEPDIRS-librte_ethdev += librte_meter
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 8d4a02630c4f..60bcc2227878 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_cmdline -lrte_meter
+LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_meter
 
 EXPORT_MAP := rte_ethdev_version.map
 
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 8d6165b2a7dd..f75d428c96d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -26,4 +26,4 @@ headers = files('rte_ethdev.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
 
-deps += ['net', 'kvargs', 'cmdline', 'meter']
+deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 873a653532ad..6338355e2557 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -4,7 +4,6 @@
 
 #include <string.h>
 
-#include <cmdline_parse_etheraddr.h>
 #include <rte_class.h>
 #include <rte_compat.h>
 #include <rte_errno.h>
@@ -43,19 +42,13 @@ static int
 eth_mac_cmp(const char *key __rte_unused,
 		const char *value, void *opaque)
 {
-	int ret;
 	struct rte_ether_addr mac;
 	const struct rte_eth_dev_data *data = opaque;
 	struct rte_eth_dev_info dev_info;
 	uint32_t index;
 
 	/* Parse devargs MAC address. */
-	/*
-	 * cannot use ether_aton_r(value, &mac)
-	 * because of include conflict with rte_ether.h
-	 */
-	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
-	if (ret < 0)
+	if (rte_ether_unformat_addr(value, &mac) < 0)
 		return -1; /* invalid devargs value */
 
 	/* Return 0 if devargs MAC is matching one of the device MACs. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 04/11] net/ether: use bitops to speedup comparison
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (2 preceding siblings ...)
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 03/11] ethdev: use new ethernet parsing function Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 05/11] cmdline: use new ethernet address parser Stephen Hemminger
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko, Olivier Matz

Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_net/rte_ether.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 77b4569b1ad4..6c07f4696a95 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -81,11 +81,10 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
+	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+
+	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea->addr_bytes[i] != 0x00)
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w = (const uint16_t *)ea;
+
+	return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 05/11] cmdline: use new ethernet address parser
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (3 preceding siblings ...)
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 04/11] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 06/11] net/bonding: " Stephen Hemminger
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Olivier Matz

Now that there is a version of ether_aton in rte_ether, it can
be used by the cmdline ethernet address parser.

Note: ether_aton_r can not be used in cmdline because
the old code would accept either bytes XX:XX:XX:XX:XX:XX
or words XXXX:XXXX:XXXX and we need to keep compatiablity.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/Makefile                                 |  2 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++-----------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/meson.build                              |  2 +-
 5 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 82b2c4bfa8ea..cc36fe7591f0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,7 +20,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
-DEPDIRS-librte_cmdline := librte_eal
+DEPDIRS-librte_cmdline := librte_eal librte_net
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index c64142b8d5a0..04057d7c671f 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cmdline.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_cmdline_version.map
 
@@ -25,7 +26,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_net -lrte_eal
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_parse_etheraddr.c b/lib/librte_cmdline/cmdline_parse_etheraddr.c
index 24e04755cd9e..2cb8dd2a1267 100644
--- a/lib/librte_cmdline/cmdline_parse_etheraddr.c
+++ b/lib/librte_cmdline/cmdline_parse_etheraddr.c
@@ -12,9 +12,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
 
 #include <rte_string_fns.h>
+#include <rte_ether.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -26,69 +26,15 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 	.get_help = cmdline_get_help_etheraddr,
 };
 
-/* the format can be either XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX */
-#define ETHER_ADDRSTRLENLONG 18
-#define ETHER_ADDRSTRLENSHORT 15
-
-#ifdef __linux__
-#define ea_oct ether_addr_octet
-#else
-#define ea_oct octet
-#endif
-
-
-static struct ether_addr *
-my_ether_aton(const char *a)
-{
-	int i;
-	char *end;
-	unsigned long o[ETHER_ADDR_LEN];
-	static struct ether_addr ether_addr;
-
-	i = 0;
-	do {
-		errno = 0;
-		o[i] = strtoul(a, &end, 16);
-		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
-			return NULL;
-		a = end + 1;
-	} while (++i != sizeof (o) / sizeof (o[0]) && end[0] != 0);
-
-	/* Junk at the end of line */
-	if (end[0] != 0)
-		return NULL;
-
-	/* Support the format XX:XX:XX:XX:XX:XX */
-	if (i == ETHER_ADDR_LEN) {
-		while (i-- != 0) {
-			if (o[i] > UINT8_MAX)
-				return NULL;
-			ether_addr.ea_oct[i] = (uint8_t)o[i];
-		}
-	/* Support the format XXXX:XXXX:XXXX */
-	} else if (i == ETHER_ADDR_LEN / 2) {
-		while (i-- != 0) {
-			if (o[i] > UINT16_MAX)
-				return NULL;
-			ether_addr.ea_oct[i * 2] = (uint8_t)(o[i] >> 8);
-			ether_addr.ea_oct[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
-		}
-	/* unknown format */
-	} else
-		return NULL;
-
-	return (struct ether_addr *)&ether_addr;
-}
-
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 	const char *buf, void *res, unsigned ressize)
 {
 	unsigned int token_len = 0;
-	char ether_str[ETHER_ADDRSTRLENLONG+1];
-	struct ether_addr *tmp;
+	char ether_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr tmp;
 
-	if (res && ressize < sizeof(struct ether_addr))
+	if (res && ressize < sizeof(tmp))
 		return -1;
 
 	if (!buf || ! *buf)
@@ -98,17 +44,16 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 		token_len++;
 
 	/* if token doesn't match possible string lengths... */
-	if ((token_len != ETHER_ADDRSTRLENLONG - 1) &&
-			(token_len != ETHER_ADDRSTRLENSHORT - 1))
+	if (token_len >= RTE_ETHER_ADDR_FMT_SIZE)
 		return -1;
 
 	strlcpy(ether_str, buf, token_len + 1);
 
-	tmp = my_ether_aton(ether_str);
-	if (tmp == NULL)
+	if (rte_ether_unformat_addr(ether_str, &tmp) < 0)
 		return -1;
+
 	if (res)
-		memcpy(res, tmp, sizeof(struct ether_addr));
+		memcpy(res, &tmp, sizeof(tmp));
 	return token_len;
 }
 
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 0fa61385fccf..07334c1b0956 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -1,10 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
-# This library is processed before EAL
-includes = [global_inc]
-
 version = 2
+allow_experimental_apis = true
 sources = files('cmdline.c',
 	'cmdline_cirbuf.c',
 	'cmdline_parse.c',
@@ -28,3 +26,5 @@ headers = files('cmdline.h',
 	'cmdline_socket.h',
 	'cmdline_cirbuf.h',
 	'cmdline_parse_portlist.h')
+
+deps += ['net']
diff --git a/lib/meson.build b/lib/meson.build
index 5ddf1ca116e5..38e6ccf13947 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -11,8 +11,8 @@
 libraries = [
 	'kvargs', # eal depends on kvargs
 	'eal', # everything depends on eal
-	'cmdline', # ethdev depends on cmdline for parsing functions
 	'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
+	'cmdline',
 	'metrics', # bitrate/latency stats depends on this
 	'hash',    # efd depends on this
 	'timer',   # eventdev depends on this
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 06/11] net/bonding: use new ethernet address parser
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (4 preceding siblings ...)
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 05/11] cmdline: use new ethernet address parser Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 07/11] app/testpmd: " Stephen Hemminger
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline library used to be the only way to parse a
mac address. Now there is rte_ether_unformat_addr.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bonding/Makefile            | 2 +-
 drivers/net/bonding/meson.build         | 2 +-
 drivers/net/bonding/rte_eth_bond_args.c | 6 +-----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 1893e3cad313..26c1782554cd 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
-LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_pci -lrte_bus_pci
 LDLIBS += -lrte_bus_vdev
 
diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build
index 00374edb2a9d..6267210adf5f 100644
--- a/drivers/net/bonding/meson.build
+++ b/drivers/net/bonding/meson.build
@@ -8,6 +8,6 @@ sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', 'rte_eth_bond_flow.c
 	'rte_eth_bond_args.c', 'rte_eth_bond_8023ad.c', 'rte_eth_bond_alb.c')
 
 deps += 'sched' # needed for rte_bitmap.h
-deps += ['ip_frag', 'cmdline']
+deps += ['ip_frag']
 
 install_headers('rte_eth_bond.h', 'rte_eth_bond_8023ad.h')
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index 01bbb06c1a84..936440fb8491 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -7,9 +7,6 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
 #include "rte_eth_bond.h"
 #include "rte_eth_bond_private.h"
 
@@ -281,8 +278,7 @@ bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
 		return -1;
 
 	/* Parse MAC */
-	return cmdline_parse_etheraddr(NULL, value, extra_args,
-		sizeof(struct rte_ether_addr));
+	return rte_ether_unformat_addr(value, extra_args);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 07/11] app/testpmd: use new ethernet address parser
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (5 preceding siblings ...)
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 06/11] net/bonding: " Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 08/11] net/virtio: use new ether addr parsing Stephen Hemminger
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Bernard Iremonger

The cmdline_parse_ether_addr does not need to be used everywhere
in testpmd. Can use rte_ether_unformat_addr instead.
As an added bonus it eliminates some code for copying.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline_flow.c |  5 ++---
 app/test-pmd/config.c       | 10 +++-------
 app/test-pmd/parameters.c   | 15 +++------------
 3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 201bd9de56e0..2b02ca29b7ac 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -18,7 +18,6 @@
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_flow.h>
 
 #include "testpmd.h"
@@ -4627,8 +4626,8 @@ parse_mac_addr(struct context *ctx, const struct token *token,
 	/* Only network endian is supported. */
 	if (!arg->hton)
 		goto error;
-	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
-	if (ret < 0 || (unsigned int)ret != len)
+	ret = rte_ether_unformat_addr(str, &tmp);
+	if (ret < 0)
 		goto error;
 	if (!ctx->object)
 		return len;
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index ab458c8d2837..1d804705d96c 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -49,7 +49,6 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include <rte_gro.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_config.h>
 
 #include "testpmd.h"
@@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 void
 set_fwd_eth_peer(portid_t port_id, char *peer_addr)
 {
-	uint8_t c, new_peer_addr[6];
+	struct rte_ether_addr new_peer_addr;
 	if (!rte_eth_dev_is_valid_port(port_id)) {
 		printf("Error: Invalid port number %i\n", port_id);
 		return;
 	}
-	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
-					sizeof(new_peer_addr)) < 0) {
+	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
 		printf("Error: Invalid ethernet address: %s\n", peer_addr);
 		return;
 	}
-	for (c = 0; c < 6; c++)
-		peer_eth_addrs[port_id].addr_bytes[c] =
-			new_peer_addr[c];
+	peer_eth_addrs[port_id] = new_peer_addr;
 }
 
 int
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 245b610641ee..975a97807009 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -39,10 +39,6 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_CMDLINE
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-#endif
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
@@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
 		if (fgets(buf, sizeof(buf), config_file) == NULL)
 			break;
 
-		if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i],
-				sizeof(peer_eth_addrs[i])) < 0) {
+		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
 			printf("Bad MAC address format on line %d\n", i+1);
 			fclose(config_file);
 			return -1;
@@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
 			}
 			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
 				char *port_end;
-				uint8_t c, peer_addr[6];
 
 				errno = 0;
 				n = strtoul(optarg, &port_end, 10);
@@ -739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
 						 "eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
 						 n, RTE_MAX_ETHPORTS);
 
-				if (cmdline_parse_etheraddr(NULL, port_end,
-						&peer_addr, sizeof(peer_addr)) < 0)
+				if (rte_ether_unformat_addr(port_end,
+							    &peer_eth_addrs[n]) < 0)
 					rte_exit(EXIT_FAILURE,
 						 "Invalid ethernet address: %s\n",
 						 port_end);
-				for (c = 0; c < 6; c++)
-					peer_eth_addrs[n].addr_bytes[c] =
-						peer_addr[c];
 				nb_peer_eth_addrs++;
 			}
 #endif
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 08/11] net/virtio: use new ether addr parsing
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (6 preceding siblings ...)
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 07/11] app/testpmd: " Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 09/11] net/failsafe: use common ether address parsing routine Stephen Hemminger
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/virtio/virtio_user/virtio_user_dev.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index e743695e4510..0bac725e7cdd 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -225,17 +225,13 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
 static inline void
 parse_mac(struct virtio_user_dev *dev, const char *mac)
 {
-	int i, r;
-	uint32_t tmp[RTE_ETHER_ADDR_LEN];
+	struct rte_ether_addr tmp;
 
 	if (!mac)
 		return;
 
-	r = sscanf(mac, "%x:%x:%x:%x:%x:%x", &tmp[0],
-			&tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
-	if (r == RTE_ETHER_ADDR_LEN) {
-		for (i = 0; i < RTE_ETHER_ADDR_LEN; ++i)
-			dev->mac_addr[i] = (uint8_t)tmp[i];
+	if (rte_ether_unformat_addr(mac, &tmp) == 0) {
+		memcpy(dev->mac_addr, &tmp, RTE_ETHER_ADDR_LEN);
 		dev->mac_specified = 1;
 	} else {
 		/* ignore the wrong mac, use random mac */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 09/11] net/failsafe: use common ether address parsing routine
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (7 preceding siblings ...)
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 08/11] net/virtio: use new ether addr parsing Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 10/11] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 11/11] net/memif: use common ethernet address parsing routine Stephen Hemminger
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Gaetan Rivet

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/failsafe/failsafe_args.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/net/failsafe/failsafe_args.c b/drivers/net/failsafe/failsafe_args.c
index d2e725bcea13..707490b94c4e 100644
--- a/drivers/net/failsafe/failsafe_args.c
+++ b/drivers/net/failsafe/failsafe_args.c
@@ -368,15 +368,11 @@ fs_get_mac_addr_arg(const char *key __rte_unused,
 		const char *value, void *out)
 {
 	struct rte_ether_addr *ea = out;
-	int ret;
 
 	if ((value == NULL) || (out == NULL))
 		return -EINVAL;
-	ret = sscanf(value, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-		&ea->addr_bytes[0], &ea->addr_bytes[1],
-		&ea->addr_bytes[2], &ea->addr_bytes[3],
-		&ea->addr_bytes[4], &ea->addr_bytes[5]);
-	return ret != RTE_ETHER_ADDR_LEN;
+
+	return rte_ether_unformat_addr(value, ea);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 10/11] net/vdev_netvsc: use common ethernet address parsing
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (8 preceding siblings ...)
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 09/11] net/failsafe: use common ether address parsing routine Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 11/11] net/memif: use common ethernet address parsing routine Stephen Hemminger
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Matan Azrad

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Matan Azrad <matan@mellanox.com>
---
 drivers/net/vdev_netvsc/vdev_netvsc.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/net/vdev_netvsc/vdev_netvsc.c b/drivers/net/vdev_netvsc/vdev_netvsc.c
index 1fcf90d7bc02..be8f19c0c63e 100644
--- a/drivers/net/vdev_netvsc/vdev_netvsc.c
+++ b/drivers/net/vdev_netvsc/vdev_netvsc.c
@@ -529,15 +529,7 @@ vdev_netvsc_netvsc_probe(const struct if_nameindex *iface,
 			} else if (!strcmp(pair->key, VDEV_NETVSC_ARG_MAC)) {
 				struct rte_ether_addr tmp;
 
-				if (sscanf(pair->value,
-					   "%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":"
-					   "%" SCNx8 ":%" SCNx8 ":%" SCNx8,
-					   &tmp.addr_bytes[0],
-					   &tmp.addr_bytes[1],
-					   &tmp.addr_bytes[2],
-					   &tmp.addr_bytes[3],
-					   &tmp.addr_bytes[4],
-					   &tmp.addr_bytes[5]) != 6) {
+				if (rte_ether_unformat_addr(pair->value, &tmp) != 0) {
 					DRV_LOG(ERR,
 						"invalid MAC address format"
 						" \"%s\"",
-- 
2.20.1


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

* [dpdk-dev] [PATCH v8 11/11] net/memif: use common ethernet address parsing routine
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (9 preceding siblings ...)
  2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 10/11] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
@ 2019-07-05 17:16   ` Stephen Hemminger
  10 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-05 17:16 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/memif/rte_eth_memif.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/memif/rte_eth_memif.c b/drivers/net/memif/rte_eth_memif.c
index e9ddf6413597..00c9b396ab85 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -1224,13 +1224,8 @@ static int
 memif_set_mac(const char *key __rte_unused, const char *value, void *extra_args)
 {
 	struct rte_ether_addr *ether_addr = (struct rte_ether_addr *)extra_args;
-	int ret = 0;
 
-	ret = sscanf(value, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-	       &ether_addr->addr_bytes[0], &ether_addr->addr_bytes[1],
-	       &ether_addr->addr_bytes[2], &ether_addr->addr_bytes[3],
-	       &ether_addr->addr_bytes[4], &ether_addr->addr_bytes[5]);
-	if (ret != 6)
+	if (rte_ether_unformat_addr(value, ether_addr) < 0)
 		MIF_LOG(WARNING, "Failed to parse mac '%s'.", value);
 	return 0;
 }
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations
  2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
                   ` (12 preceding siblings ...)
  2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
@ 2019-07-08 18:26 ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 01/11] net/ether: deinline non-critical functions Stephen Hemminger
                     ` (11 more replies)
  13 siblings, 12 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of patches around the ethernet address
manipulation routines in librte_net/rte_ether.

v9
   add missing librte_net for new octoeonx2
v8
   set rte_errno in rte_eth_unformat_addr
   drop ether_address alignment patch. Bruce can handle deprecation
   and sending the patches later
v7
   use rte_ether_unformat_addr in more drivers
v6
   add librte_net to axgbe and memif Makefile
v5
   reword commit messages to workaround check-log complaints
v4
   fix meson build
   reword commit messages
   add bonding and tespmd patches
v3 
   rebase to use rte_ether prefix
   drop aligning ethernet headers for now.

Stephen Hemminger (11):
  net/ether: deinline non-critical functions
  net/ether: add function to convert string to ethernet address
  ethdev: use new ethernet parsing function
  net/ether: use bitops to speedup comparison
  cmdline: use new ethernet address parser
  net/bonding: use new ethernet address parser
  app/testpmd: use new ethernet address parser
  net/virtio: use new ether addr parsing
  net/failsafe: use common ether address parsing routine
  net/vdev_netvsc: use common ethernet address parsing
  net/memif: use common ethernet address parsing routine

 app/test-pmd/cmdline_flow.c                   |  5 +-
 app/test-pmd/config.c                         | 10 +--
 app/test-pmd/parameters.c                     | 15 +---
 drivers/net/axgbe/Makefile                    |  2 +-
 drivers/net/bonding/Makefile                  |  2 +-
 drivers/net/bonding/meson.build               |  2 +-
 drivers/net/bonding/rte_eth_bond_args.c       |  6 +-
 drivers/net/failsafe/failsafe_args.c          |  8 +-
 drivers/net/memif/Makefile                    |  2 +-
 drivers/net/memif/rte_eth_memif.c             |  7 +-
 drivers/net/octeontx2/Makefile                |  2 +-
 drivers/net/vdev_netvsc/vdev_netvsc.c         | 10 +--
 .../net/virtio/virtio_user/virtio_user_dev.c  | 10 +--
 lib/Makefile                                  |  3 +-
 lib/librte_cmdline/Makefile                   |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c  | 71 ++---------------
 lib/librte_cmdline/meson.build                |  6 +-
 lib/librte_ethdev/Makefile                    |  2 +-
 lib/librte_ethdev/meson.build                 |  2 +-
 lib/librte_ethdev/rte_class_eth.c             |  9 +--
 lib/librte_net/Makefile                       |  1 +
 lib/librte_net/meson.build                    |  2 +-
 lib/librte_net/rte_ether.c                    | 78 +++++++++++++++++++
 lib/librte_net/rte_ether.h                    | 54 ++++++-------
 lib/librte_net/rte_net_version.map            |  8 ++
 lib/meson.build                               |  2 +-
 26 files changed, 151 insertions(+), 171 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 01/11] net/ether: deinline non-critical functions
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 02/11] net/ether: add function to convert string to ethernet address Stephen Hemminger
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Rami Rosen, Andrew Rybchenko, Olivier Matz

Formatting Ethernet address and getting a random value are
not in critical path so they should not be inlined.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Rami Rosen <ramirose@gmail.com>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/axgbe/Makefile         |  2 +-
 drivers/net/memif/Makefile         |  2 +-
 drivers/net/octeontx2/Makefile     |  2 +-
 lib/librte_net/Makefile            |  1 +
 lib/librte_net/meson.build         |  2 +-
 lib/librte_net/rte_ether.c         | 29 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 25 ++++---------------------
 lib/librte_net/rte_net_version.map |  7 +++++++
 8 files changed, 45 insertions(+), 25 deletions(-)
 create mode 100644 lib/librte_net/rte_ether.c

diff --git a/drivers/net/axgbe/Makefile b/drivers/net/axgbe/Makefile
index 72215aedaf55..c2d4336800c0 100644
--- a/drivers/net/axgbe/Makefile
+++ b/drivers/net/axgbe/Makefile
@@ -17,7 +17,7 @@ LIBABIVER := 1
 
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
 LDLIBS += -lrte_pci -lrte_bus_pci
-LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_ethdev -lrte_net
 
 #
 # all source are stored in SRCS-y
diff --git a/drivers/net/memif/Makefile b/drivers/net/memif/Makefile
index fdbdf3378019..3d92b08f259b 100644
--- a/drivers/net/memif/Makefile
+++ b/drivers/net/memif/Makefile
@@ -21,7 +21,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 # - rte_mp_reply
 # - rte_mp_request_sync
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
-LDLIBS += -lrte_ethdev -lrte_kvargs
+LDLIBS += -lrte_ethdev -lrte_kvargs -lrte_net
 LDLIBS += -lrte_hash
 LDLIBS += -lrte_bus_vdev
 
diff --git a/drivers/net/octeontx2/Makefile b/drivers/net/octeontx2/Makefile
index d08d3d854b46..66cb5f25bb2b 100644
--- a/drivers/net/octeontx2/Makefile
+++ b/drivers/net/octeontx2/Makefile
@@ -54,7 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX2_PMD) += \
 	otx2_ethdev_debug.c \
 	otx2_ethdev_devargs.c
 
-LDLIBS += -lrte_common_octeontx2 -lrte_mempool_octeontx2 -lrte_eal
+LDLIBS += -lrte_common_octeontx2 -lrte_mempool_octeontx2 -lrte_eal -lrte_net
 LDLIBS += -lrte_ethdev -lrte_bus_pci -lrte_kvargs -lrte_mbuf  -lrte_mempool -lm
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index c3082069ab50..1244c9fd54c9 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -14,6 +14,7 @@ LIBABIVER := 1
 
 SRCS-$(CONFIG_RTE_LIBRTE_NET) := rte_net.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_net_crc.c
+SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_ether.c
 SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 
 # install includes
diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build
index 7d66f693cbf3..868a93fd6b6b 100644
--- a/lib/librte_net/meson.build
+++ b/lib/librte_net/meson.build
@@ -16,5 +16,5 @@ headers = files('rte_ip.h',
 	'rte_net_crc.h',
 	'rte_mpls.h')
 
-sources = files('rte_arp.c', 'rte_net.c', 'rte_net_crc.c')
+sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c')
 deps += ['mbuf']
diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
new file mode 100644
index 000000000000..974fe815b335
--- /dev/null
+++ b/lib/librte_net/rte_ether.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <rte_ether.h>
+
+void
+rte_eth_random_addr(uint8_t *addr)
+{
+	uint64_t rand = rte_rand();
+	uint8_t *p = (uint8_t *)&rand;
+
+	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
+	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;	/* clear multicast bit */
+	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;	/* set local assignment bit */
+}
+
+void
+rte_ether_format_addr(char *buf, uint16_t size,
+		      const struct rte_ether_addr *eth_addr)
+{
+	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
+		 eth_addr->addr_bytes[0],
+		 eth_addr->addr_bytes[1],
+		 eth_addr->addr_bytes[2],
+		 eth_addr->addr_bytes[3],
+		 eth_addr->addr_bytes[4],
+		 eth_addr->addr_bytes[5]);
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 1868cb7077d2..df1a51462a37 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -207,15 +207,8 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *
  * @param addr
  *   A pointer to Ethernet address.
  */
-static inline void rte_eth_random_addr(uint8_t *addr)
-{
-	uint64_t rand = rte_rand();
-	uint8_t *p = (uint8_t *)&rand;
-
-	rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
-	addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR;  /* clear multicast bit */
-	addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;  /* set local assignment bit */
-}
+void
+rte_eth_random_addr(uint8_t *addr);
 
 /**
  * Fast copy an Ethernet address.
@@ -254,19 +247,9 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
  * @param eth_addr
  *   A pointer to a ether_addr structure.
  */
-static inline void
+void
 rte_ether_format_addr(char *buf, uint16_t size,
-		  const struct rte_ether_addr *eth_addr)
-{
-	snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
-		 eth_addr->addr_bytes[0],
-		 eth_addr->addr_bytes[1],
-		 eth_addr->addr_bytes[2],
-		 eth_addr->addr_bytes[3],
-		 eth_addr->addr_bytes[4],
-		 eth_addr->addr_bytes[5]);
-}
-
+		      const struct rte_ether_addr *eth_addr);
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index 26c06e7c7ae7..f1e1b84ab491 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -13,6 +13,13 @@ DPDK_17.05 {
 
 } DPDK_16.11;
 
+DPDK_19.08 {
+	global:
+
+	rte_eth_random_addr;
+	rte_ether_format_addr;
+} DPDK_17.05;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 02/11] net/ether: add function to convert string to ethernet address
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 01/11] net/ether: deinline non-critical functions Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 03/11] ethdev: use new ethernet parsing function Stephen Hemminger
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko

Make a function that can be used in place of eth_aton_r
to convert a string to rte_ether_addr. This function
allows both byte (xx:xx:xx:xx:xx:xx) and word (XXXX:XXXX:XXXX)
format and has the same lack of error handling as the original.

This also allows ethdev to no longer have a hard dependency
on the cmdline library.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 lib/librte_net/rte_ether.c         | 49 ++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         | 14 +++++++++
 lib/librte_net/rte_net_version.map |  1 +
 3 files changed, 64 insertions(+)

diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c
index 974fe815b335..8d040173cfc6 100644
--- a/lib/librte_net/rte_ether.c
+++ b/lib/librte_net/rte_ether.c
@@ -3,6 +3,7 @@
  */
 
 #include <rte_ether.h>
+#include <rte_errno.h>
 
 void
 rte_eth_random_addr(uint8_t *addr)
@@ -27,3 +28,51 @@ rte_ether_format_addr(char *buf, uint16_t size,
 		 eth_addr->addr_bytes[4],
 		 eth_addr->addr_bytes[5]);
 }
+
+/*
+ * Like ether_aton_r but can handle either
+ * XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX
+ */
+int
+rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
+{
+	unsigned int o0, o1, o2, o3, o4, o5;
+	int n;
+
+	n = sscanf(s, "%x:%x:%x:%x:%x:%x",
+		    &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (n == 6) {
+		/* Standard format XX:XX:XX:XX:XX:XX */
+		if (o0 > UINT8_MAX || o1 > UINT8_MAX || o2 > UINT8_MAX ||
+		    o3 > UINT8_MAX || o4 > UINT8_MAX || o5 > UINT8_MAX) {
+			rte_errno = ERANGE;
+			return -1;
+		}
+
+		ea->addr_bytes[0] = o0;
+		ea->addr_bytes[1] = o1;
+		ea->addr_bytes[2] = o2;
+		ea->addr_bytes[3] = o3;
+		ea->addr_bytes[4] = o4;
+		ea->addr_bytes[5] = o5;
+	} else if (n == 3) {
+		/* Support the format XXXX:XXXX:XXXX */
+		if (o0 > UINT16_MAX || o1 > UINT16_MAX || o2 > UINT16_MAX) {
+			rte_errno = ERANGE;
+			return -1;
+		}
+
+		ea->addr_bytes[0] = o0 >> 8;
+		ea->addr_bytes[1] = o0 & 0xff;
+		ea->addr_bytes[2] = o1 >> 8;
+		ea->addr_bytes[3] = o1 & 0xff;
+		ea->addr_bytes[4] = o2 >> 8;
+		ea->addr_bytes[5] = o2 & 0xff;
+	} else {
+		/* unknown format */
+		rte_errno = EINVAL;
+		return -1;
+	}
+	return 0;
+}
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index df1a51462a37..77b4569b1ad4 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -250,6 +250,20 @@ static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
 void
 rte_ether_format_addr(char *buf, uint16_t size,
 		      const struct rte_ether_addr *eth_addr);
+/**
+ * Convert string with Ethernet address to an ether_addr.
+ *
+ * @param str
+ *   A pointer to buffer contains the formatted MAC address.
+ * @param eth_addr
+ *   A pointer to a ether_addr structure.
+ * @return
+ *   0 if successful
+ *   -1 and sets rte_errno if invalid string
+ */
+int __rte_experimental
+rte_ether_unformat_addr(const char *str, struct rte_ether_addr *eth_addr);
+
 /**
  * Ethernet header: Contains the destination address, source address
  * and frame type.
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index f1e1b84ab491..f4c915069d57 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -25,4 +25,5 @@ EXPERIMENTAL {
 
 	rte_net_make_rarp_packet;
 	rte_net_skip_ip6_ext;
+	rte_ether_unformat_addr;
 };
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 03/11] ethdev: use new ethernet parsing function
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 01/11] net/ether: deinline non-critical functions Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 02/11] net/ether: add function to convert string to ethernet address Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 04/11] net/ether: use bitops to speedup comparison Stephen Hemminger
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_eth_unformat_addr, so that ethdev can be built and work
without the cmdline library. The dependency on cmdline was
an arrangement of convenience anyway.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/Makefile                      | 1 -
 lib/librte_ethdev/Makefile        | 2 +-
 lib/librte_ethdev/meson.build     | 2 +-
 lib/librte_ethdev/rte_class_eth.c | 9 +--------
 4 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 3ad579f68254..493aeab7572e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -25,7 +25,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
 DEPDIRS-librte_ethdev += librte_kvargs
-DEPDIRS-librte_ethdev += librte_cmdline
 DEPDIRS-librte_ethdev += librte_meter
 DIRS-$(CONFIG_RTE_LIBRTE_BBDEV) += librte_bbdev
 DEPDIRS-librte_bbdev := librte_eal librte_mempool librte_mbuf
diff --git a/lib/librte_ethdev/Makefile b/lib/librte_ethdev/Makefile
index 8d4a02630c4f..60bcc2227878 100644
--- a/lib/librte_ethdev/Makefile
+++ b/lib/librte_ethdev/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_net -lrte_eal -lrte_mempool -lrte_ring
-LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_cmdline -lrte_meter
+LDLIBS += -lrte_mbuf -lrte_kvargs -lrte_meter
 
 EXPORT_MAP := rte_ethdev_version.map
 
diff --git a/lib/librte_ethdev/meson.build b/lib/librte_ethdev/meson.build
index 8d6165b2a7dd..f75d428c96d0 100644
--- a/lib/librte_ethdev/meson.build
+++ b/lib/librte_ethdev/meson.build
@@ -26,4 +26,4 @@ headers = files('rte_ethdev.h',
 	'rte_tm.h',
 	'rte_tm_driver.h')
 
-deps += ['net', 'kvargs', 'cmdline', 'meter']
+deps += ['net', 'kvargs', 'meter']
diff --git a/lib/librte_ethdev/rte_class_eth.c b/lib/librte_ethdev/rte_class_eth.c
index 873a653532ad..6338355e2557 100644
--- a/lib/librte_ethdev/rte_class_eth.c
+++ b/lib/librte_ethdev/rte_class_eth.c
@@ -4,7 +4,6 @@
 
 #include <string.h>
 
-#include <cmdline_parse_etheraddr.h>
 #include <rte_class.h>
 #include <rte_compat.h>
 #include <rte_errno.h>
@@ -43,19 +42,13 @@ static int
 eth_mac_cmp(const char *key __rte_unused,
 		const char *value, void *opaque)
 {
-	int ret;
 	struct rte_ether_addr mac;
 	const struct rte_eth_dev_data *data = opaque;
 	struct rte_eth_dev_info dev_info;
 	uint32_t index;
 
 	/* Parse devargs MAC address. */
-	/*
-	 * cannot use ether_aton_r(value, &mac)
-	 * because of include conflict with rte_ether.h
-	 */
-	ret = cmdline_parse_etheraddr(NULL, value, &mac, sizeof(mac));
-	if (ret < 0)
+	if (rte_ether_unformat_addr(value, &mac) < 0)
 		return -1; /* invalid devargs value */
 
 	/* Return 0 if devargs MAC is matching one of the device MACs. */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 04/11] net/ether: use bitops to speedup comparison
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (2 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 03/11] ethdev: use new ethernet parsing function Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 05/11] cmdline: use new ethernet address parser Stephen Hemminger
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko, Olivier Matz

Using bit operations like or and xor is faster than a loop
on all architectures. Really just explicit unrolling.

Similar cast to uint16 unaligned is already done in
other functions here.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_net/rte_ether.h | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 77b4569b1ad4..6c07f4696a95 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -81,11 +81,10 @@ struct rte_ether_addr {
 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
 				     const struct rte_ether_addr *ea2)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
+	const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+
+	return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
 }
 
 /**
@@ -100,11 +99,9 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
  */
 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
 {
-	int i;
-	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
-		if (ea->addr_bytes[i] != 0x00)
-			return 0;
-	return 1;
+	const unaligned_uint16_t *w = (const uint16_t *)ea;
+
+	return (w[0] | w[1] | w[2]) == 0;
 }
 
 /**
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 05/11] cmdline: use new ethernet address parser
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (3 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 04/11] net/ether: use bitops to speedup comparison Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 06/11] net/bonding: " Stephen Hemminger
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Olivier Matz

Now that there is a version of ether_aton in rte_ether, it can
be used by the cmdline ethernet address parser.

Note: ether_aton_r can not be used in cmdline because
the old code would accept either bytes XX:XX:XX:XX:XX:XX
or words XXXX:XXXX:XXXX and we need to keep compatiablity.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/Makefile                                 |  2 +-
 lib/librte_cmdline/Makefile                  |  3 +-
 lib/librte_cmdline/cmdline_parse_etheraddr.c | 71 +++-----------------
 lib/librte_cmdline/meson.build               |  6 +-
 lib/meson.build                              |  2 +-
 5 files changed, 15 insertions(+), 69 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 493aeab7572e..bdb8a67e2d9d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,7 +20,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DEPDIRS-librte_timer := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
-DEPDIRS-librte_cmdline := librte_eal
+DEPDIRS-librte_cmdline := librte_eal librte_net
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ethdev
 DEPDIRS-librte_ethdev := librte_net librte_eal librte_mempool librte_ring
 DEPDIRS-librte_ethdev += librte_mbuf
diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
index c64142b8d5a0..04057d7c671f 100644
--- a/lib/librte_cmdline/Makefile
+++ b/lib/librte_cmdline/Makefile
@@ -7,6 +7,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cmdline.a
 
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_cmdline_version.map
 
@@ -25,7 +26,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-LDLIBS += -lrte_eal
+LDLIBS += -lrte_net -lrte_eal
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
diff --git a/lib/librte_cmdline/cmdline_parse_etheraddr.c b/lib/librte_cmdline/cmdline_parse_etheraddr.c
index 24e04755cd9e..2cb8dd2a1267 100644
--- a/lib/librte_cmdline/cmdline_parse_etheraddr.c
+++ b/lib/librte_cmdline/cmdline_parse_etheraddr.c
@@ -12,9 +12,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <net/ethernet.h>
 
 #include <rte_string_fns.h>
+#include <rte_ether.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -26,69 +26,15 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 	.get_help = cmdline_get_help_etheraddr,
 };
 
-/* the format can be either XX:XX:XX:XX:XX:XX or XXXX:XXXX:XXXX */
-#define ETHER_ADDRSTRLENLONG 18
-#define ETHER_ADDRSTRLENSHORT 15
-
-#ifdef __linux__
-#define ea_oct ether_addr_octet
-#else
-#define ea_oct octet
-#endif
-
-
-static struct ether_addr *
-my_ether_aton(const char *a)
-{
-	int i;
-	char *end;
-	unsigned long o[ETHER_ADDR_LEN];
-	static struct ether_addr ether_addr;
-
-	i = 0;
-	do {
-		errno = 0;
-		o[i] = strtoul(a, &end, 16);
-		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
-			return NULL;
-		a = end + 1;
-	} while (++i != sizeof (o) / sizeof (o[0]) && end[0] != 0);
-
-	/* Junk at the end of line */
-	if (end[0] != 0)
-		return NULL;
-
-	/* Support the format XX:XX:XX:XX:XX:XX */
-	if (i == ETHER_ADDR_LEN) {
-		while (i-- != 0) {
-			if (o[i] > UINT8_MAX)
-				return NULL;
-			ether_addr.ea_oct[i] = (uint8_t)o[i];
-		}
-	/* Support the format XXXX:XXXX:XXXX */
-	} else if (i == ETHER_ADDR_LEN / 2) {
-		while (i-- != 0) {
-			if (o[i] > UINT16_MAX)
-				return NULL;
-			ether_addr.ea_oct[i * 2] = (uint8_t)(o[i] >> 8);
-			ether_addr.ea_oct[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
-		}
-	/* unknown format */
-	} else
-		return NULL;
-
-	return (struct ether_addr *)&ether_addr;
-}
-
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 	const char *buf, void *res, unsigned ressize)
 {
 	unsigned int token_len = 0;
-	char ether_str[ETHER_ADDRSTRLENLONG+1];
-	struct ether_addr *tmp;
+	char ether_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr tmp;
 
-	if (res && ressize < sizeof(struct ether_addr))
+	if (res && ressize < sizeof(tmp))
 		return -1;
 
 	if (!buf || ! *buf)
@@ -98,17 +44,16 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 		token_len++;
 
 	/* if token doesn't match possible string lengths... */
-	if ((token_len != ETHER_ADDRSTRLENLONG - 1) &&
-			(token_len != ETHER_ADDRSTRLENSHORT - 1))
+	if (token_len >= RTE_ETHER_ADDR_FMT_SIZE)
 		return -1;
 
 	strlcpy(ether_str, buf, token_len + 1);
 
-	tmp = my_ether_aton(ether_str);
-	if (tmp == NULL)
+	if (rte_ether_unformat_addr(ether_str, &tmp) < 0)
 		return -1;
+
 	if (res)
-		memcpy(res, tmp, sizeof(struct ether_addr));
+		memcpy(res, &tmp, sizeof(tmp));
 	return token_len;
 }
 
diff --git a/lib/librte_cmdline/meson.build b/lib/librte_cmdline/meson.build
index 0fa61385fccf..07334c1b0956 100644
--- a/lib/librte_cmdline/meson.build
+++ b/lib/librte_cmdline/meson.build
@@ -1,10 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017 Intel Corporation
 
-# This library is processed before EAL
-includes = [global_inc]
-
 version = 2
+allow_experimental_apis = true
 sources = files('cmdline.c',
 	'cmdline_cirbuf.c',
 	'cmdline_parse.c',
@@ -28,3 +26,5 @@ headers = files('cmdline.h',
 	'cmdline_socket.h',
 	'cmdline_cirbuf.h',
 	'cmdline_parse_portlist.h')
+
+deps += ['net']
diff --git a/lib/meson.build b/lib/meson.build
index 3d77b1f9014a..e5ff83893489 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -11,8 +11,8 @@
 libraries = [
 	'kvargs', # eal depends on kvargs
 	'eal', # everything depends on eal
-	'cmdline', # ethdev depends on cmdline for parsing functions
 	'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
+	'cmdline',
 	'metrics', # bitrate/latency stats depends on this
 	'hash',    # efd depends on this
 	'timer',   # eventdev depends on this
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 06/11] net/bonding: use new ethernet address parser
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (4 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 05/11] cmdline: use new ethernet address parser Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 07/11] app/testpmd: " Stephen Hemminger
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The cmdline library used to be the only way to parse a
mac address. Now there is rte_ether_unformat_addr.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bonding/Makefile            | 2 +-
 drivers/net/bonding/meson.build         | 2 +-
 drivers/net/bonding/rte_eth_bond_args.c | 6 +-----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 1893e3cad313..26c1782554cd 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
-LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_pci -lrte_bus_pci
 LDLIBS += -lrte_bus_vdev
 
diff --git a/drivers/net/bonding/meson.build b/drivers/net/bonding/meson.build
index 00374edb2a9d..6267210adf5f 100644
--- a/drivers/net/bonding/meson.build
+++ b/drivers/net/bonding/meson.build
@@ -8,6 +8,6 @@ sources = files('rte_eth_bond_api.c', 'rte_eth_bond_pmd.c', 'rte_eth_bond_flow.c
 	'rte_eth_bond_args.c', 'rte_eth_bond_8023ad.c', 'rte_eth_bond_alb.c')
 
 deps += 'sched' # needed for rte_bitmap.h
-deps += ['ip_frag', 'cmdline']
+deps += ['ip_frag']
 
 install_headers('rte_eth_bond.h', 'rte_eth_bond_8023ad.h')
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index 01bbb06c1a84..936440fb8491 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -7,9 +7,6 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
 #include "rte_eth_bond.h"
 #include "rte_eth_bond_private.h"
 
@@ -281,8 +278,7 @@ bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
 		return -1;
 
 	/* Parse MAC */
-	return cmdline_parse_etheraddr(NULL, value, extra_args,
-		sizeof(struct rte_ether_addr));
+	return rte_ether_unformat_addr(value, extra_args);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 07/11] app/testpmd: use new ethernet address parser
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (5 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 06/11] net/bonding: " Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-21 13:42     ` Raslan Darawsheh
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 08/11] net/virtio: use new ether addr parsing Stephen Hemminger
                     ` (4 subsequent siblings)
  11 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Bernard Iremonger

The cmdline_parse_ether_addr does not need to be used everywhere
in testpmd. Can use rte_ether_unformat_addr instead.
As an added bonus it eliminates some code for copying.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline_flow.c |  5 ++---
 app/test-pmd/config.c       | 10 +++-------
 app/test-pmd/parameters.c   | 15 +++------------
 3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index e3e8448c9421..c92c748b18eb 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -18,7 +18,6 @@
 #include <rte_ethdev.h>
 #include <rte_byteorder.h>
 #include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_flow.h>
 
 #include "testpmd.h"
@@ -4734,8 +4733,8 @@ parse_mac_addr(struct context *ctx, const struct token *token,
 	/* Only network endian is supported. */
 	if (!arg->hton)
 		goto error;
-	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
-	if (ret < 0 || (unsigned int)ret != len)
+	ret = rte_ether_unformat_addr(str, &tmp);
+	if (ret < 0)
 		goto error;
 	if (!ctx->object)
 		return len;
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index ab458c8d2837..1d804705d96c 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -49,7 +49,6 @@
 #include <rte_pmd_bnxt.h>
 #endif
 #include <rte_gro.h>
-#include <cmdline_parse_etheraddr.h>
 #include <rte_config.h>
 
 #include "testpmd.h"
@@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 void
 set_fwd_eth_peer(portid_t port_id, char *peer_addr)
 {
-	uint8_t c, new_peer_addr[6];
+	struct rte_ether_addr new_peer_addr;
 	if (!rte_eth_dev_is_valid_port(port_id)) {
 		printf("Error: Invalid port number %i\n", port_id);
 		return;
 	}
-	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
-					sizeof(new_peer_addr)) < 0) {
+	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
 		printf("Error: Invalid ethernet address: %s\n", peer_addr);
 		return;
 	}
-	for (c = 0; c < 6; c++)
-		peer_eth_addrs[port_id].addr_bytes[c] =
-			new_peer_addr[c];
+	peer_eth_addrs[port_id] = new_peer_addr;
 }
 
 int
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 245b610641ee..975a97807009 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -39,10 +39,6 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_CMDLINE
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-#endif
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
@@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
 		if (fgets(buf, sizeof(buf), config_file) == NULL)
 			break;
 
-		if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i],
-				sizeof(peer_eth_addrs[i])) < 0) {
+		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
 			printf("Bad MAC address format on line %d\n", i+1);
 			fclose(config_file);
 			return -1;
@@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
 			}
 			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
 				char *port_end;
-				uint8_t c, peer_addr[6];
 
 				errno = 0;
 				n = strtoul(optarg, &port_end, 10);
@@ -739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
 						 "eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
 						 n, RTE_MAX_ETHPORTS);
 
-				if (cmdline_parse_etheraddr(NULL, port_end,
-						&peer_addr, sizeof(peer_addr)) < 0)
+				if (rte_ether_unformat_addr(port_end,
+							    &peer_eth_addrs[n]) < 0)
 					rte_exit(EXIT_FAILURE,
 						 "Invalid ethernet address: %s\n",
 						 port_end);
-				for (c = 0; c < 6; c++)
-					peer_eth_addrs[n].addr_bytes[c] =
-						peer_addr[c];
 				nb_peer_eth_addrs++;
 			}
 #endif
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 08/11] net/virtio: use new ether addr parsing
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (6 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 07/11] app/testpmd: " Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 09/11] net/failsafe: use common ether address parsing routine Stephen Hemminger
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/virtio/virtio_user/virtio_user_dev.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index c3ab9a21d107..fab87eb5b60f 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -224,17 +224,13 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
 static inline void
 parse_mac(struct virtio_user_dev *dev, const char *mac)
 {
-	int i, r;
-	uint32_t tmp[RTE_ETHER_ADDR_LEN];
+	struct rte_ether_addr tmp;
 
 	if (!mac)
 		return;
 
-	r = sscanf(mac, "%x:%x:%x:%x:%x:%x", &tmp[0],
-			&tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
-	if (r == RTE_ETHER_ADDR_LEN) {
-		for (i = 0; i < RTE_ETHER_ADDR_LEN; ++i)
-			dev->mac_addr[i] = (uint8_t)tmp[i];
+	if (rte_ether_unformat_addr(mac, &tmp) == 0) {
+		memcpy(dev->mac_addr, &tmp, RTE_ETHER_ADDR_LEN);
 		dev->mac_specified = 1;
 	} else {
 		/* ignore the wrong mac, use random mac */
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 09/11] net/failsafe: use common ether address parsing routine
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (7 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 08/11] net/virtio: use new ether addr parsing Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 10/11] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Gaetan Rivet

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/failsafe/failsafe_args.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/net/failsafe/failsafe_args.c b/drivers/net/failsafe/failsafe_args.c
index d2e725bcea13..707490b94c4e 100644
--- a/drivers/net/failsafe/failsafe_args.c
+++ b/drivers/net/failsafe/failsafe_args.c
@@ -368,15 +368,11 @@ fs_get_mac_addr_arg(const char *key __rte_unused,
 		const char *value, void *out)
 {
 	struct rte_ether_addr *ea = out;
-	int ret;
 
 	if ((value == NULL) || (out == NULL))
 		return -EINVAL;
-	ret = sscanf(value, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-		&ea->addr_bytes[0], &ea->addr_bytes[1],
-		&ea->addr_bytes[2], &ea->addr_bytes[3],
-		&ea->addr_bytes[4], &ea->addr_bytes[5]);
-	return ret != RTE_ETHER_ADDR_LEN;
+
+	return rte_ether_unformat_addr(value, ea);
 }
 
 int
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 10/11] net/vdev_netvsc: use common ethernet address parsing
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (8 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 09/11] net/failsafe: use common ether address parsing routine Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 11/11] net/memif: use common ethernet address parsing routine Stephen Hemminger
  2019-07-08 19:13   ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Ferruh Yigit
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Matan Azrad

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Matan Azrad <matan@mellanox.com>
---
 drivers/net/vdev_netvsc/vdev_netvsc.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/net/vdev_netvsc/vdev_netvsc.c b/drivers/net/vdev_netvsc/vdev_netvsc.c
index 1fcf90d7bc02..be8f19c0c63e 100644
--- a/drivers/net/vdev_netvsc/vdev_netvsc.c
+++ b/drivers/net/vdev_netvsc/vdev_netvsc.c
@@ -529,15 +529,7 @@ vdev_netvsc_netvsc_probe(const struct if_nameindex *iface,
 			} else if (!strcmp(pair->key, VDEV_NETVSC_ARG_MAC)) {
 				struct rte_ether_addr tmp;
 
-				if (sscanf(pair->value,
-					   "%" SCNx8 ":%" SCNx8 ":%" SCNx8 ":"
-					   "%" SCNx8 ":%" SCNx8 ":%" SCNx8,
-					   &tmp.addr_bytes[0],
-					   &tmp.addr_bytes[1],
-					   &tmp.addr_bytes[2],
-					   &tmp.addr_bytes[3],
-					   &tmp.addr_bytes[4],
-					   &tmp.addr_bytes[5]) != 6) {
+				if (rte_ether_unformat_addr(pair->value, &tmp) != 0) {
 					DRV_LOG(ERR,
 						"invalid MAC address format"
 						" \"%s\"",
-- 
2.20.1


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

* [dpdk-dev] [PATCH v9 11/11] net/memif: use common ethernet address parsing routine
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (9 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 10/11] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
@ 2019-07-08 18:26   ` Stephen Hemminger
  2019-07-08 19:13   ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Ferruh Yigit
  11 siblings, 0 replies; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-08 18:26 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use rte_ether_unformat_addr rather than sscanf.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/memif/rte_eth_memif.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/memif/rte_eth_memif.c b/drivers/net/memif/rte_eth_memif.c
index e9ddf6413597..00c9b396ab85 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -1224,13 +1224,8 @@ static int
 memif_set_mac(const char *key __rte_unused, const char *value, void *extra_args)
 {
 	struct rte_ether_addr *ether_addr = (struct rte_ether_addr *)extra_args;
-	int ret = 0;
 
-	ret = sscanf(value, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-	       &ether_addr->addr_bytes[0], &ether_addr->addr_bytes[1],
-	       &ether_addr->addr_bytes[2], &ether_addr->addr_bytes[3],
-	       &ether_addr->addr_bytes[4], &ether_addr->addr_bytes[5]);
-	if (ret != 6)
+	if (rte_ether_unformat_addr(value, ether_addr) < 0)
 		MIF_LOG(WARNING, "Failed to parse mac '%s'.", value);
 	return 0;
 }
-- 
2.20.1


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

* Re: [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations
  2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
                     ` (10 preceding siblings ...)
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 11/11] net/memif: use common ethernet address parsing routine Stephen Hemminger
@ 2019-07-08 19:13   ` Ferruh Yigit
  2019-07-09 15:01     ` Bruce Richardson
  11 siblings, 1 reply; 127+ messages in thread
From: Ferruh Yigit @ 2019-07-08 19:13 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 7/8/2019 7:26 PM, Stephen Hemminger wrote:
> This is a collection of patches around the ethernet address
> manipulation routines in librte_net/rte_ether.
> 
> v9
>    add missing librte_net for new octoeonx2
> v8
>    set rte_errno in rte_eth_unformat_addr
>    drop ether_address alignment patch. Bruce can handle deprecation
>    and sending the patches later
> v7
>    use rte_ether_unformat_addr in more drivers
> v6
>    add librte_net to axgbe and memif Makefile
> v5
>    reword commit messages to workaround check-log complaints
> v4
>    fix meson build
>    reword commit messages
>    add bonding and tespmd patches
> v3 
>    rebase to use rte_ether prefix
>    drop aligning ethernet headers for now.
> 
> Stephen Hemminger (11):
>   net/ether: deinline non-critical functions
>   net/ether: add function to convert string to ethernet address
>   ethdev: use new ethernet parsing function
>   net/ether: use bitops to speedup comparison
>   cmdline: use new ethernet address parser
>   net/bonding: use new ethernet address parser
>   app/testpmd: use new ethernet address parser
>   net/virtio: use new ether addr parsing
>   net/failsafe: use common ether address parsing routine
>   net/vdev_netvsc: use common ethernet address parsing
>   net/memif: use common ethernet address parsing routine

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

Series applied to dpdk-next-net/master, thanks.

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

* Re: [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations
  2019-07-08 19:13   ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Ferruh Yigit
@ 2019-07-09 15:01     ` Bruce Richardson
  0 siblings, 0 replies; 127+ messages in thread
From: Bruce Richardson @ 2019-07-09 15:01 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: Stephen Hemminger, dev

On Mon, Jul 08, 2019 at 08:13:06PM +0100, Ferruh Yigit wrote:
> On 7/8/2019 7:26 PM, Stephen Hemminger wrote:
> > This is a collection of patches around the ethernet address
> > manipulation routines in librte_net/rte_ether.
> > 
> > v9
> >    add missing librte_net for new octoeonx2
> > v8
> >    set rte_errno in rte_eth_unformat_addr
> >    drop ether_address alignment patch. Bruce can handle deprecation
> >    and sending the patches later
> > v7
> >    use rte_ether_unformat_addr in more drivers
> > v6
> >    add librte_net to axgbe and memif Makefile
> > v5
> >    reword commit messages to workaround check-log complaints
> > v4
> >    fix meson build
> >    reword commit messages
> >    add bonding and tespmd patches
> > v3 
> >    rebase to use rte_ether prefix
> >    drop aligning ethernet headers for now.
> > 
> > Stephen Hemminger (11):
> >   net/ether: deinline non-critical functions
> >   net/ether: add function to convert string to ethernet address
> >   ethdev: use new ethernet parsing function
> >   net/ether: use bitops to speedup comparison
> >   cmdline: use new ethernet address parser
> >   net/bonding: use new ethernet address parser
> >   app/testpmd: use new ethernet address parser
> >   net/virtio: use new ether addr parsing
> >   net/failsafe: use common ether address parsing routine
> >   net/vdev_netvsc: use common ethernet address parsing
> >   net/memif: use common ethernet address parsing routine
> 
> For series,
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> 
> Series applied to dpdk-next-net/master, thanks.

Deprecation notice for dropped patch:

http://patches.dpdk.org/patch/56271/

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

* Re: [dpdk-dev] [PATCH v5 6/8] cmdline: use new ethernet address parser
       [not found]     ` <8688172CD5C0B74590FAE19D9579F94B53742875@SHSMSX103.ccr.corp.intel.com>
@ 2019-07-16 16:17       ` Stephen Hemminger
  2019-07-17 14:04         ` Aaron Conole
  0 siblings, 1 reply; 127+ messages in thread
From: Stephen Hemminger @ 2019-07-16 16:17 UTC (permalink / raw)
  To: Li, WenjieX A; +Cc: Wang, FengqinX, Byrne, Stephen1, dev

On Tue, 16 Jul 2019 01:17:56 +0000
"Li, WenjieX A" <wenjiex.a.li@intel.com> wrote:

> Hi Stephen,
> 
> 
> 
> This DPDK patch makes cmdline_autotest failed. List the details as below.
> 
> Could you please help to resolve it?
> 
> Thank you!
> Test Setup
> Steps to reproduce
> List the steps to reproduce the issue.
> ./x86_64-native-linuxapp-gcc/app/test -n 1 -c 0xff
> testpmd> cmdline_autotest  
> Show the output from the previous commands.
> Testind parsing ethernet addresses...
> Error: parsing 01:23:45:67:89:A succeeded!
> Test Failed
> Expected Result
> Explain what is the expected result in text or as an example output:
> Testind parsing ethernet addresses...
> Testind parsing port lists...
> Testind parsing numbers...
> Testing parsing IP addresses...
> Testing parsing strings...
> Testing circular buffer...
> Testing library functions...
> Test OK
> 
> 
> 
> BR,
> 
> Wenjie
> 

There are two possible solutions. Make the ether_unformat_addr function
more complex and more restrictive. The new version corresponds to the FreeBSD
behavior.

The other possibility is just remove the test case.

I am leaning towards the latter as the least work.


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

* Re: [dpdk-dev] [PATCH v5 6/8] cmdline: use new ethernet address parser
  2019-07-16 16:17       ` Stephen Hemminger
@ 2019-07-17 14:04         ` Aaron Conole
  2019-07-17 14:39           ` Olivier Matz
  0 siblings, 1 reply; 127+ messages in thread
From: Aaron Conole @ 2019-07-17 14:04 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Li, WenjieX A, Wang, FengqinX, Byrne, Stephen1, dev

Stephen Hemminger <stephen@networkplumber.org> writes:

> On Tue, 16 Jul 2019 01:17:56 +0000
> "Li, WenjieX A" <wenjiex.a.li@intel.com> wrote:
>
>> Hi Stephen,
>> 
>> 
>> 
>> This DPDK patch makes cmdline_autotest failed. List the details as below.
>> 
>> Could you please help to resolve it?
>> 
>> Thank you!
>> Test Setup
>> Steps to reproduce
>> List the steps to reproduce the issue.
>> ./x86_64-native-linuxapp-gcc/app/test -n 1 -c 0xff
>> testpmd> cmdline_autotest  
>> Show the output from the previous commands.
>> Testind parsing ethernet addresses...
>> Error: parsing 01:23:45:67:89:A succeeded!
>> Test Failed
>> Expected Result
>> Explain what is the expected result in text or as an example output:
>> Testind parsing ethernet addresses...
>> Testind parsing port lists...
>> Testind parsing numbers...
>> Testing parsing IP addresses...
>> Testing parsing strings...
>> Testing circular buffer...
>> Testing library functions...
>> Test OK
>> 
>> 
>> 
>> BR,
>> 
>> Wenjie
>> 
>
> There are two possible solutions. Make the ether_unformat_addr function
> more complex and more restrictive. The new version corresponds to the FreeBSD
> behavior.

Not exactly.  The new code accepts 2 forms (X:X:X:X:X:X which is
FreeBSD, as well as X:X:X which is not).  Because of this, there is a
higher likelihood of ambiguity.  I want to submit a patch to fix this
ambiguity (but got pulled into a customer bug).  Maybe someone else can?

I think it's best to make the code slightly more complex.  I originally
submitted a change just validating the string length[0], which is probably
too restrictive.

Maybe a better version would be something like the original (rewritten
to ensure it supports things like XX:X:XX:X:XX:X format, also):

{
   unsigned long o[ETHER_ADDR_LEN];
   char *end, *input = buf;
   size_t i = 0;

   do {
     errno = 0;
     o[i] = strtoul(input, &end, 16);
     if (errno != 0 || end == input || (end && *end != ':' && *end != 0))
        return ERROR;
     input = end+1;
   } while((input - buf < buflen) && ++i < ARRAY_SIZE(o) && *end != 0);

   if (*end != 0)
      return ERROR;

   if (i == 6) /*x:x:x:x:x:x*/
   else if (i == 3) /*x:x:x*/
   else return ERROR
}

WDYT?

> The other possibility is just remove the test case.

I don't like this approach - right now its possible that a user (doing
c/p) can submit an ipv6 address which will be accepted as valid.  I
prefer to be validating the form.  Even if XX:X:X:XX:X:X is okay,
XXXX:XXXX:XX::X shouldn't be.  There's a limit to how liberal we should
be when accepting input.

> I am leaning towards the latter as the least work.

Least work isn't always the right thing.

0: http://mails.dpdk.org/archives/dev/2019-July/137827.html

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

* Re: [dpdk-dev] [PATCH v5 6/8] cmdline: use new ethernet address parser
  2019-07-17 14:04         ` Aaron Conole
@ 2019-07-17 14:39           ` Olivier Matz
  0 siblings, 0 replies; 127+ messages in thread
From: Olivier Matz @ 2019-07-17 14:39 UTC (permalink / raw)
  To: Aaron Conole
  Cc: Stephen Hemminger, Li, WenjieX A, Wang, FengqinX, Byrne, Stephen1, dev

On Wed, Jul 17, 2019 at 10:04:10AM -0400, Aaron Conole wrote:
> Stephen Hemminger <stephen@networkplumber.org> writes:
> 
> > On Tue, 16 Jul 2019 01:17:56 +0000
> > "Li, WenjieX A" <wenjiex.a.li@intel.com> wrote:
> >
> >> Hi Stephen,
> >> 
> >> 
> >> 
> >> This DPDK patch makes cmdline_autotest failed. List the details as below.
> >> 
> >> Could you please help to resolve it?
> >> 
> >> Thank you!
> >> Test Setup
> >> Steps to reproduce
> >> List the steps to reproduce the issue.
> >> ./x86_64-native-linuxapp-gcc/app/test -n 1 -c 0xff
> >> testpmd> cmdline_autotest  
> >> Show the output from the previous commands.
> >> Testind parsing ethernet addresses...
> >> Error: parsing 01:23:45:67:89:A succeeded!
> >> Test Failed
> >> Expected Result
> >> Explain what is the expected result in text or as an example output:
> >> Testind parsing ethernet addresses...
> >> Testind parsing port lists...
> >> Testind parsing numbers...
> >> Testing parsing IP addresses...
> >> Testing parsing strings...
> >> Testing circular buffer...
> >> Testing library functions...
> >> Test OK
> >> 
> >> 
> >> 
> >> BR,
> >> 
> >> Wenjie
> >> 
> >
> > There are two possible solutions. Make the ether_unformat_addr function
> > more complex and more restrictive. The new version corresponds to the FreeBSD
> > behavior.
> 
> Not exactly.  The new code accepts 2 forms (X:X:X:X:X:X which is
> FreeBSD, as well as X:X:X which is not).  Because of this, there is a
> higher likelihood of ambiguity.  I want to submit a patch to fix this
> ambiguity (but got pulled into a customer bug).  Maybe someone else can?

I will have a look at it.


> I think it's best to make the code slightly more complex.  I originally
> submitted a change just validating the string length[0], which is probably
> too restrictive.
> 
> Maybe a better version would be something like the original (rewritten
> to ensure it supports things like XX:X:XX:X:XX:X format, also):
> 
> {
>    unsigned long o[ETHER_ADDR_LEN];
>    char *end, *input = buf;
>    size_t i = 0;
> 
>    do {
>      errno = 0;
>      o[i] = strtoul(input, &end, 16);
>      if (errno != 0 || end == input || (end && *end != ':' && *end != 0))
>         return ERROR;
>      input = end+1;
>    } while((input - buf < buflen) && ++i < ARRAY_SIZE(o) && *end != 0);
> 
>    if (*end != 0)
>       return ERROR;
> 
>    if (i == 6) /*x:x:x:x:x:x*/
>    else if (i == 3) /*x:x:x*/
>    else return ERROR
> }
> 
> WDYT?
> 
> > The other possibility is just remove the test case.
> 
> I don't like this approach - right now its possible that a user (doing
> c/p) can submit an ipv6 address which will be accepted as valid.  I
> prefer to be validating the form.  Even if XX:X:X:XX:X:X is okay,
> XXXX:XXXX:XX::X shouldn't be.  There's a limit to how liberal we should
> be when accepting input.
> 
> > I am leaning towards the latter as the least work.
> 
> Least work isn't always the right thing.
> 
> 0: http://mails.dpdk.org/archives/dev/2019-July/137827.html

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

* Re: [dpdk-dev] [PATCH v9 07/11] app/testpmd: use new ethernet address parser
  2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 07/11] app/testpmd: " Stephen Hemminger
@ 2019-07-21 13:42     ` Raslan Darawsheh
  2019-07-22 12:09       ` Thomas Monjalon
  2019-07-22 16:15       ` Ferruh Yigit
  0 siblings, 2 replies; 127+ messages in thread
From: Raslan Darawsheh @ 2019-07-21 13:42 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Bernard Iremonger

Hi Guys,

We have a failure in testpmd commands when parsing rte_flow commands as  following which were interduce by this patch:

This rule is a valid rule to be added to testpmd:
flow validate 0  priority  2 ingress group 0 pattern eth dst is 98:03:9B:5C:D9:00 / end actions queue index  0 / end

but, currently with latest master it will fail with Bad arguments 

the check for get_ether_addr6/3 is expecting that you reach the end of string when it parse a MAC address but for rte_flow commands it's not the case,
since we provide the full string:
gdb) p s
$3 = 0x28225fa "98:03:9B:5C:D9:00 / end actions queue index  0 / end\n"


Kindest regards,
Raslan Darawsheh

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Stephen Hemminger
> Sent: Monday, July 8, 2019 9:26 PM
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; Bernard
> Iremonger <bernard.iremonger@intel.com>
> Subject: [dpdk-dev] [PATCH v9 07/11] app/testpmd: use new ethernet
> address parser
> 
> The cmdline_parse_ether_addr does not need to be used everywhere in
> testpmd. Can use rte_ether_unformat_addr instead.
> As an added bonus it eliminates some code for copying.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
> ---
>  app/test-pmd/cmdline_flow.c |  5 ++---
>  app/test-pmd/config.c       | 10 +++-------
>  app/test-pmd/parameters.c   | 15 +++------------
>  3 files changed, 8 insertions(+), 22 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index e3e8448c9421..c92c748b18eb 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -18,7 +18,6 @@
>  #include <rte_ethdev.h>
>  #include <rte_byteorder.h>
>  #include <cmdline_parse.h>
> -#include <cmdline_parse_etheraddr.h>
>  #include <rte_flow.h>
> 
>  #include "testpmd.h"
> @@ -4734,8 +4733,8 @@ parse_mac_addr(struct context *ctx, const struct
> token *token,
>  	/* Only network endian is supported. */
>  	if (!arg->hton)
>  		goto error;
> -	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
> -	if (ret < 0 || (unsigned int)ret != len)
> +	ret = rte_ether_unformat_addr(str, &tmp);
> +	if (ret < 0)
>  		goto error;
>  	if (!ctx->object)
>  		return len;
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> ab458c8d2837..1d804705d96c 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -49,7 +49,6 @@
>  #include <rte_pmd_bnxt.h>
>  #endif
>  #include <rte_gro.h>
> -#include <cmdline_parse_etheraddr.h>
>  #include <rte_config.h>
> 
>  #include "testpmd.h"
> @@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
> void  set_fwd_eth_peer(portid_t port_id, char *peer_addr)  {
> -	uint8_t c, new_peer_addr[6];
> +	struct rte_ether_addr new_peer_addr;
>  	if (!rte_eth_dev_is_valid_port(port_id)) {
>  		printf("Error: Invalid port number %i\n", port_id);
>  		return;
>  	}
> -	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
> -					sizeof(new_peer_addr)) < 0) {
> +	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
>  		printf("Error: Invalid ethernet address: %s\n", peer_addr);
>  		return;
>  	}
> -	for (c = 0; c < 6; c++)
> -		peer_eth_addrs[port_id].addr_bytes[c] =
> -			new_peer_addr[c];
> +	peer_eth_addrs[port_id] = new_peer_addr;
>  }
> 
>  int
> diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index
> 245b610641ee..975a97807009 100644
> --- a/app/test-pmd/parameters.c
> +++ b/app/test-pmd/parameters.c
> @@ -39,10 +39,6 @@
>  #include <rte_ether.h>
>  #include <rte_ethdev.h>
>  #include <rte_string_fns.h>
> -#ifdef RTE_LIBRTE_CMDLINE
> -#include <cmdline_parse.h>
> -#include <cmdline_parse_etheraddr.h>
> -#endif
>  #ifdef RTE_LIBRTE_PMD_BOND
>  #include <rte_eth_bond.h>
>  #endif
> @@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
>  		if (fgets(buf, sizeof(buf), config_file) == NULL)
>  			break;
> 
> -		if (cmdline_parse_etheraddr(NULL, buf,
> &peer_eth_addrs[i],
> -				sizeof(peer_eth_addrs[i])) < 0) {
> +		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
>  			printf("Bad MAC address format on line %d\n", i+1);
>  			fclose(config_file);
>  			return -1;
> @@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
>  			}
>  			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
>  				char *port_end;
> -				uint8_t c, peer_addr[6];
> 
>  				errno = 0;
>  				n = strtoul(optarg, &port_end, 10); @@ -
> 739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
>  						 "eth-peer: port %d >=
> RTE_MAX_ETHPORTS(%d)\n",
>  						 n, RTE_MAX_ETHPORTS);
> 
> -				if (cmdline_parse_etheraddr(NULL,
> port_end,
> -						&peer_addr,
> sizeof(peer_addr)) < 0)
> +				if (rte_ether_unformat_addr(port_end,
> +
> &peer_eth_addrs[n]) < 0)
>  					rte_exit(EXIT_FAILURE,
>  						 "Invalid ethernet address:
> %s\n",
>  						 port_end);
> -				for (c = 0; c < 6; c++)
> -					peer_eth_addrs[n].addr_bytes[c] =
> -						peer_addr[c];
>  				nb_peer_eth_addrs++;
>  			}
>  #endif
> --
> 2.20.1


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

* Re: [dpdk-dev] [PATCH v9 07/11] app/testpmd: use new ethernet address parser
  2019-07-21 13:42     ` Raslan Darawsheh
@ 2019-07-22 12:09       ` Thomas Monjalon
  2019-07-22 16:15       ` Ferruh Yigit
  1 sibling, 0 replies; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-22 12:09 UTC (permalink / raw)
  To: ferruh.yigit; +Cc: dev, Raslan Darawsheh, Stephen Hemminger, Bernard Iremonger

21/07/2019 15:42, Raslan Darawsheh:
> Hi Guys,
> 
> We have a failure in testpmd commands when parsing rte_flow commands as  following which were interduce by this patch:
> 
> This rule is a valid rule to be added to testpmd:
> flow validate 0  priority  2 ingress group 0 pattern eth dst is 98:03:9B:5C:D9:00 / end actions queue index  0 / end
> 
> but, currently with latest master it will fail with Bad arguments 
> 
> the check for get_ether_addr6/3 is expecting that you reach the end of string when it parse a MAC address but for rte_flow commands it's not the case,
> since we provide the full string:
> gdb) p s
> $3 = 0x28225fa "98:03:9B:5C:D9:00 / end actions queue index  0 / end\n"

Ferruh, it seems this patch must be reverted.

We probably need to adapt testpmd to the new function
and properly test it. Let's target it for -rc3 or 19.11.





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

* Re: [dpdk-dev] [PATCH v9 07/11] app/testpmd: use new ethernet address parser
  2019-07-21 13:42     ` Raslan Darawsheh
  2019-07-22 12:09       ` Thomas Monjalon
@ 2019-07-22 16:15       ` Ferruh Yigit
  1 sibling, 0 replies; 127+ messages in thread
From: Ferruh Yigit @ 2019-07-22 16:15 UTC (permalink / raw)
  To: Raslan Darawsheh, Stephen Hemminger, dev; +Cc: Bernard Iremonger

On 7/21/2019 2:42 PM, Raslan Darawsheh wrote:
> Hi Guys,
> 
> We have a failure in testpmd commands when parsing rte_flow commands as  following which were interduce by this patch:
> 
> This rule is a valid rule to be added to testpmd:
> flow validate 0  priority  2 ingress group 0 pattern eth dst is 98:03:9B:5C:D9:00 / end actions queue index  0 / end
> 
> but, currently with latest master it will fail with Bad arguments 
> 
> the check for get_ether_addr6/3 is expecting that you reach the end of string when it parse a MAC address but for rte_flow commands it's not the case,
> since we provide the full string:
> gdb) p s
> $3 = 0x28225fa "98:03:9B:5C:D9:00 / end actions queue index  0 / end\n"

Hi Raslan,

Will it work if only 'cmdline_flow.c' change reverted?

If so I suggest revert only 'cmdline_flow.c' change for rc2, and we can work on
the proper fix later.

> 
> 
> Kindest regards,
> Raslan Darawsheh
> 
>> -----Original Message-----
>> From: dev <dev-bounces@dpdk.org> On Behalf Of Stephen Hemminger
>> Sent: Monday, July 8, 2019 9:26 PM
>> To: dev@dpdk.org
>> Cc: Stephen Hemminger <stephen@networkplumber.org>; Bernard
>> Iremonger <bernard.iremonger@intel.com>
>> Subject: [dpdk-dev] [PATCH v9 07/11] app/testpmd: use new ethernet
>> address parser
>>
>> The cmdline_parse_ether_addr does not need to be used everywhere in
>> testpmd. Can use rte_ether_unformat_addr instead.
>> As an added bonus it eliminates some code for copying.
>>
>> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
>> ---
>>  app/test-pmd/cmdline_flow.c |  5 ++---
>>  app/test-pmd/config.c       | 10 +++-------
>>  app/test-pmd/parameters.c   | 15 +++------------
>>  3 files changed, 8 insertions(+), 22 deletions(-)
>>
>> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
>> index e3e8448c9421..c92c748b18eb 100644
>> --- a/app/test-pmd/cmdline_flow.c
>> +++ b/app/test-pmd/cmdline_flow.c
>> @@ -18,7 +18,6 @@
>>  #include <rte_ethdev.h>
>>  #include <rte_byteorder.h>
>>  #include <cmdline_parse.h>
>> -#include <cmdline_parse_etheraddr.h>
>>  #include <rte_flow.h>
>>
>>  #include "testpmd.h"
>> @@ -4734,8 +4733,8 @@ parse_mac_addr(struct context *ctx, const struct
>> token *token,
>>  	/* Only network endian is supported. */
>>  	if (!arg->hton)
>>  		goto error;
>> -	ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
>> -	if (ret < 0 || (unsigned int)ret != len)
>> +	ret = rte_ether_unformat_addr(str, &tmp);
>> +	if (ret < 0)
>>  		goto error;
>>  	if (!ctx->object)
>>  		return len;
>> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
>> ab458c8d2837..1d804705d96c 100644
>> --- a/app/test-pmd/config.c
>> +++ b/app/test-pmd/config.c
>> @@ -49,7 +49,6 @@
>>  #include <rte_pmd_bnxt.h>
>>  #endif
>>  #include <rte_gro.h>
>> -#include <cmdline_parse_etheraddr.h>
>>  #include <rte_config.h>
>>
>>  #include "testpmd.h"
>> @@ -2278,19 +2277,16 @@ pkt_fwd_config_display(struct fwd_config *cfg)
>> void  set_fwd_eth_peer(portid_t port_id, char *peer_addr)  {
>> -	uint8_t c, new_peer_addr[6];
>> +	struct rte_ether_addr new_peer_addr;
>>  	if (!rte_eth_dev_is_valid_port(port_id)) {
>>  		printf("Error: Invalid port number %i\n", port_id);
>>  		return;
>>  	}
>> -	if (cmdline_parse_etheraddr(NULL, peer_addr, &new_peer_addr,
>> -					sizeof(new_peer_addr)) < 0) {
>> +	if (rte_ether_unformat_addr(peer_addr, &new_peer_addr) < 0) {
>>  		printf("Error: Invalid ethernet address: %s\n", peer_addr);
>>  		return;
>>  	}
>> -	for (c = 0; c < 6; c++)
>> -		peer_eth_addrs[port_id].addr_bytes[c] =
>> -			new_peer_addr[c];
>> +	peer_eth_addrs[port_id] = new_peer_addr;
>>  }
>>
>>  int
>> diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index
>> 245b610641ee..975a97807009 100644
>> --- a/app/test-pmd/parameters.c
>> +++ b/app/test-pmd/parameters.c
>> @@ -39,10 +39,6 @@
>>  #include <rte_ether.h>
>>  #include <rte_ethdev.h>
>>  #include <rte_string_fns.h>
>> -#ifdef RTE_LIBRTE_CMDLINE
>> -#include <cmdline_parse.h>
>> -#include <cmdline_parse_etheraddr.h>
>> -#endif
>>  #ifdef RTE_LIBRTE_PMD_BOND
>>  #include <rte_eth_bond.h>
>>  #endif
>> @@ -227,8 +223,7 @@ init_peer_eth_addrs(char *config_filename)
>>  		if (fgets(buf, sizeof(buf), config_file) == NULL)
>>  			break;
>>
>> -		if (cmdline_parse_etheraddr(NULL, buf,
>> &peer_eth_addrs[i],
>> -				sizeof(peer_eth_addrs[i])) < 0) {
>> +		if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
>>  			printf("Bad MAC address format on line %d\n", i+1);
>>  			fclose(config_file);
>>  			return -1;
>> @@ -727,7 +722,6 @@ launch_args_parse(int argc, char** argv)
>>  			}
>>  			if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
>>  				char *port_end;
>> -				uint8_t c, peer_addr[6];
>>
>>  				errno = 0;
>>  				n = strtoul(optarg, &port_end, 10); @@ -
>> 739,14 +733,11 @@ launch_args_parse(int argc, char** argv)
>>  						 "eth-peer: port %d >=
>> RTE_MAX_ETHPORTS(%d)\n",
>>  						 n, RTE_MAX_ETHPORTS);
>>
>> -				if (cmdline_parse_etheraddr(NULL,
>> port_end,
>> -						&peer_addr,
>> sizeof(peer_addr)) < 0)
>> +				if (rte_ether_unformat_addr(port_end,
>> +
>> &peer_eth_addrs[n]) < 0)
>>  					rte_exit(EXIT_FAILURE,
>>  						 "Invalid ethernet address:
>> %s\n",
>>  						 port_end);
>> -				for (c = 0; c < 6; c++)
>> -					peer_eth_addrs[n].addr_bytes[c] =
>> -						peer_addr[c];
>>  				nb_peer_eth_addrs++;
>>  			}
>>  #endif
>> --
>> 2.20.1
> 


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

end of thread, other threads:[~2019-07-22 16:15 UTC | newest]

Thread overview: 127+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-16 18:04 [dpdk-dev] [PATCH v2 0/7] ether: improvements and optimizations Stephen Hemminger
2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 1/7] ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 2/7] ether: do not mark ethernet address and header as packed Stephen Hemminger
2019-05-16 20:40   ` Bruce Richardson
2019-05-16 23:17     ` Stephen Hemminger
2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 3/7] ether: deinline non-critical functions Stephen Hemminger
2019-05-16 18:29   ` Rami Rosen
2019-05-17  7:08   ` David Marchand
2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 4/7] ether: add eth_unformat_addr Stephen Hemminger
2019-05-17  7:08   ` David Marchand
2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 5/7] ethdev: use eth_unformat_addr Stephen Hemminger
2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 6/7] ether: use bitops to speedup comparison Stephen Hemminger
2019-05-16 18:04 ` [dpdk-dev] [PATCH v2 7/7] cmdline: use ether_unformat_addr Stephen Hemminger
2019-06-05  1:08 ` [dpdk-dev] [PATCH v3 0/6] net/ether: improvements and optimizations Stephen Hemminger
2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 1/6] net/rte_ether: deinline non-critical functions Stephen Hemminger
2019-06-05  8:44     ` Andrew Rybchenko
2019-06-05 16:29       ` Stephen Hemminger
2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 2/6] net/ether: add rte_eth_unformat_addr Stephen Hemminger
2019-06-05  8:55     ` Andrew Rybchenko
2019-06-05 16:31       ` Stephen Hemminger
2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 3/6] ethdev: use rte_eth_unformat_addr Stephen Hemminger
2019-06-05  8:59     ` Andrew Rybchenko
2019-06-05 15:02       ` Stephen Hemminger
2019-06-05 16:33       ` Stephen Hemminger
2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 4/6] net/ether: use bitops to speedup comparison Stephen Hemminger
2019-06-05  9:02     ` Andrew Rybchenko
2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 5/6] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
2019-06-05  9:04     ` Andrew Rybchenko
2019-06-05  1:08   ` [dpdk-dev] [PATCH v3 6/6] cmdline: use rte_ether_unformat_addr Stephen Hemminger
2019-06-05 18:09 ` [dpdk-dev] [PATCH v4 0/8] net/ether: enhancements and optimizations Stephen Hemminger
2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
2019-06-06  8:06     ` Maxime Coquelin
2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 2/8] net/ether: add rte_eth_unformat_addr Stephen Hemminger
2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 3/8] ethdev: use rte_eth_unformat_addr Stephen Hemminger
2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
2019-06-07 16:59     ` Ananyev, Konstantin
2019-06-07 18:35       ` Stephen Hemminger
2019-06-07 20:40         ` Richardson, Bruce
2019-06-08 11:51         ` Ananyev, Konstantin
2019-06-07 20:39       ` Richardson, Bruce
2019-06-08 12:15         ` Ananyev, Konstantin
2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 6/8] cmdline: use rte_ether_unformat_addr Stephen Hemminger
2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 7/8] net/bonding: use rte_ether_unformat_addr rather than cmdline_parse Stephen Hemminger
2019-06-05 18:09   ` [dpdk-dev] [PATCH v4 8/8] app/testpmd: use rte_ether_unformat_addr Stephen Hemminger
2019-06-20 14:18     ` Iremonger, Bernard
2019-06-20 16:12       ` Stephen Hemminger
2019-06-24 20:44 ` [dpdk-dev] [PATCH v5 0/8] net/ether: enhancements and optimizations Stephen Hemminger
2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
2019-07-02  7:56     ` Olivier Matz
2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 2/8] net/ether: add function to convert string to ethernet address Stephen Hemminger
2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 3/8] ethdev: use new ethernet parsing function Stephen Hemminger
2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
2019-07-02  7:53     ` Olivier Matz
2019-07-02  9:26       ` Olivier Matz
2019-07-02 15:28         ` Stephen Hemminger
2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 6/8] cmdline: use new ethernet address parser Stephen Hemminger
     [not found]     ` <8688172CD5C0B74590FAE19D9579F94B53742875@SHSMSX103.ccr.corp.intel.com>
2019-07-16 16:17       ` Stephen Hemminger
2019-07-17 14:04         ` Aaron Conole
2019-07-17 14:39           ` Olivier Matz
2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 7/8] net/bonding: " Stephen Hemminger
2019-06-24 20:44   ` [dpdk-dev] [PATCH v5 8/8] app/testpmd: " Stephen Hemminger
2019-07-02 16:50 ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Stephen Hemminger
2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 1/8] net/rte_ether: deinline non-critical functions Stephen Hemminger
2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 2/8] net/ether: add function to convert string to ethernet address Stephen Hemminger
2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 3/8] ethdev: use new ethernet parsing function Stephen Hemminger
2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 4/8] net/ether: use bitops to speedup comparison Stephen Hemminger
2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 5/8] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
2019-07-02 21:46     ` Ananyev, Konstantin
2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 6/8] cmdline: use new ethernet address parser Stephen Hemminger
2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 7/8] net/bonding: " Stephen Hemminger
2019-07-02 16:50   ` [dpdk-dev] [PATCH v6 8/8] app/testpmd: " Stephen Hemminger
2019-07-02 21:37   ` [dpdk-dev] [PATCH v6 0/8] net/ether: enhancements and optimizations Thomas Monjalon
2019-07-02 22:03     ` Stephen Hemminger
2019-07-02 22:12 ` [dpdk-dev] [PATCH v7 00/12] ether: improvements " Stephen Hemminger
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 01/12] net/rte_ether: deinline non-critical functions Stephen Hemminger
2019-07-05 14:25     ` Olivier Matz
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 02/12] net/ether: add function to convert string to ethernet address Stephen Hemminger
2019-07-05 14:25     ` Olivier Matz
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 03/12] ethdev: use new ethernet parsing function Stephen Hemminger
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 04/12] net/ether: use bitops to speedup comparison Stephen Hemminger
2019-07-05 14:34     ` Olivier Matz
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 05/12] net/ether: mark ethernet addresses as being 2-byte aligned Stephen Hemminger
2019-07-05 14:34     ` Olivier Matz
2019-07-05 15:45       ` Richardson, Bruce
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 06/12] cmdline: use new ethernet address parser Stephen Hemminger
2019-07-05 14:46     ` Olivier Matz
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 07/12] net/bonding: " Stephen Hemminger
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 08/12] app/testpmd: " Stephen Hemminger
2019-07-03 13:30     ` Iremonger, Bernard
2019-07-05 17:12       ` Stephen Hemminger
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 09/12] net/virtio: use new ether addr parsing Stephen Hemminger
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 10/12] net/failsafe: use common ether address parsing routine Stephen Hemminger
2019-07-03  9:10     ` Gaëtan Rivet
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 11/12] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
2019-07-03  8:12     ` Matan Azrad
2019-07-02 22:12   ` [dpdk-dev] [PATCH v7 12/12] net/memif: use common ethernet address parsing routine Stephen Hemminger
2019-07-05 17:16 ` [dpdk-dev] [PATCH v8 00/11] ether: improvements and optimizations Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 01/11] net/ether: deinline non-critical functions Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 02/11] net/ether: add function to convert string to ethernet address Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 03/11] ethdev: use new ethernet parsing function Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 04/11] net/ether: use bitops to speedup comparison Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 05/11] cmdline: use new ethernet address parser Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 06/11] net/bonding: " Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 07/11] app/testpmd: " Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 08/11] net/virtio: use new ether addr parsing Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 09/11] net/failsafe: use common ether address parsing routine Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 10/11] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
2019-07-05 17:16   ` [dpdk-dev] [PATCH v8 11/11] net/memif: use common ethernet address parsing routine Stephen Hemminger
2019-07-08 18:26 ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 01/11] net/ether: deinline non-critical functions Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 02/11] net/ether: add function to convert string to ethernet address Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 03/11] ethdev: use new ethernet parsing function Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 04/11] net/ether: use bitops to speedup comparison Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 05/11] cmdline: use new ethernet address parser Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 06/11] net/bonding: " Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 07/11] app/testpmd: " Stephen Hemminger
2019-07-21 13:42     ` Raslan Darawsheh
2019-07-22 12:09       ` Thomas Monjalon
2019-07-22 16:15       ` Ferruh Yigit
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 08/11] net/virtio: use new ether addr parsing Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 09/11] net/failsafe: use common ether address parsing routine Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 10/11] net/vdev_netvsc: use common ethernet address parsing Stephen Hemminger
2019-07-08 18:26   ` [dpdk-dev] [PATCH v9 11/11] net/memif: use common ethernet address parsing routine Stephen Hemminger
2019-07-08 19:13   ` [dpdk-dev] [PATCH v9 00/11] ether: improvements and optimizations Ferruh Yigit
2019-07-09 15:01     ` Bruce Richardson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).