2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
20 #include <rte_hash_crc.h>
23 #include "task_base.h"
26 #include "task_init.h"
34 struct task_base base;
39 static void init_task_lb_pos(struct task_base *tbase, struct task_args *targ)
41 struct task_lb_pos *task = (struct task_lb_pos *)tbase;
43 task->n_workers = targ->nb_worker_threads;
44 task->byte_offset = targ->byte_offset;
47 static int handle_lb_pos_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts)
49 struct task_lb_pos *task = (struct task_lb_pos *)tbase;
50 uint8_t out[MAX_PKT_BURST];
51 uint16_t offset = task->byte_offset;
54 prefetch_first(mbufs, n_pkts);
56 for (j = 0; j + PREFETCH_OFFSET < n_pkts; ++j) {
57 #ifdef PROX_PREFETCH_OFFSET
58 PREFETCH0(mbufs[j + PREFETCH_OFFSET]);
59 PREFETCH0(rte_pktmbuf_mtod(mbufs[j + PREFETCH_OFFSET - 1], void *));
61 uint8_t* pkt = rte_pktmbuf_mtod(mbufs[j], uint8_t*);
62 out[j] = pkt[offset] % task->n_workers;
64 #ifdef PROX_PREFETCH_OFFSET
65 PREFETCH0(rte_pktmbuf_mtod(mbufs[n_pkts - 1], void *));
66 for (; j < n_pkts; ++j) {
67 uint8_t* pkt = rte_pktmbuf_mtod(mbufs[j], uint8_t*);
68 out[j] = pkt[offset] % task->n_workers;
72 return task->base.tx_pkt(&task->base, mbufs, n_pkts, out);
83 struct pkt_ether_ipv4_udp {
84 prox_rte_ether_hdr ether;
85 prox_rte_ipv4_hdr ipv4;
87 } __attribute__((unused));
89 static uint8_t handle_lb_ip_port(struct task_lb_pos *task, struct rte_mbuf *mbuf)
91 union ip_port ip_port;
94 struct pkt_ether_ipv4_udp *pkt = rte_pktmbuf_mtod(mbuf, void *);
96 if (pkt->ether.ether_type != ETYPE_IPv4 ||
97 (pkt->ipv4.next_proto_id != IPPROTO_TCP &&
98 pkt->ipv4.next_proto_id != IPPROTO_UDP))
101 if (task->byte_offset == 0) {
102 ip_port.ip = pkt->ipv4.src_addr;
103 ip_port.port = pkt->udp.src_port;
106 ip_port.ip = pkt->ipv4.dst_addr;
107 ip_port.port = pkt->udp.dst_port;
110 return rte_hash_crc(&ip_port.ip_port, sizeof(ip_port.ip_port), 0) % task->n_workers;
113 static int handle_lb_ip_port_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts)
115 struct task_lb_pos *task = (struct task_lb_pos *)tbase;
116 uint8_t out[MAX_PKT_BURST];
118 uint64_t ip_port = 0;
120 for (j = 0; j + PREFETCH_OFFSET < n_pkts; ++j) {
121 #ifdef PROX_PREFETCH_OFFSET
122 PREFETCH0(mbufs[j + PREFETCH_OFFSET]);
123 PREFETCH0(rte_pktmbuf_mtod(mbufs[j + PREFETCH_OFFSET - 1], void *));
125 out[j] = handle_lb_ip_port(task, mbufs[j]);
127 #ifdef PROX_PREFETCH_OFFSET
128 PREFETCH0(rte_pktmbuf_mtod(mbufs[n_pkts - 1], void *));
129 for (; j < n_pkts; ++j) {
130 out[j] = handle_lb_ip_port(task, mbufs[j]);
134 return task->base.tx_pkt(&task->base, mbufs, n_pkts, out);
137 static struct task_init task_init_lb_pos = {
139 .init = init_task_lb_pos,
140 .handle = handle_lb_pos_bulk,
141 .size = sizeof(struct task_lb_pos)
144 static struct task_init task_init_lb_pos2 = {
146 .sub_mode_str = "ip_port",
147 .init = init_task_lb_pos,
148 .handle = handle_lb_ip_port_bulk,
149 .size = sizeof(struct task_lb_pos)
152 __attribute__((constructor)) static void reg_task_lb_pos(void)
154 reg_task(&task_init_lb_pos);
155 reg_task(&task_init_lb_pos2);