xref: /dpdk/lib/node/ip6_rewrite.c (revision a2bc05846c5bdd839ba9d13e65b02b981ea98130)
116ac29cbSAmit Prakash Shukla /* SPDX-License-Identifier: BSD-3-Clause
216ac29cbSAmit Prakash Shukla  * Copyright(C) 2023 Marvell.
316ac29cbSAmit Prakash Shukla  */
416ac29cbSAmit Prakash Shukla 
516ac29cbSAmit Prakash Shukla #include <rte_ethdev.h>
616ac29cbSAmit Prakash Shukla #include <rte_ether.h>
716ac29cbSAmit Prakash Shukla #include <rte_graph.h>
8*a2bc0584SZhirun Yan #include <rte_graph_worker.h>
916ac29cbSAmit Prakash Shukla #include <rte_ip.h>
1016ac29cbSAmit Prakash Shukla #include <rte_malloc.h>
1116ac29cbSAmit Prakash Shukla #include <rte_vect.h>
1216ac29cbSAmit Prakash Shukla 
1316ac29cbSAmit Prakash Shukla #include "rte_node_ip6_api.h"
1416ac29cbSAmit Prakash Shukla 
1516ac29cbSAmit Prakash Shukla #include "ip6_rewrite_priv.h"
1616ac29cbSAmit Prakash Shukla #include "node_private.h"
1716ac29cbSAmit Prakash Shukla 
1816ac29cbSAmit Prakash Shukla struct ip6_rewrite_node_ctx {
1916ac29cbSAmit Prakash Shukla 	/* Dynamic offset to mbuf priv1 */
2016ac29cbSAmit Prakash Shukla 	int mbuf_priv1_off;
2116ac29cbSAmit Prakash Shukla 	/* Cached next index */
2216ac29cbSAmit Prakash Shukla 	uint16_t next_index;
2316ac29cbSAmit Prakash Shukla };
2416ac29cbSAmit Prakash Shukla 
2516ac29cbSAmit Prakash Shukla static struct ip6_rewrite_node_main *ip6_rewrite_nm;
2616ac29cbSAmit Prakash Shukla 
2716ac29cbSAmit Prakash Shukla #define IP6_REWRITE_NODE_LAST_NEXT(ctx) \
2816ac29cbSAmit Prakash Shukla 	(((struct ip6_rewrite_node_ctx *)ctx)->next_index)
2916ac29cbSAmit Prakash Shukla 
3016ac29cbSAmit Prakash Shukla #define IP6_REWRITE_NODE_PRIV1_OFF(ctx) \
3116ac29cbSAmit Prakash Shukla 	(((struct ip6_rewrite_node_ctx *)ctx)->mbuf_priv1_off)
3216ac29cbSAmit Prakash Shukla 
3316ac29cbSAmit Prakash Shukla static uint16_t
ip6_rewrite_node_process(struct rte_graph * graph,struct rte_node * node,void ** objs,uint16_t nb_objs)3416ac29cbSAmit Prakash Shukla ip6_rewrite_node_process(struct rte_graph *graph, struct rte_node *node,
3516ac29cbSAmit Prakash Shukla 			 void **objs, uint16_t nb_objs)
3616ac29cbSAmit Prakash Shukla {
3716ac29cbSAmit Prakash Shukla 	struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3, **pkts;
3816ac29cbSAmit Prakash Shukla 	struct ip6_rewrite_nh_header *nh = ip6_rewrite_nm->nh;
3916ac29cbSAmit Prakash Shukla 	const int dyn = IP6_REWRITE_NODE_PRIV1_OFF(node->ctx);
4016ac29cbSAmit Prakash Shukla 	uint16_t next0, next1, next2, next3, next_index;
4116ac29cbSAmit Prakash Shukla 	uint16_t n_left_from, held = 0, last_spec = 0;
4216ac29cbSAmit Prakash Shukla 	struct rte_ipv6_hdr *ip0, *ip1, *ip2, *ip3;
4316ac29cbSAmit Prakash Shukla 	void *d0, *d1, *d2, *d3;
4416ac29cbSAmit Prakash Shukla 	void **to_next, **from;
4516ac29cbSAmit Prakash Shukla 	rte_xmm_t priv01;
4616ac29cbSAmit Prakash Shukla 	rte_xmm_t priv23;
4716ac29cbSAmit Prakash Shukla 	int i;
4816ac29cbSAmit Prakash Shukla 
4916ac29cbSAmit Prakash Shukla 	/* Speculative next as last next */
5016ac29cbSAmit Prakash Shukla 	next_index = IP6_REWRITE_NODE_LAST_NEXT(node->ctx);
5116ac29cbSAmit Prakash Shukla 	rte_prefetch0(nh);
5216ac29cbSAmit Prakash Shukla 
5316ac29cbSAmit Prakash Shukla 	pkts = (struct rte_mbuf **)objs;
5416ac29cbSAmit Prakash Shukla 	from = objs;
5516ac29cbSAmit Prakash Shukla 	n_left_from = nb_objs;
5616ac29cbSAmit Prakash Shukla 
5716ac29cbSAmit Prakash Shukla 	for (i = 0; i < 4 && i < n_left_from; i++)
5816ac29cbSAmit Prakash Shukla 		rte_prefetch0(pkts[i]);
5916ac29cbSAmit Prakash Shukla 
6016ac29cbSAmit Prakash Shukla 	/* Get stream for the speculated next node */
6116ac29cbSAmit Prakash Shukla 	to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
6216ac29cbSAmit Prakash Shukla 	/* Update Ethernet header of pkts */
6316ac29cbSAmit Prakash Shukla 	while (n_left_from >= 4) {
6416ac29cbSAmit Prakash Shukla 		if (likely(n_left_from > 7)) {
6516ac29cbSAmit Prakash Shukla 			/* Prefetch only next-mbuf struct and priv area.
6616ac29cbSAmit Prakash Shukla 			 * Data need not be prefetched as we only write.
6716ac29cbSAmit Prakash Shukla 			 */
6816ac29cbSAmit Prakash Shukla 			rte_prefetch0(pkts[4]);
6916ac29cbSAmit Prakash Shukla 			rte_prefetch0(pkts[5]);
7016ac29cbSAmit Prakash Shukla 			rte_prefetch0(pkts[6]);
7116ac29cbSAmit Prakash Shukla 			rte_prefetch0(pkts[7]);
7216ac29cbSAmit Prakash Shukla 		}
7316ac29cbSAmit Prakash Shukla 
7416ac29cbSAmit Prakash Shukla 		mbuf0 = pkts[0];
7516ac29cbSAmit Prakash Shukla 		mbuf1 = pkts[1];
7616ac29cbSAmit Prakash Shukla 		mbuf2 = pkts[2];
7716ac29cbSAmit Prakash Shukla 		mbuf3 = pkts[3];
7816ac29cbSAmit Prakash Shukla 
7916ac29cbSAmit Prakash Shukla 		pkts += 4;
8016ac29cbSAmit Prakash Shukla 		n_left_from -= 4;
8116ac29cbSAmit Prakash Shukla 		priv01.u64[0] = node_mbuf_priv1(mbuf0, dyn)->u;
8216ac29cbSAmit Prakash Shukla 		priv01.u64[1] = node_mbuf_priv1(mbuf1, dyn)->u;
8316ac29cbSAmit Prakash Shukla 		priv23.u64[0] = node_mbuf_priv1(mbuf2, dyn)->u;
8416ac29cbSAmit Prakash Shukla 		priv23.u64[1] = node_mbuf_priv1(mbuf3, dyn)->u;
8516ac29cbSAmit Prakash Shukla 
8616ac29cbSAmit Prakash Shukla 		/* Update next_hop rewrite ethernet hdr on mbuf0 */
8716ac29cbSAmit Prakash Shukla 		d0 = rte_pktmbuf_mtod(mbuf0, void *);
8816ac29cbSAmit Prakash Shukla 		rte_memcpy(d0, nh[priv01.u16[0]].rewrite_data,
8916ac29cbSAmit Prakash Shukla 			   nh[priv01.u16[0]].rewrite_len);
9016ac29cbSAmit Prakash Shukla 
9116ac29cbSAmit Prakash Shukla 		next0 = nh[priv01.u16[0]].tx_node;
9216ac29cbSAmit Prakash Shukla 		ip0 = (struct rte_ipv6_hdr *)((uint8_t *)d0 +
9316ac29cbSAmit Prakash Shukla 					      sizeof(struct rte_ether_hdr));
9416ac29cbSAmit Prakash Shukla 		ip0->hop_limits = priv01.u16[1] - 1;
9516ac29cbSAmit Prakash Shukla 
9616ac29cbSAmit Prakash Shukla 		/* Update next_hop rewrite ethernet hdr on mbuf1 */
9716ac29cbSAmit Prakash Shukla 		d1 = rte_pktmbuf_mtod(mbuf1, void *);
9816ac29cbSAmit Prakash Shukla 		rte_memcpy(d1, nh[priv01.u16[4]].rewrite_data,
9916ac29cbSAmit Prakash Shukla 			   nh[priv01.u16[4]].rewrite_len);
10016ac29cbSAmit Prakash Shukla 
10116ac29cbSAmit Prakash Shukla 		next1 = nh[priv01.u16[4]].tx_node;
10216ac29cbSAmit Prakash Shukla 		ip1 = (struct rte_ipv6_hdr *)((uint8_t *)d1 +
10316ac29cbSAmit Prakash Shukla 					      sizeof(struct rte_ether_hdr));
10416ac29cbSAmit Prakash Shukla 		ip1->hop_limits = priv01.u16[5] - 1;
10516ac29cbSAmit Prakash Shukla 
10616ac29cbSAmit Prakash Shukla 		/* Update next_hop rewrite ethernet hdr on mbuf2 */
10716ac29cbSAmit Prakash Shukla 		d2 = rte_pktmbuf_mtod(mbuf2, void *);
10816ac29cbSAmit Prakash Shukla 		rte_memcpy(d2, nh[priv23.u16[0]].rewrite_data,
10916ac29cbSAmit Prakash Shukla 			   nh[priv23.u16[0]].rewrite_len);
11016ac29cbSAmit Prakash Shukla 		next2 = nh[priv23.u16[0]].tx_node;
11116ac29cbSAmit Prakash Shukla 		ip2 = (struct rte_ipv6_hdr *)((uint8_t *)d2 +
11216ac29cbSAmit Prakash Shukla 					      sizeof(struct rte_ether_hdr));
11316ac29cbSAmit Prakash Shukla 		ip2->hop_limits = priv23.u16[1] - 1;
11416ac29cbSAmit Prakash Shukla 
11516ac29cbSAmit Prakash Shukla 		/* Update next_hop rewrite ethernet hdr on mbuf3 */
11616ac29cbSAmit Prakash Shukla 		d3 = rte_pktmbuf_mtod(mbuf3, void *);
11716ac29cbSAmit Prakash Shukla 		rte_memcpy(d3, nh[priv23.u16[4]].rewrite_data,
11816ac29cbSAmit Prakash Shukla 			   nh[priv23.u16[4]].rewrite_len);
11916ac29cbSAmit Prakash Shukla 
12016ac29cbSAmit Prakash Shukla 		next3 = nh[priv23.u16[4]].tx_node;
12116ac29cbSAmit Prakash Shukla 		ip3 = (struct rte_ipv6_hdr *)((uint8_t *)d3 +
12216ac29cbSAmit Prakash Shukla 					      sizeof(struct rte_ether_hdr));
12316ac29cbSAmit Prakash Shukla 		ip3->hop_limits = priv23.u16[5] - 1;
12416ac29cbSAmit Prakash Shukla 
12516ac29cbSAmit Prakash Shukla 		/* Enqueue four packets to next node */
12616ac29cbSAmit Prakash Shukla 		rte_edge_t fix_spec =
12716ac29cbSAmit Prakash Shukla 			((next_index == next0) && (next0 == next1) &&
12816ac29cbSAmit Prakash Shukla 			 (next1 == next2) && (next2 == next3));
12916ac29cbSAmit Prakash Shukla 
13016ac29cbSAmit Prakash Shukla 		if (unlikely(fix_spec == 0)) {
13116ac29cbSAmit Prakash Shukla 			/* Copy things successfully speculated till now */
13216ac29cbSAmit Prakash Shukla 			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
13316ac29cbSAmit Prakash Shukla 			from += last_spec;
13416ac29cbSAmit Prakash Shukla 			to_next += last_spec;
13516ac29cbSAmit Prakash Shukla 			held += last_spec;
13616ac29cbSAmit Prakash Shukla 			last_spec = 0;
13716ac29cbSAmit Prakash Shukla 
13816ac29cbSAmit Prakash Shukla 			/* next0 */
13916ac29cbSAmit Prakash Shukla 			if (next_index == next0) {
14016ac29cbSAmit Prakash Shukla 				to_next[0] = from[0];
14116ac29cbSAmit Prakash Shukla 				to_next++;
14216ac29cbSAmit Prakash Shukla 				held++;
14316ac29cbSAmit Prakash Shukla 			} else {
14416ac29cbSAmit Prakash Shukla 				rte_node_enqueue_x1(graph, node, next0,
14516ac29cbSAmit Prakash Shukla 						    from[0]);
14616ac29cbSAmit Prakash Shukla 			}
14716ac29cbSAmit Prakash Shukla 
14816ac29cbSAmit Prakash Shukla 			/* next1 */
14916ac29cbSAmit Prakash Shukla 			if (next_index == next1) {
15016ac29cbSAmit Prakash Shukla 				to_next[0] = from[1];
15116ac29cbSAmit Prakash Shukla 				to_next++;
15216ac29cbSAmit Prakash Shukla 				held++;
15316ac29cbSAmit Prakash Shukla 			} else {
15416ac29cbSAmit Prakash Shukla 				rte_node_enqueue_x1(graph, node, next1,
15516ac29cbSAmit Prakash Shukla 						    from[1]);
15616ac29cbSAmit Prakash Shukla 			}
15716ac29cbSAmit Prakash Shukla 
15816ac29cbSAmit Prakash Shukla 			/* next2 */
15916ac29cbSAmit Prakash Shukla 			if (next_index == next2) {
16016ac29cbSAmit Prakash Shukla 				to_next[0] = from[2];
16116ac29cbSAmit Prakash Shukla 				to_next++;
16216ac29cbSAmit Prakash Shukla 				held++;
16316ac29cbSAmit Prakash Shukla 			} else {
16416ac29cbSAmit Prakash Shukla 				rte_node_enqueue_x1(graph, node, next2,
16516ac29cbSAmit Prakash Shukla 						    from[2]);
16616ac29cbSAmit Prakash Shukla 			}
16716ac29cbSAmit Prakash Shukla 
16816ac29cbSAmit Prakash Shukla 			/* next3 */
16916ac29cbSAmit Prakash Shukla 			if (next_index == next3) {
17016ac29cbSAmit Prakash Shukla 				to_next[0] = from[3];
17116ac29cbSAmit Prakash Shukla 				to_next++;
17216ac29cbSAmit Prakash Shukla 				held++;
17316ac29cbSAmit Prakash Shukla 			} else {
17416ac29cbSAmit Prakash Shukla 				rte_node_enqueue_x1(graph, node, next3,
17516ac29cbSAmit Prakash Shukla 						    from[3]);
17616ac29cbSAmit Prakash Shukla 			}
17716ac29cbSAmit Prakash Shukla 
17816ac29cbSAmit Prakash Shukla 			from += 4;
17916ac29cbSAmit Prakash Shukla 
18016ac29cbSAmit Prakash Shukla 			/* Change speculation if last two are same */
18116ac29cbSAmit Prakash Shukla 			if ((next_index != next3) && (next2 == next3)) {
18216ac29cbSAmit Prakash Shukla 				/* Put the current speculated node */
18316ac29cbSAmit Prakash Shukla 				rte_node_next_stream_put(graph, node,
18416ac29cbSAmit Prakash Shukla 							 next_index, held);
18516ac29cbSAmit Prakash Shukla 				held = 0;
18616ac29cbSAmit Prakash Shukla 
18716ac29cbSAmit Prakash Shukla 				/* Get next speculated stream */
18816ac29cbSAmit Prakash Shukla 				next_index = next3;
18916ac29cbSAmit Prakash Shukla 				to_next = rte_node_next_stream_get(
19016ac29cbSAmit Prakash Shukla 					graph, node, next_index, nb_objs);
19116ac29cbSAmit Prakash Shukla 			}
19216ac29cbSAmit Prakash Shukla 		} else {
19316ac29cbSAmit Prakash Shukla 			last_spec += 4;
19416ac29cbSAmit Prakash Shukla 		}
19516ac29cbSAmit Prakash Shukla 	}
19616ac29cbSAmit Prakash Shukla 
19716ac29cbSAmit Prakash Shukla 	while (n_left_from > 0) {
19816ac29cbSAmit Prakash Shukla 		mbuf0 = pkts[0];
19916ac29cbSAmit Prakash Shukla 
20016ac29cbSAmit Prakash Shukla 		pkts += 1;
20116ac29cbSAmit Prakash Shukla 		n_left_from -= 1;
20216ac29cbSAmit Prakash Shukla 
20316ac29cbSAmit Prakash Shukla 		d0 = rte_pktmbuf_mtod(mbuf0, void *);
20416ac29cbSAmit Prakash Shukla 		rte_memcpy(d0, nh[node_mbuf_priv1(mbuf0, dyn)->nh].rewrite_data,
20516ac29cbSAmit Prakash Shukla 			   nh[node_mbuf_priv1(mbuf0, dyn)->nh].rewrite_len);
20616ac29cbSAmit Prakash Shukla 
20716ac29cbSAmit Prakash Shukla 		next0 = nh[node_mbuf_priv1(mbuf0, dyn)->nh].tx_node;
20816ac29cbSAmit Prakash Shukla 		ip0 = (struct rte_ipv6_hdr *)((uint8_t *)d0 +
20916ac29cbSAmit Prakash Shukla 					      sizeof(struct rte_ether_hdr));
21016ac29cbSAmit Prakash Shukla 		ip0->hop_limits = node_mbuf_priv1(mbuf0, dyn)->ttl - 1;
21116ac29cbSAmit Prakash Shukla 
21216ac29cbSAmit Prakash Shukla 		if (unlikely(next_index ^ next0)) {
21316ac29cbSAmit Prakash Shukla 			/* Copy things successfully speculated till now */
21416ac29cbSAmit Prakash Shukla 			rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
21516ac29cbSAmit Prakash Shukla 			from += last_spec;
21616ac29cbSAmit Prakash Shukla 			to_next += last_spec;
21716ac29cbSAmit Prakash Shukla 			held += last_spec;
21816ac29cbSAmit Prakash Shukla 			last_spec = 0;
21916ac29cbSAmit Prakash Shukla 
22016ac29cbSAmit Prakash Shukla 			rte_node_enqueue_x1(graph, node, next0, from[0]);
22116ac29cbSAmit Prakash Shukla 			from += 1;
22216ac29cbSAmit Prakash Shukla 		} else {
22316ac29cbSAmit Prakash Shukla 			last_spec += 1;
22416ac29cbSAmit Prakash Shukla 		}
22516ac29cbSAmit Prakash Shukla 	}
22616ac29cbSAmit Prakash Shukla 
22716ac29cbSAmit Prakash Shukla 	/* !!! Home run !!! */
22816ac29cbSAmit Prakash Shukla 	if (likely(last_spec == nb_objs)) {
22916ac29cbSAmit Prakash Shukla 		rte_node_next_stream_move(graph, node, next_index);
23016ac29cbSAmit Prakash Shukla 		return nb_objs;
23116ac29cbSAmit Prakash Shukla 	}
23216ac29cbSAmit Prakash Shukla 
23316ac29cbSAmit Prakash Shukla 	held += last_spec;
23416ac29cbSAmit Prakash Shukla 	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
23516ac29cbSAmit Prakash Shukla 	rte_node_next_stream_put(graph, node, next_index, held);
23616ac29cbSAmit Prakash Shukla 	/* Save the last next used */
23716ac29cbSAmit Prakash Shukla 	IP6_REWRITE_NODE_LAST_NEXT(node->ctx) = next_index;
23816ac29cbSAmit Prakash Shukla 
23916ac29cbSAmit Prakash Shukla 	return nb_objs;
24016ac29cbSAmit Prakash Shukla }
24116ac29cbSAmit Prakash Shukla 
24216ac29cbSAmit Prakash Shukla static int
ip6_rewrite_node_init(const struct rte_graph * graph,struct rte_node * node)24316ac29cbSAmit Prakash Shukla ip6_rewrite_node_init(const struct rte_graph *graph, struct rte_node *node)
24416ac29cbSAmit Prakash Shukla {
24516ac29cbSAmit Prakash Shukla 	static bool init_once;
24616ac29cbSAmit Prakash Shukla 
24716ac29cbSAmit Prakash Shukla 	RTE_SET_USED(graph);
24816ac29cbSAmit Prakash Shukla 	RTE_BUILD_BUG_ON(sizeof(struct ip6_rewrite_node_ctx) > RTE_NODE_CTX_SZ);
24916ac29cbSAmit Prakash Shukla 
25016ac29cbSAmit Prakash Shukla 	if (!init_once) {
25116ac29cbSAmit Prakash Shukla 		node_mbuf_priv1_dynfield_offset = rte_mbuf_dynfield_register(
25216ac29cbSAmit Prakash Shukla 				&node_mbuf_priv1_dynfield_desc);
25316ac29cbSAmit Prakash Shukla 		if (node_mbuf_priv1_dynfield_offset < 0)
25416ac29cbSAmit Prakash Shukla 			return -rte_errno;
25516ac29cbSAmit Prakash Shukla 		init_once = true;
25616ac29cbSAmit Prakash Shukla 	}
25716ac29cbSAmit Prakash Shukla 	IP6_REWRITE_NODE_PRIV1_OFF(node->ctx) = node_mbuf_priv1_dynfield_offset;
25816ac29cbSAmit Prakash Shukla 
25916ac29cbSAmit Prakash Shukla 	node_dbg("ip6_rewrite", "Initialized ip6_rewrite node");
26016ac29cbSAmit Prakash Shukla 
26116ac29cbSAmit Prakash Shukla 	return 0;
26216ac29cbSAmit Prakash Shukla }
26316ac29cbSAmit Prakash Shukla 
26416ac29cbSAmit Prakash Shukla int
ip6_rewrite_set_next(uint16_t port_id,uint16_t next_index)26516ac29cbSAmit Prakash Shukla ip6_rewrite_set_next(uint16_t port_id, uint16_t next_index)
26616ac29cbSAmit Prakash Shukla {
26716ac29cbSAmit Prakash Shukla 	if (ip6_rewrite_nm == NULL) {
26816ac29cbSAmit Prakash Shukla 		ip6_rewrite_nm = rte_zmalloc(
26916ac29cbSAmit Prakash Shukla 			"ip6_rewrite", sizeof(struct ip6_rewrite_node_main),
27016ac29cbSAmit Prakash Shukla 			RTE_CACHE_LINE_SIZE);
27116ac29cbSAmit Prakash Shukla 		if (ip6_rewrite_nm == NULL)
27216ac29cbSAmit Prakash Shukla 			return -ENOMEM;
27316ac29cbSAmit Prakash Shukla 	}
27416ac29cbSAmit Prakash Shukla 	ip6_rewrite_nm->next_index[port_id] = next_index;
27516ac29cbSAmit Prakash Shukla 
27616ac29cbSAmit Prakash Shukla 	return 0;
27716ac29cbSAmit Prakash Shukla }
27816ac29cbSAmit Prakash Shukla 
27916ac29cbSAmit Prakash Shukla int
rte_node_ip6_rewrite_add(uint16_t next_hop,uint8_t * rewrite_data,uint8_t rewrite_len,uint16_t dst_port)28016ac29cbSAmit Prakash Shukla rte_node_ip6_rewrite_add(uint16_t next_hop, uint8_t *rewrite_data,
28116ac29cbSAmit Prakash Shukla 			 uint8_t rewrite_len, uint16_t dst_port)
28216ac29cbSAmit Prakash Shukla {
28316ac29cbSAmit Prakash Shukla 	struct ip6_rewrite_nh_header *nh;
28416ac29cbSAmit Prakash Shukla 
28516ac29cbSAmit Prakash Shukla 	if (next_hop >= RTE_GRAPH_IP6_REWRITE_MAX_NH)
28616ac29cbSAmit Prakash Shukla 		return -EINVAL;
28716ac29cbSAmit Prakash Shukla 
28816ac29cbSAmit Prakash Shukla 	if (rewrite_len > RTE_GRAPH_IP6_REWRITE_MAX_LEN)
28916ac29cbSAmit Prakash Shukla 		return -EINVAL;
29016ac29cbSAmit Prakash Shukla 
29116ac29cbSAmit Prakash Shukla 	if (ip6_rewrite_nm == NULL) {
29216ac29cbSAmit Prakash Shukla 		ip6_rewrite_nm = rte_zmalloc(
29316ac29cbSAmit Prakash Shukla 			"ip6_rewrite", sizeof(struct ip6_rewrite_node_main),
29416ac29cbSAmit Prakash Shukla 			RTE_CACHE_LINE_SIZE);
29516ac29cbSAmit Prakash Shukla 		if (ip6_rewrite_nm == NULL)
29616ac29cbSAmit Prakash Shukla 			return -ENOMEM;
29716ac29cbSAmit Prakash Shukla 	}
29816ac29cbSAmit Prakash Shukla 
29916ac29cbSAmit Prakash Shukla 	/* Check if dst port doesn't exist as edge */
30016ac29cbSAmit Prakash Shukla 	if (!ip6_rewrite_nm->next_index[dst_port])
30116ac29cbSAmit Prakash Shukla 		return -EINVAL;
30216ac29cbSAmit Prakash Shukla 
30316ac29cbSAmit Prakash Shukla 	/* Update next hop */
30416ac29cbSAmit Prakash Shukla 	nh = &ip6_rewrite_nm->nh[next_hop];
30516ac29cbSAmit Prakash Shukla 
30616ac29cbSAmit Prakash Shukla 	memcpy(nh->rewrite_data, rewrite_data, rewrite_len);
30716ac29cbSAmit Prakash Shukla 	nh->tx_node = ip6_rewrite_nm->next_index[dst_port];
30816ac29cbSAmit Prakash Shukla 	nh->rewrite_len = rewrite_len;
30916ac29cbSAmit Prakash Shukla 	nh->enabled = true;
31016ac29cbSAmit Prakash Shukla 
31116ac29cbSAmit Prakash Shukla 	return 0;
31216ac29cbSAmit Prakash Shukla }
31316ac29cbSAmit Prakash Shukla 
31416ac29cbSAmit Prakash Shukla static struct rte_node_register ip6_rewrite_node = {
31516ac29cbSAmit Prakash Shukla 	.process = ip6_rewrite_node_process,
31616ac29cbSAmit Prakash Shukla 	.name = "ip6_rewrite",
31716ac29cbSAmit Prakash Shukla 	/* Default edge i.e '0' is pkt drop */
31816ac29cbSAmit Prakash Shukla 	.nb_edges = 1,
31916ac29cbSAmit Prakash Shukla 	.next_nodes = {
32016ac29cbSAmit Prakash Shukla 		[0] = "pkt_drop",
32116ac29cbSAmit Prakash Shukla 	},
32216ac29cbSAmit Prakash Shukla 	.init = ip6_rewrite_node_init,
32316ac29cbSAmit Prakash Shukla };
32416ac29cbSAmit Prakash Shukla 
32516ac29cbSAmit Prakash Shukla struct rte_node_register *
ip6_rewrite_node_get(void)32616ac29cbSAmit Prakash Shukla ip6_rewrite_node_get(void)
32716ac29cbSAmit Prakash Shukla {
32816ac29cbSAmit Prakash Shukla 	return &ip6_rewrite_node;
32916ac29cbSAmit Prakash Shukla }
33016ac29cbSAmit Prakash Shukla 
33116ac29cbSAmit Prakash Shukla RTE_NODE_REGISTER(ip6_rewrite_node);
332