19510dd1fSConor Walsh /* SPDX-License-Identifier: BSD-3-Clause 29510dd1fSConor Walsh * Copyright(c) 2021 Intel Corporation 39510dd1fSConor Walsh */ 49510dd1fSConor Walsh 56a094e32SConor Walsh #include <stdio.h> 66a094e32SConor Walsh #include <stddef.h> 76a094e32SConor Walsh #include <stdint.h> 86a094e32SConor Walsh #include <sys/socket.h> 96a094e32SConor Walsh #include <arpa/inet.h> 106a094e32SConor Walsh 119510dd1fSConor Walsh #include <rte_fib.h> 129510dd1fSConor Walsh #include <rte_fib6.h> 139510dd1fSConor Walsh 149510dd1fSConor Walsh #include "l3fwd.h" 156a094e32SConor Walsh #if defined RTE_ARCH_X86 166a094e32SConor Walsh #include "l3fwd_sse.h" 176a094e32SConor Walsh #elif defined __ARM_NEON 186a094e32SConor Walsh #include "l3fwd_neon.h" 196a094e32SConor Walsh #elif defined RTE_ARCH_PPC_64 206a094e32SConor Walsh #include "l3fwd_altivec.h" 213cc97770SStanislaw Kardach #else 223cc97770SStanislaw Kardach #include "l3fwd_common.h" 236a094e32SConor Walsh #endif 249510dd1fSConor Walsh #include "l3fwd_event.h" 259510dd1fSConor Walsh #include "l3fwd_route.h" 269510dd1fSConor Walsh 276a094e32SConor Walsh /* Configure how many packets ahead to prefetch for fib. */ 286a094e32SConor Walsh #define FIB_PREFETCH_OFFSET 4 296a094e32SConor Walsh 306a094e32SConor Walsh /* A non-existent portid is needed to denote a default hop for fib. */ 316a094e32SConor Walsh #define FIB_DEFAULT_HOP 999 326a094e32SConor Walsh 336a094e32SConor Walsh /* 346a094e32SConor Walsh * If the machine has SSE, NEON or PPC 64 then multiple packets 356a094e32SConor Walsh * can be sent at once if not only single packets will be sent 366a094e32SConor Walsh */ 376a094e32SConor Walsh #if defined RTE_ARCH_X86 || defined __ARM_NEON \ 386a094e32SConor Walsh || defined RTE_ARCH_PPC_64 396a094e32SConor Walsh #define FIB_SEND_MULTI 406a094e32SConor Walsh #endif 416a094e32SConor Walsh 426a094e32SConor Walsh static struct rte_fib *ipv4_l3fwd_fib_lookup_struct[NB_SOCKETS]; 436a094e32SConor Walsh static struct rte_fib6 *ipv6_l3fwd_fib_lookup_struct[NB_SOCKETS]; 446a094e32SConor Walsh 456a094e32SConor Walsh /* Parse packet type and ip address. */ 466a094e32SConor Walsh static inline void 476a094e32SConor Walsh fib_parse_packet(struct rte_mbuf *mbuf, 486a094e32SConor Walsh uint32_t *ipv4, uint32_t *ipv4_cnt, 496cb10a9bSRobin Jarry struct rte_ipv6_addr *ipv6, 506a094e32SConor Walsh uint32_t *ipv6_cnt, uint8_t *ip_type) 516a094e32SConor Walsh { 526a094e32SConor Walsh struct rte_ether_hdr *eth_hdr; 536a094e32SConor Walsh struct rte_ipv4_hdr *ipv4_hdr; 546a094e32SConor Walsh struct rte_ipv6_hdr *ipv6_hdr; 556a094e32SConor Walsh 566a094e32SConor Walsh eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *); 576a094e32SConor Walsh /* IPv4 */ 586a094e32SConor Walsh if (mbuf->packet_type & RTE_PTYPE_L3_IPV4) { 596a094e32SConor Walsh ipv4_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1); 606a094e32SConor Walsh *ipv4 = rte_be_to_cpu_32(ipv4_hdr->dst_addr); 616a094e32SConor Walsh /* Store type of packet in type_arr (IPv4=1, IPv6=0). */ 626a094e32SConor Walsh *ip_type = 1; 636a094e32SConor Walsh (*ipv4_cnt)++; 646a094e32SConor Walsh } 656a094e32SConor Walsh /* IPv6 */ 666a094e32SConor Walsh else { 676a094e32SConor Walsh ipv6_hdr = (struct rte_ipv6_hdr *)(eth_hdr + 1); 686cb10a9bSRobin Jarry *ipv6 = ipv6_hdr->dst_addr; 696a094e32SConor Walsh *ip_type = 0; 706a094e32SConor Walsh (*ipv6_cnt)++; 716a094e32SConor Walsh } 726a094e32SConor Walsh } 736a094e32SConor Walsh 746a094e32SConor Walsh /* 756a094e32SConor Walsh * If the machine does not have SSE, NEON or PPC 64 then the packets 766a094e32SConor Walsh * are sent one at a time using send_single_packet() 776a094e32SConor Walsh */ 786a094e32SConor Walsh #if !defined FIB_SEND_MULTI 796a094e32SConor Walsh static inline void 8081476d0fSPavan Nikhilesh process_packet(struct rte_mbuf *pkt, uint16_t *hop) 8181476d0fSPavan Nikhilesh { 8281476d0fSPavan Nikhilesh struct rte_ether_hdr *eth_hdr; 8381476d0fSPavan Nikhilesh 8481476d0fSPavan Nikhilesh /* Run rfc1812 if packet is ipv4 and checks enabled. */ 8581476d0fSPavan Nikhilesh #if defined DO_RFC_1812_CHECKS 8681476d0fSPavan Nikhilesh rfc1812_process( 8781476d0fSPavan Nikhilesh (struct rte_ipv4_hdr *)(rte_pktmbuf_mtod( 8881476d0fSPavan Nikhilesh pkt, struct rte_ether_hdr *) + 8981476d0fSPavan Nikhilesh 1), 9081476d0fSPavan Nikhilesh hop, pkt->packet_type); 9181476d0fSPavan Nikhilesh #endif 9281476d0fSPavan Nikhilesh 9381476d0fSPavan Nikhilesh /* Set MAC addresses. */ 9481476d0fSPavan Nikhilesh eth_hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *); 9581476d0fSPavan Nikhilesh *(uint64_t *)ð_hdr->dst_addr = dest_eth_addr[*hop]; 9681476d0fSPavan Nikhilesh rte_ether_addr_copy(&ports_eth_addr[*hop], ð_hdr->src_addr); 9781476d0fSPavan Nikhilesh } 9881476d0fSPavan Nikhilesh 9981476d0fSPavan Nikhilesh static inline void 1006a094e32SConor Walsh fib_send_single(int nb_tx, struct lcore_conf *qconf, 1016a094e32SConor Walsh struct rte_mbuf **pkts_burst, uint16_t hops[nb_tx]) 1026a094e32SConor Walsh { 1036a094e32SConor Walsh int32_t j; 1046a094e32SConor Walsh 1056a094e32SConor Walsh for (j = 0; j < nb_tx; j++) { 10681476d0fSPavan Nikhilesh process_packet(pkts_burst[j], &hops[j]); 10781476d0fSPavan Nikhilesh if (hops[j] == BAD_PORT) { 10881476d0fSPavan Nikhilesh rte_pktmbuf_free(pkts_burst[j]); 10981476d0fSPavan Nikhilesh continue; 11081476d0fSPavan Nikhilesh } 1116a094e32SConor Walsh /* Send single packet. */ 1126a094e32SConor Walsh send_single_packet(qconf, pkts_burst[j], hops[j]); 1136a094e32SConor Walsh } 1146a094e32SConor Walsh } 1156a094e32SConor Walsh #endif 1166a094e32SConor Walsh 1176a094e32SConor Walsh /* Bulk parse, fib lookup and send. */ 1186a094e32SConor Walsh static inline void 1196a094e32SConor Walsh fib_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, 1206a094e32SConor Walsh uint16_t portid, struct lcore_conf *qconf) 1216a094e32SConor Walsh { 1226a094e32SConor Walsh uint32_t ipv4_arr[nb_rx]; 1236cb10a9bSRobin Jarry struct rte_ipv6_addr ipv6_arr[nb_rx]; 124ebab0e8bSKonstantin Ananyev uint16_t hops[SENDM_PORT_OVERHEAD(nb_rx)]; 1256a094e32SConor Walsh uint64_t hopsv4[nb_rx], hopsv6[nb_rx]; 1266a094e32SConor Walsh uint8_t type_arr[nb_rx]; 1276a094e32SConor Walsh uint32_t ipv4_cnt = 0, ipv6_cnt = 0; 1286a094e32SConor Walsh uint32_t ipv4_arr_assem = 0, ipv6_arr_assem = 0; 1296a094e32SConor Walsh uint16_t nh; 1306a094e32SConor Walsh int32_t i; 1316a094e32SConor Walsh 1326a094e32SConor Walsh /* Prefetch first packets. */ 1336a094e32SConor Walsh for (i = 0; i < FIB_PREFETCH_OFFSET && i < nb_rx; i++) 1346a094e32SConor Walsh rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i], void *)); 1356a094e32SConor Walsh 1366a094e32SConor Walsh /* Parse packet info and prefetch. */ 1376a094e32SConor Walsh for (i = 0; i < (nb_rx - FIB_PREFETCH_OFFSET); i++) { 1386a094e32SConor Walsh /* Prefetch packet. */ 1396a094e32SConor Walsh rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[ 1406a094e32SConor Walsh i + FIB_PREFETCH_OFFSET], void *)); 1416a094e32SConor Walsh fib_parse_packet(pkts_burst[i], 1426a094e32SConor Walsh &ipv4_arr[ipv4_cnt], &ipv4_cnt, 1436cb10a9bSRobin Jarry &ipv6_arr[ipv6_cnt], &ipv6_cnt, 1446a094e32SConor Walsh &type_arr[i]); 1456a094e32SConor Walsh } 1466a094e32SConor Walsh 1476a094e32SConor Walsh /* Parse remaining packet info. */ 1486a094e32SConor Walsh for (; i < nb_rx; i++) 1496a094e32SConor Walsh fib_parse_packet(pkts_burst[i], 1506a094e32SConor Walsh &ipv4_arr[ipv4_cnt], &ipv4_cnt, 1516cb10a9bSRobin Jarry &ipv6_arr[ipv6_cnt], &ipv6_cnt, 1526a094e32SConor Walsh &type_arr[i]); 1536a094e32SConor Walsh 1546a094e32SConor Walsh /* Lookup IPv4 hops if IPv4 packets are present. */ 1556a094e32SConor Walsh if (likely(ipv4_cnt > 0)) 1566a094e32SConor Walsh rte_fib_lookup_bulk(qconf->ipv4_lookup_struct, 1576a094e32SConor Walsh ipv4_arr, hopsv4, ipv4_cnt); 1586a094e32SConor Walsh 1596a094e32SConor Walsh /* Lookup IPv6 hops if IPv6 packets are present. */ 1606a094e32SConor Walsh if (ipv6_cnt > 0) 1616a094e32SConor Walsh rte_fib6_lookup_bulk(qconf->ipv6_lookup_struct, 1626a094e32SConor Walsh ipv6_arr, hopsv6, ipv6_cnt); 1636a094e32SConor Walsh 1646a094e32SConor Walsh /* Add IPv4 and IPv6 hops to one array depending on type. */ 1656a094e32SConor Walsh for (i = 0; i < nb_rx; i++) { 1666a094e32SConor Walsh if (type_arr[i]) 1676a094e32SConor Walsh nh = (uint16_t)hopsv4[ipv4_arr_assem++]; 1686a094e32SConor Walsh else 1696a094e32SConor Walsh nh = (uint16_t)hopsv6[ipv6_arr_assem++]; 1706a094e32SConor Walsh hops[i] = nh != FIB_DEFAULT_HOP ? nh : portid; 1716a094e32SConor Walsh } 1726a094e32SConor Walsh 1736a094e32SConor Walsh #if defined FIB_SEND_MULTI 1746a094e32SConor Walsh send_packets_multi(qconf, pkts_burst, hops, nb_rx); 1756a094e32SConor Walsh #else 1766a094e32SConor Walsh fib_send_single(nb_rx, qconf, pkts_burst, hops); 1776a094e32SConor Walsh #endif 1786a094e32SConor Walsh } 1796a094e32SConor Walsh 1809510dd1fSConor Walsh /* Main fib processing loop. */ 1819510dd1fSConor Walsh int 1829510dd1fSConor Walsh fib_main_loop(__rte_unused void *dummy) 1839510dd1fSConor Walsh { 1846a094e32SConor Walsh struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 1856a094e32SConor Walsh unsigned int lcore_id; 1866a094e32SConor Walsh uint64_t prev_tsc, diff_tsc, cur_tsc; 1876a094e32SConor Walsh int i, nb_rx; 1886a094e32SConor Walsh uint16_t portid; 189b23c5bd7SSivaprasad Tummala uint16_t queueid; 1906a094e32SConor Walsh struct lcore_conf *qconf; 1916a094e32SConor Walsh const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / 1926a094e32SConor Walsh US_PER_S * BURST_TX_DRAIN_US; 1936a094e32SConor Walsh 1946a094e32SConor Walsh lcore_id = rte_lcore_id(); 1956a094e32SConor Walsh qconf = &lcore_conf[lcore_id]; 1966a094e32SConor Walsh 1976018b5acSConor Walsh const uint16_t n_rx_q = qconf->n_rx_queue; 1986018b5acSConor Walsh const uint16_t n_tx_p = qconf->n_tx_port; 1996018b5acSConor Walsh if (n_rx_q == 0) { 2006a094e32SConor Walsh RTE_LOG(INFO, L3FWD, "lcore %u has nothing to do\n", lcore_id); 2019510dd1fSConor Walsh return 0; 2029510dd1fSConor Walsh } 2039510dd1fSConor Walsh 2046a094e32SConor Walsh RTE_LOG(INFO, L3FWD, "entering main loop on lcore %u\n", lcore_id); 2056a094e32SConor Walsh 2066018b5acSConor Walsh for (i = 0; i < n_rx_q; i++) { 2076a094e32SConor Walsh 2086a094e32SConor Walsh portid = qconf->rx_queue_list[i].port_id; 2096a094e32SConor Walsh queueid = qconf->rx_queue_list[i].queue_id; 2106a094e32SConor Walsh RTE_LOG(INFO, L3FWD, 211b23c5bd7SSivaprasad Tummala " -- lcoreid=%u portid=%u rxqueueid=%" PRIu16 "\n", 2126a094e32SConor Walsh lcore_id, portid, queueid); 2136a094e32SConor Walsh } 2146a094e32SConor Walsh 2156a094e32SConor Walsh cur_tsc = rte_rdtsc(); 21691470c0dSConor Walsh prev_tsc = cur_tsc; 21791470c0dSConor Walsh 21891470c0dSConor Walsh while (!force_quit) { 2196a094e32SConor Walsh 2206a094e32SConor Walsh /* TX burst queue drain. */ 2216a094e32SConor Walsh diff_tsc = cur_tsc - prev_tsc; 2226a094e32SConor Walsh if (unlikely(diff_tsc > drain_tsc)) { 2236a094e32SConor Walsh 2246018b5acSConor Walsh for (i = 0; i < n_tx_p; ++i) { 2256a094e32SConor Walsh portid = qconf->tx_port_id[i]; 2266a094e32SConor Walsh if (qconf->tx_mbufs[portid].len == 0) 2276a094e32SConor Walsh continue; 2286a094e32SConor Walsh send_burst(qconf, 2296a094e32SConor Walsh qconf->tx_mbufs[portid].len, 2306a094e32SConor Walsh portid); 2316a094e32SConor Walsh qconf->tx_mbufs[portid].len = 0; 2326a094e32SConor Walsh } 2336a094e32SConor Walsh 2346a094e32SConor Walsh prev_tsc = cur_tsc; 2356a094e32SConor Walsh } 2366a094e32SConor Walsh 2376a094e32SConor Walsh /* Read packet from RX queues. */ 2386018b5acSConor Walsh for (i = 0; i < n_rx_q; ++i) { 2396a094e32SConor Walsh portid = qconf->rx_queue_list[i].port_id; 2406a094e32SConor Walsh queueid = qconf->rx_queue_list[i].queue_id; 2416a094e32SConor Walsh nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst, 242*d5c4897eSJie Hai nb_pkt_per_burst); 2436a094e32SConor Walsh if (nb_rx == 0) 2446a094e32SConor Walsh continue; 2456a094e32SConor Walsh 2466a094e32SConor Walsh /* Use fib to lookup port IDs and transmit them. */ 2476a094e32SConor Walsh fib_send_packets(nb_rx, pkts_burst, portid, qconf); 2486a094e32SConor Walsh } 24991470c0dSConor Walsh 25091470c0dSConor Walsh cur_tsc = rte_rdtsc(); 2516a094e32SConor Walsh } 2526a094e32SConor Walsh 2536a094e32SConor Walsh return 0; 2546a094e32SConor Walsh } 2556a094e32SConor Walsh 256ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 2576a094e32SConor Walsh /* One eventdev loop for single and burst using fib. */ 2586a094e32SConor Walsh static __rte_always_inline void 2596a094e32SConor Walsh fib_event_loop(struct l3fwd_event_resources *evt_rsrc, 2606a094e32SConor Walsh const uint8_t flags) 2616a094e32SConor Walsh { 2626a094e32SConor Walsh const int event_p_id = l3fwd_get_free_event_port(evt_rsrc); 2636a094e32SConor Walsh const uint8_t tx_q_id = evt_rsrc->evq.event_q_id[ 2646a094e32SConor Walsh evt_rsrc->evq.nb_queues - 1]; 2656a094e32SConor Walsh const uint8_t event_d_id = evt_rsrc->event_d_id; 2666a094e32SConor Walsh const uint16_t deq_len = evt_rsrc->deq_depth; 2676a094e32SConor Walsh struct rte_event events[MAX_PKT_BURST]; 26855b22fb3SPavan Nikhilesh int i, nb_enq = 0, nb_deq = 0; 2696a094e32SConor Walsh struct lcore_conf *lconf; 2706a094e32SConor Walsh unsigned int lcore_id; 2716a094e32SConor Walsh 2726a094e32SConor Walsh uint32_t ipv4_arr[MAX_PKT_BURST]; 2736cb10a9bSRobin Jarry struct rte_ipv6_addr ipv6_arr[MAX_PKT_BURST]; 2746a094e32SConor Walsh uint64_t hopsv4[MAX_PKT_BURST], hopsv6[MAX_PKT_BURST]; 27581476d0fSPavan Nikhilesh uint16_t nh, hops[MAX_PKT_BURST]; 2766a094e32SConor Walsh uint8_t type_arr[MAX_PKT_BURST]; 2776a094e32SConor Walsh uint32_t ipv4_cnt, ipv6_cnt; 2786a094e32SConor Walsh uint32_t ipv4_arr_assem, ipv6_arr_assem; 2796a094e32SConor Walsh 2806a094e32SConor Walsh if (event_p_id < 0) 2816a094e32SConor Walsh return; 2826a094e32SConor Walsh 2836a094e32SConor Walsh lcore_id = rte_lcore_id(); 2846a094e32SConor Walsh 2856a094e32SConor Walsh lconf = &lcore_conf[lcore_id]; 2866a094e32SConor Walsh 2876a094e32SConor Walsh RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, lcore_id); 2886a094e32SConor Walsh 2896a094e32SConor Walsh while (!force_quit) { 2906a094e32SConor Walsh /* Read events from RX queues. */ 2916a094e32SConor Walsh nb_deq = rte_event_dequeue_burst(event_d_id, event_p_id, 2926a094e32SConor Walsh events, deq_len, 0); 2936a094e32SConor Walsh if (nb_deq == 0) { 2946a094e32SConor Walsh rte_pause(); 2956a094e32SConor Walsh continue; 2966a094e32SConor Walsh } 2976a094e32SConor Walsh 2986a094e32SConor Walsh /* Reset counters. */ 2996a094e32SConor Walsh ipv4_cnt = 0; 3006a094e32SConor Walsh ipv6_cnt = 0; 3016a094e32SConor Walsh ipv4_arr_assem = 0; 3026a094e32SConor Walsh ipv6_arr_assem = 0; 3036a094e32SConor Walsh 3046a094e32SConor Walsh /* Prefetch first packets. */ 3056a094e32SConor Walsh for (i = 0; i < FIB_PREFETCH_OFFSET && i < nb_deq; i++) 3066a094e32SConor Walsh rte_prefetch0(rte_pktmbuf_mtod(events[i].mbuf, void *)); 3076a094e32SConor Walsh 3086a094e32SConor Walsh /* Parse packet info and prefetch. */ 3096a094e32SConor Walsh for (i = 0; i < (nb_deq - FIB_PREFETCH_OFFSET); i++) { 3106a094e32SConor Walsh if (flags & L3FWD_EVENT_TX_ENQ) { 3116a094e32SConor Walsh events[i].queue_id = tx_q_id; 3126a094e32SConor Walsh events[i].op = RTE_EVENT_OP_FORWARD; 3136a094e32SConor Walsh } 3146a094e32SConor Walsh 3156a094e32SConor Walsh if (flags & L3FWD_EVENT_TX_DIRECT) 3166a094e32SConor Walsh rte_event_eth_tx_adapter_txq_set(events[i].mbuf, 3176a094e32SConor Walsh 0); 3186a094e32SConor Walsh 3196a094e32SConor Walsh /* Prefetch packet. */ 3206a094e32SConor Walsh rte_prefetch0(rte_pktmbuf_mtod(events[ 3216a094e32SConor Walsh i + FIB_PREFETCH_OFFSET].mbuf, 3226a094e32SConor Walsh void *)); 3236a094e32SConor Walsh 3246a094e32SConor Walsh fib_parse_packet(events[i].mbuf, 3256a094e32SConor Walsh &ipv4_arr[ipv4_cnt], &ipv4_cnt, 3266cb10a9bSRobin Jarry &ipv6_arr[ipv6_cnt], &ipv6_cnt, 3276a094e32SConor Walsh &type_arr[i]); 3286a094e32SConor Walsh } 3296a094e32SConor Walsh 3306a094e32SConor Walsh /* Parse remaining packet info. */ 3316a094e32SConor Walsh for (; i < nb_deq; i++) { 3326a094e32SConor Walsh if (flags & L3FWD_EVENT_TX_ENQ) { 3336a094e32SConor Walsh events[i].queue_id = tx_q_id; 3346a094e32SConor Walsh events[i].op = RTE_EVENT_OP_FORWARD; 3356a094e32SConor Walsh } 3366a094e32SConor Walsh 3376a094e32SConor Walsh if (flags & L3FWD_EVENT_TX_DIRECT) 3386a094e32SConor Walsh rte_event_eth_tx_adapter_txq_set(events[i].mbuf, 3396a094e32SConor Walsh 0); 3406a094e32SConor Walsh 3416a094e32SConor Walsh fib_parse_packet(events[i].mbuf, 3426a094e32SConor Walsh &ipv4_arr[ipv4_cnt], &ipv4_cnt, 3436cb10a9bSRobin Jarry &ipv6_arr[ipv6_cnt], &ipv6_cnt, 3446a094e32SConor Walsh &type_arr[i]); 3456a094e32SConor Walsh } 3466a094e32SConor Walsh 3476a094e32SConor Walsh /* Lookup IPv4 hops if IPv4 packets are present. */ 3486a094e32SConor Walsh if (likely(ipv4_cnt > 0)) 3496a094e32SConor Walsh rte_fib_lookup_bulk(lconf->ipv4_lookup_struct, 3506a094e32SConor Walsh ipv4_arr, hopsv4, ipv4_cnt); 3516a094e32SConor Walsh 3526a094e32SConor Walsh /* Lookup IPv6 hops if IPv6 packets are present. */ 3536a094e32SConor Walsh if (ipv6_cnt > 0) 3546a094e32SConor Walsh rte_fib6_lookup_bulk(lconf->ipv6_lookup_struct, 3556a094e32SConor Walsh ipv6_arr, hopsv6, ipv6_cnt); 3566a094e32SConor Walsh 3576a094e32SConor Walsh /* Assign ports looked up in fib depending on IPv4 or IPv6 */ 3586a094e32SConor Walsh for (i = 0; i < nb_deq; i++) { 3596a094e32SConor Walsh if (type_arr[i]) 3606a094e32SConor Walsh nh = (uint16_t)hopsv4[ipv4_arr_assem++]; 3616a094e32SConor Walsh else 3626a094e32SConor Walsh nh = (uint16_t)hopsv6[ipv6_arr_assem++]; 3639a518054SMohammad Iqbal Ahmad 36481476d0fSPavan Nikhilesh hops[i] = nh != FIB_DEFAULT_HOP ? 36581476d0fSPavan Nikhilesh nh : 36681476d0fSPavan Nikhilesh events[i].mbuf->port; 36781476d0fSPavan Nikhilesh process_packet(events[i].mbuf, &hops[i]); 36881476d0fSPavan Nikhilesh events[i].mbuf->port = hops[i] != BAD_PORT ? 36981476d0fSPavan Nikhilesh hops[i] : 37081476d0fSPavan Nikhilesh events[i].mbuf->port; 3716a094e32SConor Walsh } 3726a094e32SConor Walsh 3736a094e32SConor Walsh if (flags & L3FWD_EVENT_TX_ENQ) { 3746a094e32SConor Walsh nb_enq = rte_event_enqueue_burst(event_d_id, event_p_id, 3756a094e32SConor Walsh events, nb_deq); 3766a094e32SConor Walsh while (nb_enq < nb_deq && !force_quit) 3776a094e32SConor Walsh nb_enq += rte_event_enqueue_burst(event_d_id, 3786a094e32SConor Walsh event_p_id, events + nb_enq, 3796a094e32SConor Walsh nb_deq - nb_enq); 3806a094e32SConor Walsh } 3816a094e32SConor Walsh 3826a094e32SConor Walsh if (flags & L3FWD_EVENT_TX_DIRECT) { 3836a094e32SConor Walsh nb_enq = rte_event_eth_tx_adapter_enqueue(event_d_id, 3846a094e32SConor Walsh event_p_id, events, nb_deq, 0); 3856a094e32SConor Walsh while (nb_enq < nb_deq && !force_quit) 3866a094e32SConor Walsh nb_enq += rte_event_eth_tx_adapter_enqueue( 3876a094e32SConor Walsh event_d_id, event_p_id, 3886a094e32SConor Walsh events + nb_enq, 3896a094e32SConor Walsh nb_deq - nb_enq, 0); 3906a094e32SConor Walsh } 3916a094e32SConor Walsh } 39255b22fb3SPavan Nikhilesh 39355b22fb3SPavan Nikhilesh l3fwd_event_worker_cleanup(event_d_id, event_p_id, events, nb_enq, 39455b22fb3SPavan Nikhilesh nb_deq, 0); 3956a094e32SConor Walsh } 3966a094e32SConor Walsh 3979510dd1fSConor Walsh int __rte_noinline 3989510dd1fSConor Walsh fib_event_main_loop_tx_d(__rte_unused void *dummy) 3999510dd1fSConor Walsh { 4006a094e32SConor Walsh struct l3fwd_event_resources *evt_rsrc = 4016a094e32SConor Walsh l3fwd_get_eventdev_rsrc(); 4026a094e32SConor Walsh 4036a094e32SConor Walsh fib_event_loop(evt_rsrc, L3FWD_EVENT_TX_DIRECT); 4049510dd1fSConor Walsh return 0; 4059510dd1fSConor Walsh } 4069510dd1fSConor Walsh 4079510dd1fSConor Walsh int __rte_noinline 4089510dd1fSConor Walsh fib_event_main_loop_tx_d_burst(__rte_unused void *dummy) 4099510dd1fSConor Walsh { 4106a094e32SConor Walsh struct l3fwd_event_resources *evt_rsrc = 4116a094e32SConor Walsh l3fwd_get_eventdev_rsrc(); 4126a094e32SConor Walsh 4136a094e32SConor Walsh fib_event_loop(evt_rsrc, L3FWD_EVENT_TX_DIRECT); 4149510dd1fSConor Walsh return 0; 4159510dd1fSConor Walsh } 4169510dd1fSConor Walsh 4179510dd1fSConor Walsh int __rte_noinline 4189510dd1fSConor Walsh fib_event_main_loop_tx_q(__rte_unused void *dummy) 4199510dd1fSConor Walsh { 4206a094e32SConor Walsh struct l3fwd_event_resources *evt_rsrc = 4216a094e32SConor Walsh l3fwd_get_eventdev_rsrc(); 4226a094e32SConor Walsh 4236a094e32SConor Walsh fib_event_loop(evt_rsrc, L3FWD_EVENT_TX_ENQ); 4249510dd1fSConor Walsh return 0; 4259510dd1fSConor Walsh } 4269510dd1fSConor Walsh 4279510dd1fSConor Walsh int __rte_noinline 4289510dd1fSConor Walsh fib_event_main_loop_tx_q_burst(__rte_unused void *dummy) 4299510dd1fSConor Walsh { 4306a094e32SConor Walsh struct l3fwd_event_resources *evt_rsrc = 4316a094e32SConor Walsh l3fwd_get_eventdev_rsrc(); 4326a094e32SConor Walsh 4336a094e32SConor Walsh fib_event_loop(evt_rsrc, L3FWD_EVENT_TX_ENQ); 4349510dd1fSConor Walsh return 0; 4359510dd1fSConor Walsh } 4369510dd1fSConor Walsh 437e8adca19SShijith Thotton static __rte_always_inline void 43881476d0fSPavan Nikhilesh fib_process_event_vector(struct rte_event_vector *vec, uint8_t *type_arr, 4396cb10a9bSRobin Jarry struct rte_ipv6_addr *ipv6_arr, uint64_t *hopsv4, uint64_t *hopsv6, 44081476d0fSPavan Nikhilesh uint32_t *ipv4_arr, uint16_t *hops) 441e8adca19SShijith Thotton { 442e8adca19SShijith Thotton uint32_t ipv4_arr_assem, ipv6_arr_assem; 443e8adca19SShijith Thotton struct rte_mbuf **mbufs = vec->mbufs; 444e8adca19SShijith Thotton uint32_t ipv4_cnt, ipv6_cnt; 445e8adca19SShijith Thotton struct lcore_conf *lconf; 446e8adca19SShijith Thotton uint16_t nh; 447e8adca19SShijith Thotton int i; 448e8adca19SShijith Thotton 449e8adca19SShijith Thotton lconf = &lcore_conf[rte_lcore_id()]; 450e8adca19SShijith Thotton 451e8adca19SShijith Thotton /* Reset counters. */ 452e8adca19SShijith Thotton ipv4_cnt = 0; 453e8adca19SShijith Thotton ipv6_cnt = 0; 454e8adca19SShijith Thotton ipv4_arr_assem = 0; 455e8adca19SShijith Thotton ipv6_arr_assem = 0; 456e8adca19SShijith Thotton 457e8adca19SShijith Thotton /* Prefetch first packets. */ 458e8adca19SShijith Thotton for (i = 0; i < FIB_PREFETCH_OFFSET && i < vec->nb_elem; i++) 459e8adca19SShijith Thotton rte_prefetch0(rte_pktmbuf_mtod(mbufs[i], void *)); 460e8adca19SShijith Thotton 461e8adca19SShijith Thotton /* Parse packet info and prefetch. */ 462e8adca19SShijith Thotton for (i = 0; i < (vec->nb_elem - FIB_PREFETCH_OFFSET); i++) { 463e8adca19SShijith Thotton rte_prefetch0(rte_pktmbuf_mtod(mbufs[i + FIB_PREFETCH_OFFSET], 464e8adca19SShijith Thotton void *)); 465e8adca19SShijith Thotton fib_parse_packet(mbufs[i], &ipv4_arr[ipv4_cnt], &ipv4_cnt, 4666cb10a9bSRobin Jarry &ipv6_arr[ipv6_cnt], &ipv6_cnt, &type_arr[i]); 467e8adca19SShijith Thotton } 468e8adca19SShijith Thotton 469e8adca19SShijith Thotton /* Parse remaining packet info. */ 470e8adca19SShijith Thotton for (; i < vec->nb_elem; i++) 471e8adca19SShijith Thotton fib_parse_packet(mbufs[i], &ipv4_arr[ipv4_cnt], &ipv4_cnt, 4726cb10a9bSRobin Jarry &ipv6_arr[ipv6_cnt], &ipv6_cnt, &type_arr[i]); 473e8adca19SShijith Thotton 474e8adca19SShijith Thotton /* Lookup IPv4 hops if IPv4 packets are present. */ 475e8adca19SShijith Thotton if (likely(ipv4_cnt > 0)) 476e8adca19SShijith Thotton rte_fib_lookup_bulk(lconf->ipv4_lookup_struct, ipv4_arr, hopsv4, 477e8adca19SShijith Thotton ipv4_cnt); 478e8adca19SShijith Thotton 479e8adca19SShijith Thotton /* Lookup IPv6 hops if IPv6 packets are present. */ 480e8adca19SShijith Thotton if (ipv6_cnt > 0) 48181476d0fSPavan Nikhilesh rte_fib6_lookup_bulk( 48281476d0fSPavan Nikhilesh lconf->ipv6_lookup_struct, 4836cb10a9bSRobin Jarry ipv6_arr, hopsv6, 48481476d0fSPavan Nikhilesh ipv6_cnt); 485e8adca19SShijith Thotton 486e8adca19SShijith Thotton /* Assign ports looked up in fib depending on IPv4 or IPv6 */ 487e8adca19SShijith Thotton for (i = 0; i < vec->nb_elem; i++) { 488e8adca19SShijith Thotton if (type_arr[i]) 489e8adca19SShijith Thotton nh = (uint16_t)hopsv4[ipv4_arr_assem++]; 490e8adca19SShijith Thotton else 491e8adca19SShijith Thotton nh = (uint16_t)hopsv6[ipv6_arr_assem++]; 492e8adca19SShijith Thotton if (nh != FIB_DEFAULT_HOP) 49381476d0fSPavan Nikhilesh hops[i] = nh; 49481476d0fSPavan Nikhilesh else 49581476d0fSPavan Nikhilesh hops[i] = vec->attr_valid ? vec->port : 49681476d0fSPavan Nikhilesh vec->mbufs[i]->port; 497e8adca19SShijith Thotton } 49881476d0fSPavan Nikhilesh 49981476d0fSPavan Nikhilesh #if defined FIB_SEND_MULTI 50081476d0fSPavan Nikhilesh uint16_t k; 50181476d0fSPavan Nikhilesh k = RTE_ALIGN_FLOOR(vec->nb_elem, FWDSTEP); 50281476d0fSPavan Nikhilesh 50381476d0fSPavan Nikhilesh for (i = 0; i != k; i += FWDSTEP) 50481476d0fSPavan Nikhilesh processx4_step3(&vec->mbufs[i], &hops[i]); 50581476d0fSPavan Nikhilesh for (; i < vec->nb_elem; i++) 50681476d0fSPavan Nikhilesh process_packet(vec->mbufs[i], &hops[i]); 50781476d0fSPavan Nikhilesh #else 50881476d0fSPavan Nikhilesh for (i = 0; i < vec->nb_elem; i++) 50981476d0fSPavan Nikhilesh process_packet(vec->mbufs[i], &hops[i]); 51081476d0fSPavan Nikhilesh #endif 51181476d0fSPavan Nikhilesh 51281476d0fSPavan Nikhilesh process_event_vector(vec, hops); 513e8adca19SShijith Thotton } 514e8adca19SShijith Thotton 515e8adca19SShijith Thotton static __rte_always_inline void 516e8adca19SShijith Thotton fib_event_loop_vector(struct l3fwd_event_resources *evt_rsrc, 517e8adca19SShijith Thotton const uint8_t flags) 518e8adca19SShijith Thotton { 519e8adca19SShijith Thotton const int event_p_id = l3fwd_get_free_event_port(evt_rsrc); 520e8adca19SShijith Thotton const uint8_t tx_q_id = 521e8adca19SShijith Thotton evt_rsrc->evq.event_q_id[evt_rsrc->evq.nb_queues - 1]; 522e8adca19SShijith Thotton const uint8_t event_d_id = evt_rsrc->event_d_id; 523e8adca19SShijith Thotton const uint16_t deq_len = evt_rsrc->deq_depth; 524e8adca19SShijith Thotton struct rte_event events[MAX_PKT_BURST]; 5256cb10a9bSRobin Jarry uint8_t *type_arr; 5266cb10a9bSRobin Jarry struct rte_ipv6_addr *ipv6_arr; 52755b22fb3SPavan Nikhilesh int nb_enq = 0, nb_deq = 0, i; 52881476d0fSPavan Nikhilesh uint64_t *hopsv4, *hopsv6; 52981476d0fSPavan Nikhilesh uint32_t *ipv4_arr; 53081476d0fSPavan Nikhilesh uint16_t *hops; 53181476d0fSPavan Nikhilesh uintptr_t mem; 532e8adca19SShijith Thotton 53381476d0fSPavan Nikhilesh mem = (uintptr_t)rte_zmalloc( 53481476d0fSPavan Nikhilesh "vector_fib", 53581476d0fSPavan Nikhilesh (sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint64_t) + 53681476d0fSPavan Nikhilesh sizeof(uint64_t) + sizeof(uint16_t) + sizeof(uint8_t *) + 5376cb10a9bSRobin Jarry sizeof(struct rte_ipv6_addr)) * 53881476d0fSPavan Nikhilesh evt_rsrc->vector_size, 53981476d0fSPavan Nikhilesh RTE_CACHE_LINE_SIZE); 54081476d0fSPavan Nikhilesh if (mem == 0) 541e8adca19SShijith Thotton return; 54281476d0fSPavan Nikhilesh ipv4_arr = (uint32_t *)mem; 54381476d0fSPavan Nikhilesh type_arr = (uint8_t *)&ipv4_arr[evt_rsrc->vector_size]; 54481476d0fSPavan Nikhilesh hopsv4 = (uint64_t *)&type_arr[evt_rsrc->vector_size]; 54581476d0fSPavan Nikhilesh hopsv6 = (uint64_t *)&hopsv4[evt_rsrc->vector_size]; 54681476d0fSPavan Nikhilesh hops = (uint16_t *)&hopsv6[evt_rsrc->vector_size]; 5476cb10a9bSRobin Jarry ipv6_arr = (struct rte_ipv6_addr *)&hops[evt_rsrc->vector_size]; 54881476d0fSPavan Nikhilesh 54981476d0fSPavan Nikhilesh if (event_p_id < 0) { 55081476d0fSPavan Nikhilesh rte_free((void *)mem); 55181476d0fSPavan Nikhilesh return; 55281476d0fSPavan Nikhilesh } 553e8adca19SShijith Thotton 554e8adca19SShijith Thotton RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, 555e8adca19SShijith Thotton rte_lcore_id()); 556e8adca19SShijith Thotton 557e8adca19SShijith Thotton while (!force_quit) { 558e8adca19SShijith Thotton /* Read events from RX queues. */ 559e8adca19SShijith Thotton nb_deq = rte_event_dequeue_burst(event_d_id, event_p_id, events, 560e8adca19SShijith Thotton deq_len, 0); 561e8adca19SShijith Thotton if (nb_deq == 0) { 562e8adca19SShijith Thotton rte_pause(); 563e8adca19SShijith Thotton continue; 564e8adca19SShijith Thotton } 565e8adca19SShijith Thotton 566e8adca19SShijith Thotton for (i = 0; i < nb_deq; i++) { 567e8adca19SShijith Thotton if (flags & L3FWD_EVENT_TX_ENQ) { 568e8adca19SShijith Thotton events[i].queue_id = tx_q_id; 569e8adca19SShijith Thotton events[i].op = RTE_EVENT_OP_FORWARD; 570e8adca19SShijith Thotton } 571e8adca19SShijith Thotton 57281476d0fSPavan Nikhilesh fib_process_event_vector(events[i].vec, type_arr, 57381476d0fSPavan Nikhilesh ipv6_arr, hopsv4, hopsv6, 57481476d0fSPavan Nikhilesh ipv4_arr, hops); 575e8adca19SShijith Thotton } 576e8adca19SShijith Thotton 577e8adca19SShijith Thotton if (flags & L3FWD_EVENT_TX_ENQ) { 578e8adca19SShijith Thotton nb_enq = rte_event_enqueue_burst(event_d_id, event_p_id, 579e8adca19SShijith Thotton events, nb_deq); 580e8adca19SShijith Thotton while (nb_enq < nb_deq && !force_quit) 581e8adca19SShijith Thotton nb_enq += rte_event_enqueue_burst( 582e8adca19SShijith Thotton event_d_id, event_p_id, events + nb_enq, 583e8adca19SShijith Thotton nb_deq - nb_enq); 584e8adca19SShijith Thotton } 585e8adca19SShijith Thotton 586e8adca19SShijith Thotton if (flags & L3FWD_EVENT_TX_DIRECT) { 587e8adca19SShijith Thotton nb_enq = rte_event_eth_tx_adapter_enqueue( 588e8adca19SShijith Thotton event_d_id, event_p_id, events, nb_deq, 0); 589e8adca19SShijith Thotton while (nb_enq < nb_deq && !force_quit) 590e8adca19SShijith Thotton nb_enq += rte_event_eth_tx_adapter_enqueue( 591e8adca19SShijith Thotton event_d_id, event_p_id, events + nb_enq, 592e8adca19SShijith Thotton nb_deq - nb_enq, 0); 593e8adca19SShijith Thotton } 594e8adca19SShijith Thotton } 59555b22fb3SPavan Nikhilesh 59655b22fb3SPavan Nikhilesh l3fwd_event_worker_cleanup(event_d_id, event_p_id, events, nb_enq, 59755b22fb3SPavan Nikhilesh nb_deq, 1); 59881476d0fSPavan Nikhilesh rte_free((void *)mem); 599e8adca19SShijith Thotton } 600e8adca19SShijith Thotton 601e8adca19SShijith Thotton int __rte_noinline 602e8adca19SShijith Thotton fib_event_main_loop_tx_d_vector(__rte_unused void *dummy) 603e8adca19SShijith Thotton { 604e8adca19SShijith Thotton struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 605e8adca19SShijith Thotton 606e8adca19SShijith Thotton fib_event_loop_vector(evt_rsrc, L3FWD_EVENT_TX_DIRECT); 607e8adca19SShijith Thotton return 0; 608e8adca19SShijith Thotton } 609e8adca19SShijith Thotton 610e8adca19SShijith Thotton int __rte_noinline 611e8adca19SShijith Thotton fib_event_main_loop_tx_d_burst_vector(__rte_unused void *dummy) 612e8adca19SShijith Thotton { 613e8adca19SShijith Thotton struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 614e8adca19SShijith Thotton 615e8adca19SShijith Thotton fib_event_loop_vector(evt_rsrc, L3FWD_EVENT_TX_DIRECT); 616e8adca19SShijith Thotton return 0; 617e8adca19SShijith Thotton } 618e8adca19SShijith Thotton 619e8adca19SShijith Thotton int __rte_noinline 620e8adca19SShijith Thotton fib_event_main_loop_tx_q_vector(__rte_unused void *dummy) 621e8adca19SShijith Thotton { 622e8adca19SShijith Thotton struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 623e8adca19SShijith Thotton 624e8adca19SShijith Thotton fib_event_loop_vector(evt_rsrc, L3FWD_EVENT_TX_ENQ); 625e8adca19SShijith Thotton return 0; 626e8adca19SShijith Thotton } 627e8adca19SShijith Thotton 628e8adca19SShijith Thotton int __rte_noinline 629e8adca19SShijith Thotton fib_event_main_loop_tx_q_burst_vector(__rte_unused void *dummy) 630e8adca19SShijith Thotton { 631e8adca19SShijith Thotton struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 632e8adca19SShijith Thotton 633e8adca19SShijith Thotton fib_event_loop_vector(evt_rsrc, L3FWD_EVENT_TX_ENQ); 634e8adca19SShijith Thotton return 0; 635e8adca19SShijith Thotton } 636ef827078SBruce Richardson #endif 637e8adca19SShijith Thotton 6389a212dc0SConor Fogarty /* Function to setup fib. 8< */ 6399510dd1fSConor Walsh void 6406a094e32SConor Walsh setup_fib(const int socketid) 6416a094e32SConor Walsh { 642fc89b4c8SPavan Nikhilesh struct rte_eth_dev_info dev_info; 6436a094e32SConor Walsh struct rte_fib6_conf config; 644e194f3cdSVladimir Medvedkin struct rte_fib_conf config_ipv4 = { 0 }; 64552def963SSean Morrissey int i; 6466a094e32SConor Walsh int ret; 6476a094e32SConor Walsh char s[64]; 6486a094e32SConor Walsh char abuf[INET6_ADDRSTRLEN]; 6496a094e32SConor Walsh 6506a094e32SConor Walsh /* Create the fib IPv4 table. */ 6516a094e32SConor Walsh config_ipv4.type = RTE_FIB_DIR24_8; 6526a094e32SConor Walsh config_ipv4.max_routes = (1 << 16); 65311c5b9b5SVladimir Medvedkin config_ipv4.rib_ext_sz = 0; 6546a094e32SConor Walsh config_ipv4.default_nh = FIB_DEFAULT_HOP; 6556a094e32SConor Walsh config_ipv4.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B; 6566a094e32SConor Walsh config_ipv4.dir24_8.num_tbl8 = (1 << 15); 6576a094e32SConor Walsh snprintf(s, sizeof(s), "IPV4_L3FWD_FIB_%d", socketid); 6586a094e32SConor Walsh ipv4_l3fwd_fib_lookup_struct[socketid] = 6596a094e32SConor Walsh rte_fib_create(s, socketid, &config_ipv4); 6606a094e32SConor Walsh if (ipv4_l3fwd_fib_lookup_struct[socketid] == NULL) 6616a094e32SConor Walsh rte_exit(EXIT_FAILURE, 6626a094e32SConor Walsh "Unable to create the l3fwd FIB table on socket %d\n", 6636a094e32SConor Walsh socketid); 6646a094e32SConor Walsh 66552def963SSean Morrissey 6666a094e32SConor Walsh /* Populate the fib ipv4 table. */ 66752def963SSean Morrissey for (i = 0; i < route_num_v4; i++) { 6686a094e32SConor Walsh struct in_addr in; 6696a094e32SConor Walsh 6706a094e32SConor Walsh /* Skip unused ports. */ 67152def963SSean Morrissey if ((1 << route_base_v4[i].if_out & 6726a094e32SConor Walsh enabled_port_mask) == 0) 6736a094e32SConor Walsh continue; 6746a094e32SConor Walsh 675a937954eSStephen Hemminger ret = rte_eth_dev_info_get(route_base_v4[i].if_out, &dev_info); 676a937954eSStephen Hemminger if (ret < 0) 677a937954eSStephen Hemminger rte_exit(EXIT_FAILURE, 678a937954eSStephen Hemminger "Unable to get device info for port %u\n", 679a937954eSStephen Hemminger route_base_v4[i].if_out); 680a937954eSStephen Hemminger 6816a094e32SConor Walsh ret = rte_fib_add(ipv4_l3fwd_fib_lookup_struct[socketid], 68252def963SSean Morrissey route_base_v4[i].ip, 68352def963SSean Morrissey route_base_v4[i].depth, 68452def963SSean Morrissey route_base_v4[i].if_out); 6856a094e32SConor Walsh 6866a094e32SConor Walsh if (ret < 0) { 68752def963SSean Morrissey free(route_base_v4); 6886a094e32SConor Walsh rte_exit(EXIT_FAILURE, 6896a094e32SConor Walsh "Unable to add entry %u to the l3fwd FIB table on socket %d\n", 6906a094e32SConor Walsh i, socketid); 6916a094e32SConor Walsh } 6926a094e32SConor Walsh 69352def963SSean Morrissey in.s_addr = htonl(route_base_v4[i].ip); 6946a094e32SConor Walsh if (inet_ntop(AF_INET, &in, abuf, sizeof(abuf)) != NULL) { 695fc89b4c8SPavan Nikhilesh printf("FIB: Adding route %s / %d (%d) [%s]\n", abuf, 69652def963SSean Morrissey route_base_v4[i].depth, 69752def963SSean Morrissey route_base_v4[i].if_out, 698ec5ecd7eSDavid Marchand rte_dev_name(dev_info.device)); 6996a094e32SConor Walsh } else { 700fc89b4c8SPavan Nikhilesh printf("FIB: IPv4 route added to port %d [%s]\n", 70152def963SSean Morrissey route_base_v4[i].if_out, 702ec5ecd7eSDavid Marchand rte_dev_name(dev_info.device)); 7036a094e32SConor Walsh } 7046a094e32SConor Walsh } 7059a212dc0SConor Fogarty /* >8 End of setup fib. */ 7066a094e32SConor Walsh 7076a094e32SConor Walsh /* Create the fib IPv6 table. */ 7086a094e32SConor Walsh snprintf(s, sizeof(s), "IPV6_L3FWD_FIB_%d", socketid); 7096a094e32SConor Walsh 7106a094e32SConor Walsh config.type = RTE_FIB6_TRIE; 7116a094e32SConor Walsh config.max_routes = (1 << 16) - 1; 71211c5b9b5SVladimir Medvedkin config.rib_ext_sz = 0; 7136a094e32SConor Walsh config.default_nh = FIB_DEFAULT_HOP; 7146a094e32SConor Walsh config.trie.nh_sz = RTE_FIB6_TRIE_4B; 7156a094e32SConor Walsh config.trie.num_tbl8 = (1 << 15); 7166a094e32SConor Walsh ipv6_l3fwd_fib_lookup_struct[socketid] = rte_fib6_create(s, socketid, 7176a094e32SConor Walsh &config); 71852def963SSean Morrissey if (ipv6_l3fwd_fib_lookup_struct[socketid] == NULL) { 71952def963SSean Morrissey free(route_base_v4); 7206a094e32SConor Walsh rte_exit(EXIT_FAILURE, 7216a094e32SConor Walsh "Unable to create the l3fwd FIB table on socket %d\n", 7226a094e32SConor Walsh socketid); 72352def963SSean Morrissey } 7246a094e32SConor Walsh 7256a094e32SConor Walsh /* Populate the fib IPv6 table. */ 72652def963SSean Morrissey for (i = 0; i < route_num_v6; i++) { 7276a094e32SConor Walsh 7286a094e32SConor Walsh /* Skip unused ports. */ 72952def963SSean Morrissey if ((1 << route_base_v6[i].if_out & 7306a094e32SConor Walsh enabled_port_mask) == 0) 7316a094e32SConor Walsh continue; 7326a094e32SConor Walsh 733a937954eSStephen Hemminger ret = rte_eth_dev_info_get(route_base_v6[i].if_out, &dev_info); 734a937954eSStephen Hemminger if (ret < 0) 735a937954eSStephen Hemminger rte_exit(EXIT_FAILURE, 736a937954eSStephen Hemminger "Unable to get device info for port %u\n", 737a937954eSStephen Hemminger route_base_v6[i].if_out); 738a937954eSStephen Hemminger 7396a094e32SConor Walsh ret = rte_fib6_add(ipv6_l3fwd_fib_lookup_struct[socketid], 7406cb10a9bSRobin Jarry &route_base_v6[i].ip6, 74152def963SSean Morrissey route_base_v6[i].depth, 74252def963SSean Morrissey route_base_v6[i].if_out); 7436a094e32SConor Walsh 7446a094e32SConor Walsh if (ret < 0) { 74552def963SSean Morrissey free(route_base_v4); 74652def963SSean Morrissey free(route_base_v6); 7476a094e32SConor Walsh rte_exit(EXIT_FAILURE, 7486a094e32SConor Walsh "Unable to add entry %u to the l3fwd FIB table on socket %d\n", 7496a094e32SConor Walsh i, socketid); 7506a094e32SConor Walsh } 7516a094e32SConor Walsh 7526cb10a9bSRobin Jarry if (inet_ntop(AF_INET6, &route_base_v6[i].ip6, 7536a094e32SConor Walsh abuf, sizeof(abuf)) != NULL) { 754fc89b4c8SPavan Nikhilesh printf("FIB: Adding route %s / %d (%d) [%s]\n", abuf, 75552def963SSean Morrissey route_base_v6[i].depth, 75652def963SSean Morrissey route_base_v6[i].if_out, 757ec5ecd7eSDavid Marchand rte_dev_name(dev_info.device)); 7586a094e32SConor Walsh } else { 759fc89b4c8SPavan Nikhilesh printf("FIB: IPv6 route added to port %d [%s]\n", 76052def963SSean Morrissey route_base_v6[i].if_out, 761ec5ecd7eSDavid Marchand rte_dev_name(dev_info.device)); 7626a094e32SConor Walsh } 7636a094e32SConor Walsh } 7646a094e32SConor Walsh } 7659510dd1fSConor Walsh 7669510dd1fSConor Walsh /* Return ipv4 fib lookup struct. */ 7679510dd1fSConor Walsh void * 7686a094e32SConor Walsh fib_get_ipv4_l3fwd_lookup_struct(const int socketid) 7699510dd1fSConor Walsh { 7706a094e32SConor Walsh return ipv4_l3fwd_fib_lookup_struct[socketid]; 7719510dd1fSConor Walsh } 7729510dd1fSConor Walsh 7739510dd1fSConor Walsh /* Return ipv6 fib lookup struct. */ 7749510dd1fSConor Walsh void * 7756a094e32SConor Walsh fib_get_ipv6_l3fwd_lookup_struct(const int socketid) 7769510dd1fSConor Walsh { 7776a094e32SConor Walsh return ipv6_l3fwd_fib_lookup_struct[socketid]; 7789510dd1fSConor Walsh } 779