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.
26 #include <rte_common.h>
27 #include <rte_malloc.h>
29 #include <rte_byteorder.h>
30 #include <rte_table_stub.h>
31 #include <rte_table_hash.h>
32 #include <rte_pipeline.h>
36 #include <rte_jhash.h>
37 #include <rte_cycles.h>
38 #include <rte_hexdump.h>
39 #include "pipeline_actions_common.h"
40 #include "hash_func.h"
41 #include "vnf_common.h"
42 #include "pipeline_common_be.h"
43 #include "pipeline_arpicmp_be.h"
45 #include "hash_func.h"
46 #include "vnf_common.h"
49 #include"pipeline_common_fe.h"
51 #include "lib_icmpv6.h"
52 #include "interface.h"
55 /* Shared among all VNFs including LB */
56 struct app_params *myApp;
57 struct rte_pipeline *myP;
58 struct pipeline_arpicmp *gp_arp;
59 uint8_t num_vnf_threads;
61 struct pipeline_arpicmp {
63 pipeline_msg_req_handler
64 custom_handlers[PIPELINE_ARPICMP_MSG_REQS];
65 uint64_t receivedPktCount;
66 uint64_t droppedPktCount;
67 uint64_t sentPktCount;
68 uint8_t links_map[PIPELINE_MAX_PORT_IN];
69 uint8_t outport_id[PIPELINE_MAX_PORT_IN];
71 } __rte_cache_aligned;
73 void pipelines_port_info(void)
75 struct app_params *app = myApp;
77 for (pipeline = 0; pipeline < app->n_pipelines; pipeline++) {
78 printf("*** PIPELINE %d ***\n\n", pipeline);
80 printf("*** OUTPORTs ***\n");
81 for (i = 1; i < app->pipeline_params[pipeline].n_pktq_out;
83 switch (app->pipeline_params[pipeline].pktq_out[i].
85 case APP_PKTQ_OUT_SWQ:
86 printf("pktq_out[%d]:%s\n", i,
87 app->swq_params[app->pipeline_params
89 pktq_out[i].id].name);
91 case APP_PKTQ_OUT_HWQ:
92 printf("pktq_out[%d]:%s\n", i,
93 app->hwq_out_params[app->pipeline_params
98 printf("Not OUT SWQ or HWQ\n");
101 printf("*** INPORTs ***\n");
102 for (i = 0; i < app->pipeline_params[pipeline].n_pktq_in; i++) {
103 switch (app->pipeline_params[pipeline].pktq_in[i]
105 case APP_PKTQ_IN_SWQ:
106 printf("pktq_in[%d]:%s\n", i,
107 app->swq_params[app->pipeline_params
109 pktq_in[i].id].name);
111 case APP_PKTQ_IN_HWQ:
112 printf("pktq_in[%d]:%s\n", i,
113 app->hwq_in_params[app->pipeline_params
115 pktq_in[i].id].name);
118 printf("Not IN SWQ or HWQ\n");
124 void pipelines_map_info(void)
128 printf("PIPELINE_MAX_PORT_IN %d\n", PIPELINE_MAX_PORT_IN);
129 printf("lb_outport_id[%d", lb_outport_id[0]);
130 for (i = 1; i < PIPELINE_MAX_PORT_IN; i++)
131 printf(",%d", lb_outport_id[i]);
134 printf("vnf_to_loadb_map[%d", vnf_to_loadb_map[0]);
135 for (i = 1; i < PIPELINE_MAX_PORT_IN; i++)
136 printf(",%d", vnf_to_loadb_map[i]);
139 printf("port_to_loadb_map[%d", port_to_loadb_map[0]);
140 for (i = 1; i < PIPELINE_MAX_PORT_IN; i++)
141 printf(",%d", port_to_loadb_map[i]);
144 printf("loadb_pipeline_nums[%d", loadb_pipeline_nums[0]);
145 for (i = 1; i < PIPELINE_MAX_PORT_IN; i++)
146 printf(",%d", loadb_pipeline_nums[i]);
149 printf("loadb_pipeline[%p", loadb_pipeline[0]);
150 for (i = 1; i < PIPELINE_MAX_PORT_IN; i++)
151 printf(",%p", loadb_pipeline[i]);
155 void register_pipeline_Qs(uint8_t pipeline_num, struct pipeline *p)
157 struct rte_port_ethdev_reader *hwq;
158 struct rte_port_ring_writer *out_swq;
159 struct rte_port_ring_reader *in_swq;
160 struct rte_pipeline *rte = p->p;
161 uint8_t port_count = 0;
162 int queue_out = 0xff, queue_in = 0xff;
164 printf("Calling register_pipeline_Qs in PIPELINE%d\n", pipeline_num);
165 for (port_count = 0; port_count < rte->num_ports_out; port_count++) {
167 switch (myApp->pipeline_params[pipeline_num].
168 pktq_out[port_count].type){
170 case APP_PKTQ_OUT_SWQ:
172 if (port_count >= rte->num_ports_in) {
174 /* Dont register ARP output Q */
175 if (rte->num_ports_out % rte->num_ports_in)
176 if (port_count == rte->num_ports_out - 1)
179 temp = ((port_count) % rte->num_ports_in);
181 in_swq = rte->ports_in[temp].h_port;
182 out_swq = rte->ports_out[port_count].h_port;
183 printf("in_swq : %s\n",
186 sscanf(in_swq->ring->name, "SWQ%d",
189 printf("Unable to read SWQ number\n");
192 printf("out_swq: %s\n",
193 out_swq->ring->name);
195 sscanf(out_swq->ring->name, "SWQ%d",
198 printf("Unable to read SWQ number\n");
201 if (queue_in < 128 && queue_out < 128) {
202 SWQ_to_Port_map[queue_out] =
203 SWQ_to_Port_map[queue_in];
204 printf("SWQ_to_Port_map[%d]%d\n", queue_out,
205 SWQ_to_Port_map[queue_out]);
210 switch (myApp->pipeline_params[pipeline_num].
211 pktq_in[port_count].type){
213 case APP_PKTQ_IN_HWQ:
214 hwq = rte->ports_in[port_count].h_port;
215 out_swq = rte->ports_out[port_count].h_port;
216 printf("out_swq: %s\n",
217 out_swq->ring->name);
219 sscanf(out_swq->ring->name, "SWQ%d",
223 printf("Unable to read SWQ number\n");
226 if (queue_out < 128) {
227 SWQ_to_Port_map[queue_out] = hwq->port_id;
228 printf("SWQ_to_Port_map[%d]%d\n", queue_out,
229 SWQ_to_Port_map[queue_out]);
233 case APP_PKTQ_IN_SWQ:
234 in_swq = rte->ports_in[port_count].h_port;
235 out_swq = rte->ports_out[port_count].h_port;
236 printf("in_swq : %s\n",
239 sscanf(in_swq->ring->name, "SWQ%d",
242 printf("Unable to read SWQ number\n");
245 printf("out_swq: %s\n",
246 out_swq->ring->name);
248 sscanf(out_swq->ring->name, "SWQ%d",
251 printf("Unable to read SWQ number\n");
254 if (queue_in < 128 && queue_out < 128){
255 SWQ_to_Port_map[queue_out] =
256 SWQ_to_Port_map[queue_in];
257 printf("SWQ_to_Port_map[%d]%d\n", queue_out,
258 SWQ_to_Port_map[queue_out]);
263 printf("This never hits\n");
268 case APP_PKTQ_OUT_HWQ:
269 printf("This is HWQ\n");
273 printf("set_phy_outport_map: This never hits\n");
278 void set_link_map(uint8_t pipeline_num, struct pipeline *p, uint8_t *map)
280 struct rte_port_ethdev_writer *hwq;
281 struct rte_port_ring_writer *out_swq;
282 struct rte_pipeline *rte = p->p;
284 uint8_t port_count = 0;
285 int index = 0, queue_out = 0xff;
287 printf("Calling set_link_map in PIPELINE%d\n", pipeline_num);
288 for (port_count = 0; port_count < rte->num_ports_out; port_count++) {
290 switch (myApp->pipeline_params[pipeline_num].
291 pktq_out[port_count].type){
293 case APP_PKTQ_OUT_HWQ:
294 hwq = rte->ports_out[port_count].h_port;
295 map[index++] = hwq->port_id;
296 printf("links_map[%d]:%d\n", index - 1, map[index - 1]);
299 case APP_PKTQ_OUT_SWQ:
300 out_swq = rte->ports_out[port_count].h_port;
301 printf("set_link_map out_swq: %s\n",
302 out_swq->ring->name);
303 int status = sscanf(out_swq->ring->name, "SWQ%d",
306 printf("Unable to read SWQ number\n");
310 if (queue_out < 128) {
311 map[index++] = SWQ_to_Port_map[queue_out];
312 printf("links_map[%s]:%d\n", out_swq->ring->name,
318 printf("set_phy_outport_map: This never hits\n");
323 void set_outport_id(uint8_t pipeline_num, struct pipeline *p, uint8_t *map)
325 uint8_t port_count = 0;
326 int queue_out = 0xff, index = 0;
328 struct rte_port_ethdev_writer *hwq;
329 struct rte_port_ring_writer *out_swq;
330 struct rte_pipeline *rte = p->p;
332 printf("\n**** set_outport_id() with pipeline_num:%d ****\n\n",
335 port_count < rte->num_ports_out;
338 switch (myApp->pipeline_params[pipeline_num].
339 pktq_out[port_count].type) {
341 case APP_PKTQ_OUT_HWQ:
342 hwq = rte->ports_out[port_count].h_port;
345 map[hwq->port_id] = index;
346 printf("hwq port_id:%d index:%d\n",
347 hwq->port_id, index);
348 map[hwq->port_id] = index++;
349 printf("hwq port_id:%d index:%d\n",
350 hwq->port_id, index-1);
351 printf("outport_id[%d]:%d\n", index - 1,
356 case APP_PKTQ_OUT_SWQ:
358 /* Dont register ARP output Q */
359 if (port_count >= rte->num_ports_in)
360 if (rte->num_ports_out % rte->num_ports_in)
361 if (port_count == rte->num_ports_out - 1)
363 out_swq = rte->ports_out[port_count].h_port;
364 printf("set_outport_id out_swq: %s\n",
365 out_swq->ring->name);
366 int temp = sscanf(out_swq->ring->name, "SWQ%d",
369 printf("Unable to read SWQ number\n");
373 if (queue_out < 128 && index >= 0) {
374 map[SWQ_to_Port_map[queue_out]] = index++;
375 printf("outport_id[%s]:%d\n", out_swq->ring->name,
376 map[SWQ_to_Port_map[queue_out]]);
387 void set_phy_outport_id(uint8_t pipeline_num, struct pipeline *p, uint8_t *map)
389 uint8_t port_count = 0;
392 struct rte_port_ethdev_writer *hwq;
393 struct rte_pipeline *rte = p->p;
395 printf("\n**** set_phy_outport_id() with pipeline_num:%d ****\n\n",
398 port_count < myApp->pipeline_params[pipeline_num].n_pktq_out;
401 switch (myApp->pipeline_params[pipeline_num].
402 pktq_out[port_count].type) {
404 case APP_PKTQ_OUT_HWQ:
405 hwq = rte->ports_out[port_count].h_port;
406 map[hwq->port_id] = index++;
407 printf("outport_id[%d]:%d\n", index - 1,
418 void set_phy_inport_id(uint8_t pipeline_num, struct pipeline *p, uint8_t *map)
420 uint8_t port_count = 0;
423 struct rte_port_ethdev_reader *hwq;
424 struct rte_pipeline *rte = p->p;
426 printf("\n**** set_phy_inport_id() with pipeline_num:%d ****\n\n",
429 port_count < myApp->pipeline_params[pipeline_num].n_pktq_in;
432 switch (myApp->pipeline_params[pipeline_num].
433 pktq_in[port_count].type) {
435 case APP_PKTQ_IN_HWQ:
436 hwq = rte->ports_in[port_count].h_port;
437 map[hwq->port_id] = index++;
438 printf("outport_id[%d]:%d\n", index - 1,
449 static void *pipeline_arpicmp_msg_req_custom_handler(struct pipeline *p,
452 static pipeline_msg_req_handler handlers[] = {
453 [PIPELINE_MSG_REQ_PING] =
454 pipeline_msg_req_ping_handler,
455 [PIPELINE_MSG_REQ_STATS_PORT_IN] =
456 pipeline_msg_req_stats_port_in_handler,
457 [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
458 pipeline_msg_req_stats_port_out_handler,
459 [PIPELINE_MSG_REQ_STATS_TABLE] =
460 pipeline_msg_req_stats_table_handler,
461 [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
462 pipeline_msg_req_port_in_enable_handler,
463 [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
464 pipeline_msg_req_port_in_disable_handler,
465 [PIPELINE_MSG_REQ_CUSTOM] =
466 pipeline_arpicmp_msg_req_custom_handler,
470 static void *pipeline_arpicmp_msg_req_entry_dbg_handler(struct pipeline *p,
472 static void *pipeline_arpicmp_msg_req_entry_dbg_handler(
473 __rte_unused struct pipeline *p,
474 __rte_unused void *msg)
476 /*have to handle dbg commands*/
480 static __rte_unused pipeline_msg_req_handler custom_handlers[] = {
481 [PIPELINE_ARPICMP_MSG_REQ_ENTRY_DBG] =
482 pipeline_arpicmp_msg_req_entry_dbg_handler,
486 * Function for pipeline custom handlers
489 * A void pointer to pipeline
491 * void pointer for incoming data
494 * void pointer of response
496 void *pipeline_arpicmp_msg_req_custom_handler(struct pipeline *p, void *msg)
498 struct pipeline_arpicmp *p_arp = (struct pipeline_arpicmp *)p;
499 struct pipeline_custom_msg_req *req = msg;
500 pipeline_msg_req_handler f_handle;
502 f_handle = (req->subtype < PIPELINE_ARPICMP_MSG_REQS) ?
503 p_arp->custom_handlers[req->subtype] :
504 pipeline_msg_req_invalid_handler;
506 if (f_handle == NULL)
507 f_handle = pipeline_msg_req_invalid_handler;
509 return f_handle(p, req);
512 uint32_t arpicmp_pkt_print_count;
514 pkt_key_arpicmp(struct rte_mbuf *pkt, uint32_t pkt_num, void *arg)
517 struct pipeline_arpicmp_in_port_h_arg *ap = arg;
518 struct pipeline_arpicmp *p_arp = (struct pipeline_arpicmp *)ap->p;
520 p_arp->receivedPktCount++;
522 uint8_t in_port_id = pkt->port;
524 uint32_t pkt_mask = 1 << pkt_num;
525 uint32_t eth_proto_offset = MBUF_HDR_ROOM + 12;
527 uint32_t prot_offset =
528 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_PROTOCOL_OFST;
530 uint16_t *eth_proto =
531 RTE_MBUF_METADATA_UINT16_PTR(pkt, eth_proto_offset);
533 /* header room + eth hdr size + src_aadr offset in ip header */
535 uint32_t prot_offset_ipv6 =
536 MBUF_HDR_ROOM + ETH_HDR_SIZE + IPV6_HDR_PROTOCOL_OFST;
538 if (rte_be_to_cpu_16(*eth_proto) == ETHER_TYPE_IPv6)
539 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt, prot_offset_ipv6);
541 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt, prot_offset);
543 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt, prot_offset);
546 if ((ARPICMP_DEBUG > 2) && (arpicmp_pkt_print_count < 10)) {
548 arpicmp_pkt_print_count++;
549 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
550 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
551 rte_be_to_cpu_16(*eth_proto), *protocol, ETH_TYPE_ARP,
552 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
555 /* Classifier for ICMP pass-through*/
556 if ((rte_be_to_cpu_16(*eth_proto) == ETH_TYPE_ARP) ||
557 ((rte_be_to_cpu_16(*eth_proto) == ETH_TYPE_IPV4)
558 && (*protocol == IP_PROTOCOL_ICMP)
560 process_arpicmp_pkt(pkt, ifm_get_port(in_port_id));
564 else if ((rte_be_to_cpu_16(*eth_proto) == ETH_TYPE_IPV6)
565 && (*protocol == ICMPV6_PROTOCOL_ID)) {
566 process_icmpv6_pkt(pkt, ifm_get_port(in_port_id));
571 /* Drop the pkt if not ARP/ICMP */
572 rte_pipeline_ah_packet_drop(p_arp->p.p, pkt_mask);
573 p_arp->droppedPktCount++;
578 pkt4_key_arpicmp(struct rte_mbuf **pkt, uint32_t pkt_num, void *arg)
581 struct pipeline_arpicmp_in_port_h_arg *ap = arg;
582 struct pipeline_arpicmp *p_arp = (struct pipeline_arpicmp *)ap->p;
583 p_arp->receivedPktCount += 4;
585 uint32_t eth_proto_offset = MBUF_HDR_ROOM + 12;
586 uint8_t in_port_id = pkt[0]->port;
588 uint32_t prot_offset =
589 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_PROTOCOL_OFST;
591 /* header room + eth hdr size + src_aadr offset in ip header */
592 uint32_t pkt_mask0 = 1 << pkt_num;
593 uint32_t pkt_mask1 = 1 << (pkt_num + 1);
594 uint32_t pkt_mask2 = 1 << (pkt_num + 2);
595 uint32_t pkt_mask3 = 1 << (pkt_num + 3);
597 uint16_t *eth_proto0 =
598 RTE_MBUF_METADATA_UINT16_PTR(pkt[0], eth_proto_offset);
599 uint16_t *eth_proto1 =
600 RTE_MBUF_METADATA_UINT16_PTR(pkt[1], eth_proto_offset);
601 uint16_t *eth_proto2 =
602 RTE_MBUF_METADATA_UINT16_PTR(pkt[2], eth_proto_offset);
603 uint16_t *eth_proto3 =
604 RTE_MBUF_METADATA_UINT16_PTR(pkt[3], eth_proto_offset);
612 uint32_t prot_offset_ipv6 =
613 MBUF_HDR_ROOM + ETH_HDR_SIZE + IPV6_HDR_PROTOCOL_OFST;
619 if (rte_be_to_cpu_16(*eth_proto0) == ETHER_TYPE_IPv6)
621 RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset_ipv6);
623 protocol0 = RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset);
626 if (rte_be_to_cpu_16(*eth_proto1) == ETHER_TYPE_IPv6)
628 RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset_ipv6);
630 protocol1 = RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset);
633 if (rte_be_to_cpu_16(*eth_proto2) == ETHER_TYPE_IPv6)
635 RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset_ipv6);
637 protocol2 = RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset);
640 if (rte_be_to_cpu_16(*eth_proto3) == ETHER_TYPE_IPv6)
642 RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset_ipv6);
644 protocol3 = RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset);
646 protocol0 = RTE_MBUF_METADATA_UINT8_PTR(pkt[0], prot_offset);
647 protocol1 = RTE_MBUF_METADATA_UINT8_PTR(pkt[1], prot_offset);
648 protocol2 = RTE_MBUF_METADATA_UINT8_PTR(pkt[2], prot_offset);
649 protocol3 = RTE_MBUF_METADATA_UINT8_PTR(pkt[3], prot_offset);
652 if ((ARPICMP_DEBUG > 2) && (arpicmp_pkt_print_count < 10)) {
654 arpicmp_pkt_print_count++;
655 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
656 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
657 rte_be_to_cpu_16(*eth_proto0), *protocol0, ETH_TYPE_ARP,
658 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
662 if ((rte_be_to_cpu_16(*eth_proto0) == ETH_TYPE_ARP) ||
663 ((rte_be_to_cpu_16(*eth_proto0) == ETH_TYPE_IPV4)
664 && (*protocol0 == IP_PROTOCOL_ICMP)
666 process_arpicmp_pkt(pkt[0], ifm_get_port(in_port_id));
671 else if ((rte_be_to_cpu_16(*eth_proto0) == ETH_TYPE_IPV6)
672 && (*protocol0 == ICMPV6_PROTOCOL_ID)) {
673 process_icmpv6_pkt(pkt[0], ifm_get_port(in_port_id));
679 /* Drop the pkt if not ARP/ICMP */
680 rte_pipeline_ah_packet_drop(p_arp->p.p, pkt_mask0);
681 p_arp->droppedPktCount++;
684 if ((ARPICMP_DEBUG > 2) && (arpicmp_pkt_print_count < 10)) {
686 arpicmp_pkt_print_count++;
687 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
688 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
689 rte_be_to_cpu_16(*eth_proto1), *protocol1, ETH_TYPE_ARP,
690 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
693 if ((rte_be_to_cpu_16(*eth_proto1) == ETH_TYPE_ARP) ||
694 ((rte_be_to_cpu_16(*eth_proto1) == ETH_TYPE_IPV4)
695 && (*protocol1 == IP_PROTOCOL_ICMP)
697 process_arpicmp_pkt(pkt[1], ifm_get_port(in_port_id));
701 else if ((rte_be_to_cpu_16(*eth_proto1) == ETH_TYPE_IPV6)
702 && (*protocol1 == ICMPV6_PROTOCOL_ID)) {
703 process_icmpv6_pkt(pkt[1], ifm_get_port(in_port_id));
709 /* Drop the pkt if not ARP/ICMP */
710 rte_pipeline_ah_packet_drop(p_arp->p.p, pkt_mask1);
711 p_arp->droppedPktCount++;
714 if ((ARPICMP_DEBUG > 2) && (arpicmp_pkt_print_count < 10)) {
716 arpicmp_pkt_print_count++;
717 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
718 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
719 rte_be_to_cpu_16(*eth_proto2), *protocol2, ETH_TYPE_ARP,
720 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
723 if ((rte_be_to_cpu_16(*eth_proto2) == ETH_TYPE_ARP) ||
724 ((rte_be_to_cpu_16(*eth_proto2) == ETH_TYPE_IPV4)
725 && (*protocol2 == IP_PROTOCOL_ICMP)
727 process_arpicmp_pkt(pkt[2], ifm_get_port(in_port_id));
731 else if ((rte_be_to_cpu_16(*eth_proto2) == ETH_TYPE_IPV6)
732 && (*protocol2 == ICMPV6_PROTOCOL_ID)) {
733 process_icmpv6_pkt(pkt[2], ifm_get_port(in_port_id));
739 /* Drop the pkt if not ARP/ICMP */
740 rte_pipeline_ah_packet_drop(p_arp->p.p, pkt_mask2);
741 p_arp->droppedPktCount++;
744 if ((ARPICMP_DEBUG > 2) && (arpicmp_pkt_print_count < 10)) {
746 arpicmp_pkt_print_count++;
747 printf("\nEth Typ %x, Prot %x, ETH_TYPE_ARP %x, "
748 "ETH_TYPE_IPV4 %x, IP_PROTOCOL_ICMP %x\n",
749 rte_be_to_cpu_16(*eth_proto3), *protocol3, ETH_TYPE_ARP,
750 ETH_TYPE_IPV4, IP_PROTOCOL_ICMP);
753 if ((rte_be_to_cpu_16(*eth_proto3) == ETH_TYPE_ARP) ||
754 ((rte_be_to_cpu_16(*eth_proto3) == ETH_TYPE_IPV4)
755 && (*protocol3 == IP_PROTOCOL_ICMP)
758 process_arpicmp_pkt(pkt[3], ifm_get_port(in_port_id));
763 else if ((rte_be_to_cpu_16(*eth_proto3) == ETH_TYPE_IPV6)
764 && (*protocol3 == ICMPV6_PROTOCOL_ID)) {
766 process_icmpv6_pkt(pkt[3], ifm_get_port(in_port_id));
771 /* Drop the pkt if not ARP/ICMP */
772 rte_pipeline_ah_packet_drop(p_arp->p.p, pkt_mask3);
773 p_arp->droppedPktCount++;
778 PIPELINE_ARPICMP_KEY_PORT_IN_AH(
783 static void *pipeline_arpicmp_init(struct pipeline_params *params,
784 __rte_unused void *arg)
787 struct pipeline_arpicmp *p_arp;
788 uint32_t size, i, in_ports_arg_size;
790 printf("Start pipeline_arpicmp_init\n");
792 /* Check input arguments */
793 if ((params == NULL) ||
794 (params->n_ports_in == 0) ||
795 (params->n_ports_out == 0))
798 /* Memory allocation */
799 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_arpicmp));
800 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
801 p_arp = (struct pipeline_arpicmp *)p;
806 struct app_params *app = (struct app_params *)arg;
809 PLOG(p, HIGH, "ARPICMP");
810 strcpy(p->name, params->name);
811 p->log_level = params->log_level;
813 p_arp->receivedPktCount = 0;
814 p_arp->droppedPktCount = 0;
815 gw_init(rte_eth_dev_count());
816 lib_arp_init(params, app);
820 struct rte_pipeline_params pipeline_params = {
822 .socket_id = params->socket_id,
824 //.offset_port_id = arp_meta_offset,
827 p->p = rte_pipeline_create(&pipeline_params);
834 p->n_ports_in = params->n_ports_in;
835 p->n_ports_out = params->n_ports_out;
838 /* Memory allocation for in_port_h_arg */
839 in_ports_arg_size = RTE_CACHE_LINE_ROUNDUP(
840 (sizeof(struct pipeline_arpicmp_in_port_h_arg)) *
841 (params->n_ports_in));
842 struct pipeline_arpicmp_in_port_h_arg *ap =
843 (struct pipeline_arpicmp_in_port_h_arg *)rte_zmalloc(NULL,
845 RTE_CACHE_LINE_SIZE);
850 for (i = 0; i < p->n_ports_in; i++) {
851 /* passing our txrx pipeline in call back arg */
853 (ap[i]).in_port_id = i;
854 struct rte_pipeline_port_in_params port_params = {
856 pipeline_port_in_params_get_ops(¶ms->
859 pipeline_port_in_params_convert(¶ms->
863 .burst_size = params->port_in[i].burst_size,
866 port_params.f_action = port_in_ah_arpicmp;
868 int status = rte_pipeline_port_in_create(p->p,
873 rte_pipeline_free(p->p);
880 for (i = 0; i < p->n_ports_out; i++) {
881 struct rte_pipeline_port_out_params port_params = {
883 pipeline_port_out_params_get_ops(¶ms->
886 pipeline_port_out_params_convert(¶ms->
892 int status = rte_pipeline_port_out_create(p->p,
897 rte_pipeline_free(p->p);
902 int pipeline_num = 0;
904 int status = sscanf(params->name, "PIPELINE%d", &pipeline_num);
908 printf("Unable to read pipeline number\n");
911 p_arp->pipeline_num = (uint8_t) pipeline_num;
913 register_pipeline_Qs(p_arp->pipeline_num, p);
914 set_phy_outport_id(p_arp->pipeline_num, p, p_arp->outport_id);
918 struct rte_pipeline_table_params table_params = {
919 .ops = &rte_table_stub_ops,
921 .f_action_hit = NULL,
922 .f_action_miss = NULL,
924 .action_data_size = 0,
927 int status = rte_pipeline_table_create(p->p,
932 rte_pipeline_free(p->p);
938 /* Connecting input ports to tables */
939 for (i = 0; i < p->n_ports_in; i++) {
941 int status = rte_pipeline_port_in_connect_to_table(p->p,
949 rte_pipeline_free(p->p);
956 /* Enable input ports */
957 for (i = 0; i < p->n_ports_in; i++) {
958 int status = rte_pipeline_port_in_enable(p->p,
962 rte_pipeline_free(p->p);
968 /* Check pipeline consistency */
969 if (rte_pipeline_check(p->p) < 0) {
970 rte_pipeline_free(p->p);
976 p->n_msgq = params->n_msgq;
977 for (i = 0; i < p->n_msgq; i++)
978 p->msgq_in[i] = params->msgq_in[i];
979 for (i = 0; i < p->n_msgq; i++)
980 p->msgq_out[i] = params->msgq_out[i];
982 /* Message handlers */
983 memcpy(p->handlers, handlers, sizeof(p->handlers));
988 static int pipeline_arpicmp_free(void *pipeline)
990 struct pipeline *p = (struct pipeline *)pipeline;
992 /* Check input arguments */
997 rte_pipeline_free(p->p);
1002 static int pipeline_arpicmp_timer(void *pipeline)
1004 struct pipeline *p = (struct pipeline *)pipeline;
1006 pipeline_msg_req_handle(p);
1007 rte_pipeline_flush(p->p);
1013 pipeline_arpicmp_track(void *pipeline, uint32_t port_in, uint32_t *port_out)
1015 struct pipeline *p = (struct pipeline *)pipeline;
1017 /* Check input arguments */
1018 if ((p == NULL) || (port_in >= p->n_ports_in) || (port_out == NULL))
1021 *port_out = port_in / p->n_ports_in;
1025 struct pipeline_be_ops pipeline_arpicmp_be_ops = {
1026 .f_init = pipeline_arpicmp_init,
1027 .f_free = pipeline_arpicmp_free,
1029 .f_timer = pipeline_arpicmp_timer,
1030 .f_track = pipeline_arpicmp_track,