diff options
Diffstat (limited to 'examples/l4fwd/pkt_dpdk_legacy.h')
-rw-r--r-- | examples/l4fwd/pkt_dpdk_legacy.h | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/examples/l4fwd/pkt_dpdk_legacy.h b/examples/l4fwd/pkt_dpdk_legacy.h new file mode 100644 index 0000000..d840978 --- /dev/null +++ b/examples/l4fwd/pkt_dpdk_legacy.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PKT_DPDK_LEGACY_H_ +#define PKT_DPDK_LEGACY_H_ + +#include "dpdk_version.h" + +struct ptype2cb { + uint32_t mask; + const char *name; + rte_rx_callback_fn fn; +}; + +enum { + ETHER_PTYPE = 0x1, + IPV4_PTYPE = 0x2, + IPV4_EXT_PTYPE = 0x4, + IPV6_PTYPE = 0x8, + IPV6_EXT_PTYPE = 0x10, + TCP_PTYPE = 0x20, + UDP_PTYPE = 0x40, +}; + +#ifdef DPDK_VERSION_GE_1604 + +static uint32_t +get_ptypes(const struct netbe_port *uprt) +{ + uint32_t smask; + int32_t i, rc; + const uint32_t pmask = RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK | + RTE_PTYPE_L4_MASK; + + smask = 0; + rc = rte_eth_dev_get_supported_ptypes(uprt->id, pmask, NULL, 0); + if (rc < 0) { + RTE_LOG(ERR, USER1, + "%s(port=%u) failed to get supported ptypes;\n", + __func__, uprt->id); + return smask; + } + + uint32_t ptype[rc]; + rc = rte_eth_dev_get_supported_ptypes(uprt->id, pmask, ptype, rc); + + for (i = 0; i != rc; i++) { + switch (ptype[i]) { + case RTE_PTYPE_L2_ETHER: + smask |= ETHER_PTYPE; + break; + case RTE_PTYPE_L3_IPV4: + case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN: + smask |= IPV4_PTYPE; + break; + case RTE_PTYPE_L3_IPV4_EXT: + smask |= IPV4_EXT_PTYPE; + break; + case RTE_PTYPE_L3_IPV6: + case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN: + smask |= IPV6_PTYPE; + break; + case RTE_PTYPE_L3_IPV6_EXT: + smask |= IPV6_EXT_PTYPE; + break; + case RTE_PTYPE_L4_TCP: + smask |= TCP_PTYPE; + break; + case RTE_PTYPE_L4_UDP: + smask |= UDP_PTYPE; + break; + } + } + + return smask; +} + +#else + +static uint32_t +get_ptypes(__rte_unused const struct netbe_port *uprt) +{ + return 0; +} + +#endif /* DPDK_VERSION_GE_1604 */ + +int +setup_rx_cb(const struct netbe_port *uprt, struct netbe_lcore *lc, + uint16_t qid, uint32_t arp) +{ + int32_t rc; + uint32_t i, n, smask; + void *cb; + const struct ptype2cb *ptype2cb; + + static const struct ptype2cb tcp_ptype2cb[] = { + { + .mask = ETHER_PTYPE | IPV4_PTYPE | IPV4_EXT_PTYPE | + IPV6_PTYPE | IPV6_EXT_PTYPE | TCP_PTYPE, + .name = "HW l2/l3x/l4-tcp ptype", + .fn = type0_tcp_rx_callback, + }, + { + .mask = ETHER_PTYPE | IPV4_PTYPE | IPV6_PTYPE | + TCP_PTYPE, + .name = "HW l2/l3/l4-tcp ptype", + .fn = type1_tcp_rx_callback, + }, + { + .mask = 0, + .name = "tcp no HW ptype", + .fn = typen_tcp_rx_callback, + }, + }; + + static const struct ptype2cb tcp_arp_ptype2cb[] = { + { + .mask = 0, + .name = "tcp with arp no HW ptype", + .fn = typen_tcp_arp_rx_callback, + }, + }; + + static const struct ptype2cb udp_ptype2cb[] = { + { + .mask = ETHER_PTYPE | IPV4_PTYPE | IPV4_EXT_PTYPE | + IPV6_PTYPE | IPV6_EXT_PTYPE | UDP_PTYPE, + .name = "HW l2/l3x/l4-udp ptype", + .fn = type0_udp_rx_callback, + }, + { + .mask = ETHER_PTYPE | IPV4_PTYPE | IPV6_PTYPE | + UDP_PTYPE, + .name = "HW l2/l3/l4-udp ptype", + .fn = type1_udp_rx_callback, + }, + { + .mask = 0, + .name = "udp no HW ptype", + .fn = typen_udp_rx_callback, + }, + }; + + smask = get_ptypes(uprt); + + if (lc->proto == TLE_PROTO_TCP) { + if (arp != 0) { + ptype2cb = tcp_arp_ptype2cb; + n = RTE_DIM(tcp_arp_ptype2cb); + } else { + ptype2cb = tcp_ptype2cb; + n = RTE_DIM(tcp_ptype2cb); + } + } else if (lc->proto == TLE_PROTO_UDP) { + ptype2cb = udp_ptype2cb; + n = RTE_DIM(udp_ptype2cb); + } else { + RTE_LOG(ERR, USER1, + "%s(lc=%u) unsupported proto: %u\n", + __func__, lc->id, lc->proto); + return -EINVAL; + } + + for (i = 0; i != n; i++) { + if ((smask & ptype2cb[i].mask) == ptype2cb[i].mask) { + cb = rte_eth_add_rx_callback(uprt->id, qid, + ptype2cb[i].fn, lc); + rc = -rte_errno; + RTE_LOG(ERR, USER1, + "%s(port=%u), setup RX callback \"%s\" " + "returns %p;\n", + __func__, uprt->id, ptype2cb[i].name, cb); + return ((cb == NULL) ? rc : 0); + } + } + + /* no proper callback found. */ + RTE_LOG(ERR, USER1, + "%s(port=%u) failed to find an appropriate callback;\n", + __func__, uprt->id); + return -ENOENT; +} + +#endif /* PKT_DPDK_LEGACY_H_ */ |