summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Simonart <xavier.simonart@intel.com>2020-07-11 15:54:49 +0200
committerXavier Simonart <xavier.simonart@intel.com>2020-09-21 10:09:46 +0200
commitdcbc010d7e50d5d42ce5ecba9b6a2234998e7c88 (patch)
tree46c7ef3eb1d1d0b385b57c707d14fbc04080316c
parent91a44713bf414610246df57478b406a5561b725f (diff)
Improve performance in IPv6 generator
Change-Id: I3abc92652402162d15249e345446debdeb778176 Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
-rw-r--r--VNFs/DPPD-PROX/handle_swap.c4
-rw-r--r--VNFs/DPPD-PROX/packet_utils.c64
-rw-r--r--VNFs/DPPD-PROX/packet_utils.h2
-rw-r--r--VNFs/DPPD-PROX/tx_pkt.c3
4 files changed, 28 insertions, 45 deletions
diff --git a/VNFs/DPPD-PROX/handle_swap.c b/VNFs/DPPD-PROX/handle_swap.c
index e097bc05..094199e4 100644
--- a/VNFs/DPPD-PROX/handle_swap.c
+++ b/VNFs/DPPD-PROX/handle_swap.c
@@ -61,7 +61,7 @@ static void write_src_and_dst_mac(struct task_swap *task, struct rte_mbuf *mbuf)
rte_memcpy(hdr, task->src_dst_mac, sizeof(task->src_dst_mac));
} else {
hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
- if (likely((task->runtime_flags & TASK_ARG_SRC_MAC_SET) == 0)) {
+ if (unlikely((task->runtime_flags & TASK_ARG_SRC_MAC_SET) == 0)) {
/* dst mac will be used as src mac */
prox_rte_ether_addr_copy(&hdr->d_addr, &mac);
}
@@ -71,7 +71,7 @@ static void write_src_and_dst_mac(struct task_swap *task, struct rte_mbuf *mbuf)
else
prox_rte_ether_addr_copy(&hdr->s_addr, &hdr->d_addr);
- if (unlikely(task->runtime_flags & TASK_ARG_SRC_MAC_SET)) {
+ if (likely(task->runtime_flags & TASK_ARG_SRC_MAC_SET)) {
prox_rte_ether_addr_copy((prox_rte_ether_addr *)&task->src_dst_mac[6], &hdr->s_addr);
} else {
prox_rte_ether_addr_copy(&mac, &hdr->s_addr);
diff --git a/VNFs/DPPD-PROX/packet_utils.c b/VNFs/DPPD-PROX/packet_utils.c
index 7be978db..bb942998 100644
--- a/VNFs/DPPD-PROX/packet_utils.c
+++ b/VNFs/DPPD-PROX/packet_utils.c
@@ -46,7 +46,7 @@ static inline int find_ip(struct ether_hdr_arp *pkt, uint16_t len, uint32_t *ip_
*vlan = 0;
// Unstack VLAN tags
- while (((ether_type == ETYPE_8021ad) || (ether_type == ETYPE_VLAN)) && (l2_len + sizeof(prox_rte_vlan_hdr) < len)) {
+ while (((ether_type == ETYPE_VLAN) || (ether_type == ETYPE_8021ad)) && (l2_len + sizeof(prox_rte_vlan_hdr) < len)) {
vlan_hdr = (prox_rte_vlan_hdr *)((uint8_t *)pkt + l2_len);
l2_len +=4;
ether_type = vlan_hdr->eth_proto;
@@ -100,40 +100,23 @@ static inline void find_vlan(struct ether_hdr_arp *pkt, uint16_t len, uint16_t *
static inline struct ipv6_addr *find_ip6(prox_rte_ether_hdr *pkt, uint16_t len, struct ipv6_addr *ip_dst, uint16_t *vlan)
{
- prox_rte_vlan_hdr *vlan_hdr;
- prox_rte_ipv6_hdr *ip;
uint16_t ether_type = pkt->ether_type;
uint16_t l2_len = sizeof(prox_rte_ether_hdr);
-
*vlan = 0;
- // Unstack VLAN tags
- while (((ether_type == ETYPE_8021ad) || (ether_type == ETYPE_VLAN)) && (l2_len + sizeof(prox_rte_vlan_hdr) < len)) {
- vlan_hdr = (prox_rte_vlan_hdr *)((uint8_t *)pkt + l2_len);
- l2_len +=4;
- ether_type = vlan_hdr->eth_proto;
- *vlan = rte_be_to_cpu_16(vlan_hdr->vlan_tci & 0xFF0F); // Store VLAN, or CVLAN if QinQ
- }
- switch (ether_type) {
- case ETYPE_MPLSU:
- case ETYPE_MPLSM:
- // In case of MPLS, next hop MAC is based on MPLS, not destination IP
- l2_len = 0;
- break;
- case ETYPE_IPv4:
- case ETYPE_EoGRE:
- case ETYPE_ARP:
- l2_len = 0;
- break;
- case ETYPE_IPv6:
- break;
- default:
- l2_len = 0;
- plog_warn("Unsupported packet type %x - CRC might be wrong\n", ether_type);
- break;
+ if ((ether_type == ETYPE_VLAN) || (ether_type == ETYPE_8021ad)) {
+ prox_rte_vlan_hdr *vlan_hdr = (prox_rte_vlan_hdr *)((uint8_t *)pkt + l2_len);
+ ether_type = vlan_hdr->eth_proto;
+ l2_len +=4;
+ *vlan = rte_be_to_cpu_16(vlan_hdr->vlan_tci & 0xFF0F);
+ if (ether_type == ETYPE_VLAN) {
+ vlan_hdr = (prox_rte_vlan_hdr *)(vlan_hdr + 1);
+ ether_type = vlan_hdr->eth_proto;
+ l2_len +=4;
+ *vlan = rte_be_to_cpu_16(vlan_hdr->vlan_tci & 0xFF0F);
+ }
}
-
- if (l2_len && (l2_len + sizeof(prox_rte_ipv6_hdr) <= len)) {
+ if ((ether_type == ETYPE_IPv6) && (l2_len + sizeof(prox_rte_ipv6_hdr) <= len)) {
prox_rte_ipv6_hdr *ip = (prox_rte_ipv6_hdr *)((uint8_t *)pkt + l2_len);
// TODO: implement LPM => replace ip_dst by next hop IP DST
memcpy(ip_dst, &ip->dst_addr, sizeof(struct ipv6_addr));
@@ -148,7 +131,7 @@ void send_unsollicited_neighbour_advertisement(struct task_base *tbase)
uint8_t out = 0, port_id = tbase->l3.reachable_port_id;
struct rte_mbuf *mbuf = NULL;
- if (memcmp(&tbase->l3.local_ipv6, &null_addr, 16) != 0) {
+ if (*(__int128 *)(&tbase->l3.local_ipv6) != 0) {
ret = rte_mempool_get(tbase->l3.arp_nd_pool, (void **)&mbuf);
if (likely(ret == 0)) {
mbuf->port = port_id;
@@ -160,7 +143,7 @@ void send_unsollicited_neighbour_advertisement(struct task_base *tbase)
return;
}
}
- if (memcmp(&tbase->l3.global_ipv6, &null_addr, 16) != 0) {
+ if (*(__int128 *)(&tbase->l3.global_ipv6) != 0) {
ret = rte_mempool_get(tbase->l3.arp_nd_pool, (void **)&mbuf);
if (likely(ret == 0)) {
mbuf->port = port_id;
@@ -365,14 +348,13 @@ int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_d
return DROP_MBUF;
}
-int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv6_addr *ip_dst, uint16_t *vlan)
+int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv6_addr *ip_dst, uint16_t *vlan, uint64_t tsc)
{
const uint64_t hz = rte_get_tsc_hz();
prox_rte_ether_hdr *packet = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *);
prox_rte_ether_addr *mac = &packet->d_addr;
struct ipv6_addr *used_ip_src;
- uint64_t tsc = rte_rdtsc();
uint16_t len = rte_pktmbuf_pkt_len(mbuf);
struct ipv6_addr *pkt_src_ip6;
@@ -383,33 +365,33 @@ int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv
struct l3_base *l3 = &(tbase->l3);
// Configure source IP
- if (memcmp(&l3->local_ipv6, ip_dst, 8) == 0) {
+ if (*(uint64_t *)(&l3->local_ipv6) == *(uint64_t *)ip_dst) {
// Same prefix as local -> use local
used_ip_src = &l3->local_ipv6;
- } else if (memcmp(&l3->global_ipv6 , ip_dst, 8) == 0) {
+ } else if (*(uint64_t *)(&l3->global_ipv6) == *(uint64_t *)ip_dst) {
// Same prefix as global -> use global
used_ip_src = &l3->global_ipv6;
- } else if (memcmp(&l3->gw.ip6 , &null_addr, sizeof(struct ipv6_addr)) != 0) {
+ } else if (*(__int128 *)(&l3->gw.ip6) != 0) {
used_ip_src = &l3->global_ipv6;
memcpy(ip_dst, &l3->gw.ip6, sizeof(struct ipv6_addr));
- } else if (memcmp(&l3->global_ipv6 , &null_addr, sizeof(struct ipv6_addr)) != 0) {
+ } else if (*(__int128 *)(&l3->global_ipv6) != 0) {
// Global IP is defined -> use it
used_ip_src = &l3->global_ipv6;
} else {
plog_info("Error as trying to send a packet to "IPv6_BYTES_FMT" using "IPv6_BYTES_FMT" (local)\n", IPv6_BYTES(ip_dst->bytes), IPv6_BYTES(l3->local_ipv6.bytes));
return DROP_MBUF;
}
- memcpy(pkt_src_ip6, used_ip_src, sizeof(struct ipv6_addr));
+ rte_memcpy(pkt_src_ip6, used_ip_src, sizeof(struct ipv6_addr));
// Configure dst mac
if (likely(l3->n_pkts < 4)) {
for (unsigned int idx = 0; idx < l3->n_pkts; idx++) {
- if (memcmp(ip_dst, &l3->optimized_arp_table[idx].ip6, sizeof(struct ipv6_addr)) == 0) {
+ if (*(__int128 *)ip_dst == *(__int128 *)(&l3->optimized_arp_table[idx].ip6)) {
// IP address already in table
if ((tsc < l3->optimized_arp_table[idx].arp_ndp_retransmit_timeout) && (tsc < l3->optimized_arp_table[idx].reachable_timeout)) {
// MAC address was recently updated in table, use it
// plog_dbg("Valid MAC address found => send packet\n");
- memcpy(mac, &l3->optimized_arp_table[idx].mac, sizeof(prox_rte_ether_addr));
+ rte_memcpy(mac, &l3->optimized_arp_table[idx].mac, sizeof(prox_rte_ether_addr));
return SEND_MBUF;
} else if (tsc > l3->optimized_arp_table[idx].arp_ndp_retransmit_timeout) {
// NDP not sent since a long time, send NDP
diff --git a/VNFs/DPPD-PROX/packet_utils.h b/VNFs/DPPD-PROX/packet_utils.h
index ce54a89e..ef15cd22 100644
--- a/VNFs/DPPD-PROX/packet_utils.h
+++ b/VNFs/DPPD-PROX/packet_utils.h
@@ -79,7 +79,7 @@ struct l3_base {
void task_init_l3(struct task_base *tbase, struct task_args *targ);
void task_start_l3(struct task_base *tbase, struct task_args *targ);
int write_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t *ip_dst, uint16_t *vlan, uint64_t **time, uint64_t tsc);
-int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv6_addr *ip_dst, uint16_t *vlan);
+int write_ip6_dst_mac(struct task_base *tbase, struct rte_mbuf *mbuf, struct ipv6_addr *ip_dst, uint16_t *vlan, uint64_t tsc);
void task_set_gateway_ip(struct task_base *tbase, uint32_t ip);
void task_set_local_ip(struct task_base *tbase, uint32_t ip);
void handle_ctrl_plane_pkts(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts);
diff --git a/VNFs/DPPD-PROX/tx_pkt.c b/VNFs/DPPD-PROX/tx_pkt.c
index d93c5fba..551056af 100644
--- a/VNFs/DPPD-PROX/tx_pkt.c
+++ b/VNFs/DPPD-PROX/tx_pkt.c
@@ -66,11 +66,12 @@ int tx_pkt_ndp(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts
const struct port_queue *port_queue = &tbase->tx_params_hw.tx_port_queue[0];
struct rte_mbuf *mbuf = NULL; // used when one need to send both an ARP and a mbuf
uint16_t vlan;
+ uint64_t tsc = rte_rdtsc();
for (int j = 0; j < n_pkts; j++) {
if ((out) && (out[j] >= OUT_HANDLED))
continue;
- if (unlikely((rc = write_ip6_dst_mac(tbase, mbufs[j], &ip_dst, &vlan)) != SEND_MBUF)) {
+ if (unlikely((rc = write_ip6_dst_mac(tbase, mbufs[j], &ip_dst, &vlan, tsc)) != SEND_MBUF)) {
if (j - first) {
ret = tbase->aux->tx_pkt_l2(tbase, mbufs + first, j - first, out);
ok += ret;