18f4127e4SGavin Hu /* SPDX-License-Identifier: BSD-3-Clause 28f4127e4SGavin Hu * Copyright(c) 2016-2018 Intel Corporation. 38f4127e4SGavin Hu * Copyright(c) 2017-2018 Linaro Limited. 466d8bc00SJianbo Liu */ 566d8bc00SJianbo Liu 666d8bc00SJianbo Liu 766d8bc00SJianbo Liu #ifndef _L3FWD_COMMON_H_ 866d8bc00SJianbo Liu #define _L3FWD_COMMON_H_ 966d8bc00SJianbo Liu 10732115ceSRahul Bhansali #include "pkt_group.h" 11732115ceSRahul Bhansali 1266d8bc00SJianbo Liu #ifdef DO_RFC_1812_CHECKS 1366d8bc00SJianbo Liu 1466d8bc00SJianbo Liu #define IPV4_MIN_VER_IHL 0x45 1566d8bc00SJianbo Liu #define IPV4_MAX_VER_IHL 0x4f 1666d8bc00SJianbo Liu #define IPV4_MAX_VER_IHL_DIFF (IPV4_MAX_VER_IHL - IPV4_MIN_VER_IHL) 1766d8bc00SJianbo Liu 1866d8bc00SJianbo Liu /* Minimum value of IPV4 total length (20B) in network byte order. */ 19a7c528e5SOlivier Matz #define IPV4_MIN_LEN_BE (sizeof(struct rte_ipv4_hdr) << 8) 2066d8bc00SJianbo Liu 2166d8bc00SJianbo Liu /* 22*ebab0e8bSKonstantin Ananyev * send_packet_multi() specific number of dest ports 23*ebab0e8bSKonstantin Ananyev * due to implementation we need to allocate array bigger then 24*ebab0e8bSKonstantin Ananyev * actual max number of elements in the array. 25*ebab0e8bSKonstantin Ananyev */ 26*ebab0e8bSKonstantin Ananyev #define SENDM_PORT_OVERHEAD(x) (x) 27*ebab0e8bSKonstantin Ananyev 28*ebab0e8bSKonstantin Ananyev /* 2966d8bc00SJianbo Liu * From http://www.rfc-editor.org/rfc/rfc1812.txt section 5.2.2: 3066d8bc00SJianbo Liu * - The IP version number must be 4. 3166d8bc00SJianbo Liu * - The IP header length field must be large enough to hold the 3266d8bc00SJianbo Liu * minimum length legal IP datagram (20 bytes = 5 words). 3366d8bc00SJianbo Liu * - The IP total length field must be large enough to hold the IP 3466d8bc00SJianbo Liu * datagram header, whose length is specified in the IP header length 3566d8bc00SJianbo Liu * field. 3666d8bc00SJianbo Liu * If we encounter invalid IPV4 packet, then set destination port for it 3766d8bc00SJianbo Liu * to BAD_PORT value. 3866d8bc00SJianbo Liu */ 3966d8bc00SJianbo Liu static __rte_always_inline void 40a7c528e5SOlivier Matz rfc1812_process(struct rte_ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t ptype) 4166d8bc00SJianbo Liu { 4266d8bc00SJianbo Liu uint8_t ihl; 4366d8bc00SJianbo Liu 4466d8bc00SJianbo Liu if (RTE_ETH_IS_IPV4_HDR(ptype)) { 4566d8bc00SJianbo Liu ihl = ipv4_hdr->version_ihl - IPV4_MIN_VER_IHL; 4666d8bc00SJianbo Liu 4766d8bc00SJianbo Liu ipv4_hdr->time_to_live--; 4866d8bc00SJianbo Liu ipv4_hdr->hdr_checksum++; 4966d8bc00SJianbo Liu 5066d8bc00SJianbo Liu if (ihl > IPV4_MAX_VER_IHL_DIFF || 5166d8bc00SJianbo Liu ((uint8_t)ipv4_hdr->total_length == 0 && 5266d8bc00SJianbo Liu ipv4_hdr->total_length < IPV4_MIN_LEN_BE)) 5366d8bc00SJianbo Liu dp[0] = BAD_PORT; 5466d8bc00SJianbo Liu 5566d8bc00SJianbo Liu } 5666d8bc00SJianbo Liu } 5766d8bc00SJianbo Liu 5866d8bc00SJianbo Liu #else 5966d8bc00SJianbo Liu #define rfc1812_process(mb, dp, ptype) do { } while (0) 6066d8bc00SJianbo Liu #endif /* DO_RFC_1812_CHECKS */ 6166d8bc00SJianbo Liu 6266d8bc00SJianbo Liu static __rte_always_inline void 63f8244c63SZhiyong Yang send_packetsx4(struct lcore_conf *qconf, uint16_t port, struct rte_mbuf *m[], 6466d8bc00SJianbo Liu uint32_t num) 6566d8bc00SJianbo Liu { 6666d8bc00SJianbo Liu uint32_t len, j, n; 6766d8bc00SJianbo Liu 6866d8bc00SJianbo Liu len = qconf->tx_mbufs[port].len; 6966d8bc00SJianbo Liu 7066d8bc00SJianbo Liu /* 7166d8bc00SJianbo Liu * If TX buffer for that queue is empty, and we have enough packets, 7266d8bc00SJianbo Liu * then send them straightway. 7366d8bc00SJianbo Liu */ 7466d8bc00SJianbo Liu if (num >= MAX_TX_BURST && len == 0) { 7566d8bc00SJianbo Liu n = rte_eth_tx_burst(port, qconf->tx_queue_id[port], m, num); 7666d8bc00SJianbo Liu if (unlikely(n < num)) { 7766d8bc00SJianbo Liu do { 7866d8bc00SJianbo Liu rte_pktmbuf_free(m[n]); 7966d8bc00SJianbo Liu } while (++n < num); 8066d8bc00SJianbo Liu } 8166d8bc00SJianbo Liu return; 8266d8bc00SJianbo Liu } 8366d8bc00SJianbo Liu 8466d8bc00SJianbo Liu /* 8566d8bc00SJianbo Liu * Put packets into TX buffer for that queue. 8666d8bc00SJianbo Liu */ 8766d8bc00SJianbo Liu 8866d8bc00SJianbo Liu n = len + num; 8966d8bc00SJianbo Liu n = (n > MAX_PKT_BURST) ? MAX_PKT_BURST - len : num; 9066d8bc00SJianbo Liu 9166d8bc00SJianbo Liu j = 0; 9266d8bc00SJianbo Liu switch (n % FWDSTEP) { 9366d8bc00SJianbo Liu while (j < n) { 9466d8bc00SJianbo Liu case 0: 9566d8bc00SJianbo Liu qconf->tx_mbufs[port].m_table[len + j] = m[j]; 9666d8bc00SJianbo Liu j++; 9766d8bc00SJianbo Liu /* fallthrough */ 9866d8bc00SJianbo Liu case 3: 9966d8bc00SJianbo Liu qconf->tx_mbufs[port].m_table[len + j] = m[j]; 10066d8bc00SJianbo Liu j++; 10166d8bc00SJianbo Liu /* fallthrough */ 10266d8bc00SJianbo Liu case 2: 10366d8bc00SJianbo Liu qconf->tx_mbufs[port].m_table[len + j] = m[j]; 10466d8bc00SJianbo Liu j++; 10566d8bc00SJianbo Liu /* fallthrough */ 10666d8bc00SJianbo Liu case 1: 10766d8bc00SJianbo Liu qconf->tx_mbufs[port].m_table[len + j] = m[j]; 10866d8bc00SJianbo Liu j++; 10966d8bc00SJianbo Liu } 11066d8bc00SJianbo Liu } 11166d8bc00SJianbo Liu 11266d8bc00SJianbo Liu len += n; 11366d8bc00SJianbo Liu 11466d8bc00SJianbo Liu /* enough pkts to be sent */ 11566d8bc00SJianbo Liu if (unlikely(len == MAX_PKT_BURST)) { 11666d8bc00SJianbo Liu 11766d8bc00SJianbo Liu send_burst(qconf, MAX_PKT_BURST, port); 11866d8bc00SJianbo Liu 11966d8bc00SJianbo Liu /* copy rest of the packets into the TX buffer. */ 12066d8bc00SJianbo Liu len = num - n; 1210490d69dSRahul Bhansali if (len == 0) 1220490d69dSRahul Bhansali goto exit; 1230490d69dSRahul Bhansali 12466d8bc00SJianbo Liu j = 0; 12566d8bc00SJianbo Liu switch (len % FWDSTEP) { 12666d8bc00SJianbo Liu while (j < len) { 12766d8bc00SJianbo Liu case 0: 12866d8bc00SJianbo Liu qconf->tx_mbufs[port].m_table[j] = m[n + j]; 12966d8bc00SJianbo Liu j++; 13066d8bc00SJianbo Liu /* fallthrough */ 13166d8bc00SJianbo Liu case 3: 13266d8bc00SJianbo Liu qconf->tx_mbufs[port].m_table[j] = m[n + j]; 13366d8bc00SJianbo Liu j++; 13466d8bc00SJianbo Liu /* fallthrough */ 13566d8bc00SJianbo Liu case 2: 13666d8bc00SJianbo Liu qconf->tx_mbufs[port].m_table[j] = m[n + j]; 13766d8bc00SJianbo Liu j++; 13866d8bc00SJianbo Liu /* fallthrough */ 13966d8bc00SJianbo Liu case 1: 14066d8bc00SJianbo Liu qconf->tx_mbufs[port].m_table[j] = m[n + j]; 14166d8bc00SJianbo Liu j++; 14266d8bc00SJianbo Liu } 14366d8bc00SJianbo Liu } 14466d8bc00SJianbo Liu } 14566d8bc00SJianbo Liu 1460490d69dSRahul Bhansali exit: 14766d8bc00SJianbo Liu qconf->tx_mbufs[port].len = len; 14866d8bc00SJianbo Liu } 14966d8bc00SJianbo Liu 15066d8bc00SJianbo Liu #endif /* _L3FWD_COMMON_H_ */ 151