From: Stephen Hemminger Date: Fri, 5 Jul 2019 17:16:17 +0000 (-0700) Subject: net: add function to convert string to ethernet address X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=596d31092d322b7a8387f352311ffeb658547914;p=dpdk.git net: add function to convert string to ethernet address 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 Reviewed-by: Andrew Rybchenko --- diff --git a/lib/librte_net/rte_ether.c b/lib/librte_net/rte_ether.c index 974fe815b3..8d040173cf 100644 --- a/lib/librte_net/rte_ether.c +++ b/lib/librte_net/rte_ether.c @@ -3,6 +3,7 @@ */ #include +#include 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 df1a51462a..c4ff4cd8d3 100644 --- a/lib/librte_net/rte_ether.h +++ b/lib/librte_net/rte_ether.h @@ -250,6 +250,21 @@ 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 + */ +__rte_experimental +int +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 4001f45579..fffc4a3723 100644 --- a/lib/librte_net/rte_net_version.map +++ b/lib/librte_net/rte_net_version.map @@ -26,4 +26,5 @@ EXPERIMENTAL { rte_net_make_rarp_packet; rte_net_skip_ip6_ext; + rte_ether_unformat_addr; };