From 3858c27833d1417e01e8a6c84c372ece2201946f Mon Sep 17 00:00:00 2001 From: Rohit M P Date: Thu, 23 Apr 2020 21:48:58 +0530 Subject: [PATCH] [Bug Fix] Add Check for Validating Ports This fixes the invalid port print error message that would occur when an NF attempted to use retrieve the mac address of a port that wasn't bound to DPDK. Developers can now retrieve a fake mac addr for testing purposes or a real mac address in case the request port is bound. Commit log: * Add check for invalid port * Update bound ports detection * Format code * Conform with bash linter * Add onvm_macaddr_get * Remove redundant warning * Update with call to onvm_macaddr_get * Update examples/load_balancer/load_balancer.c * Update onvm_macaddr_get macro to function * Update onvm_macaddr_get usage * Add onvm_get_fake_macaddr * Update onvm_get_macaddr usage * Seperate onvm_get_macaddr and onvm_get_fake_macaddr * Update examples/speed_tester/speed_tester.c * Update style * Try to get real MAC address before using a fake * Remove redundant else statement --- examples/load_balancer/load_balancer.c | 8 ++++++-- examples/load_generator/load_generator.c | 4 +++- examples/scaling_example/scaling.c | 4 +++- examples/speed_tester/speed_tester.c | 4 +++- onvm/go.sh | 7 +++++++ onvm/onvm_nflib/onvm_common.h | 26 ++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/examples/load_balancer/load_balancer.c b/examples/load_balancer/load_balancer.c index 09d0e0d65..a945cf110 100644 --- a/examples/load_balancer/load_balancer.c +++ b/examples/load_balancer/load_balancer.c @@ -531,7 +531,9 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, } if (pkt->port == lb->server_port) { - rte_eth_macaddr_get(lb->client_port, &ehdr->s_addr); + if (onvm_get_macaddr(lb->client_port, &ehdr->s_addr) == -1) { + rte_exit(EXIT_FAILURE, "Failed to obtain MAC address\n"); + } for (i = 0; i < ETHER_ADDR_LEN; i++) { ehdr->d_addr.addr_bytes[i] = flow_info->s_addr_bytes[i]; } @@ -539,7 +541,9 @@ packet_handler(struct rte_mbuf *pkt, struct onvm_pkt_meta *meta, ip->src_addr = lb->ip_lb_client; meta->destination = lb->client_port; } else { - rte_eth_macaddr_get(lb->server_port, &ehdr->s_addr); + if (onvm_get_macaddr(lb->server_port, &ehdr->s_addr) == -1) { + rte_exit(EXIT_FAILURE, "Failed to obtain MAC address\n"); + } for (i = 0; i < ETHER_ADDR_LEN; i++) { ehdr->d_addr.addr_bytes[i] = lb->server[flow_info->dest].d_addr_bytes[i]; } diff --git a/examples/load_generator/load_generator.c b/examples/load_generator/load_generator.c index c59d6f507..1a59929df 100644 --- a/examples/load_generator/load_generator.c +++ b/examples/load_generator/load_generator.c @@ -327,7 +327,9 @@ nf_setup(struct onvm_nf_local_ctx *nf_local_ctx) { rte_exit(EXIT_FAILURE, "Failed to allocate common ehdr\n"); } - rte_eth_macaddr_get(0, &ehdr->s_addr); + if (onvm_get_macaddr(0, &ehdr->s_addr) == -1) { + rte_exit(EXIT_FAILURE, "Failed to obtain MAC address\n"); + } for (j = 0; j < ETHER_ADDR_LEN; ++j) { ehdr->d_addr.addr_bytes[j] = d_addr_bytes[j]; } diff --git a/examples/scaling_example/scaling.c b/examples/scaling_example/scaling.c index 45a296a7a..401c049c1 100644 --- a/examples/scaling_example/scaling.c +++ b/examples/scaling_example/scaling.c @@ -184,7 +184,9 @@ nf_setup(__attribute__((unused)) struct onvm_nf_local_ctx *nf_local_ctx) { ehdr = (struct ether_hdr *)rte_pktmbuf_append(pkt, packet_size); /* Using manager mac addr for source*/ - rte_eth_macaddr_get(0, &ehdr->s_addr); + if (onvm_get_macaddr(0, &ehdr->s_addr) == -1) { + onvm_get_fake_macaddr(&ehdr->s_addr); + } for (j = 0; j < ETHER_ADDR_LEN; ++j) { ehdr->d_addr.addr_bytes[j] = d_addr_bytes[j]; } diff --git a/examples/speed_tester/speed_tester.c b/examples/speed_tester/speed_tester.c index f8c563cfe..736970fd0 100644 --- a/examples/speed_tester/speed_tester.c +++ b/examples/speed_tester/speed_tester.c @@ -378,7 +378,9 @@ nf_setup(struct onvm_nf_local_ctx *nf_local_ctx) { /*using manager mac addr for source *using input string for dest addr */ - rte_eth_macaddr_get(0, &ehdr->s_addr); + if (onvm_get_macaddr(0, &ehdr->s_addr) == -1) { + onvm_get_fake_macaddr(&ehdr->s_addr); + } for (j = 0; j < ETHER_ADDR_LEN; ++j) { ehdr->d_addr.addr_bytes[j] = d_addr_bytes[j]; } diff --git a/onvm/go.sh b/onvm/go.sh index b010ba987..4113d3405 100755 --- a/onvm/go.sh +++ b/onvm/go.sh @@ -52,6 +52,13 @@ then usage fi +ports_detected=$("$RTE_SDK"/usertools/dpdk-devbind.py --status-dev net | sed '/Network devices using kernel driver/q' | grep -c "drv") +if [[ $ports_detected -lt $ports ]] +then + echo "Error: Invalid port mask. Insufficient NICs bound." + exit 1 +fi + while getopts "a:r:d:s:t:l:p:z:cv" opt; do case $opt in a) virt_addr="--base-virtaddr=$OPTARG";; diff --git a/onvm/onvm_nflib/onvm_common.h b/onvm/onvm_nflib/onvm_common.h index 079f5589f..bb623d5b1 100755 --- a/onvm/onvm_nflib/onvm_common.h +++ b/onvm/onvm_nflib/onvm_common.h @@ -54,6 +54,7 @@ #include #include #include +#include #include "onvm_config_common.h" #include "onvm_msg_common.h" @@ -495,4 +496,29 @@ whether_wakeup_client(struct onvm_nf *nf, struct nf_wakeup_info *nf_wakeup_info) #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1 +/* + * Updates the ether_addr struct with a fake, safe MAC address. + */ +static inline int +onvm_get_fake_macaddr(struct ether_addr *mac_addr) { + uint16_t *mac_addr_bytes = (uint16_t *)((struct ether_addr *)(mac_addr)->addr_bytes); + mac_addr_bytes[0] = 2; + mac_addr_bytes[1] = 0; + mac_addr_bytes[2] = 0; + return 0; +} + +/* + * Tries to fetch the MAC address of the port_id. + * Return 0 if port is valid, -1 if port is invalid. + */ +static inline int +onvm_get_macaddr(uint8_t port_id, struct ether_addr *mac_addr) { + if (!rte_eth_dev_is_valid_port(port_id)) { + return -1; + } + rte_eth_macaddr_get(port_id, mac_addr); + return 0; +} + #endif // _ONVM_COMMON_H_