2 // Copyright (c) 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.
19 #include <rte_common.h>
20 #include <rte_malloc.h>
21 #include <rte_byteorder.h>
22 #include <rte_table_stub.h>
23 #include <rte_table_hash.h>
24 #include <rte_pipeline.h>
26 #include "pipeline_txrx_be.h"
27 #include "pipeline_actions_common.h"
29 #include "hash_func.h"
30 #include "pipeline_arpicmp_be.h"
31 #include "vnf_common.h"
34 #include "lib_icmpv6.h"
40 struct pipeline_txrx {
42 pipeline_msg_req_handler
43 custom_handlers[PIPELINE_TXRX_MSG_REQS];
44 uint64_t receivedPktCount;
45 uint64_t droppedPktCount;
46 uint8_t links_map[PIPELINE_MAX_PORT_IN];
47 uint8_t outport_id[PIPELINE_MAX_PORT_IN];
50 } __rte_cache_aligned;
56 static void *pipeline_txrx_msg_req_custom_handler(struct pipeline *p,
59 static pipeline_msg_req_handler handlers[] = {
60 [PIPELINE_MSG_REQ_PING] =
61 pipeline_msg_req_ping_handler,
62 [PIPELINE_MSG_REQ_STATS_PORT_IN] =
63 pipeline_msg_req_stats_port_in_handler,
64 [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
65 pipeline_msg_req_stats_port_out_handler,
66 [PIPELINE_MSG_REQ_STATS_TABLE] =
67 pipeline_msg_req_stats_table_handler,
68 [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
69 pipeline_msg_req_port_in_enable_handler,
70 [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
71 pipeline_msg_req_port_in_disable_handler,
72 [PIPELINE_MSG_REQ_CUSTOM] =
73 pipeline_txrx_msg_req_custom_handler,
77 static void *pipeline_txrx_msg_req_entry_dbg_handler(struct pipeline *p,
79 static void *pipeline_txrx_msg_req_entry_dbg_handler(
80 __rte_unused struct pipeline *p,
81 __rte_unused void *msg)
83 /*have to handle dbg commands*/
87 static __rte_unused pipeline_msg_req_handler custom_handlers[] = {
88 [PIPELINE_TXRX_MSG_REQ_ENTRY_DBG] =
89 pipeline_txrx_msg_req_entry_dbg_handler,
93 * Function for pipeline custom handlers
96 * A void pointer to pipeline
98 * void pointer for incoming data
101 * void pointer of response
103 void *pipeline_txrx_msg_req_custom_handler(struct pipeline *p, void *msg)
105 struct pipeline_txrx *p_txrx = (struct pipeline_txrx *)p;
106 struct pipeline_custom_msg_req *req = msg;
107 pipeline_msg_req_handler f_handle;
109 f_handle = (req->subtype < PIPELINE_TXRX_MSG_REQS) ?
110 p_txrx->custom_handlers[req->subtype] :
111 pipeline_msg_req_invalid_handler;
113 if (f_handle == NULL)
114 f_handle = pipeline_msg_req_invalid_handler;
116 return f_handle(p, req);
119 /* Not needed as no arguments are needed for TxRX
120 * ARP arguments are handled in ARP module
123 pipeline_txrx_parse_args(struct pipeline_txrx *p,
124 struct pipeline_params *params);
126 pipeline_txrx_parse_args(struct pipeline_txrx *p,
127 struct pipeline_params *params)
130 uint8_t txrx_type_present = 0;
133 printf("TXRX pipeline_txrx_parse_args params->n_args: %d\n",
136 for (i = 0; i < params->n_args; i++) {
137 char *arg_name = params->args_name[i];
138 char *arg_value = params->args_value[i];
141 printf("TXRX args[%d]: %s %d, %s\n", i, arg_name,
142 atoi(arg_value), arg_value);
144 /* txrx_type = val */
145 if (strcmp(arg_name, "pipeline_txrx_type") == 0) {
146 if (txrx_type_present)
148 txrx_type_present = 1;
151 if (strcmp(arg_value, "TXTX") == 0) {
152 p->txrx_type = TYPE_TXTX;
153 printf("pipeline_txrx_type is TXTX\n");
155 if (strcmp(arg_value, "RXRX") == 0) {
156 p->txrx_type = TYPE_RXRX;
157 printf("pipeline_txrx_type is RXRX\n");
163 if (!txrx_type_present) {
164 printf("TXRX type not specified\n");
172 uint32_t txrx_pkt_print_count;
174 pkt_work_txrx(struct rte_mbuf *pkt, uint32_t pkt_num, void *arg)
177 struct pipeline_txrx_in_port_h_arg *ap = arg;
178 struct pipeline_txrx *p_txrx = (struct pipeline_txrx *)ap->p;
179 uint8_t solicited_node_multicast_addr[16] =
180 {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00};
182 p_txrx->receivedPktCount++;
184 if (p_txrx->txrx_type == TYPE_TXTX)
187 uint8_t in_port_id = pkt->port;
188 uint32_t eth_proto_offset = MBUF_HDR_ROOM + 12;
190 uint32_t pkt_mask = 1 << pkt_num;
191 /* ARP outport number */
192 uint32_t out_port = p_txrx->p.n_ports_out - 1;
194 uint16_t *eth_proto =
195 RTE_MBUF_METADATA_UINT16_PTR(pkt, eth_proto_offset);
198 uint32_t prot_offset =
199 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_PROTOCOL_OFST;
202 struct ipv6_hdr *ipv6_h;
203 ipv6_h = rte_pktmbuf_mtod_offset (pkt, struct ipv6_hdr *, sizeof(struct ether_hdr));
204 uint32_t prot_offset_ipv6 =
205 MBUF_HDR_ROOM + ETH_HDR_SIZE + IPV6_HDR_PROTOCOL_OFST;
207 if (rte_be_to_cpu_16(*eth_proto) == ETHER_TYPE_IPv6)
208 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt, prot_offset_ipv6);
210 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt, prot_offset);
212 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt, prot_offset);
216 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
218 txrx_pkt_print_count++;
219 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
220 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
221 rte_be_to_cpu_16(*eth_proto), *protocol, ETH_TYPE_ARP,
222 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
224 /* Classifier for ICMP pass-through*/
225 struct app_link_params *link;
227 link = &myApp->link_params[in_port_id];
229 /* header room + eth hdr size + src_aadr offset in ip header */
230 uint32_t dst_addr_offset =
231 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
232 uint32_t *dst_addr = RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset);
235 if (rte_be_to_cpu_16(*eth_proto) == ETH_TYPE_IPV4)
236 printf ("%s: linkIp: %x, dst_addr: %x\n", __FUNCTION__, link->ip, *dst_addr);
239 switch (rte_be_to_cpu_16(*eth_proto)) {
241 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
243 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
247 if ((*protocol == IP_PROTOCOL_ICMP) &&
248 (link->ip == rte_be_to_cpu_32(*dst_addr))) {
249 if (is_phy_port_privte(pkt->port)) {
250 rte_pipeline_port_out_packet_insert(
253 rte_pipeline_ah_packet_drop(
263 if (*protocol == ICMPV6_PROTOCOL_ID) {
265 if (!memcmp(ipv6_h->dst_addr, link->ipv6, 16)
266 || !memcmp(ipv6_h->dst_addr, solicited_node_multicast_addr, 13)) {
268 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
270 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
273 printf("Dropping the IPv6 pkt\n");
274 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
281 default: /* Not valid pkt */
282 printf("Dropping the pkt\n");
283 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
291 pkt4_work_txrx(struct rte_mbuf **pkt, uint32_t pkt_num, void *arg)
293 struct pipeline_txrx_in_port_h_arg *ap = arg;
294 struct pipeline_txrx *p_txrx = (struct pipeline_txrx *)ap->p;
295 uint8_t solicited_node_multicast_addr[16] =
296 {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00};
299 if (p_txrx->txrx_type == TYPE_TXTX)
302 uint16_t in_port_id = (*pkt)->port;
303 uint32_t eth_proto_offset = MBUF_HDR_ROOM + 12;
306 uint32_t pkt_mask0 = 1 << pkt_num;
307 uint32_t pkt_mask1 = 1 << (pkt_num + 1);
308 uint32_t pkt_mask2 = 1 << (pkt_num + 2);
309 uint32_t pkt_mask3 = 1 << (pkt_num + 3);
311 /* ARP outport number */
312 uint32_t out_port = p_txrx->p.n_ports_out - 1;
314 uint16_t *eth_proto0 =
315 RTE_MBUF_METADATA_UINT16_PTR(pkt[0], eth_proto_offset);
316 uint16_t *eth_proto1 =
317 RTE_MBUF_METADATA_UINT16_PTR(pkt[1], eth_proto_offset);
318 uint16_t *eth_proto2 =
319 RTE_MBUF_METADATA_UINT16_PTR(pkt[2], eth_proto_offset);
320 uint16_t *eth_proto3 =
321 RTE_MBUF_METADATA_UINT16_PTR(pkt[3], eth_proto_offset);
323 uint8_t *protocol0, *protocol1, *protocol2, *protocol3;
324 uint32_t prot_offset =
325 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_PROTOCOL_OFST;
328 struct ipv6_hdr *ipv6_h0, *ipv6_h1, *ipv6_h2, *ipv6_h3;
329 ipv6_h0 = rte_pktmbuf_mtod_offset (pkt[0], struct ipv6_hdr *, sizeof(struct ether_hdr));
330 uint32_t prot_offset_ipv6 =
331 MBUF_HDR_ROOM + ETH_HDR_SIZE + IPV6_HDR_PROTOCOL_OFST;
334 if (rte_be_to_cpu_16(*eth_proto0) == ETHER_TYPE_IPv6)
336 RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset_ipv6);
338 protocol0 = RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset);
341 ipv6_h1 = rte_pktmbuf_mtod_offset (pkt[1], struct ipv6_hdr *, sizeof(struct ether_hdr));
342 if (rte_be_to_cpu_16(*eth_proto1) == ETHER_TYPE_IPv6)
344 RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset_ipv6);
346 protocol1 = RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset);
349 ipv6_h2 = rte_pktmbuf_mtod_offset (pkt[2], struct ipv6_hdr *, sizeof(struct ether_hdr));
350 if (rte_be_to_cpu_16(*eth_proto2) == ETHER_TYPE_IPv6)
352 RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset_ipv6);
354 protocol2 = RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset);
357 ipv6_h3 = rte_pktmbuf_mtod_offset (pkt[3], struct ipv6_hdr *, sizeof(struct ether_hdr));
358 if (rte_be_to_cpu_16(*eth_proto3) == ETHER_TYPE_IPv6)
360 RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset_ipv6);
362 protocol3 = RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset);
364 protocol0 = RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset);
365 protocol1 = RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset);
366 protocol2 = RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset);
367 protocol3 = RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset);
370 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
372 txrx_pkt_print_count++;
373 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
374 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
375 rte_be_to_cpu_16(*eth_proto0), *protocol0, ETH_TYPE_ARP,
376 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
379 struct app_link_params *link;
381 link = &myApp->link_params[in_port_id];
383 /* header room + eth hdr size + src_aadr offset in ip header */
384 uint32_t dst_addr_offset0 =
385 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
386 uint32_t *dst_addr0 =
387 RTE_MBUF_METADATA_UINT32_PTR(pkt[0], dst_addr_offset0);
390 if (rte_be_to_cpu_16(*eth_proto0) == ETH_TYPE_IPV4)
391 printf ("%s: linkIp: %x, dst_addr0: %x\n", __FUNCTION__, link->ip, *dst_addr0);
394 switch (rte_be_to_cpu_16(*eth_proto0)) {
396 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
398 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
402 if ((*protocol0 == IP_PROTOCOL_ICMP) &&
403 (link->ip == rte_be_to_cpu_32(*dst_addr0))) {
404 if (is_phy_port_privte(pkt[0]->port)) {
405 rte_pipeline_port_out_packet_insert(
406 p_txrx->p.p, out_port, pkt[0]);
407 rte_pipeline_ah_packet_drop(
408 p_txrx->p.p, pkt_mask0);
416 if (*protocol0 == ICMPV6_PROTOCOL_ID) {
418 if (!memcmp(ipv6_h0->dst_addr, link->ipv6, 16)
419 || !memcmp(ipv6_h0->dst_addr, solicited_node_multicast_addr, 13)) {
421 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
423 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
427 printf("Dropping the IPv6 pkt\n");
428 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
435 default: /* Not valid pkt */
436 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
441 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
443 txrx_pkt_print_count++;
444 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
445 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
446 rte_be_to_cpu_16(*eth_proto1), *protocol1, ETH_TYPE_ARP,
447 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
450 /* header room + eth hdr size + src_aadr offset in ip header */
451 uint32_t dst_addr_offset1 =
452 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
453 uint32_t *dst_addr1 =
454 RTE_MBUF_METADATA_UINT32_PTR(pkt[1], dst_addr_offset1);
457 if (rte_be_to_cpu_16(*eth_proto1) == ETH_TYPE_IPV4)
458 printf ("%s: linkIp: %x, dst_addr1: %x\n", __FUNCTION__, link->ip, *dst_addr1);
460 switch (rte_be_to_cpu_16(*eth_proto1)) {
462 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
464 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
468 if ((*protocol1 == IP_PROTOCOL_ICMP) &&
469 (link->ip == rte_be_to_cpu_32(*dst_addr1))) {
470 if (is_phy_port_privte(pkt[1]->port)) {
471 rte_pipeline_port_out_packet_insert(
474 rte_pipeline_ah_packet_drop(
484 if (*protocol1 == ICMPV6_PROTOCOL_ID) {
486 if (!memcmp(ipv6_h1->dst_addr, link->ipv6, 16)
487 || !memcmp(ipv6_h1->dst_addr, solicited_node_multicast_addr, 13)) {
489 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
491 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
494 printf("Dropping the IPv6 pkt\n");
495 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
502 default: /* Not valid pkt */
503 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
507 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
509 txrx_pkt_print_count++;
510 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
511 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
512 rte_be_to_cpu_16(*eth_proto2), *protocol2, ETH_TYPE_ARP,
513 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
516 /* header room + eth hdr size + src_aadr offset in ip header */
517 uint32_t dst_addr_offset2 =
518 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
519 uint32_t *dst_addr2 =
520 RTE_MBUF_METADATA_UINT32_PTR(pkt[2], dst_addr_offset2);
523 if (rte_be_to_cpu_16(*eth_proto2) == ETH_TYPE_IPV4)
524 printf ("%s: linkIp: %x, dst_addr2: %x\n", __FUNCTION__, link->ip, *dst_addr2);
526 switch (rte_be_to_cpu_16(*eth_proto2)) {
528 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
530 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
534 if ((*protocol2 == IP_PROTOCOL_ICMP) &&
535 (link->ip == rte_be_to_cpu_32(*dst_addr2))) {
536 if (is_phy_port_privte(pkt[2]->port)) {
537 rte_pipeline_port_out_packet_insert(
540 rte_pipeline_ah_packet_drop(
550 if (*protocol2 == ICMPV6_PROTOCOL_ID) {
552 if (!memcmp(ipv6_h2->dst_addr, link->ipv6, 16)
553 || !memcmp(ipv6_h2->dst_addr, solicited_node_multicast_addr, 13)) {
555 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
557 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
560 printf("Dropping the IPv6 pkt\n");
561 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
568 default: /* Not valid pkt */
569 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
573 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
575 txrx_pkt_print_count++;
576 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
577 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
578 rte_be_to_cpu_16(*eth_proto3), *protocol3, ETH_TYPE_ARP,
579 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
582 /* header room + eth hdr size + src_aadr offset in ip header */
583 uint32_t dst_addr_offset3 =
584 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
585 uint32_t *dst_addr3 =
586 RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset3);
589 if (rte_be_to_cpu_16(*eth_proto3) == ETH_TYPE_IPV4)
590 printf ("%s: linkIp: %x, dst_addr3: %x\n", __FUNCTION__, link->ip, *dst_addr3);
592 switch (rte_be_to_cpu_16(*eth_proto3)) {
594 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
596 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
600 if ((*protocol3 == IP_PROTOCOL_ICMP) &&
601 (link->ip == rte_be_to_cpu_32(*dst_addr3))) {
602 if (is_phy_port_privte(pkt[3]->port)) {
603 rte_pipeline_port_out_packet_insert(
606 rte_pipeline_ah_packet_drop(
616 if (*protocol3 == ICMPV6_PROTOCOL_ID) {
618 if (!memcmp(ipv6_h3->dst_addr, link->ipv6, 16)
619 || !memcmp(ipv6_h3->dst_addr, solicited_node_multicast_addr, 13)) {
621 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
623 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
626 printf("Dropping the IPv6 pkt\n");
627 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
634 default: /* Not valid pkt */
635 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
639 p_txrx->receivedPktCount += 4;
643 PIPELINE_TXRX_KEY_PORT_IN_AH(port_in_ah_txrx, pkt_work_txrx, pkt4_work_txrx);
645 static void *pipeline_txrx_init(struct pipeline_params *params,
646 __rte_unused void *arg)
649 struct pipeline_txrx *p_pt;
650 uint32_t size, i, in_ports_arg_size;
652 printf("Start pipeline_txrx_init\n");
654 /* Check input arguments */
655 if ((params == NULL) ||
656 (params->n_ports_in == 0) ||
657 (params->n_ports_out == 0))
660 /* Memory allocation */
661 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_txrx));
662 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
663 p_pt = (struct pipeline_txrx *)p;
667 PLOG(p, HIGH, "TXRX");
668 strcpy(p->name, params->name);
669 p->log_level = params->log_level;
671 p_pt->receivedPktCount = 0;
672 p_pt->droppedPktCount = 0;
673 for (i = 0; i < PIPELINE_MAX_PORT_IN; i++)
674 p_pt->links_map[i] = 0xff;
676 p_pt->pipeline_num = 0;
677 printf("txrx initialization of variables done\n");
679 /* Parse arguments */
680 if (pipeline_txrx_parse_args(p_pt, params))
685 struct rte_pipeline_params pipeline_params = {
687 .socket_id = params->socket_id,
691 p->p = rte_pipeline_create(&pipeline_params);
698 p->n_ports_in = params->n_ports_in;
699 p->n_ports_out = params->n_ports_out;
700 p->n_tables = p->n_ports_in;
702 /* Memory allocation for in_port_h_arg */
704 RTE_CACHE_LINE_ROUNDUP((sizeof
705 (struct pipeline_txrx_in_port_h_arg)) *
706 (params->n_ports_in));
707 struct pipeline_txrx_in_port_h_arg *ap =
708 (struct pipeline_txrx_in_port_h_arg *)rte_zmalloc(NULL,
710 RTE_CACHE_LINE_SIZE);
714 for (i = 0; i < p->n_ports_in; i++) {
715 /* passing our txrx pipeline in call back arg */
717 (ap[i]).in_port_id = i;
718 struct rte_pipeline_port_in_params port_params = {
720 pipeline_port_in_params_get_ops(¶ms->
723 pipeline_port_in_params_convert(¶ms->
727 .burst_size = params->port_in[i].burst_size,
730 port_params.f_action = port_in_ah_txrx;
732 int status = rte_pipeline_port_in_create(p->p,
737 rte_pipeline_free(p->p);
744 for (i = 0; i < p->n_ports_out; i++) {
745 struct rte_pipeline_port_out_params port_params = {
747 pipeline_port_out_params_get_ops(¶ms->
750 pipeline_port_out_params_convert(¶ms->
756 int status = rte_pipeline_port_out_create(p->p,
761 rte_pipeline_free(p->p);
767 int pipeline_num = 0;
768 int status = sscanf(params->name, "PIPELINE%d", &pipeline_num);
770 printf("Unable to read pipeline number\n");
773 p_pt->pipeline_num = (uint8_t) pipeline_num;
775 register_pipeline_Qs(p_pt->pipeline_num, p);
776 set_link_map(p_pt->pipeline_num, p, p_pt->links_map);
777 set_outport_id(p_pt->pipeline_num, p, p_pt->outport_id);
780 for (i = 0; i < p->n_ports_in; i++) {
781 struct rte_pipeline_table_params table_params = {
782 .ops = &rte_table_stub_ops,
784 .f_action_hit = NULL,
785 .f_action_miss = NULL,
787 .action_data_size = 0,
790 int status = rte_pipeline_table_create(p->p,
795 rte_pipeline_free(p->p);
801 /* Connecting input ports to tables */
802 for (i = 0; i < p->n_ports_in; i++) {
803 int status = rte_pipeline_port_in_connect_to_table(p->p,
811 rte_pipeline_free(p->p);
817 /* Add entries to tables */
818 for (i = 0; i < p->n_ports_in; i++) {
819 struct rte_pipeline_table_entry default_entry = {
820 .action = RTE_PIPELINE_ACTION_PORT,
821 .port_id = p->port_out_id[i],
824 struct rte_pipeline_table_entry *default_entry_ptr;
826 int status = rte_pipeline_table_default_entry_add(
834 rte_pipeline_free(p->p);
840 /* Enable input ports */
841 for (i = 0; i < p->n_ports_in; i++) {
842 int status = rte_pipeline_port_in_enable(p->p,
846 rte_pipeline_free(p->p);
852 /* Check pipeline consistency */
853 if (rte_pipeline_check(p->p) < 0) {
854 rte_pipeline_free(p->p);
860 p->n_msgq = params->n_msgq;
861 for (i = 0; i < p->n_msgq; i++)
862 p->msgq_in[i] = params->msgq_in[i];
863 for (i = 0; i < p->n_msgq; i++)
864 p->msgq_out[i] = params->msgq_out[i];
866 /* Message handlers */
867 memcpy(p->handlers, handlers, sizeof(p->handlers));
872 static int pipeline_txrx_free(void *pipeline)
874 struct pipeline *p = (struct pipeline *)pipeline;
876 /* Check input arguments */
881 rte_pipeline_free(p->p);
886 static int pipeline_txrx_timer(void *pipeline)
888 struct pipeline *p = (struct pipeline *)pipeline;
890 pipeline_msg_req_handle(p);
891 rte_pipeline_flush(p->p);
897 pipeline_txrx_track(void *pipeline, uint32_t port_in, uint32_t *port_out)
899 struct pipeline *p = (struct pipeline *)pipeline;
901 /* Check input arguments */
902 if ((p == NULL) || (port_in >= p->n_ports_in) || (port_out == NULL))
905 *port_out = port_in / p->n_ports_in;
909 struct pipeline_be_ops pipeline_txrx_be_ops = {
910 .f_init = pipeline_txrx_init,
911 .f_free = pipeline_txrx_free,
913 .f_timer = pipeline_txrx_timer,
914 .f_track = pipeline_txrx_track,