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"
41 struct pipeline_txrx {
43 pipeline_msg_req_handler
44 custom_handlers[PIPELINE_TXRX_MSG_REQS];
45 uint64_t receivedPktCount;
46 uint64_t droppedPktCount;
47 uint8_t links_map[PIPELINE_MAX_PORT_IN];
48 uint8_t outport_id[PIPELINE_MAX_PORT_IN];
51 } __rte_cache_aligned;
57 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_hijack(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) {
264 if (!memcmp(ipv6_h->dst_addr, link->ipv6, 16)
265 || !memcmp(ipv6_h->dst_addr, solicited_node_multicast_addr, 13)) {
266 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
268 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
270 printf("Dropping the IPv6 pkt\n");
271 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
277 default: /* Not valid pkt */
278 printf("Dropping the pkt\n");
279 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
287 pkt4_work_txrx(struct rte_mbuf **pkt, uint32_t pkt_num, void *arg)
289 struct pipeline_txrx_in_port_h_arg *ap = arg;
290 struct pipeline_txrx *p_txrx = (struct pipeline_txrx *)ap->p;
291 uint8_t solicited_node_multicast_addr[16] =
292 {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00};
295 if (p_txrx->txrx_type == TYPE_TXTX)
298 uint16_t in_port_id = (*pkt)->port;
299 uint32_t eth_proto_offset = MBUF_HDR_ROOM + 12;
302 uint32_t pkt_mask0 = 1 << pkt_num;
303 uint32_t pkt_mask1 = 1 << (pkt_num + 1);
304 uint32_t pkt_mask2 = 1 << (pkt_num + 2);
305 uint32_t pkt_mask3 = 1 << (pkt_num + 3);
307 /* ARP outport number */
308 uint32_t out_port = p_txrx->p.n_ports_out - 1;
310 uint16_t *eth_proto0 =
311 RTE_MBUF_METADATA_UINT16_PTR(pkt[0], eth_proto_offset);
312 uint16_t *eth_proto1 =
313 RTE_MBUF_METADATA_UINT16_PTR(pkt[1], eth_proto_offset);
314 uint16_t *eth_proto2 =
315 RTE_MBUF_METADATA_UINT16_PTR(pkt[2], eth_proto_offset);
316 uint16_t *eth_proto3 =
317 RTE_MBUF_METADATA_UINT16_PTR(pkt[3], eth_proto_offset);
319 uint8_t *protocol0, *protocol1, *protocol2, *protocol3;
320 uint32_t prot_offset =
321 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_PROTOCOL_OFST;
324 struct ipv6_hdr *ipv6_h0, *ipv6_h1, *ipv6_h2, *ipv6_h3;
325 ipv6_h0 = rte_pktmbuf_mtod_offset (pkt[0], struct ipv6_hdr *, sizeof(struct ether_hdr));
326 uint32_t prot_offset_ipv6 =
327 MBUF_HDR_ROOM + ETH_HDR_SIZE + IPV6_HDR_PROTOCOL_OFST;
330 if (rte_be_to_cpu_16(*eth_proto0) == ETHER_TYPE_IPv6)
332 RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset_ipv6);
334 protocol0 = RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset);
337 ipv6_h1 = rte_pktmbuf_mtod_offset (pkt[1], struct ipv6_hdr *, sizeof(struct ether_hdr));
338 if (rte_be_to_cpu_16(*eth_proto1) == ETHER_TYPE_IPv6)
340 RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset_ipv6);
342 protocol1 = RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset);
345 ipv6_h2 = rte_pktmbuf_mtod_offset (pkt[2], struct ipv6_hdr *, sizeof(struct ether_hdr));
346 if (rte_be_to_cpu_16(*eth_proto2) == ETHER_TYPE_IPv6)
348 RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset_ipv6);
350 protocol2 = RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset);
353 ipv6_h3 = rte_pktmbuf_mtod_offset (pkt[3], struct ipv6_hdr *, sizeof(struct ether_hdr));
354 if (rte_be_to_cpu_16(*eth_proto3) == ETHER_TYPE_IPv6)
356 RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset_ipv6);
358 protocol3 = RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset);
360 protocol0 = RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset);
361 protocol1 = RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset);
362 protocol2 = RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset);
363 protocol3 = RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset);
366 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
368 txrx_pkt_print_count++;
369 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
370 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
371 rte_be_to_cpu_16(*eth_proto0), *protocol0, ETH_TYPE_ARP,
372 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
375 struct app_link_params *link;
377 link = &myApp->link_params[in_port_id];
379 /* header room + eth hdr size + src_aadr offset in ip header */
380 uint32_t dst_addr_offset0 =
381 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
382 uint32_t *dst_addr0 =
383 RTE_MBUF_METADATA_UINT32_PTR(pkt[0], dst_addr_offset0);
386 if (rte_be_to_cpu_16(*eth_proto0) == ETH_TYPE_IPV4)
387 printf ("%s: linkIp: %x, dst_addr0: %x\n", __FUNCTION__, link->ip, *dst_addr0);
390 switch (rte_be_to_cpu_16(*eth_proto0)) {
392 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
394 rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask0);
398 if ((*protocol0 == IP_PROTOCOL_ICMP) &&
399 (link->ip == rte_be_to_cpu_32(*dst_addr0))) {
400 if (is_phy_port_privte(pkt[0]->port)) {
401 rte_pipeline_port_out_packet_insert(
402 p_txrx->p.p, out_port, pkt[0]);
403 rte_pipeline_ah_packet_drop(
404 p_txrx->p.p, pkt_mask0);
412 if (*protocol0 == ICMPV6_PROTOCOL_ID) {
413 if (!memcmp(ipv6_h0->dst_addr, link->ipv6, 16)
414 || !memcmp(ipv6_h0->dst_addr, solicited_node_multicast_addr, 13)) {
415 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
417 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
420 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
426 default: /* Not valid pkt */
427 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
432 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
434 txrx_pkt_print_count++;
435 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
436 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
437 rte_be_to_cpu_16(*eth_proto1), *protocol1, ETH_TYPE_ARP,
438 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
441 /* header room + eth hdr size + src_aadr offset in ip header */
442 uint32_t dst_addr_offset1 =
443 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
444 uint32_t *dst_addr1 =
445 RTE_MBUF_METADATA_UINT32_PTR(pkt[1], dst_addr_offset1);
448 if (rte_be_to_cpu_16(*eth_proto1) == ETH_TYPE_IPV4)
449 printf ("%s: linkIp: %x, dst_addr1: %x\n", __FUNCTION__, link->ip, *dst_addr1);
451 switch (rte_be_to_cpu_16(*eth_proto1)) {
453 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
455 rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask1);
459 if ((*protocol1 == IP_PROTOCOL_ICMP) &&
460 (link->ip == rte_be_to_cpu_32(*dst_addr1))) {
461 if (is_phy_port_privte(pkt[1]->port)) {
462 rte_pipeline_port_out_packet_insert(
465 rte_pipeline_ah_packet_drop(
475 if (*protocol1 == ICMPV6_PROTOCOL_ID) {
477 if (!memcmp(ipv6_h1->dst_addr, link->ipv6, 16)
478 || !memcmp(ipv6_h1->dst_addr, solicited_node_multicast_addr, 13)) {
480 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
482 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
485 printf("Dropping the IPv6 pkt\n");
486 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
493 default: /* Not valid pkt */
494 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
498 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
500 txrx_pkt_print_count++;
501 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
502 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
503 rte_be_to_cpu_16(*eth_proto2), *protocol2, ETH_TYPE_ARP,
504 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
507 /* header room + eth hdr size + src_aadr offset in ip header */
508 uint32_t dst_addr_offset2 =
509 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
510 uint32_t *dst_addr2 =
511 RTE_MBUF_METADATA_UINT32_PTR(pkt[2], dst_addr_offset2);
514 if (rte_be_to_cpu_16(*eth_proto2) == ETH_TYPE_IPV4)
515 printf ("%s: linkIp: %x, dst_addr2: %x\n", __FUNCTION__, link->ip, *dst_addr2);
517 switch (rte_be_to_cpu_16(*eth_proto2)) {
519 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
521 rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask2);
525 if ((*protocol2 == IP_PROTOCOL_ICMP) &&
526 (link->ip == rte_be_to_cpu_32(*dst_addr2))) {
527 if (is_phy_port_privte(pkt[2]->port)) {
528 rte_pipeline_port_out_packet_insert(
531 rte_pipeline_ah_packet_drop(
541 if (*protocol2 == ICMPV6_PROTOCOL_ID) {
543 if (!memcmp(ipv6_h2->dst_addr, link->ipv6, 16)
544 || !memcmp(ipv6_h2->dst_addr, solicited_node_multicast_addr, 13)) {
546 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
548 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
551 printf("Dropping the IPv6 pkt\n");
552 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
559 default: /* Not valid pkt */
560 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
564 if ((TXRX_DEBUG > 2) && (txrx_pkt_print_count < 10)) {
566 txrx_pkt_print_count++;
567 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
568 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
569 rte_be_to_cpu_16(*eth_proto3), *protocol3, ETH_TYPE_ARP,
570 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
573 /* header room + eth hdr size + src_aadr offset in ip header */
574 uint32_t dst_addr_offset3 =
575 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
576 uint32_t *dst_addr3 =
577 RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset3);
580 if (rte_be_to_cpu_16(*eth_proto3) == ETH_TYPE_IPV4)
581 printf ("%s: linkIp: %x, dst_addr3: %x\n", __FUNCTION__, link->ip, *dst_addr3);
583 switch (rte_be_to_cpu_16(*eth_proto3)) {
585 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
587 rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask3);
591 if ((*protocol3 == IP_PROTOCOL_ICMP) &&
592 (link->ip == rte_be_to_cpu_32(*dst_addr3))) {
593 if (is_phy_port_privte(pkt[3]->port)) {
594 rte_pipeline_port_out_packet_insert(
597 rte_pipeline_ah_packet_drop(
607 if (*protocol3 == ICMPV6_PROTOCOL_ID) {
609 if (!memcmp(ipv6_h3->dst_addr, link->ipv6, 16)
610 || !memcmp(ipv6_h3->dst_addr, solicited_node_multicast_addr, 13)) {
612 rte_pipeline_port_out_packet_insert(p_txrx->p.p,
614 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
617 printf("Dropping the IPv6 pkt\n");
618 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
625 default: /* Not valid pkt */
626 rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
630 p_txrx->receivedPktCount += 4;
634 PIPELINE_TXRX_KEY_PORT_IN_AH(port_in_ah_txrx, pkt_work_txrx, pkt4_work_txrx);
636 static void *pipeline_txrx_init(struct pipeline_params *params,
637 __rte_unused void *arg)
640 struct pipeline_txrx *p_pt;
641 uint32_t size, i, in_ports_arg_size;
643 printf("Start pipeline_txrx_init\n");
645 /* Check input arguments */
646 if ((params == NULL) ||
647 (params->n_ports_in == 0) ||
648 (params->n_ports_out == 0))
651 /* Memory allocation */
652 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_txrx));
653 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
654 p_pt = (struct pipeline_txrx *)p;
658 PLOG(p, HIGH, "TXRX");
659 strcpy(p->name, params->name);
660 p->log_level = params->log_level;
662 p_pt->receivedPktCount = 0;
663 p_pt->droppedPktCount = 0;
664 for (i = 0; i < PIPELINE_MAX_PORT_IN; i++)
665 p_pt->links_map[i] = 0xff;
667 p_pt->pipeline_num = 0;
668 printf("txrx initialization of variables done\n");
670 /* Parse arguments */
671 if (pipeline_txrx_parse_args(p_pt, params))
676 struct rte_pipeline_params pipeline_params = {
678 .socket_id = params->socket_id,
682 p->p = rte_pipeline_create(&pipeline_params);
689 p->n_ports_in = params->n_ports_in;
690 p->n_ports_out = params->n_ports_out;
691 p->n_tables = p->n_ports_in;
693 /* Memory allocation for in_port_h_arg */
695 RTE_CACHE_LINE_ROUNDUP((sizeof
696 (struct pipeline_txrx_in_port_h_arg)) *
697 (params->n_ports_in));
698 struct pipeline_txrx_in_port_h_arg *ap =
699 (struct pipeline_txrx_in_port_h_arg *)rte_zmalloc(NULL,
701 RTE_CACHE_LINE_SIZE);
705 for (i = 0; i < p->n_ports_in; i++) {
706 /* passing our txrx pipeline in call back arg */
708 (ap[i]).in_port_id = i;
709 struct rte_pipeline_port_in_params port_params = {
711 pipeline_port_in_params_get_ops(¶ms->
714 pipeline_port_in_params_convert(¶ms->
718 .burst_size = params->port_in[i].burst_size,
721 port_params.f_action = port_in_ah_txrx;
723 int status = rte_pipeline_port_in_create(p->p,
728 rte_pipeline_free(p->p);
735 for (i = 0; i < p->n_ports_out; i++) {
736 struct rte_pipeline_port_out_params port_params = {
738 pipeline_port_out_params_get_ops(¶ms->
741 pipeline_port_out_params_convert(¶ms->
747 int status = rte_pipeline_port_out_create(p->p,
752 rte_pipeline_free(p->p);
758 int pipeline_num = 0;
759 int status = sscanf(params->name, "PIPELINE%d", &pipeline_num);
761 printf("Unable to read pipeline number\n");
764 p_pt->pipeline_num = (uint8_t) pipeline_num;
766 register_pipeline_Qs(p_pt->pipeline_num, p);
767 set_link_map(p_pt->pipeline_num, p, p_pt->links_map);
768 set_outport_id(p_pt->pipeline_num, p, p_pt->outport_id);
771 for (i = 0; i < p->n_ports_in; i++) {
772 struct rte_pipeline_table_params table_params = {
773 .ops = &rte_table_stub_ops,
775 .f_action_hit = NULL,
776 .f_action_miss = NULL,
778 .action_data_size = 0,
781 int status = rte_pipeline_table_create(p->p,
786 rte_pipeline_free(p->p);
792 /* Connecting input ports to tables */
793 for (i = 0; i < p->n_ports_in; i++) {
794 int status = rte_pipeline_port_in_connect_to_table(p->p,
802 rte_pipeline_free(p->p);
808 /* Add entries to tables */
809 for (i = 0; i < p->n_ports_in; i++) {
810 struct rte_pipeline_table_entry default_entry = {
811 .action = RTE_PIPELINE_ACTION_PORT,
812 .port_id = p->port_out_id[i],
815 struct rte_pipeline_table_entry *default_entry_ptr;
817 int status = rte_pipeline_table_default_entry_add(
825 rte_pipeline_free(p->p);
831 /* Enable input ports */
832 for (i = 0; i < p->n_ports_in; i++) {
833 int status = rte_pipeline_port_in_enable(p->p,
837 rte_pipeline_free(p->p);
843 /* Check pipeline consistency */
844 if (rte_pipeline_check(p->p) < 0) {
845 rte_pipeline_free(p->p);
851 p->n_msgq = params->n_msgq;
852 for (i = 0; i < p->n_msgq; i++)
853 p->msgq_in[i] = params->msgq_in[i];
854 for (i = 0; i < p->n_msgq; i++)
855 p->msgq_out[i] = params->msgq_out[i];
857 /* Message handlers */
858 memcpy(p->handlers, handlers, sizeof(p->handlers));
863 static int pipeline_txrx_free(void *pipeline)
865 struct pipeline *p = (struct pipeline *)pipeline;
867 /* Check input arguments */
872 rte_pipeline_free(p->p);
877 static int pipeline_txrx_timer(void *pipeline)
879 struct pipeline *p = (struct pipeline *)pipeline;
881 pipeline_msg_req_handle(p);
882 rte_pipeline_flush(p->p);
888 pipeline_txrx_track(void *pipeline, uint32_t port_in, uint32_t *port_out)
890 struct pipeline *p = (struct pipeline *)pipeline;
892 /* Check input arguments */
893 if ((p == NULL) || (port_in >= p->n_ports_in) || (port_out == NULL))
896 *port_out = port_in / p->n_ports_in;
900 struct pipeline_be_ops pipeline_txrx_be_ops = {
901 .f_init = pipeline_txrx_init,
902 .f_free = pipeline_txrx_free,
904 .f_timer = pipeline_txrx_timer,
905 .f_track = pipeline_txrx_track,