X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_node%2Fip4_rewrite.c;h=99ecb457ffc6d756b77827d582a4da9e51a096c6;hb=2b9a66e1b606d3813d72dd81c626949e09706e27;hp=333e347615fa17e794552c243dc2042ed8a53e1d;hpb=0d352661e066fe2cb386753c89368f014fc4396b;p=dpdk.git diff --git a/lib/librte_node/ip4_rewrite.c b/lib/librte_node/ip4_rewrite.c index 333e347615..99ecb457ff 100644 --- a/lib/librte_node/ip4_rewrite.c +++ b/lib/librte_node/ip4_rewrite.c @@ -19,14 +19,28 @@ #include "ip4_rewrite_priv.h" #include "node_private.h" +struct ip4_rewrite_node_ctx { + /* Dynamic offset to mbuf priv1 */ + int mbuf_priv1_off; + /* Cached next index */ + uint16_t next_index; +}; + static struct ip4_rewrite_node_main *ip4_rewrite_nm; +#define IP4_REWRITE_NODE_LAST_NEXT(ctx) \ + (((struct ip4_rewrite_node_ctx *)ctx)->next_index) + +#define IP4_REWRITE_NODE_PRIV1_OFF(ctx) \ + (((struct ip4_rewrite_node_ctx *)ctx)->mbuf_priv1_off) + static uint16_t ip4_rewrite_node_process(struct rte_graph *graph, struct rte_node *node, void **objs, uint16_t nb_objs) { struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3, **pkts; struct ip4_rewrite_nh_header *nh = ip4_rewrite_nm->nh; + const int dyn = IP4_REWRITE_NODE_PRIV1_OFF(node->ctx); uint16_t next0, next1, next2, next3, next_index; struct rte_ipv4_hdr *ip0, *ip1, *ip2, *ip3; uint16_t n_left_from, held = 0, last_spec = 0; @@ -37,7 +51,7 @@ ip4_rewrite_node_process(struct rte_graph *graph, struct rte_node *node, int i; /* Speculative next as last next */ - next_index = *(uint16_t *)node->ctx; + next_index = IP4_REWRITE_NODE_LAST_NEXT(node->ctx); rte_prefetch0(nh); pkts = (struct rte_mbuf **)objs; @@ -68,10 +82,10 @@ ip4_rewrite_node_process(struct rte_graph *graph, struct rte_node *node, pkts += 4; n_left_from -= 4; - priv01.u64[0] = node_mbuf_priv1(mbuf0)->u; - priv01.u64[1] = node_mbuf_priv1(mbuf1)->u; - priv23.u64[0] = node_mbuf_priv1(mbuf2)->u; - priv23.u64[1] = node_mbuf_priv1(mbuf3)->u; + priv01.u64[0] = node_mbuf_priv1(mbuf0, dyn)->u; + priv01.u64[1] = node_mbuf_priv1(mbuf1, dyn)->u; + priv23.u64[0] = node_mbuf_priv1(mbuf2, dyn)->u; + priv23.u64[1] = node_mbuf_priv1(mbuf3, dyn)->u; /* Increment checksum by one. */ priv01.u32[1] += rte_cpu_to_be_16(0x0100); @@ -203,17 +217,17 @@ ip4_rewrite_node_process(struct rte_graph *graph, struct rte_node *node, n_left_from -= 1; d0 = rte_pktmbuf_mtod(mbuf0, void *); - rte_memcpy(d0, nh[node_mbuf_priv1(mbuf0)->nh].rewrite_data, - nh[node_mbuf_priv1(mbuf0)->nh].rewrite_len); + rte_memcpy(d0, nh[node_mbuf_priv1(mbuf0, dyn)->nh].rewrite_data, + nh[node_mbuf_priv1(mbuf0, dyn)->nh].rewrite_len); - next0 = nh[node_mbuf_priv1(mbuf0)->nh].tx_node; + next0 = nh[node_mbuf_priv1(mbuf0, dyn)->nh].tx_node; ip0 = (struct rte_ipv4_hdr *)((uint8_t *)d0 + sizeof(struct rte_ether_hdr)); - chksum = node_mbuf_priv1(mbuf0)->cksum + + chksum = node_mbuf_priv1(mbuf0, dyn)->cksum + rte_cpu_to_be_16(0x0100); chksum += chksum >= 0xffff; ip0->hdr_checksum = chksum; - ip0->time_to_live = node_mbuf_priv1(mbuf0)->ttl - 1; + ip0->time_to_live = node_mbuf_priv1(mbuf0, dyn)->ttl - 1; if (unlikely(next_index ^ next0)) { /* Copy things successfully speculated till now */ @@ -240,7 +254,7 @@ ip4_rewrite_node_process(struct rte_graph *graph, struct rte_node *node, rte_memcpy(to_next, from, last_spec * sizeof(from[0])); rte_node_next_stream_put(graph, node, next_index, held); /* Save the last next used */ - *(uint16_t *)node->ctx = next_index; + IP4_REWRITE_NODE_LAST_NEXT(node->ctx) = next_index; return nb_objs; } @@ -248,14 +262,75 @@ ip4_rewrite_node_process(struct rte_graph *graph, struct rte_node *node, static int ip4_rewrite_node_init(const struct rte_graph *graph, struct rte_node *node) { + static bool init_once; RTE_SET_USED(graph); - RTE_SET_USED(node); + RTE_BUILD_BUG_ON(sizeof(struct ip4_rewrite_node_ctx) > RTE_NODE_CTX_SZ); + + if (!init_once) { + node_mbuf_priv1_dynfield_offset = rte_mbuf_dynfield_register( + &node_mbuf_priv1_dynfield_desc); + if (node_mbuf_priv1_dynfield_offset < 0) + return -rte_errno; + init_once = true; + } + IP4_REWRITE_NODE_PRIV1_OFF(node->ctx) = node_mbuf_priv1_dynfield_offset; + node_dbg("ip4_rewrite", "Initialized ip4_rewrite node initialized"); return 0; } +int +ip4_rewrite_set_next(uint16_t port_id, uint16_t next_index) +{ + if (ip4_rewrite_nm == NULL) { + ip4_rewrite_nm = rte_zmalloc( + "ip4_rewrite", sizeof(struct ip4_rewrite_node_main), + RTE_CACHE_LINE_SIZE); + if (ip4_rewrite_nm == NULL) + return -ENOMEM; + } + ip4_rewrite_nm->next_index[port_id] = next_index; + + return 0; +} + +int +rte_node_ip4_rewrite_add(uint16_t next_hop, uint8_t *rewrite_data, + uint8_t rewrite_len, uint16_t dst_port) +{ + struct ip4_rewrite_nh_header *nh; + + if (next_hop >= RTE_GRAPH_IP4_REWRITE_MAX_NH) + return -EINVAL; + + if (rewrite_len > RTE_GRAPH_IP4_REWRITE_MAX_LEN) + return -EINVAL; + + if (ip4_rewrite_nm == NULL) { + ip4_rewrite_nm = rte_zmalloc( + "ip4_rewrite", sizeof(struct ip4_rewrite_node_main), + RTE_CACHE_LINE_SIZE); + if (ip4_rewrite_nm == NULL) + return -ENOMEM; + } + + /* Check if dst port doesn't exist as edge */ + if (!ip4_rewrite_nm->next_index[dst_port]) + return -EINVAL; + + /* Update next hop */ + nh = &ip4_rewrite_nm->nh[next_hop]; + + memcpy(nh->rewrite_data, rewrite_data, rewrite_len); + nh->tx_node = ip4_rewrite_nm->next_index[dst_port]; + nh->rewrite_len = rewrite_len; + nh->enabled = true; + + return 0; +} + static struct rte_node_register ip4_rewrite_node = { .process = ip4_rewrite_node_process, .name = "ip4_rewrite", @@ -267,4 +342,10 @@ static struct rte_node_register ip4_rewrite_node = { .init = ip4_rewrite_node_init, }; +struct rte_node_register * +ip4_rewrite_node_get(void) +{ + return &ip4_rewrite_node; +} + RTE_NODE_REGISTER(ip4_rewrite_node);