From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mailrelay1.rambler.ru (mailrelay1.rambler.ru [81.19.66.239]) by dpdk.org (Postfix) with ESMTP id 8AD3E7CD1 for ; Fri, 27 Apr 2018 00:03:45 +0200 (CEST) Received: from testlab1.ipnoc.rambler.tech (unknown [10.201.1.3]) by mailrelay1.rambler.ru (Postfix) with ESMTP id 40XB0d1HTfzKj3; Fri, 27 Apr 2018 01:03:45 +0300 (MSK) From: Medvedkin Vladimir To: dev@dpdk.org Cc: bruce.richardson@intel.com, thomas@monjalon.net, cristian.dumitrescu@intel.com, Medvedkin Vladimir Date: Fri, 27 Apr 2018 01:03:34 +0300 Message-Id: <1524780214-23196-5-git-send-email-medvedkinv@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1524780214-23196-1-git-send-email-medvedkinv@gmail.com> References: <1524780214-23196-1-git-send-email-medvedkinv@gmail.com> X-Rcpt-To: , , , , Subject: [dpdk-dev] [PATCH v4 4/4] Add support for lpm and rib bulk lookup X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Apr 2018 22:03:46 -0000 Signed-off-by: Medvedkin Vladimir --- examples/l3fwd/l3fwd_lpm.c | 132 +++++++++++++++++++++++++++++++++++++++++++++ examples/l3fwd/meson.build | 2 +- 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c index a747126..9ad1ddc 100644 --- a/examples/l3fwd/l3fwd_lpm.c +++ b/examples/l3fwd/l3fwd_lpm.c @@ -24,9 +24,12 @@ #include #include #include +#include #include #include "l3fwd.h" +#define BULK_LOOKUP +#define USE_RIB struct ipv4_l3fwd_lpm_route { uint32_t ip; @@ -72,7 +75,11 @@ struct ipv6_l3fwd_lpm_route { #define IPV6_L3FWD_LPM_MAX_RULES 1024 #define IPV6_L3FWD_LPM_NUMBER_TBL8S (1 << 16) +#if defined(BULK_LOOKUP) && defined(USE_RIB) +struct rte_rib *ipv4_l3fwd_lpm_lookup_struct[NB_SOCKETS]; +#else struct rte_lpm *ipv4_l3fwd_lpm_lookup_struct[NB_SOCKETS]; +#endif struct rte_lpm6 *ipv6_l3fwd_lpm_lookup_struct[NB_SOCKETS]; static inline uint16_t @@ -168,6 +175,104 @@ struct ipv6_l3fwd_lpm_route { #include "l3fwd_lpm.h" #endif +static __rte_always_inline int +l3fwd_rib_handle_pkt(struct rte_mbuf *m, uint32_t *dst_ip) +{ + struct ipv4_hdr *ipv4_hdr; + + if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) { + /* Handle IPv4 headers.*/ + ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, + sizeof(struct ether_hdr)); +#ifdef DO_RFC_1812_CHECKS + /* Check to make sure the packet is valid (RFC1812) */ + if (is_valid_ipv4_pkt(ipv4_hdr, m->pkt_len) < 0) + return -1; + /* Update time to live and header checksum */ + --(ipv4_hdr->time_to_live); + ++(ipv4_hdr->hdr_checksum); +#endif + *dst_ip = rte_be_to_cpu_32(ipv4_hdr->dst_addr); + } else + return -1; + + return 0; +} + +static inline void +l3fwd_rib_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, + uint16_t portid, struct lcore_conf *qconf) +{ + struct rte_mbuf *send_pkts[MAX_PKT_BURST]; +#ifdef USE_RIB + uint64_t next_hops[MAX_PKT_BURST]; +#else + uint32_t next_hops[MAX_PKT_BURST]; +#endif + uint32_t dst_ips[MAX_PKT_BURST]; +#ifdef USE_RIB + struct rte_rib *rib = qconf->ipv4_lookup_struct; +#else + struct rte_lpm *rib = qconf->ipv4_lookup_struct; +#endif + struct ether_hdr *eth_hdr; + int32_t j, k = 0; + int ret; + uint16_t dst_port; + + for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++) + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j], void *)); + + for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) { + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[ + j + PREFETCH_OFFSET], void *)); + + ret = l3fwd_rib_handle_pkt(pkts_burst[j], &dst_ips[k]); + if (ret != 0) { + rte_pktmbuf_free(pkts_burst[j]); + continue; + } + send_pkts[k++] = pkts_burst[j]; + } + + for (; j < nb_rx; j++) { + ret = l3fwd_rib_handle_pkt(pkts_burst[j], &dst_ips[k]); + if (ret != 0) { + rte_pktmbuf_free(pkts_burst[j]); + continue; + } + send_pkts[k++] = pkts_burst[j]; + } + +#ifdef USE_RIB + ret = rte_rib_fib_lookup_bulk(rib, dst_ips, next_hops, k); +#else + ret = rte_lpm_lookup_bulk(rib, dst_ips, next_hops, k); +#endif + if (ret != 0) { + for (j = 0; j < k; j++) + rte_pktmbuf_free(send_pkts[j]); + } else { + for (j = 0; j < k; j++) { +#ifdef USE_RIB + dst_port = next_hops[j]; +#else + dst_port = next_hops[j] & 0x00FFFFFF; +#endif + if (dst_port >= RTE_MAX_ETHPORTS || + (enabled_port_mask & 1 << dst_port) == 0) { + dst_port = portid; + } + eth_hdr = rte_pktmbuf_mtod(send_pkts[j], struct ether_hdr *); + /* dst addr */ + *(uint64_t *)ð_hdr->d_addr = dest_eth_addr[dst_port]; + /* src addr */ + ether_addr_copy(&ports_eth_addr[dst_port], ð_hdr->s_addr); + send_single_packet(qconf, send_pkts[j], dst_port); + } + } +} + /* main processing loop */ int lpm_main_loop(__attribute__((unused)) void *dummy) @@ -237,6 +342,10 @@ struct ipv6_l3fwd_lpm_route { if (nb_rx == 0) continue; +#if defined(BULK_LOOKUP) + l3fwd_rib_send_packets(nb_rx, pkts_burst, + portid, qconf); +#else #if defined RTE_ARCH_X86 || defined RTE_MACHINE_CPUFLAG_NEON \ || defined RTE_ARCH_PPC_64 l3fwd_lpm_send_packets(nb_rx, pkts_burst, @@ -245,6 +354,7 @@ struct ipv6_l3fwd_lpm_route { l3fwd_lpm_no_opt_send_packets(nb_rx, pkts_burst, portid, qconf); #endif /* X86 */ +#endif /* BULK_LOOKUP*/ } } @@ -255,18 +365,36 @@ struct ipv6_l3fwd_lpm_route { setup_lpm(const int socketid) { struct rte_lpm6_config config; +#if defined(BULK_LOOKUP) && defined(USE_RIB) + struct rte_rib_conf config_ipv4; +#else struct rte_lpm_config config_ipv4; +#endif unsigned i; int ret; char s[64]; /* create the LPM table */ +#if defined(BULK_LOOKUP) && defined(USE_RIB) + config_ipv4.type = RTE_RIB_DIR24_8; + config_ipv4.max_nodes = IPV4_L3FWD_LPM_MAX_RULES; + config_ipv4.node_sz = sizeof(struct rte_rib_node); + config_ipv4.fib_conf.dir24_8.def_nh = 0; + config_ipv4.fib_conf.dir24_8.nh_sz = RTE_DIR24_8_4B; + config_ipv4.fib_conf.dir24_8.num_tbl8 = IPV4_L3FWD_LPM_NUMBER_TBL8S; +#else config_ipv4.max_rules = IPV4_L3FWD_LPM_MAX_RULES; config_ipv4.number_tbl8s = IPV4_L3FWD_LPM_NUMBER_TBL8S; config_ipv4.flags = 0; +#endif snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socketid); + ipv4_l3fwd_lpm_lookup_struct[socketid] = +#if defined(BULK_LOOKUP) && defined(USE_RIB) + rte_rib_create(s, socketid, &config_ipv4); +#else rte_lpm_create(s, socketid, &config_ipv4); +#endif if (ipv4_l3fwd_lpm_lookup_struct[socketid] == NULL) rte_exit(EXIT_FAILURE, "Unable to create the l3fwd LPM table on socket %d\n", @@ -280,7 +408,11 @@ struct ipv6_l3fwd_lpm_route { enabled_port_mask) == 0) continue; +#if defined(BULK_LOOKUP) && defined(USE_RIB) + ret = rte_rib_add(ipv4_l3fwd_lpm_lookup_struct[socketid], +#else ret = rte_lpm_add(ipv4_l3fwd_lpm_lookup_struct[socketid], +#endif ipv4_l3fwd_lpm_route_array[i].ip, ipv4_l3fwd_lpm_route_array[i].depth, ipv4_l3fwd_lpm_route_array[i].if_out); diff --git a/examples/l3fwd/meson.build b/examples/l3fwd/meson.build index cbef07f..f742fb1 100644 --- a/examples/l3fwd/meson.build +++ b/examples/l3fwd/meson.build @@ -6,7 +6,7 @@ # To build this example as a standalone application with an already-installed # DPDK instance, use 'make' -deps += ['hash', 'lpm'] +deps += ['hash', 'lpm', 'rib'] allow_experimental_apis = true sources = files( 'l3fwd_em.c', 'l3fwd_lpm.c', 'main.c' -- 1.8.3.1