From 7286b2518ec8e4398b512ce95def9166a7af2e4a Mon Sep 17 00:00:00 2001 From: Deepak S Date: Thu, 13 Jul 2017 21:26:50 -0700 Subject: Adding PROX(Packet pROcessing eXecution engine) VNF to sampleVNF JIRA: SAMPLEVNF-55 PROX is a DPDK-based application implementing Telco use-cases such as a simplified BRAS/BNG, light-weight AFTR... It also allows configuring finer grained network functions like QoS, Routing, load-balancing... (We are moving PROX version v039 to sampleVNF https://01.org/intel-data-plane-performance-demonstrators/prox-overview) Change-Id: Ia3cb02cf0e49ac5596e922c197ff7e010293d033 Signed-off-by: Deepak S --- VNFs/DPPD-PROX/handle_lb_pos.c | 156 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 VNFs/DPPD-PROX/handle_lb_pos.c (limited to 'VNFs/DPPD-PROX/handle_lb_pos.c') diff --git a/VNFs/DPPD-PROX/handle_lb_pos.c b/VNFs/DPPD-PROX/handle_lb_pos.c new file mode 100644 index 00000000..4324e94d --- /dev/null +++ b/VNFs/DPPD-PROX/handle_lb_pos.c @@ -0,0 +1,156 @@ +/* +// Copyright (c) 2010-2017 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +#include +#include +#include +#include + +#include "log.h" +#include "task_base.h" +#include "defines.h" +#include "tx_pkt.h" +#include "task_init.h" +#include "quit.h" +#include "mpls.h" +#include "etypes.h" +#include "gre.h" +#include "prefetch.h" + +struct task_lb_pos { + struct task_base base; + uint16_t byte_offset; + uint8_t n_workers; +}; + +static void init_task_lb_pos(struct task_base *tbase, struct task_args *targ) +{ + struct task_lb_pos *task = (struct task_lb_pos *)tbase; + + task->n_workers = targ->nb_worker_threads; + task->byte_offset = targ->byte_offset; +} + +static int handle_lb_pos_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts) +{ + struct task_lb_pos *task = (struct task_lb_pos *)tbase; + uint8_t out[MAX_PKT_BURST]; + uint16_t offset = task->byte_offset; + uint16_t j; + + prefetch_first(mbufs, n_pkts); + + for (j = 0; j + PREFETCH_OFFSET < n_pkts; ++j) { +#ifdef PROX_PREFETCH_OFFSET + PREFETCH0(mbufs[j + PREFETCH_OFFSET]); + PREFETCH0(rte_pktmbuf_mtod(mbufs[j + PREFETCH_OFFSET - 1], void *)); +#endif + uint8_t* pkt = rte_pktmbuf_mtod(mbufs[j], uint8_t*); + out[j] = pkt[offset] % task->n_workers; + } +#ifdef PROX_PREFETCH_OFFSET + PREFETCH0(rte_pktmbuf_mtod(mbufs[n_pkts - 1], void *)); + for (; j < n_pkts; ++j) { + uint8_t* pkt = rte_pktmbuf_mtod(mbufs[j], uint8_t*); + out[j] = pkt[offset] % task->n_workers; + } +#endif + + return task->base.tx_pkt(&task->base, mbufs, n_pkts, out); +} + +union ip_port { + struct { + uint32_t ip; + uint32_t port; + }; + uint64_t ip_port; +}; + +struct pkt_ether_ipv4_udp { + struct ether_hdr ether; + struct ipv4_hdr ipv4; + struct udp_hdr udp; +} __attribute__((unused)); + +static uint8_t handle_lb_ip_port(struct task_lb_pos *task, struct rte_mbuf *mbuf) +{ + union ip_port ip_port; + uint8_t ret; + + struct pkt_ether_ipv4_udp *pkt = rte_pktmbuf_mtod(mbuf, void *); + + if (pkt->ether.ether_type != ETYPE_IPv4 || + (pkt->ipv4.next_proto_id != IPPROTO_TCP && + pkt->ipv4.next_proto_id != IPPROTO_UDP)) + return OUT_DISCARD; + + if (task->byte_offset == 0) { + ip_port.ip = pkt->ipv4.src_addr; + ip_port.port = pkt->udp.src_port; + } + else { + ip_port.ip = pkt->ipv4.dst_addr; + ip_port.port = pkt->udp.dst_port; + } + + return rte_hash_crc(&ip_port.ip_port, sizeof(ip_port.ip_port), 0) % task->n_workers; +} + +static int handle_lb_ip_port_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts) +{ + struct task_lb_pos *task = (struct task_lb_pos *)tbase; + uint8_t out[MAX_PKT_BURST]; + uint16_t j; + uint64_t ip_port = 0; + + for (j = 0; j + PREFETCH_OFFSET < n_pkts; ++j) { +#ifdef PROX_PREFETCH_OFFSET + PREFETCH0(mbufs[j + PREFETCH_OFFSET]); + PREFETCH0(rte_pktmbuf_mtod(mbufs[j + PREFETCH_OFFSET - 1], void *)); +#endif + out[j] = handle_lb_ip_port(task, mbufs[j]); + } +#ifdef PROX_PREFETCH_OFFSET + PREFETCH0(rte_pktmbuf_mtod(mbufs[n_pkts - 1], void *)); + for (; j < n_pkts; ++j) { + out[j] = handle_lb_ip_port(task, mbufs[j]); + } +#endif + + return task->base.tx_pkt(&task->base, mbufs, n_pkts, out); +} + +static struct task_init task_init_lb_pos = { + .mode_str = "lbpos", + .init = init_task_lb_pos, + .handle = handle_lb_pos_bulk, + .size = sizeof(struct task_lb_pos) +}; + +static struct task_init task_init_lb_pos2 = { + .mode_str = "lbpos", + .sub_mode_str = "ip_port", + .init = init_task_lb_pos, + .handle = handle_lb_ip_port_bulk, + .size = sizeof(struct task_lb_pos) +}; + +__attribute__((constructor)) static void reg_task_lb_pos(void) +{ + reg_task(&task_init_lb_pos); + reg_task(&task_init_lb_pos2); +} -- cgit 1.2.3-korg