diff options
author | 2020-04-24 21:52:12 +0200 | |
---|---|---|
committer | 2020-05-29 23:28:44 +0200 | |
commit | ca250755c6ecad89fc30507a4c6707eedc658f5d (patch) | |
tree | c3a573bc038ba7872e0a19b4927c1ae96803fe68 /VNFs/DPPD-PROX/handle_swap.c | |
parent | fa869940dd9bb459ac599fe80c26c9d3e720fd31 (diff) |
Added support for netlink
Through this commit ARP and ICMP messages are forwarded to the kernel
when vdev tap devices are enabled, as well as PROX l3 mode.
ICMP support has also been added to master (i.e. PROX L3 mode) and to
swap (so when L3 submode is not enabled).
Change-Id: Ie6bf52cbae7171bfca041ff18651d4ec866f44cd
Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
Diffstat (limited to 'VNFs/DPPD-PROX/handle_swap.c')
-rw-r--r-- | VNFs/DPPD-PROX/handle_swap.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/VNFs/DPPD-PROX/handle_swap.c b/VNFs/DPPD-PROX/handle_swap.c index 457c2fac..a7a153a4 100644 --- a/VNFs/DPPD-PROX/handle_swap.c +++ b/VNFs/DPPD-PROX/handle_swap.c @@ -1,5 +1,5 @@ /* -// Copyright (c) 2010-2017 Intel Corporation +// Copyright (c) 2010-2020 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ #include "qinq.h" #include "gre.h" #include "prefetch.h" +#include "defines.h" #include "igmp.h" #include "prox_cksum.h" #include "prox_compat.h" @@ -38,6 +39,10 @@ struct task_swap { uint8_t src_dst_mac[12]; uint32_t local_ipv4; int offload_crc; + uint64_t last_echo_req_rcvd_tsc; + uint64_t last_echo_rep_rcvd_tsc; + uint32_t n_echo_req; + uint32_t n_echo_rep; }; #define NB_IGMP_MBUF 1024 @@ -79,6 +84,21 @@ static inline void build_mcast_mac(uint32_t ip, prox_rte_ether_addr *dst_mac) memcpy(dst_mac, &mac, sizeof(prox_rte_ether_addr)); } +static inline void build_icmp_reply_message(struct task_base *tbase, struct rte_mbuf *mbuf) +{ + struct task_swap *task = (struct task_swap *)tbase; + prox_rte_ether_hdr *hdr = rte_pktmbuf_mtod(mbuf, prox_rte_ether_hdr *); + prox_rte_ether_addr dst_mac; + prox_rte_ether_addr_copy(&hdr->s_addr, &dst_mac); + prox_rte_ether_addr_copy(&hdr->d_addr, &hdr->s_addr); + prox_rte_ether_addr_copy(&dst_mac, &hdr->d_addr); + prox_rte_ipv4_hdr *ip_hdr = (prox_rte_ipv4_hdr *)(hdr + 1); + ip_hdr->dst_addr = ip_hdr->src_addr; + ip_hdr->src_addr = task->local_ipv4; + prox_rte_icmp_hdr *picmp = (prox_rte_icmp_hdr *)(ip_hdr + 1); + picmp->icmp_type = PROX_RTE_IP_ICMP_ECHO_REPLY; +} + static inline void build_igmp_message(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t ip, uint8_t igmp_message) { struct task_swap *task = (struct task_swap *)tbase; @@ -131,6 +151,7 @@ static int handle_swap_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, ui prox_rte_vlan_hdr *vlan; uint16_t j; struct igmpv2_hdr *pigmp; + prox_rte_icmp_hdr *picmp; uint8_t type; for (j = 0; j < n_pkts; ++j) { @@ -239,6 +260,39 @@ static int handle_swap_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, ui udp_hdr->src_port = port; write_src_and_dst_mac(task, mbufs[j]); break; + case IPPROTO_ICMP: + picmp = (prox_rte_icmp_hdr *)(ip_hdr + 1); + type = picmp->icmp_type; + if (type == PROX_RTE_IP_ICMP_ECHO_REQUEST) { + if (ip_hdr->dst_addr == task->local_ipv4) { + task->n_echo_req++; + if (rte_rdtsc() - task->last_echo_req_rcvd_tsc > rte_get_tsc_hz()) { + plog_info("Received %u Echo Request on IP "IPv4_BYTES_FMT" (last received from IP "IPv4_BYTES_FMT")\n", task->n_echo_req, IPv4_BYTES(((uint8_t*)&ip_hdr->dst_addr)), IPv4_BYTES(((uint8_t*)&ip_hdr->src_addr))); + task->n_echo_req = 0; + task->last_echo_req_rcvd_tsc = rte_rdtsc(); + } + build_icmp_reply_message(tbase, mbufs[j]); + } else { + out[j] = OUT_DISCARD; + continue; + } + } else if (type == PROX_RTE_IP_ICMP_ECHO_REPLY) { + if (ip_hdr->dst_addr == task->local_ipv4) { + task->n_echo_rep++; + if (rte_rdtsc() - task->last_echo_rep_rcvd_tsc > rte_get_tsc_hz()) { + plog_info("Received %u Echo Reply on IP "IPv4_BYTES_FMT" (last received from IP "IPv4_BYTES_FMT")\n", task->n_echo_rep, IPv4_BYTES(((uint8_t*)&ip_hdr->dst_addr)), IPv4_BYTES(((uint8_t*)&ip_hdr->src_addr))); + task->n_echo_rep = 0; + task->last_echo_rep_rcvd_tsc = rte_rdtsc(); + } + } else { + out[j] = OUT_DISCARD; + continue; + } + } else { + out[j] = OUT_DISCARD; + continue; + } + break; case IPPROTO_IGMP: pigmp = (struct igmpv2_hdr *)(ip_hdr + 1); // TODO: check packet len |