4 * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include <rte_common.h>
41 #include <rte_malloc.h>
43 #include <rte_byteorder.h>
44 #include <rte_table_lpm.h>
45 #include <rte_table_hash.h>
46 #include <rte_pipeline.h>
48 #include "pipeline_routing_be.h"
49 #include "pipeline_actions_common.h"
51 #include "hash_func.h"
53 #define MPLS_LABEL(label, exp, s, ttl) \
54 (((((uint64_t) (label)) & 0xFFFFFLLU) << 12) | \
55 ((((uint64_t) (exp)) & 0x7LLU) << 9) | \
56 ((((uint64_t) (s)) & 0x1LLU) << 8) | \
57 (((uint64_t) (ttl)) & 0xFFLU))
59 #define RTE_SCHED_PORT_HIERARCHY(subport, pipe, \
60 traffic_class, queue, color) \
61 ((((uint64_t) (queue)) & 0x3) | \
62 ((((uint64_t) (traffic_class)) & 0x3) << 2) | \
63 ((((uint64_t) (color)) & 0x3) << 4) | \
64 ((((uint64_t) (subport)) & 0xFFFF) << 16) | \
65 ((((uint64_t) (pipe)) & 0xFFFFFFFF) << 32))
68 /* Network Byte Order (NBO) */
69 #define SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr, ethertype) \
70 (((uint64_t) macaddr) | (((uint64_t) rte_cpu_to_be_16(ethertype)) << 48))
72 #ifndef PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s
73 #define PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s 256
76 struct pipeline_routing
{
78 struct pipeline_routing_params params
;
79 pipeline_msg_req_handler custom_handlers
[PIPELINE_ROUTING_MSG_REQS
];
80 uint64_t macaddr
[PIPELINE_MAX_PORT_OUT
];
81 } __rte_cache_aligned
;
87 pipeline_routing_msg_req_custom_handler(struct pipeline
*p
, void *msg
);
89 static pipeline_msg_req_handler handlers
[] = {
90 [PIPELINE_MSG_REQ_PING
] =
91 pipeline_msg_req_ping_handler
,
92 [PIPELINE_MSG_REQ_STATS_PORT_IN
] =
93 pipeline_msg_req_stats_port_in_handler
,
94 [PIPELINE_MSG_REQ_STATS_PORT_OUT
] =
95 pipeline_msg_req_stats_port_out_handler
,
96 [PIPELINE_MSG_REQ_STATS_TABLE
] =
97 pipeline_msg_req_stats_table_handler
,
98 [PIPELINE_MSG_REQ_PORT_IN_ENABLE
] =
99 pipeline_msg_req_port_in_enable_handler
,
100 [PIPELINE_MSG_REQ_PORT_IN_DISABLE
] =
101 pipeline_msg_req_port_in_disable_handler
,
102 [PIPELINE_MSG_REQ_CUSTOM
] =
103 pipeline_routing_msg_req_custom_handler
,
107 pipeline_routing_msg_req_route_add_handler(struct pipeline
*p
,
111 pipeline_routing_msg_req_route_del_handler(struct pipeline
*p
,
115 pipeline_routing_msg_req_route_add_default_handler(struct pipeline
*p
,
119 pipeline_routing_msg_req_route_del_default_handler(struct pipeline
*p
,
123 pipeline_routing_msg_req_arp_add_handler(struct pipeline
*p
,
127 pipeline_routing_msg_req_arp_del_handler(struct pipeline
*p
,
131 pipeline_routing_msg_req_arp_add_default_handler(struct pipeline
*p
,
135 pipeline_routing_msg_req_arp_del_default_handler(struct pipeline
*p
,
139 pipeline_routing_msg_req_set_macaddr_handler(struct pipeline
*p
,
142 static pipeline_msg_req_handler custom_handlers
[] = {
143 [PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD
] =
144 pipeline_routing_msg_req_route_add_handler
,
145 [PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL
] =
146 pipeline_routing_msg_req_route_del_handler
,
147 [PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT
] =
148 pipeline_routing_msg_req_route_add_default_handler
,
149 [PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT
] =
150 pipeline_routing_msg_req_route_del_default_handler
,
151 [PIPELINE_ROUTING_MSG_REQ_ARP_ADD
] =
152 pipeline_routing_msg_req_arp_add_handler
,
153 [PIPELINE_ROUTING_MSG_REQ_ARP_DEL
] =
154 pipeline_routing_msg_req_arp_del_handler
,
155 [PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT
] =
156 pipeline_routing_msg_req_arp_add_default_handler
,
157 [PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT
] =
158 pipeline_routing_msg_req_arp_del_default_handler
,
159 [PIPELINE_ROUTING_MSG_REQ_SET_MACADDR
] =
160 pipeline_routing_msg_req_set_macaddr_handler
,
166 struct routing_table_entry
{
167 struct rte_pipeline_table_entry head
;
169 uint32_t port_id
; /* Output port ID */
170 uint32_t ip
; /* Next hop IP address (only valid for remote routes) */
173 uint16_t data_offset
;
174 uint16_t ether_l2_length
;
176 uint16_t slab_offset
[4];
183 } __attribute__((__packed__
));
185 #define MACADDR_DST_WRITE(slab_ptr, slab) \
187 struct layout *dst = (struct layout *) (slab_ptr); \
188 struct layout *src = (struct layout *) &(slab); \
194 static inline __attribute__((always_inline
)) void
196 struct rte_mbuf
*pkt
,
197 struct rte_pipeline_table_entry
*table_entry
,
205 struct pipeline_routing
*p_rt
= arg
;
207 struct routing_table_entry
*entry
=
208 (struct routing_table_entry
*) table_entry
;
210 struct ipv4_hdr
*ip
= (struct ipv4_hdr
*)
211 RTE_MBUF_METADATA_UINT8_PTR(pkt
, p_rt
->params
.ip_hdr_offset
);
213 enum rte_meter_color pkt_color
= (enum rte_meter_color
)
214 RTE_MBUF_METADATA_UINT32(pkt
, p_rt
->params
.color_offset
);
216 struct pipeline_routing_arp_key_ipv4
*arp_key
=
217 (struct pipeline_routing_arp_key_ipv4
*)
218 RTE_MBUF_METADATA_UINT8_PTR(pkt
, p_rt
->params
.arp_key_offset
);
220 uint64_t *slab0_ptr
, *slab1_ptr
, *slab2_ptr
, *slab3_ptr
, sched
;
221 uint32_t ip_da
, nh_ip
, port_id
;
222 uint16_t total_length
, data_offset
, ether_l2_length
;
225 total_length
= rte_bswap16(ip
->total_length
);
226 ip_da
= ip
->dst_addr
;
227 data_offset
= entry
->data_offset
;
228 ether_l2_length
= entry
->ether_l2_length
;
229 slab0_ptr
= RTE_MBUF_METADATA_UINT64_PTR(pkt
, entry
->slab_offset
[0]);
230 slab1_ptr
= RTE_MBUF_METADATA_UINT64_PTR(pkt
, entry
->slab_offset
[1]);
231 slab2_ptr
= RTE_MBUF_METADATA_UINT64_PTR(pkt
, entry
->slab_offset
[2]);
232 slab3_ptr
= RTE_MBUF_METADATA_UINT64_PTR(pkt
, entry
->slab_offset
[3]);
235 port_id
= entry
->port_id
;
237 if (entry
->flags
& PIPELINE_ROUTING_ROUTE_LOCAL
)
242 total_length
+= ether_l2_length
;
244 if (qinq
&& qinq_sched
) {
245 uint32_t dscp
= ip
->type_of_service
>> 2;
246 uint32_t svlan
, cvlan
, tc
, tc_q
;
248 if (qinq_sched
== 1) {
249 uint64_t slab_qinq
= rte_bswap64(entry
->slab
[0]);
251 svlan
= (slab_qinq
>> 48) & 0xFFF;
252 cvlan
= (slab_qinq
>> 16) & 0xFFF;
253 tc
= (dscp
>> 2) & 0x3;
256 uint32_t ip_src
= rte_bswap32(ip
->src_addr
);
259 cvlan
= (ip_src
>> 16) & 0xFFF;
260 tc
= (ip_src
>> 2) & 0x3;
263 sched
= RTE_SCHED_PORT_HIERARCHY(svlan
,
271 pkt
->data_off
= data_offset
;
272 pkt
->data_len
= total_length
;
273 pkt
->pkt_len
= total_length
;
275 if ((qinq
== 0) && (mpls
== 0)) {
276 *slab0_ptr
= entry
->slab
[0];
279 MACADDR_DST_WRITE(slab1_ptr
, entry
->slab
[1]);
283 *slab0_ptr
= entry
->slab
[0];
284 *slab1_ptr
= entry
->slab
[1];
287 MACADDR_DST_WRITE(slab2_ptr
, entry
->slab
[2]);
290 pkt
->hash
.sched
.lo
= sched
& 0xFFFFFFFF;
291 pkt
->hash
.sched
.hi
= sched
>> 32;
296 if (mpls_color_mark
) {
297 uint64_t mpls_exp
= rte_bswap64(
298 (MPLS_LABEL(0, pkt_color
, 0, 0) << 32) |
299 MPLS_LABEL(0, pkt_color
, 0, 0));
301 *slab0_ptr
= entry
->slab
[0] | mpls_exp
;
302 *slab1_ptr
= entry
->slab
[1] | mpls_exp
;
303 *slab2_ptr
= entry
->slab
[2];
305 *slab0_ptr
= entry
->slab
[0];
306 *slab1_ptr
= entry
->slab
[1];
307 *slab2_ptr
= entry
->slab
[2];
311 MACADDR_DST_WRITE(slab3_ptr
, entry
->slab
[3]);
315 arp_key
->port_id
= port_id
;
320 static inline __attribute__((always_inline
)) void
322 struct rte_mbuf
**pkts
,
323 struct rte_pipeline_table_entry
**table_entries
,
331 struct pipeline_routing
*p_rt
= arg
;
333 struct routing_table_entry
*entry0
=
334 (struct routing_table_entry
*) table_entries
[0];
335 struct routing_table_entry
*entry1
=
336 (struct routing_table_entry
*) table_entries
[1];
337 struct routing_table_entry
*entry2
=
338 (struct routing_table_entry
*) table_entries
[2];
339 struct routing_table_entry
*entry3
=
340 (struct routing_table_entry
*) table_entries
[3];
342 struct ipv4_hdr
*ip0
= (struct ipv4_hdr
*)
343 RTE_MBUF_METADATA_UINT8_PTR(pkts
[0],
344 p_rt
->params
.ip_hdr_offset
);
345 struct ipv4_hdr
*ip1
= (struct ipv4_hdr
*)
346 RTE_MBUF_METADATA_UINT8_PTR(pkts
[1],
347 p_rt
->params
.ip_hdr_offset
);
348 struct ipv4_hdr
*ip2
= (struct ipv4_hdr
*)
349 RTE_MBUF_METADATA_UINT8_PTR(pkts
[2],
350 p_rt
->params
.ip_hdr_offset
);
351 struct ipv4_hdr
*ip3
= (struct ipv4_hdr
*)
352 RTE_MBUF_METADATA_UINT8_PTR(pkts
[3],
353 p_rt
->params
.ip_hdr_offset
);
355 enum rte_meter_color pkt0_color
= (enum rte_meter_color
)
356 RTE_MBUF_METADATA_UINT32(pkts
[0], p_rt
->params
.color_offset
);
357 enum rte_meter_color pkt1_color
= (enum rte_meter_color
)
358 RTE_MBUF_METADATA_UINT32(pkts
[1], p_rt
->params
.color_offset
);
359 enum rte_meter_color pkt2_color
= (enum rte_meter_color
)
360 RTE_MBUF_METADATA_UINT32(pkts
[2], p_rt
->params
.color_offset
);
361 enum rte_meter_color pkt3_color
= (enum rte_meter_color
)
362 RTE_MBUF_METADATA_UINT32(pkts
[3], p_rt
->params
.color_offset
);
364 struct pipeline_routing_arp_key_ipv4
*arp_key0
=
365 (struct pipeline_routing_arp_key_ipv4
*)
366 RTE_MBUF_METADATA_UINT8_PTR(pkts
[0],
367 p_rt
->params
.arp_key_offset
);
368 struct pipeline_routing_arp_key_ipv4
*arp_key1
=
369 (struct pipeline_routing_arp_key_ipv4
*)
370 RTE_MBUF_METADATA_UINT8_PTR(pkts
[1],
371 p_rt
->params
.arp_key_offset
);
372 struct pipeline_routing_arp_key_ipv4
*arp_key2
=
373 (struct pipeline_routing_arp_key_ipv4
*)
374 RTE_MBUF_METADATA_UINT8_PTR(pkts
[2],
375 p_rt
->params
.arp_key_offset
);
376 struct pipeline_routing_arp_key_ipv4
*arp_key3
=
377 (struct pipeline_routing_arp_key_ipv4
*)
378 RTE_MBUF_METADATA_UINT8_PTR(pkts
[3],
379 p_rt
->params
.arp_key_offset
);
381 uint64_t *slab0_ptr0
, *slab1_ptr0
, *slab2_ptr0
, *slab3_ptr0
;
382 uint64_t *slab0_ptr1
, *slab1_ptr1
, *slab2_ptr1
, *slab3_ptr1
;
383 uint64_t *slab0_ptr2
, *slab1_ptr2
, *slab2_ptr2
, *slab3_ptr2
;
384 uint64_t *slab0_ptr3
, *slab1_ptr3
, *slab2_ptr3
, *slab3_ptr3
;
385 uint64_t sched0
, sched1
, sched2
, sched3
;
387 uint32_t ip_da0
, nh_ip0
, port_id0
;
388 uint32_t ip_da1
, nh_ip1
, port_id1
;
389 uint32_t ip_da2
, nh_ip2
, port_id2
;
390 uint32_t ip_da3
, nh_ip3
, port_id3
;
392 uint16_t total_length0
, data_offset0
, ether_l2_length0
;
393 uint16_t total_length1
, data_offset1
, ether_l2_length1
;
394 uint16_t total_length2
, data_offset2
, ether_l2_length2
;
395 uint16_t total_length3
, data_offset3
, ether_l2_length3
;
398 total_length0
= rte_bswap16(ip0
->total_length
);
399 total_length1
= rte_bswap16(ip1
->total_length
);
400 total_length2
= rte_bswap16(ip2
->total_length
);
401 total_length3
= rte_bswap16(ip3
->total_length
);
403 ip_da0
= ip0
->dst_addr
;
404 ip_da1
= ip1
->dst_addr
;
405 ip_da2
= ip2
->dst_addr
;
406 ip_da3
= ip3
->dst_addr
;
408 data_offset0
= entry0
->data_offset
;
409 data_offset1
= entry1
->data_offset
;
410 data_offset2
= entry2
->data_offset
;
411 data_offset3
= entry3
->data_offset
;
413 ether_l2_length0
= entry0
->ether_l2_length
;
414 ether_l2_length1
= entry1
->ether_l2_length
;
415 ether_l2_length2
= entry2
->ether_l2_length
;
416 ether_l2_length3
= entry3
->ether_l2_length
;
418 slab0_ptr0
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[0],
419 entry0
->slab_offset
[0]);
420 slab1_ptr0
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[0],
421 entry0
->slab_offset
[1]);
422 slab2_ptr0
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[0],
423 entry0
->slab_offset
[2]);
424 slab3_ptr0
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[0],
425 entry0
->slab_offset
[3]);
427 slab0_ptr1
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[1],
428 entry1
->slab_offset
[0]);
429 slab1_ptr1
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[1],
430 entry1
->slab_offset
[1]);
431 slab2_ptr1
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[1],
432 entry1
->slab_offset
[2]);
433 slab3_ptr1
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[1],
434 entry1
->slab_offset
[3]);
436 slab0_ptr2
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[2],
437 entry2
->slab_offset
[0]);
438 slab1_ptr2
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[2],
439 entry2
->slab_offset
[1]);
440 slab2_ptr2
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[2],
441 entry2
->slab_offset
[2]);
442 slab3_ptr2
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[2],
443 entry2
->slab_offset
[3]);
445 slab0_ptr3
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[3],
446 entry3
->slab_offset
[0]);
447 slab1_ptr3
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[3],
448 entry3
->slab_offset
[1]);
449 slab2_ptr3
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[3],
450 entry3
->slab_offset
[2]);
451 slab3_ptr3
= RTE_MBUF_METADATA_UINT64_PTR(pkts
[3],
452 entry3
->slab_offset
[3]);
455 port_id0
= entry0
->port_id
;
457 if (entry0
->flags
& PIPELINE_ROUTING_ROUTE_LOCAL
)
460 port_id1
= entry1
->port_id
;
462 if (entry1
->flags
& PIPELINE_ROUTING_ROUTE_LOCAL
)
465 port_id2
= entry2
->port_id
;
467 if (entry2
->flags
& PIPELINE_ROUTING_ROUTE_LOCAL
)
470 port_id3
= entry3
->port_id
;
472 if (entry3
->flags
& PIPELINE_ROUTING_ROUTE_LOCAL
)
477 total_length0
+= ether_l2_length0
;
478 total_length1
+= ether_l2_length1
;
479 total_length2
+= ether_l2_length2
;
480 total_length3
+= ether_l2_length3
;
482 if (qinq
&& qinq_sched
) {
483 uint32_t dscp0
= ip0
->type_of_service
>> 2;
484 uint32_t dscp1
= ip1
->type_of_service
>> 2;
485 uint32_t dscp2
= ip2
->type_of_service
>> 2;
486 uint32_t dscp3
= ip3
->type_of_service
>> 2;
487 uint32_t svlan0
, cvlan0
, tc0
, tc_q0
;
488 uint32_t svlan1
, cvlan1
, tc1
, tc_q1
;
489 uint32_t svlan2
, cvlan2
, tc2
, tc_q2
;
490 uint32_t svlan3
, cvlan3
, tc3
, tc_q3
;
492 if (qinq_sched
== 1) {
493 uint64_t slab_qinq0
= rte_bswap64(entry0
->slab
[0]);
494 uint64_t slab_qinq1
= rte_bswap64(entry1
->slab
[0]);
495 uint64_t slab_qinq2
= rte_bswap64(entry2
->slab
[0]);
496 uint64_t slab_qinq3
= rte_bswap64(entry3
->slab
[0]);
498 svlan0
= (slab_qinq0
>> 48) & 0xFFF;
499 svlan1
= (slab_qinq1
>> 48) & 0xFFF;
500 svlan2
= (slab_qinq2
>> 48) & 0xFFF;
501 svlan3
= (slab_qinq3
>> 48) & 0xFFF;
503 cvlan0
= (slab_qinq0
>> 16) & 0xFFF;
504 cvlan1
= (slab_qinq1
>> 16) & 0xFFF;
505 cvlan2
= (slab_qinq2
>> 16) & 0xFFF;
506 cvlan3
= (slab_qinq3
>> 16) & 0xFFF;
508 tc0
= (dscp0
>> 2) & 0x3;
509 tc1
= (dscp1
>> 2) & 0x3;
510 tc2
= (dscp2
>> 2) & 0x3;
511 tc3
= (dscp3
>> 2) & 0x3;
518 uint32_t ip_src0
= rte_bswap32(ip0
->src_addr
);
519 uint32_t ip_src1
= rte_bswap32(ip1
->src_addr
);
520 uint32_t ip_src2
= rte_bswap32(ip2
->src_addr
);
521 uint32_t ip_src3
= rte_bswap32(ip3
->src_addr
);
528 cvlan0
= (ip_src0
>> 16) & 0xFFF;
529 cvlan1
= (ip_src1
>> 16) & 0xFFF;
530 cvlan2
= (ip_src2
>> 16) & 0xFFF;
531 cvlan3
= (ip_src3
>> 16) & 0xFFF;
533 tc0
= (ip_src0
>> 2) & 0x3;
534 tc1
= (ip_src1
>> 2) & 0x3;
535 tc2
= (ip_src2
>> 2) & 0x3;
536 tc3
= (ip_src3
>> 2) & 0x3;
538 tc_q0
= ip_src0
& 0x3;
539 tc_q1
= ip_src1
& 0x3;
540 tc_q2
= ip_src2
& 0x3;
541 tc_q3
= ip_src3
& 0x3;
544 sched0
= RTE_SCHED_PORT_HIERARCHY(svlan0
,
549 sched1
= RTE_SCHED_PORT_HIERARCHY(svlan1
,
554 sched2
= RTE_SCHED_PORT_HIERARCHY(svlan2
,
559 sched3
= RTE_SCHED_PORT_HIERARCHY(svlan3
,
568 pkts
[0]->data_off
= data_offset0
;
569 pkts
[1]->data_off
= data_offset1
;
570 pkts
[2]->data_off
= data_offset2
;
571 pkts
[3]->data_off
= data_offset3
;
573 pkts
[0]->data_len
= total_length0
;
574 pkts
[1]->data_len
= total_length1
;
575 pkts
[2]->data_len
= total_length2
;
576 pkts
[3]->data_len
= total_length3
;
578 pkts
[0]->pkt_len
= total_length0
;
579 pkts
[1]->pkt_len
= total_length1
;
580 pkts
[2]->pkt_len
= total_length2
;
581 pkts
[3]->pkt_len
= total_length3
;
583 if ((qinq
== 0) && (mpls
== 0)) {
584 *slab0_ptr0
= entry0
->slab
[0];
585 *slab0_ptr1
= entry1
->slab
[0];
586 *slab0_ptr2
= entry2
->slab
[0];
587 *slab0_ptr3
= entry3
->slab
[0];
590 MACADDR_DST_WRITE(slab1_ptr0
, entry0
->slab
[1]);
591 MACADDR_DST_WRITE(slab1_ptr1
, entry1
->slab
[1]);
592 MACADDR_DST_WRITE(slab1_ptr2
, entry2
->slab
[1]);
593 MACADDR_DST_WRITE(slab1_ptr3
, entry3
->slab
[1]);
598 *slab0_ptr0
= entry0
->slab
[0];
599 *slab0_ptr1
= entry1
->slab
[0];
600 *slab0_ptr2
= entry2
->slab
[0];
601 *slab0_ptr3
= entry3
->slab
[0];
603 *slab1_ptr0
= entry0
->slab
[1];
604 *slab1_ptr1
= entry1
->slab
[1];
605 *slab1_ptr2
= entry2
->slab
[1];
606 *slab1_ptr3
= entry3
->slab
[1];
609 MACADDR_DST_WRITE(slab2_ptr0
, entry0
->slab
[2]);
610 MACADDR_DST_WRITE(slab2_ptr1
, entry1
->slab
[2]);
611 MACADDR_DST_WRITE(slab2_ptr2
, entry2
->slab
[2]);
612 MACADDR_DST_WRITE(slab2_ptr3
, entry3
->slab
[2]);
616 pkts
[0]->hash
.sched
.lo
= sched0
& 0xFFFFFFFF;
617 pkts
[0]->hash
.sched
.hi
= sched0
>> 32;
618 pkts
[1]->hash
.sched
.lo
= sched1
& 0xFFFFFFFF;
619 pkts
[1]->hash
.sched
.hi
= sched1
>> 32;
620 pkts
[2]->hash
.sched
.lo
= sched2
& 0xFFFFFFFF;
621 pkts
[2]->hash
.sched
.hi
= sched2
>> 32;
622 pkts
[3]->hash
.sched
.lo
= sched3
& 0xFFFFFFFF;
623 pkts
[3]->hash
.sched
.hi
= sched3
>> 32;
628 if (mpls_color_mark
) {
629 uint64_t mpls_exp0
= rte_bswap64(
630 (MPLS_LABEL(0, pkt0_color
, 0, 0) << 32) |
631 MPLS_LABEL(0, pkt0_color
, 0, 0));
632 uint64_t mpls_exp1
= rte_bswap64(
633 (MPLS_LABEL(0, pkt1_color
, 0, 0) << 32) |
634 MPLS_LABEL(0, pkt1_color
, 0, 0));
635 uint64_t mpls_exp2
= rte_bswap64(
636 (MPLS_LABEL(0, pkt2_color
, 0, 0) << 32) |
637 MPLS_LABEL(0, pkt2_color
, 0, 0));
638 uint64_t mpls_exp3
= rte_bswap64(
639 (MPLS_LABEL(0, pkt3_color
, 0, 0) << 32) |
640 MPLS_LABEL(0, pkt3_color
, 0, 0));
642 *slab0_ptr0
= entry0
->slab
[0] | mpls_exp0
;
643 *slab0_ptr1
= entry1
->slab
[0] | mpls_exp1
;
644 *slab0_ptr2
= entry2
->slab
[0] | mpls_exp2
;
645 *slab0_ptr3
= entry3
->slab
[0] | mpls_exp3
;
647 *slab1_ptr0
= entry0
->slab
[1] | mpls_exp0
;
648 *slab1_ptr1
= entry1
->slab
[1] | mpls_exp1
;
649 *slab1_ptr2
= entry2
->slab
[1] | mpls_exp2
;
650 *slab1_ptr3
= entry3
->slab
[1] | mpls_exp3
;
652 *slab2_ptr0
= entry0
->slab
[2];
653 *slab2_ptr1
= entry1
->slab
[2];
654 *slab2_ptr2
= entry2
->slab
[2];
655 *slab2_ptr3
= entry3
->slab
[2];
657 *slab0_ptr0
= entry0
->slab
[0];
658 *slab0_ptr1
= entry1
->slab
[0];
659 *slab0_ptr2
= entry2
->slab
[0];
660 *slab0_ptr3
= entry3
->slab
[0];
662 *slab1_ptr0
= entry0
->slab
[1];
663 *slab1_ptr1
= entry1
->slab
[1];
664 *slab1_ptr2
= entry2
->slab
[1];
665 *slab1_ptr3
= entry3
->slab
[1];
667 *slab2_ptr0
= entry0
->slab
[2];
668 *slab2_ptr1
= entry1
->slab
[2];
669 *slab2_ptr2
= entry2
->slab
[2];
670 *slab2_ptr3
= entry3
->slab
[2];
674 MACADDR_DST_WRITE(slab3_ptr0
, entry0
->slab
[3]);
675 MACADDR_DST_WRITE(slab3_ptr1
, entry1
->slab
[3]);
676 MACADDR_DST_WRITE(slab3_ptr2
, entry2
->slab
[3]);
677 MACADDR_DST_WRITE(slab3_ptr3
, entry3
->slab
[3]);
682 arp_key0
->port_id
= port_id0
;
683 arp_key1
->port_id
= port_id1
;
684 arp_key2
->port_id
= port_id2
;
685 arp_key3
->port_id
= port_id3
;
687 arp_key0
->ip
= nh_ip0
;
688 arp_key1
->ip
= nh_ip1
;
689 arp_key2
->ip
= nh_ip2
;
690 arp_key3
->ip
= nh_ip3
;
694 #define PKT_WORK_ROUTING_ETHERNET(arp) \
696 pkt_work_routing_ether_arp##arp( \
697 struct rte_mbuf *pkt, \
698 struct rte_pipeline_table_entry *table_entry, \
701 pkt_work_routing(pkt, table_entry, arg, arp, 0, 0, 0, 0);\
704 #define PKT4_WORK_ROUTING_ETHERNET(arp) \
706 pkt4_work_routing_ether_arp##arp( \
707 struct rte_mbuf **pkts, \
708 struct rte_pipeline_table_entry **table_entries, \
711 pkt4_work_routing(pkts, table_entries, arg, arp, 0, 0, 0, 0);\
714 #define routing_table_ah_hit_ether(arp) \
715 PKT_WORK_ROUTING_ETHERNET(arp) \
716 PKT4_WORK_ROUTING_ETHERNET(arp) \
717 PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_arp##arp, \
718 pkt_work_routing_ether_arp##arp, \
719 pkt4_work_routing_ether_arp##arp)
721 routing_table_ah_hit_ether(0)
722 routing_table_ah_hit_ether(1)
724 #define PKT_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
726 pkt_work_routing_ether_qinq_sched##sched##_arp##arp( \
727 struct rte_mbuf *pkt, \
728 struct rte_pipeline_table_entry *table_entry, \
731 pkt_work_routing(pkt, table_entry, arg, arp, 1, sched, 0, 0);\
734 #define PKT4_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
736 pkt4_work_routing_ether_qinq_sched##sched##_arp##arp( \
737 struct rte_mbuf **pkts, \
738 struct rte_pipeline_table_entry **table_entries, \
741 pkt4_work_routing(pkts, table_entries, arg, arp, 1, sched, 0, 0);\
744 #define routing_table_ah_hit_ether_qinq(sched, arp) \
745 PKT_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
746 PKT4_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
747 PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_qinq_sched##sched##_arp##arp,\
748 pkt_work_routing_ether_qinq_sched##sched##_arp##arp, \
749 pkt4_work_routing_ether_qinq_sched##sched##_arp##arp)
751 routing_table_ah_hit_ether_qinq(0, 0)
752 routing_table_ah_hit_ether_qinq(1, 0)
753 routing_table_ah_hit_ether_qinq(2, 0)
754 routing_table_ah_hit_ether_qinq(0, 1)
755 routing_table_ah_hit_ether_qinq(1, 1)
756 routing_table_ah_hit_ether_qinq(2, 1)
758 #define PKT_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
760 pkt_work_routing_ether_mpls_color##color##_arp##arp( \
761 struct rte_mbuf *pkt, \
762 struct rte_pipeline_table_entry *table_entry, \
765 pkt_work_routing(pkt, table_entry, arg, arp, 0, 0, 1, color);\
768 #define PKT4_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
770 pkt4_work_routing_ether_mpls_color##color##_arp##arp( \
771 struct rte_mbuf **pkts, \
772 struct rte_pipeline_table_entry **table_entries, \
775 pkt4_work_routing(pkts, table_entries, arg, arp, 0, 0, 1, color);\
778 #define routing_table_ah_hit_ether_mpls(color, arp) \
779 PKT_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
780 PKT4_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
781 PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_mpls_color##color##_arp##arp,\
782 pkt_work_routing_ether_mpls_color##color##_arp##arp, \
783 pkt4_work_routing_ether_mpls_color##color##_arp##arp)
785 routing_table_ah_hit_ether_mpls(0, 0)
786 routing_table_ah_hit_ether_mpls(1, 0)
787 routing_table_ah_hit_ether_mpls(0, 1)
788 routing_table_ah_hit_ether_mpls(1, 1)
790 static rte_pipeline_table_action_handler_hit
791 get_routing_table_ah_hit(struct pipeline_routing
*p
)
793 if (p
->params
.dbg_ah_disable
)
796 switch (p
->params
.encap
) {
797 case PIPELINE_ROUTING_ENCAP_ETHERNET
:
798 return (p
->params
.n_arp_entries
) ?
799 routing_table_ah_hit_ether_arp1
:
800 routing_table_ah_hit_ether_arp0
;
802 case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ
:
803 if (p
->params
.n_arp_entries
)
804 switch (p
->params
.qinq_sched
) {
806 return routing_table_ah_hit_ether_qinq_sched0_arp1
;
808 return routing_table_ah_hit_ether_qinq_sched1_arp1
;
810 return routing_table_ah_hit_ether_qinq_sched2_arp1
;
815 switch (p
->params
.qinq_sched
) {
817 return routing_table_ah_hit_ether_qinq_sched0_arp0
;
819 return routing_table_ah_hit_ether_qinq_sched1_arp0
;
821 return routing_table_ah_hit_ether_qinq_sched2_arp0
;
826 case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS
:
827 if (p
->params
.n_arp_entries
)
828 if (p
->params
.mpls_color_mark
)
829 return routing_table_ah_hit_ether_mpls_color1_arp1
;
831 return routing_table_ah_hit_ether_mpls_color0_arp1
;
833 if (p
->params
.mpls_color_mark
)
834 return routing_table_ah_hit_ether_mpls_color1_arp0
;
836 return routing_table_ah_hit_ether_mpls_color0_arp0
;
846 struct arp_table_entry
{
847 struct rte_pipeline_table_entry head
;
856 struct rte_mbuf
*pkt
,
857 struct rte_pipeline_table_entry
*table_entry
,
858 __rte_unused
void *arg
)
860 struct arp_table_entry
*entry
= (struct arp_table_entry
*) table_entry
;
863 uint64_t macaddr_dst
= entry
->macaddr
;
864 uint64_t *slab_ptr
= (uint64_t *) ((char *) pkt
->buf_addr
+
865 (pkt
->data_off
- 2));
870 MACADDR_DST_WRITE(slab_ptr
, macaddr_dst
);
875 struct rte_mbuf
**pkts
,
876 struct rte_pipeline_table_entry
**table_entries
,
877 __rte_unused
void *arg
)
879 struct arp_table_entry
*entry0
=
880 (struct arp_table_entry
*) table_entries
[0];
881 struct arp_table_entry
*entry1
=
882 (struct arp_table_entry
*) table_entries
[1];
883 struct arp_table_entry
*entry2
=
884 (struct arp_table_entry
*) table_entries
[2];
885 struct arp_table_entry
*entry3
=
886 (struct arp_table_entry
*) table_entries
[3];
889 uint64_t macaddr_dst0
= entry0
->macaddr
;
890 uint64_t macaddr_dst1
= entry1
->macaddr
;
891 uint64_t macaddr_dst2
= entry2
->macaddr
;
892 uint64_t macaddr_dst3
= entry3
->macaddr
;
894 uint64_t *slab_ptr0
= (uint64_t *) ((char *) pkts
[0]->buf_addr
+
895 (pkts
[0]->data_off
- 2));
896 uint64_t *slab_ptr1
= (uint64_t *) ((char *) pkts
[1]->buf_addr
+
897 (pkts
[1]->data_off
- 2));
898 uint64_t *slab_ptr2
= (uint64_t *) ((char *) pkts
[2]->buf_addr
+
899 (pkts
[2]->data_off
- 2));
900 uint64_t *slab_ptr3
= (uint64_t *) ((char *) pkts
[3]->buf_addr
+
901 (pkts
[3]->data_off
- 2));
906 MACADDR_DST_WRITE(slab_ptr0
, macaddr_dst0
);
907 MACADDR_DST_WRITE(slab_ptr1
, macaddr_dst1
);
908 MACADDR_DST_WRITE(slab_ptr2
, macaddr_dst2
);
909 MACADDR_DST_WRITE(slab_ptr3
, macaddr_dst3
);
912 PIPELINE_TABLE_AH_HIT(arp_table_ah_hit
,
916 static rte_pipeline_table_action_handler_hit
917 get_arp_table_ah_hit(struct pipeline_routing
*p
)
919 if (p
->params
.dbg_ah_disable
)
922 return arp_table_ah_hit
;
929 pipeline_routing_parse_args(struct pipeline_routing_params
*p
,
930 struct pipeline_params
*params
)
932 uint32_t n_routes_present
= 0;
933 uint32_t port_local_dest_present
= 0;
934 uint32_t encap_present
= 0;
935 uint32_t qinq_sched_present
= 0;
936 uint32_t mpls_color_mark_present
= 0;
937 uint32_t n_arp_entries_present
= 0;
938 uint32_t ip_hdr_offset_present
= 0;
939 uint32_t arp_key_offset_present
= 0;
940 uint32_t color_offset_present
= 0;
941 uint32_t dbg_ah_disable_present
= 0;
945 p
->n_routes
= PIPELINE_ROUTING_N_ROUTES_DEFAULT
;
946 p
->port_local_dest
= params
->n_ports_out
- 1;
947 p
->encap
= PIPELINE_ROUTING_ENCAP_ETHERNET
;
949 p
->mpls_color_mark
= 0;
950 p
->n_arp_entries
= 0;
951 p
->dbg_ah_disable
= 0;
953 for (i
= 0; i
< params
->n_args
; i
++) {
954 char *arg_name
= params
->args_name
[i
];
955 char *arg_value
= params
->args_value
[i
];
958 if (strcmp(arg_name
, "n_routes") == 0) {
961 PIPELINE_PARSE_ERR_DUPLICATE(
962 n_routes_present
== 0, params
->name
,
964 n_routes_present
= 1;
966 status
= parser_read_uint32(&p
->n_routes
,
968 PIPELINE_PARSE_ERR_INV_VAL(((status
!= -EINVAL
) &&
969 (p
->n_routes
!= 0)), params
->name
,
970 arg_name
, arg_value
);
971 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
972 params
->name
, arg_name
, arg_value
);
976 /* port_local_dest */
977 if (strcmp(arg_name
, "port_local_dest") == 0) {
980 PIPELINE_PARSE_ERR_DUPLICATE(
981 port_local_dest_present
== 0, params
->name
,
983 port_local_dest_present
= 1;
985 status
= parser_read_uint32(&p
->port_local_dest
,
987 PIPELINE_PARSE_ERR_INV_VAL(((status
== 0) &&
988 (p
->port_local_dest
< params
->n_ports_out
)),
989 params
->name
, arg_name
, arg_value
);
995 if (strcmp(arg_name
, "encap") == 0) {
996 PIPELINE_PARSE_ERR_DUPLICATE(encap_present
== 0,
997 params
->name
, arg_name
);
1001 if (strcmp(arg_value
, "ethernet") == 0) {
1002 p
->encap
= PIPELINE_ROUTING_ENCAP_ETHERNET
;
1007 if (strcmp(arg_value
, "ethernet_qinq") == 0) {
1008 p
->encap
= PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ
;
1013 if (strcmp(arg_value
, "ethernet_mpls") == 0) {
1014 p
->encap
= PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS
;
1019 PIPELINE_PARSE_ERR_INV_VAL(0, params
->name
,
1020 arg_name
, arg_value
);
1024 if (strcmp(arg_name
, "qinq_sched") == 0) {
1027 PIPELINE_PARSE_ERR_DUPLICATE(
1028 qinq_sched_present
== 0, params
->name
,
1030 qinq_sched_present
= 1;
1032 status
= parser_read_arg_bool(arg_value
);
1033 if (status
== -EINVAL
) {
1034 if (strcmp(arg_value
, "test") == 0) {
1039 p
->qinq_sched
= status
;
1043 PIPELINE_PARSE_ERR_INV_VAL(0, params
->name
,
1044 arg_name
, arg_value
);
1047 /* mpls_color_mark */
1048 if (strcmp(arg_name
, "mpls_color_mark") == 0) {
1051 PIPELINE_PARSE_ERR_DUPLICATE(
1052 mpls_color_mark_present
== 0,
1053 params
->name
, arg_name
);
1054 mpls_color_mark_present
= 1;
1057 status
= parser_read_arg_bool(arg_value
);
1059 p
->mpls_color_mark
= status
;
1063 PIPELINE_PARSE_ERR_INV_VAL(0, params
->name
,
1064 arg_name
, arg_value
);
1068 if (strcmp(arg_name
, "n_arp_entries") == 0) {
1071 PIPELINE_PARSE_ERR_DUPLICATE(
1072 n_arp_entries_present
== 0, params
->name
,
1074 n_arp_entries_present
= 1;
1076 status
= parser_read_uint32(&p
->n_arp_entries
,
1078 PIPELINE_PARSE_ERR_INV_VAL((status
!= -EINVAL
),
1079 params
->name
, arg_name
, arg_value
);
1080 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
1081 params
->name
, arg_name
, arg_value
);
1087 if (strcmp(arg_name
, "ip_hdr_offset") == 0) {
1090 PIPELINE_PARSE_ERR_DUPLICATE(
1091 ip_hdr_offset_present
== 0, params
->name
,
1093 ip_hdr_offset_present
= 1;
1095 status
= parser_read_uint32(&p
->ip_hdr_offset
,
1097 PIPELINE_PARSE_ERR_INV_VAL((status
!= -EINVAL
),
1098 params
->name
, arg_name
, arg_value
);
1099 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
1100 params
->name
, arg_name
, arg_value
);
1105 /* arp_key_offset */
1106 if (strcmp(arg_name
, "arp_key_offset") == 0) {
1109 PIPELINE_PARSE_ERR_DUPLICATE(
1110 arp_key_offset_present
== 0, params
->name
,
1112 arp_key_offset_present
= 1;
1114 status
= parser_read_uint32(&p
->arp_key_offset
,
1116 PIPELINE_PARSE_ERR_INV_VAL((status
!= -EINVAL
),
1117 params
->name
, arg_name
, arg_value
);
1118 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
1119 params
->name
, arg_name
, arg_value
);
1125 if (strcmp(arg_name
, "color_offset") == 0) {
1128 PIPELINE_PARSE_ERR_DUPLICATE(
1129 color_offset_present
== 0, params
->name
,
1131 color_offset_present
= 1;
1133 status
= parser_read_uint32(&p
->color_offset
,
1135 PIPELINE_PARSE_ERR_INV_VAL((status
!= -EINVAL
),
1136 params
->name
, arg_name
, arg_value
);
1137 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
1138 params
->name
, arg_name
, arg_value
);
1144 if (strcmp(arg_name
, "dbg_ah_disable") == 0) {
1147 PIPELINE_PARSE_ERR_DUPLICATE(
1148 dbg_ah_disable_present
== 0, params
->name
,
1150 dbg_ah_disable_present
= 1;
1152 status
= parser_read_arg_bool(arg_value
);
1154 p
->dbg_ah_disable
= status
;
1158 PIPELINE_PARSE_ERR_INV_VAL(0, params
->name
,
1159 arg_name
, arg_value
);
1165 PIPELINE_PARSE_ERR_INV_ENT(0, params
->name
, arg_name
);
1168 /* Check that mandatory arguments are present */
1169 PIPELINE_PARSE_ERR_MANDATORY(ip_hdr_offset_present
, params
->name
,
1172 /* Check relations between arguments */
1174 case PIPELINE_ROUTING_ENCAP_ETHERNET
:
1175 PIPELINE_ARG_CHECK((!p
->qinq_sched
), "Parse error in "
1176 "section \"%s\": encap = ethernet, therefore "
1177 "qinq_sched = yes/test is not allowed",
1179 PIPELINE_ARG_CHECK((!p
->mpls_color_mark
), "Parse error "
1180 "in section \"%s\": encap = ethernet, therefore "
1181 "mpls_color_mark = yes is not allowed",
1183 PIPELINE_ARG_CHECK((!color_offset_present
), "Parse error "
1184 "in section \"%s\": encap = ethernet, therefore "
1185 "color_offset is not allowed",
1189 case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ
:
1190 PIPELINE_ARG_CHECK((!p
->mpls_color_mark
), "Parse error "
1191 "in section \"%s\": encap = ethernet_qinq, "
1192 "therefore mpls_color_mark = yes is not allowed",
1194 PIPELINE_ARG_CHECK((!color_offset_present
), "Parse error "
1195 "in section \"%s\": encap = ethernet_qinq, "
1196 "therefore color_offset is not allowed",
1200 case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS
:
1201 PIPELINE_ARG_CHECK((!p
->qinq_sched
), "Parse error in "
1202 "section \"%s\": encap = ethernet_mpls, therefore "
1203 "qinq_sched = yes/test is not allowed",
1208 PIPELINE_ARG_CHECK((!(p
->n_arp_entries
&&
1209 (!arp_key_offset_present
))), "Parse error in section "
1210 "\"%s\": n_arp_entries is set while "
1211 "arp_key_offset is not set", params
->name
);
1213 PIPELINE_ARG_CHECK((!((p
->n_arp_entries
== 0) &&
1214 arp_key_offset_present
)), "Parse error in section "
1215 "\"%s\": arp_key_offset present while "
1216 "n_arp_entries is not set", params
->name
);
1222 pipeline_routing_init(struct pipeline_params
*params
,
1223 __rte_unused
void *arg
)
1226 struct pipeline_routing
*p_rt
;
1229 /* Check input arguments */
1230 if ((params
== NULL
) ||
1231 (params
->n_ports_in
== 0) ||
1232 (params
->n_ports_out
== 0))
1235 /* Memory allocation */
1236 size
= RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing
));
1237 p
= rte_zmalloc(NULL
, size
, RTE_CACHE_LINE_SIZE
);
1238 p_rt
= (struct pipeline_routing
*) p
;
1242 strcpy(p
->name
, params
->name
);
1243 p
->log_level
= params
->log_level
;
1245 PLOG(p
, HIGH
, "Routing");
1247 /* Parse arguments */
1248 if (pipeline_routing_parse_args(&p_rt
->params
, params
))
1253 struct rte_pipeline_params pipeline_params
= {
1254 .name
= params
->name
,
1255 .socket_id
= params
->socket_id
,
1256 .offset_port_id
= 0,
1259 p
->p
= rte_pipeline_create(&pipeline_params
);
1267 p
->n_ports_in
= params
->n_ports_in
;
1268 for (i
= 0; i
< p
->n_ports_in
; i
++) {
1269 struct rte_pipeline_port_in_params port_params
= {
1270 .ops
= pipeline_port_in_params_get_ops(
1271 ¶ms
->port_in
[i
]),
1272 .arg_create
= pipeline_port_in_params_convert(
1273 ¶ms
->port_in
[i
]),
1276 .burst_size
= params
->port_in
[i
].burst_size
,
1279 int status
= rte_pipeline_port_in_create(p
->p
,
1284 rte_pipeline_free(p
->p
);
1291 p
->n_ports_out
= params
->n_ports_out
;
1292 for (i
= 0; i
< p
->n_ports_out
; i
++) {
1293 struct rte_pipeline_port_out_params port_params
= {
1294 .ops
= pipeline_port_out_params_get_ops(
1295 ¶ms
->port_out
[i
]),
1296 .arg_create
= pipeline_port_out_params_convert(
1297 ¶ms
->port_out
[i
]),
1302 int status
= rte_pipeline_port_out_create(p
->p
,
1304 &p
->port_out_id
[i
]);
1307 rte_pipeline_free(p
->p
);
1316 struct rte_table_lpm_params table_lpm_params
= {
1318 .n_rules
= p_rt
->params
.n_routes
,
1319 .number_tbl8s
= PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s
,
1321 .entry_unique_size
= sizeof(struct routing_table_entry
),
1322 .offset
= p_rt
->params
.ip_hdr_offset
+
1323 __builtin_offsetof(struct ipv4_hdr
, dst_addr
),
1326 struct rte_pipeline_table_params table_params
= {
1327 .ops
= &rte_table_lpm_ops
,
1328 .arg_create
= &table_lpm_params
,
1329 .f_action_hit
= get_routing_table_ah_hit(p_rt
),
1330 .f_action_miss
= NULL
,
1333 sizeof(struct routing_table_entry
) -
1334 sizeof(struct rte_pipeline_table_entry
),
1339 status
= rte_pipeline_table_create(p
->p
,
1344 rte_pipeline_free(p
->p
);
1350 /* ARP table configuration */
1351 if (p_rt
->params
.n_arp_entries
) {
1352 struct rte_table_hash_key8_ext_params table_arp_params
= {
1353 .n_entries
= p_rt
->params
.n_arp_entries
,
1354 .n_entries_ext
= p_rt
->params
.n_arp_entries
,
1355 .f_hash
= hash_default_key8
,
1357 .signature_offset
= 0, /* Unused */
1358 .key_offset
= p_rt
->params
.arp_key_offset
,
1361 struct rte_pipeline_table_params table_params
= {
1362 .ops
= &rte_table_hash_key8_ext_dosig_ops
,
1363 .arg_create
= &table_arp_params
,
1364 .f_action_hit
= get_arp_table_ah_hit(p_rt
),
1365 .f_action_miss
= NULL
,
1367 .action_data_size
= sizeof(struct arp_table_entry
) -
1368 sizeof(struct rte_pipeline_table_entry
),
1373 status
= rte_pipeline_table_create(p
->p
,
1378 rte_pipeline_free(p
->p
);
1386 /* Connecting input ports to tables */
1387 for (i
= 0; i
< p
->n_ports_in
; i
++) {
1388 int status
= rte_pipeline_port_in_connect_to_table(p
->p
,
1393 rte_pipeline_free(p
->p
);
1399 /* Enable input ports */
1400 for (i
= 0; i
< p
->n_ports_in
; i
++) {
1401 int status
= rte_pipeline_port_in_enable(p
->p
,
1405 rte_pipeline_free(p
->p
);
1411 /* Check pipeline consistency */
1412 if (rte_pipeline_check(p
->p
) < 0) {
1413 rte_pipeline_free(p
->p
);
1418 /* Message queues */
1419 p
->n_msgq
= params
->n_msgq
;
1420 for (i
= 0; i
< p
->n_msgq
; i
++)
1421 p
->msgq_in
[i
] = params
->msgq_in
[i
];
1422 for (i
= 0; i
< p
->n_msgq
; i
++)
1423 p
->msgq_out
[i
] = params
->msgq_out
[i
];
1425 /* Message handlers */
1426 memcpy(p
->handlers
, handlers
, sizeof(p
->handlers
));
1427 memcpy(p_rt
->custom_handlers
,
1429 sizeof(p_rt
->custom_handlers
));
1435 pipeline_routing_free(void *pipeline
)
1437 struct pipeline
*p
= (struct pipeline
*) pipeline
;
1439 /* Check input arguments */
1443 /* Free resources */
1444 rte_pipeline_free(p
->p
);
1450 pipeline_routing_timer(void *pipeline
)
1452 struct pipeline
*p
= (struct pipeline
*) pipeline
;
1454 pipeline_msg_req_handle(p
);
1455 rte_pipeline_flush(p
->p
);
1461 pipeline_routing_msg_req_custom_handler(struct pipeline
*p
,
1464 struct pipeline_routing
*p_rt
= (struct pipeline_routing
*) p
;
1465 struct pipeline_custom_msg_req
*req
= msg
;
1466 pipeline_msg_req_handler f_handle
;
1468 f_handle
= (req
->subtype
< PIPELINE_ROUTING_MSG_REQS
) ?
1469 p_rt
->custom_handlers
[req
->subtype
] :
1470 pipeline_msg_req_invalid_handler
;
1472 if (f_handle
== NULL
)
1473 f_handle
= pipeline_msg_req_invalid_handler
;
1475 return f_handle(p
, req
);
1479 pipeline_routing_msg_req_route_add_handler(struct pipeline
*p
, void *msg
)
1481 struct pipeline_routing
*p_rt
= (struct pipeline_routing
*) p
;
1482 struct pipeline_routing_route_add_msg_req
*req
= msg
;
1483 struct pipeline_routing_route_add_msg_rsp
*rsp
= msg
;
1485 struct rte_table_lpm_key key
= {
1486 .ip
= req
->key
.key
.ipv4
.ip
,
1487 .depth
= req
->key
.key
.ipv4
.depth
,
1490 struct routing_table_entry entry_arp0
= {
1492 .action
= RTE_PIPELINE_ACTION_PORT
,
1493 {.port_id
= p
->port_out_id
[req
->data
.port_id
]},
1496 .flags
= req
->data
.flags
,
1497 .port_id
= req
->data
.port_id
,
1500 .ether_l2_length
= 0,
1505 struct routing_table_entry entry_arp1
= {
1507 .action
= RTE_PIPELINE_ACTION_TABLE
,
1508 {.table_id
= p
->table_id
[1]},
1511 .flags
= req
->data
.flags
,
1512 .port_id
= req
->data
.port_id
,
1513 .ip
= rte_bswap32(req
->data
.ethernet
.ip
),
1515 .ether_l2_length
= 0,
1520 struct rte_pipeline_table_entry
*entry
= (p_rt
->params
.n_arp_entries
) ?
1521 (struct rte_pipeline_table_entry
*) &entry_arp1
:
1522 (struct rte_pipeline_table_entry
*) &entry_arp0
;
1524 if ((req
->key
.type
!= PIPELINE_ROUTING_ROUTE_IPV4
) ||
1525 ((p_rt
->params
.n_arp_entries
== 0) &&
1526 (req
->data
.flags
& PIPELINE_ROUTING_ROUTE_ARP
)) ||
1527 (p_rt
->params
.n_arp_entries
&&
1528 ((req
->data
.flags
& PIPELINE_ROUTING_ROUTE_ARP
) == 0)) ||
1529 ((p_rt
->params
.encap
!= PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ
) &&
1530 (req
->data
.flags
& PIPELINE_ROUTING_ROUTE_QINQ
)) ||
1531 ((p_rt
->params
.encap
== PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ
) &&
1532 ((req
->data
.flags
& PIPELINE_ROUTING_ROUTE_QINQ
) == 0)) ||
1533 ((p_rt
->params
.encap
!= PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS
) &&
1534 (req
->data
.flags
& PIPELINE_ROUTING_ROUTE_MPLS
)) ||
1535 ((p_rt
->params
.encap
== PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS
) &&
1536 ((req
->data
.flags
& PIPELINE_ROUTING_ROUTE_MPLS
) == 0))) {
1541 /* Ether - ARP off */
1542 if ((p_rt
->params
.encap
== PIPELINE_ROUTING_ENCAP_ETHERNET
) &&
1543 (p_rt
->params
.n_arp_entries
== 0)) {
1544 uint64_t macaddr_src
= p_rt
->macaddr
[req
->data
.port_id
];
1545 uint64_t macaddr_dst
;
1546 uint64_t ethertype
= ETHER_TYPE_IPv4
;
1548 macaddr_dst
= *((uint64_t *)&(req
->data
.ethernet
.macaddr
));
1549 macaddr_dst
= rte_bswap64(macaddr_dst
<< 16);
1551 entry_arp0
.slab
[0] =
1552 SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src
, ethertype
);
1553 entry_arp0
.slab_offset
[0] = p_rt
->params
.ip_hdr_offset
- 8;
1555 entry_arp0
.slab
[1] = rte_bswap64(macaddr_dst
);
1556 entry_arp0
.slab_offset
[1] = p_rt
->params
.ip_hdr_offset
- 2 * 8;
1558 entry_arp0
.data_offset
= entry_arp0
.slab_offset
[1] + 2
1559 - sizeof(struct rte_mbuf
);
1560 entry_arp0
.ether_l2_length
= 14;
1563 /* Ether - ARP on */
1564 if ((p_rt
->params
.encap
== PIPELINE_ROUTING_ENCAP_ETHERNET
) &&
1565 p_rt
->params
.n_arp_entries
) {
1566 uint64_t macaddr_src
= p_rt
->macaddr
[req
->data
.port_id
];
1567 uint64_t ethertype
= ETHER_TYPE_IPv4
;
1569 entry_arp1
.slab
[0] =
1570 SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src
, ethertype
);
1571 entry_arp1
.slab_offset
[0] = p_rt
->params
.ip_hdr_offset
- 8;
1573 entry_arp1
.data_offset
= entry_arp1
.slab_offset
[0] - 6
1574 - sizeof(struct rte_mbuf
);
1575 entry_arp1
.ether_l2_length
= 14;
1578 /* Ether QinQ - ARP off */
1579 if ((p_rt
->params
.encap
== PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ
) &&
1580 (p_rt
->params
.n_arp_entries
== 0)) {
1581 uint64_t macaddr_src
= p_rt
->macaddr
[req
->data
.port_id
];
1582 uint64_t macaddr_dst
;
1583 uint64_t ethertype_ipv4
= ETHER_TYPE_IPv4
;
1584 uint64_t ethertype_vlan
= 0x8100;
1585 uint64_t ethertype_qinq
= 0x9100;
1586 uint64_t svlan
= req
->data
.l2
.qinq
.svlan
;
1587 uint64_t cvlan
= req
->data
.l2
.qinq
.cvlan
;
1589 macaddr_dst
= *((uint64_t *)&(req
->data
.ethernet
.macaddr
));
1590 macaddr_dst
= rte_bswap64(macaddr_dst
<< 16);
1592 entry_arp0
.slab
[0] = rte_bswap64((svlan
<< 48) |
1593 (ethertype_vlan
<< 32) |
1596 entry_arp0
.slab_offset
[0] = p_rt
->params
.ip_hdr_offset
- 8;
1598 entry_arp0
.slab
[1] =
1599 SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src
, ethertype_qinq
);
1600 entry_arp0
.slab_offset
[1] = p_rt
->params
.ip_hdr_offset
- 2 * 8;
1602 entry_arp0
.slab
[2] = rte_bswap64(macaddr_dst
);
1603 entry_arp0
.slab_offset
[2] = p_rt
->params
.ip_hdr_offset
- 3 * 8;
1605 entry_arp0
.data_offset
= entry_arp0
.slab_offset
[2] + 2
1606 - sizeof(struct rte_mbuf
);
1607 entry_arp0
.ether_l2_length
= 22;
1610 /* Ether QinQ - ARP on */
1611 if ((p_rt
->params
.encap
== PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ
) &&
1612 p_rt
->params
.n_arp_entries
) {
1613 uint64_t macaddr_src
= p_rt
->macaddr
[req
->data
.port_id
];
1614 uint64_t ethertype_ipv4
= ETHER_TYPE_IPv4
;
1615 uint64_t ethertype_vlan
= 0x8100;
1616 uint64_t ethertype_qinq
= 0x9100;
1617 uint64_t svlan
= req
->data
.l2
.qinq
.svlan
;
1618 uint64_t cvlan
= req
->data
.l2
.qinq
.cvlan
;
1620 entry_arp1
.slab
[0] = rte_bswap64((svlan
<< 48) |
1621 (ethertype_vlan
<< 32) |
1624 entry_arp1
.slab_offset
[0] = p_rt
->params
.ip_hdr_offset
- 8;
1626 entry_arp1
.slab
[1] =
1627 SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src
, ethertype_qinq
);
1628 entry_arp1
.slab_offset
[1] = p_rt
->params
.ip_hdr_offset
- 2 * 8;
1630 entry_arp1
.data_offset
= entry_arp1
.slab_offset
[1] - 6
1631 - sizeof(struct rte_mbuf
);
1632 entry_arp1
.ether_l2_length
= 22;
1635 /* Ether MPLS - ARP off */
1636 if ((p_rt
->params
.encap
== PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS
) &&
1637 (p_rt
->params
.n_arp_entries
== 0)) {
1638 uint64_t macaddr_src
= p_rt
->macaddr
[req
->data
.port_id
];
1639 uint64_t macaddr_dst
;
1640 uint64_t ethertype_mpls
= 0x8847;
1642 uint64_t label0
= req
->data
.l2
.mpls
.labels
[0];
1643 uint64_t label1
= req
->data
.l2
.mpls
.labels
[1];
1644 uint64_t label2
= req
->data
.l2
.mpls
.labels
[2];
1645 uint64_t label3
= req
->data
.l2
.mpls
.labels
[3];
1646 uint32_t n_labels
= req
->data
.l2
.mpls
.n_labels
;
1648 macaddr_dst
= *((uint64_t *)&(req
->data
.ethernet
.macaddr
));
1649 macaddr_dst
= rte_bswap64(macaddr_dst
<< 16);
1653 entry_arp0
.slab
[0] = 0;
1654 entry_arp0
.slab_offset
[0] =
1655 p_rt
->params
.ip_hdr_offset
- 8;
1657 entry_arp0
.slab
[1] = rte_bswap64(
1658 MPLS_LABEL(label0
, 0, 1, 0));
1659 entry_arp0
.slab_offset
[1] =
1660 p_rt
->params
.ip_hdr_offset
- 8;
1664 entry_arp0
.slab
[0] = 0;
1665 entry_arp0
.slab_offset
[0] =
1666 p_rt
->params
.ip_hdr_offset
- 8;
1668 entry_arp0
.slab
[1] = rte_bswap64(
1669 (MPLS_LABEL(label0
, 0, 0, 0) << 32) |
1670 MPLS_LABEL(label1
, 0, 1, 0));
1671 entry_arp0
.slab_offset
[1] =
1672 p_rt
->params
.ip_hdr_offset
- 8;
1676 entry_arp0
.slab
[0] = rte_bswap64(
1677 (MPLS_LABEL(label1
, 0, 0, 0) << 32) |
1678 MPLS_LABEL(label2
, 0, 1, 0));
1679 entry_arp0
.slab_offset
[0] =
1680 p_rt
->params
.ip_hdr_offset
- 8;
1682 entry_arp0
.slab
[1] = rte_bswap64(
1683 MPLS_LABEL(label0
, 0, 0, 0));
1684 entry_arp0
.slab_offset
[1] =
1685 p_rt
->params
.ip_hdr_offset
- 2 * 8;
1689 entry_arp0
.slab
[0] = rte_bswap64(
1690 (MPLS_LABEL(label2
, 0, 0, 0) << 32) |
1691 MPLS_LABEL(label3
, 0, 1, 0));
1692 entry_arp0
.slab_offset
[0] =
1693 p_rt
->params
.ip_hdr_offset
- 8;
1695 entry_arp0
.slab
[1] = rte_bswap64(
1696 (MPLS_LABEL(label0
, 0, 0, 0) << 32) |
1697 MPLS_LABEL(label1
, 0, 0, 0));
1698 entry_arp0
.slab_offset
[1] =
1699 p_rt
->params
.ip_hdr_offset
- 2 * 8;
1707 entry_arp0
.slab
[2] =
1708 SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src
, ethertype_mpls
);
1709 entry_arp0
.slab_offset
[2] = p_rt
->params
.ip_hdr_offset
-
1712 entry_arp0
.slab
[3] = rte_bswap64(macaddr_dst
);
1713 entry_arp0
.slab_offset
[3] = p_rt
->params
.ip_hdr_offset
-
1714 (n_labels
* 4 + 2 * 8);
1716 entry_arp0
.data_offset
= entry_arp0
.slab_offset
[3] + 2
1717 - sizeof(struct rte_mbuf
);
1718 entry_arp0
.ether_l2_length
= n_labels
* 4 + 14;
1721 /* Ether MPLS - ARP on */
1722 if ((p_rt
->params
.encap
== PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS
) &&
1723 p_rt
->params
.n_arp_entries
) {
1724 uint64_t macaddr_src
= p_rt
->macaddr
[req
->data
.port_id
];
1725 uint64_t ethertype_mpls
= 0x8847;
1727 uint64_t label0
= req
->data
.l2
.mpls
.labels
[0];
1728 uint64_t label1
= req
->data
.l2
.mpls
.labels
[1];
1729 uint64_t label2
= req
->data
.l2
.mpls
.labels
[2];
1730 uint64_t label3
= req
->data
.l2
.mpls
.labels
[3];
1731 uint32_t n_labels
= req
->data
.l2
.mpls
.n_labels
;
1735 entry_arp1
.slab
[0] = 0;
1736 entry_arp1
.slab_offset
[0] =
1737 p_rt
->params
.ip_hdr_offset
- 8;
1739 entry_arp1
.slab
[1] = rte_bswap64(
1740 MPLS_LABEL(label0
, 0, 1, 0));
1741 entry_arp1
.slab_offset
[1] =
1742 p_rt
->params
.ip_hdr_offset
- 8;
1746 entry_arp1
.slab
[0] = 0;
1747 entry_arp1
.slab_offset
[0] =
1748 p_rt
->params
.ip_hdr_offset
- 8;
1750 entry_arp1
.slab
[1] = rte_bswap64(
1751 (MPLS_LABEL(label0
, 0, 0, 0) << 32) |
1752 MPLS_LABEL(label1
, 0, 1, 0));
1753 entry_arp1
.slab_offset
[1] =
1754 p_rt
->params
.ip_hdr_offset
- 8;
1758 entry_arp1
.slab
[0] = rte_bswap64(
1759 (MPLS_LABEL(label1
, 0, 0, 0) << 32) |
1760 MPLS_LABEL(label2
, 0, 1, 0));
1761 entry_arp1
.slab_offset
[0] =
1762 p_rt
->params
.ip_hdr_offset
- 8;
1764 entry_arp1
.slab
[1] = rte_bswap64(
1765 MPLS_LABEL(label0
, 0, 0, 0));
1766 entry_arp1
.slab_offset
[1] =
1767 p_rt
->params
.ip_hdr_offset
- 2 * 8;
1771 entry_arp1
.slab
[0] = rte_bswap64(
1772 (MPLS_LABEL(label2
, 0, 0, 0) << 32) |
1773 MPLS_LABEL(label3
, 0, 1, 0));
1774 entry_arp1
.slab_offset
[0] =
1775 p_rt
->params
.ip_hdr_offset
- 8;
1777 entry_arp1
.slab
[1] = rte_bswap64(
1778 (MPLS_LABEL(label0
, 0, 0, 0) << 32) |
1779 MPLS_LABEL(label1
, 0, 0, 0));
1780 entry_arp1
.slab_offset
[1] =
1781 p_rt
->params
.ip_hdr_offset
- 2 * 8;
1789 entry_arp1
.slab
[2] =
1790 SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src
, ethertype_mpls
);
1791 entry_arp1
.slab_offset
[2] = p_rt
->params
.ip_hdr_offset
-
1794 entry_arp1
.data_offset
= entry_arp1
.slab_offset
[2] - 6
1795 - sizeof(struct rte_mbuf
);
1796 entry_arp1
.ether_l2_length
= n_labels
* 4 + 14;
1799 rsp
->status
= rte_pipeline_table_entry_add(p
->p
,
1804 (struct rte_pipeline_table_entry
**) &rsp
->entry_ptr
);
1810 pipeline_routing_msg_req_route_del_handler(struct pipeline
*p
, void *msg
)
1812 struct pipeline_routing_route_delete_msg_req
*req
= msg
;
1813 struct pipeline_routing_route_delete_msg_rsp
*rsp
= msg
;
1815 struct rte_table_lpm_key key
= {
1816 .ip
= req
->key
.key
.ipv4
.ip
,
1817 .depth
= req
->key
.key
.ipv4
.depth
,
1820 if (req
->key
.type
!= PIPELINE_ROUTING_ROUTE_IPV4
) {
1825 rsp
->status
= rte_pipeline_table_entry_delete(p
->p
,
1835 pipeline_routing_msg_req_route_add_default_handler(struct pipeline
*p
,
1838 struct pipeline_routing_route_add_default_msg_req
*req
= msg
;
1839 struct pipeline_routing_route_add_default_msg_rsp
*rsp
= msg
;
1841 struct routing_table_entry default_entry
= {
1843 .action
= RTE_PIPELINE_ACTION_PORT
,
1844 {.port_id
= p
->port_out_id
[req
->port_id
]},
1852 rsp
->status
= rte_pipeline_table_default_entry_add(p
->p
,
1854 (struct rte_pipeline_table_entry
*) &default_entry
,
1855 (struct rte_pipeline_table_entry
**) &rsp
->entry_ptr
);
1861 pipeline_routing_msg_req_route_del_default_handler(struct pipeline
*p
,
1864 struct pipeline_routing_route_delete_default_msg_rsp
*rsp
= msg
;
1866 rsp
->status
= rte_pipeline_table_default_entry_delete(p
->p
,
1874 pipeline_routing_msg_req_arp_add_handler(struct pipeline
*p
, void *msg
)
1876 struct pipeline_routing_arp_add_msg_req
*req
= msg
;
1877 struct pipeline_routing_arp_add_msg_rsp
*rsp
= msg
;
1879 struct pipeline_routing_arp_key_ipv4 key
= {
1880 .port_id
= req
->key
.key
.ipv4
.port_id
,
1881 .ip
= rte_bswap32(req
->key
.key
.ipv4
.ip
),
1884 struct arp_table_entry entry
= {
1886 .action
= RTE_PIPELINE_ACTION_PORT
,
1887 {.port_id
= p
->port_out_id
[req
->key
.key
.ipv4
.port_id
]},
1890 .macaddr
= 0, /* set below */
1893 if (req
->key
.type
!= PIPELINE_ROUTING_ARP_IPV4
) {
1898 entry
.macaddr
= *((uint64_t *)&(req
->macaddr
));
1899 entry
.macaddr
= entry
.macaddr
<< 16;
1901 rsp
->status
= rte_pipeline_table_entry_add(p
->p
,
1904 (struct rte_pipeline_table_entry
*) &entry
,
1906 (struct rte_pipeline_table_entry
**) &rsp
->entry_ptr
);
1912 pipeline_routing_msg_req_arp_del_handler(struct pipeline
*p
, void *msg
)
1914 struct pipeline_routing_arp_delete_msg_req
*req
= msg
;
1915 struct pipeline_routing_arp_delete_msg_rsp
*rsp
= msg
;
1917 struct pipeline_routing_arp_key_ipv4 key
= {
1918 .port_id
= req
->key
.key
.ipv4
.port_id
,
1919 .ip
= rte_bswap32(req
->key
.key
.ipv4
.ip
),
1922 if (req
->key
.type
!= PIPELINE_ROUTING_ARP_IPV4
) {
1927 rsp
->status
= rte_pipeline_table_entry_delete(p
->p
,
1937 pipeline_routing_msg_req_arp_add_default_handler(struct pipeline
*p
, void *msg
)
1939 struct pipeline_routing_arp_add_default_msg_req
*req
= msg
;
1940 struct pipeline_routing_arp_add_default_msg_rsp
*rsp
= msg
;
1942 struct arp_table_entry default_entry
= {
1944 .action
= RTE_PIPELINE_ACTION_PORT
,
1945 {.port_id
= p
->port_out_id
[req
->port_id
]},
1951 rsp
->status
= rte_pipeline_table_default_entry_add(p
->p
,
1953 (struct rte_pipeline_table_entry
*) &default_entry
,
1954 (struct rte_pipeline_table_entry
**) &rsp
->entry_ptr
);
1960 pipeline_routing_msg_req_arp_del_default_handler(struct pipeline
*p
, void *msg
)
1962 struct pipeline_routing_arp_delete_default_msg_rsp
*rsp
= msg
;
1964 rsp
->status
= rte_pipeline_table_default_entry_delete(p
->p
,
1972 pipeline_routing_msg_req_set_macaddr_handler(struct pipeline
*p
, void *msg
)
1974 struct pipeline_routing
*p_rt
= (struct pipeline_routing
*) p
;
1975 struct pipeline_routing_set_macaddr_msg_req
*req
= msg
;
1976 struct pipeline_routing_set_macaddr_msg_rsp
*rsp
= msg
;
1979 for (port_id
= 0; port_id
< p
->n_ports_out
; port_id
++)
1980 p_rt
->macaddr
[port_id
] = req
->macaddr
[port_id
];
1987 struct pipeline_be_ops pipeline_routing_be_ops
= {
1988 .f_init
= pipeline_routing_init
,
1989 .f_free
= pipeline_routing_free
,
1991 .f_timer
= pipeline_routing_timer
,