X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fl3fwd%2Fl3fwd_fib.c;h=e02e4b3f5a2ada13a4b746f353d830fc385598a1;hb=3cc977704be6d4db3655da5afb2e87f114cd42d3;hp=d083ddfdd5c4b03d4301e13eb685aa876c416dd2;hpb=6018b5ac7477c6ba8fbf28128dd4ebbafbeaffd0;p=dpdk.git diff --git a/examples/l3fwd/l3fwd_fib.c b/examples/l3fwd/l3fwd_fib.c index d083ddfdd5..e02e4b3f5a 100644 --- a/examples/l3fwd/l3fwd_fib.c +++ b/examples/l3fwd/l3fwd_fib.c @@ -18,6 +18,8 @@ #include "l3fwd_neon.h" #elif defined RTE_ARCH_PPC_64 #include "l3fwd_altivec.h" +#else +#include "l3fwd_common.h" #endif #include "l3fwd_event.h" #include "l3fwd_route.h" @@ -92,9 +94,9 @@ fib_send_single(int nb_tx, struct lcore_conf *qconf, /* Set MAC addresses. */ eth_hdr = rte_pktmbuf_mtod(pkts_burst[j], struct rte_ether_hdr *); - *(uint64_t *)ð_hdr->d_addr = dest_eth_addr[hops[j]]; + *(uint64_t *)ð_hdr->dst_addr = dest_eth_addr[hops[j]]; rte_ether_addr_copy(&ports_eth_addr[hops[j]], - ð_hdr->s_addr); + ð_hdr->src_addr); /* Send single packet. */ send_single_packet(qconf, pkts_burst[j], hops[j]); @@ -252,9 +254,9 @@ fib_event_loop(struct l3fwd_event_resources *evt_rsrc, const uint8_t event_d_id = evt_rsrc->event_d_id; const uint16_t deq_len = evt_rsrc->deq_depth; struct rte_event events[MAX_PKT_BURST]; + int i, nb_enq = 0, nb_deq = 0; struct lcore_conf *lconf; unsigned int lcore_id; - int nb_enq, nb_deq, i; uint32_t ipv4_arr[MAX_PKT_BURST]; uint8_t ipv6_arr[MAX_PKT_BURST][RTE_FIB6_IPV6_ADDR_SIZE]; @@ -370,6 +372,9 @@ fib_event_loop(struct l3fwd_event_resources *evt_rsrc, nb_deq - nb_enq, 0); } } + + l3fwd_event_worker_cleanup(event_d_id, event_p_id, events, nb_enq, + nb_deq, 0); } int __rte_noinline @@ -412,13 +417,181 @@ fib_event_main_loop_tx_q_burst(__rte_unused void *dummy) return 0; } -/* Function to setup fib. */ +static __rte_always_inline void +fib_process_event_vector(struct rte_event_vector *vec) +{ + uint8_t ipv6_arr[MAX_PKT_BURST][RTE_FIB6_IPV6_ADDR_SIZE]; + uint64_t hopsv4[MAX_PKT_BURST], hopsv6[MAX_PKT_BURST]; + uint32_t ipv4_arr_assem, ipv6_arr_assem; + struct rte_mbuf **mbufs = vec->mbufs; + uint32_t ipv4_arr[MAX_PKT_BURST]; + uint8_t type_arr[MAX_PKT_BURST]; + uint32_t ipv4_cnt, ipv6_cnt; + struct lcore_conf *lconf; + uint16_t nh; + int i; + + lconf = &lcore_conf[rte_lcore_id()]; + + /* Reset counters. */ + ipv4_cnt = 0; + ipv6_cnt = 0; + ipv4_arr_assem = 0; + ipv6_arr_assem = 0; + + /* Prefetch first packets. */ + for (i = 0; i < FIB_PREFETCH_OFFSET && i < vec->nb_elem; i++) + rte_prefetch0(rte_pktmbuf_mtod(mbufs[i], void *)); + + /* Parse packet info and prefetch. */ + for (i = 0; i < (vec->nb_elem - FIB_PREFETCH_OFFSET); i++) { + rte_prefetch0(rte_pktmbuf_mtod(mbufs[i + FIB_PREFETCH_OFFSET], + void *)); + fib_parse_packet(mbufs[i], &ipv4_arr[ipv4_cnt], &ipv4_cnt, + ipv6_arr[ipv6_cnt], &ipv6_cnt, &type_arr[i]); + } + + /* Parse remaining packet info. */ + for (; i < vec->nb_elem; i++) + fib_parse_packet(mbufs[i], &ipv4_arr[ipv4_cnt], &ipv4_cnt, + ipv6_arr[ipv6_cnt], &ipv6_cnt, &type_arr[i]); + + /* Lookup IPv4 hops if IPv4 packets are present. */ + if (likely(ipv4_cnt > 0)) + rte_fib_lookup_bulk(lconf->ipv4_lookup_struct, ipv4_arr, hopsv4, + ipv4_cnt); + + /* Lookup IPv6 hops if IPv6 packets are present. */ + if (ipv6_cnt > 0) + rte_fib6_lookup_bulk(lconf->ipv6_lookup_struct, ipv6_arr, + hopsv6, ipv6_cnt); + + if (vec->attr_valid) { + nh = type_arr[0] ? (uint16_t)hopsv4[0] : (uint16_t)hopsv6[0]; + if (nh != FIB_DEFAULT_HOP) + vec->port = nh; + else + vec->attr_valid = 0; + } + + /* Assign ports looked up in fib depending on IPv4 or IPv6 */ + for (i = 0; i < vec->nb_elem; i++) { + if (type_arr[i]) + nh = (uint16_t)hopsv4[ipv4_arr_assem++]; + else + nh = (uint16_t)hopsv6[ipv6_arr_assem++]; + if (nh != FIB_DEFAULT_HOP) + mbufs[i]->port = nh; + event_vector_attr_validate(vec, mbufs[i]); + } +} + +static __rte_always_inline void +fib_event_loop_vector(struct l3fwd_event_resources *evt_rsrc, + const uint8_t flags) +{ + const int event_p_id = l3fwd_get_free_event_port(evt_rsrc); + const uint8_t tx_q_id = + evt_rsrc->evq.event_q_id[evt_rsrc->evq.nb_queues - 1]; + const uint8_t event_d_id = evt_rsrc->event_d_id; + const uint16_t deq_len = evt_rsrc->deq_depth; + struct rte_event events[MAX_PKT_BURST]; + int nb_enq = 0, nb_deq = 0, i; + + if (event_p_id < 0) + return; + + RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, + rte_lcore_id()); + + while (!force_quit) { + /* Read events from RX queues. */ + nb_deq = rte_event_dequeue_burst(event_d_id, event_p_id, events, + deq_len, 0); + if (nb_deq == 0) { + rte_pause(); + continue; + } + + for (i = 0; i < nb_deq; i++) { + if (flags & L3FWD_EVENT_TX_ENQ) { + events[i].queue_id = tx_q_id; + events[i].op = RTE_EVENT_OP_FORWARD; + } + + fib_process_event_vector(events[i].vec); + + if (flags & L3FWD_EVENT_TX_DIRECT) + event_vector_txq_set(events[i].vec, 0); + } + + if (flags & L3FWD_EVENT_TX_ENQ) { + nb_enq = rte_event_enqueue_burst(event_d_id, event_p_id, + events, nb_deq); + while (nb_enq < nb_deq && !force_quit) + nb_enq += rte_event_enqueue_burst( + event_d_id, event_p_id, events + nb_enq, + nb_deq - nb_enq); + } + + if (flags & L3FWD_EVENT_TX_DIRECT) { + nb_enq = rte_event_eth_tx_adapter_enqueue( + event_d_id, event_p_id, events, nb_deq, 0); + while (nb_enq < nb_deq && !force_quit) + nb_enq += rte_event_eth_tx_adapter_enqueue( + event_d_id, event_p_id, events + nb_enq, + nb_deq - nb_enq, 0); + } + } + + l3fwd_event_worker_cleanup(event_d_id, event_p_id, events, nb_enq, + nb_deq, 1); +} + +int __rte_noinline +fib_event_main_loop_tx_d_vector(__rte_unused void *dummy) +{ + struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); + + fib_event_loop_vector(evt_rsrc, L3FWD_EVENT_TX_DIRECT); + return 0; +} + +int __rte_noinline +fib_event_main_loop_tx_d_burst_vector(__rte_unused void *dummy) +{ + struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); + + fib_event_loop_vector(evt_rsrc, L3FWD_EVENT_TX_DIRECT); + return 0; +} + +int __rte_noinline +fib_event_main_loop_tx_q_vector(__rte_unused void *dummy) +{ + struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); + + fib_event_loop_vector(evt_rsrc, L3FWD_EVENT_TX_ENQ); + return 0; +} + +int __rte_noinline +fib_event_main_loop_tx_q_burst_vector(__rte_unused void *dummy) +{ + struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); + + fib_event_loop_vector(evt_rsrc, L3FWD_EVENT_TX_ENQ); + return 0; +} + +/* Function to setup fib. 8< */ void setup_fib(const int socketid) { + struct rte_eth_dev_info dev_info; struct rte_fib6_conf config; struct rte_fib_conf config_ipv4; - unsigned int i; + int i; int ret; char s[64]; char abuf[INET6_ADDRSTRLEN]; @@ -426,6 +599,7 @@ setup_fib(const int socketid) /* Create the fib IPv4 table. */ config_ipv4.type = RTE_FIB_DIR24_8; config_ipv4.max_routes = (1 << 16); + config_ipv4.rib_ext_sz = 0; config_ipv4.default_nh = FIB_DEFAULT_HOP; config_ipv4.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B; config_ipv4.dir24_8.num_tbl8 = (1 << 15); @@ -437,81 +611,95 @@ setup_fib(const int socketid) "Unable to create the l3fwd FIB table on socket %d\n", socketid); + /* Populate the fib ipv4 table. */ - for (i = 0; i < RTE_DIM(ipv4_l3fwd_route_array); i++) { + for (i = 0; i < route_num_v4; i++) { struct in_addr in; /* Skip unused ports. */ - if ((1 << ipv4_l3fwd_route_array[i].if_out & + if ((1 << route_base_v4[i].if_out & enabled_port_mask) == 0) continue; + rte_eth_dev_info_get(route_base_v4[i].if_out, + &dev_info); ret = rte_fib_add(ipv4_l3fwd_fib_lookup_struct[socketid], - ipv4_l3fwd_route_array[i].ip, - ipv4_l3fwd_route_array[i].depth, - ipv4_l3fwd_route_array[i].if_out); + route_base_v4[i].ip, + route_base_v4[i].depth, + route_base_v4[i].if_out); if (ret < 0) { + free(route_base_v4); rte_exit(EXIT_FAILURE, "Unable to add entry %u to the l3fwd FIB table on socket %d\n", i, socketid); } - in.s_addr = htonl(ipv4_l3fwd_route_array[i].ip); + in.s_addr = htonl(route_base_v4[i].ip); if (inet_ntop(AF_INET, &in, abuf, sizeof(abuf)) != NULL) { - printf("FIB: Adding route %s / %d (%d)\n", - abuf, - ipv4_l3fwd_route_array[i].depth, - ipv4_l3fwd_route_array[i].if_out); + printf("FIB: Adding route %s / %d (%d) [%s]\n", abuf, + route_base_v4[i].depth, + route_base_v4[i].if_out, + dev_info.device->name); } else { - printf("FIB: IPv4 route added to port %d\n", - ipv4_l3fwd_route_array[i].if_out); + printf("FIB: IPv4 route added to port %d [%s]\n", + route_base_v4[i].if_out, + dev_info.device->name); } } + /* >8 End of setup fib. */ /* Create the fib IPv6 table. */ snprintf(s, sizeof(s), "IPV6_L3FWD_FIB_%d", socketid); config.type = RTE_FIB6_TRIE; config.max_routes = (1 << 16) - 1; + config.rib_ext_sz = 0; config.default_nh = FIB_DEFAULT_HOP; config.trie.nh_sz = RTE_FIB6_TRIE_4B; config.trie.num_tbl8 = (1 << 15); ipv6_l3fwd_fib_lookup_struct[socketid] = rte_fib6_create(s, socketid, &config); - if (ipv6_l3fwd_fib_lookup_struct[socketid] == NULL) + if (ipv6_l3fwd_fib_lookup_struct[socketid] == NULL) { + free(route_base_v4); rte_exit(EXIT_FAILURE, "Unable to create the l3fwd FIB table on socket %d\n", socketid); + } /* Populate the fib IPv6 table. */ - for (i = 0; i < RTE_DIM(ipv6_l3fwd_route_array); i++) { + for (i = 0; i < route_num_v6; i++) { /* Skip unused ports. */ - if ((1 << ipv6_l3fwd_route_array[i].if_out & + if ((1 << route_base_v6[i].if_out & enabled_port_mask) == 0) continue; + rte_eth_dev_info_get(route_base_v6[i].if_out, + &dev_info); ret = rte_fib6_add(ipv6_l3fwd_fib_lookup_struct[socketid], - ipv6_l3fwd_route_array[i].ip, - ipv6_l3fwd_route_array[i].depth, - ipv6_l3fwd_route_array[i].if_out); + route_base_v6[i].ip_8, + route_base_v6[i].depth, + route_base_v6[i].if_out); if (ret < 0) { + free(route_base_v4); + free(route_base_v6); rte_exit(EXIT_FAILURE, "Unable to add entry %u to the l3fwd FIB table on socket %d\n", i, socketid); } - if (inet_ntop(AF_INET6, ipv6_l3fwd_route_array[i].ip, + if (inet_ntop(AF_INET6, route_base_v6[i].ip_8, abuf, sizeof(abuf)) != NULL) { - printf("FIB: Adding route %s / %d (%d)\n", - abuf, - ipv6_l3fwd_route_array[i].depth, - ipv6_l3fwd_route_array[i].if_out); + printf("FIB: Adding route %s / %d (%d) [%s]\n", abuf, + route_base_v6[i].depth, + route_base_v6[i].if_out, + dev_info.device->name); } else { - printf("FIB: IPv6 route added to port %d\n", - ipv6_l3fwd_route_array[i].if_out); + printf("FIB: IPv6 route added to port %d [%s]\n", + route_base_v6[i].if_out, + dev_info.device->name); } } }