Both drivers open coded a random MAC address: take 32 bits from
rte_rand(), clear the multicast bit and set the local assignment bit.
That is what rte_eth_random_addr() does, and it now takes its
randomness from the operating system rather than rte_rand().
The enetc version also wrote past the end of the six byte address.
After incrementing a uint32_t pointer to the last two bytes it stored
a full uint32_t there, overrunning hw->mac.addr by two bytes. The
address bytes are now read explicitly instead of through a wider
pointer, which also makes the value written to PMAR1 independent of
the host byte order.
Note that the read path at the top of the same function has the same
overrun. It is left alone here, this patch only changes the code that
generates the address.
Fixes: a7fc52fcadb1 ("net/enetc: introduce ENETC4 PMD")
Cc: [email protected]
Signed-off-by: Stephen Hemminger <[email protected]>
---
drivers/net/enetc/enetc4_vf.c | 22 +++++++++++-----------
drivers/net/enetfec/enet_ethdev.c | 16 ++--------------
2 files changed, 13 insertions(+), 25 deletions(-)
diff --git a/drivers/net/enetc/enetc4_vf.c b/drivers/net/enetc/enetc4_vf.c
index ef5f1e6d66..df3b4bd89b 100644
--- a/drivers/net/enetc/enetc4_vf.c
+++ b/drivers/net/enetc/enetc4_vf.c
@@ -4,7 +4,6 @@
#include <stdbool.h>
#include <rte_kvargs.h>
-#include <rte_random.h>
#include <dpaax_iova_table.h>
#include "enetc_logs.h"
#include "enetc.h"
@@ -1252,18 +1251,19 @@ enetc4_vf_mac_init(struct enetc_eth_hw *hw, struct
rte_eth_dev *eth_dev)
low_mac = (uint16_t)*mac;
if ((high_mac | low_mac) == 0) {
- char *first_byte;
+ const uint8_t *addr = hw->mac.addr;
+
ENETC_PMD_NOTICE("MAC is not available for this SI, "
"set random MAC");
- mac = (uint32_t *)hw->mac.addr;
- *mac = (uint32_t)rte_rand();
- first_byte = (char *)mac;
- *first_byte &= 0xfe; /* clear multicast bit */
- *first_byte |= 0x02; /* set local assignment bit (IEEE802) */
- enetc4_port_wr(enetc_hw, ENETC4_PMAR0, *mac);
- mac++;
- *mac = (uint16_t)rte_rand();
- enetc4_port_wr(enetc_hw, ENETC4_PMAR1, *mac);
+ rte_eth_random_addr(hw->mac.addr);
+ /* The address is six bytes, read the last two explicitly
+ * rather than through a wider pointer.
+ */
+ enetc4_port_wr(enetc_hw, ENETC4_PMAR0,
+ addr[0] | addr[1] << 8 |
+ addr[2] << 16 | (uint32_t)addr[3] << 24);
+ enetc4_port_wr(enetc_hw, ENETC4_PMAR1,
+ addr[4] | addr[5] << 8);
enetc_print_ethaddr("New address: ",
(const struct rte_ether_addr *)hw->mac.addr);
}
diff --git a/drivers/net/enetfec/enet_ethdev.c
b/drivers/net/enetfec/enet_ethdev.c
index c7ef097875..691f634d80 100644
--- a/drivers/net/enetfec/enet_ethdev.c
+++ b/drivers/net/enetfec/enet_ethdev.c
@@ -637,20 +637,8 @@ pmd_enetfec_probe(struct rte_vdev_device *vdev)
*mac = (uint16_t)(tmac >> ENETFEC_MAC_SHIFT);
high_mac = (uint16_t)(*mac);
- if ((high_mac | low_mac) == 0 || (high_mac | low_mac) ==
ENETFEC_MAC_RESET) {
- uint8_t *first_byte;
-
- mac = (uint16_t *)addr.addr_bytes;
- tmac = (uint32_t)rte_rand();
- first_byte = (uint8_t *)&tmac;
- *first_byte &= (uint8_t)~RTE_ETHER_GROUP_ADDR; /* clear
multicast bit */
- *first_byte |= RTE_ETHER_LOCAL_ADMIN_ADDR; /* set local
assignment bit (IEEE802) */
- *mac = (uint16_t)tmac;
- mac++;
- *mac = (uint16_t)(tmac >> ENETFEC_MAC_SHIFT);
- mac++;
- *mac = (uint16_t)rte_rand();
- }
+ if ((high_mac | low_mac) == 0 || (high_mac | low_mac) ==
ENETFEC_MAC_RESET)
+ rte_eth_random_addr(addr.addr_bytes);
enetfec_set_mac_address(dev, &addr);
--
2.53.0