summaryrefslogtreecommitdiffstats
path: root/VNFs/vFW/pipeline/pipeline_vfw_be.c
diff options
context:
space:
mode:
authorDeepak S <deepak.s@linux.intel.com>2017-07-20 11:22:20 +0000
committerGerrit Code Review <gerrit@opnfv.org>2017-07-20 11:22:20 +0000
commit51759157a499326cfe69ec0eecb00b1c5879bf50 (patch)
treebb2197d5344b52ec015323a4fd5e36d6ec6937e4 /VNFs/vFW/pipeline/pipeline_vfw_be.c
parentcfe2f779d4365dba03659b64668cb301fae53c95 (diff)
parent0e51437be874b6831e95639f4c1ad6b0133c2a28 (diff)
Merge "[l2l3 stack] implements new arp state machine & arp buffering"
Diffstat (limited to 'VNFs/vFW/pipeline/pipeline_vfw_be.c')
-rw-r--r--VNFs/vFW/pipeline/pipeline_vfw_be.c251
1 files changed, 122 insertions, 129 deletions
diff --git a/VNFs/vFW/pipeline/pipeline_vfw_be.c b/VNFs/vFW/pipeline/pipeline_vfw_be.c
index b659ee58..f6ada29a 100644
--- a/VNFs/vFW/pipeline/pipeline_vfw_be.c
+++ b/VNFs/vFW/pipeline/pipeline_vfw_be.c
@@ -177,6 +177,7 @@ __rte_cache_aligned;
* to avoid useless table lookup
*/
/***** ARP local cache *****/
+#if 0
uint8_t link_hw_laddr_valid[MAX_NUM_LOCAL_MAC_ADDRESS] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
@@ -200,6 +201,8 @@ static struct ether_addr link_hw_laddr[MAX_NUM_LOCAL_MAC_ADDRESS] = {
{.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
{.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }
};
+#endif
+uint64_t arp_pkts_mask;
/* Start TSC measurement */
/* Prefetch counters and pipe before this function */
@@ -228,11 +231,11 @@ static inline void end_tsc_measure(
}
}
-static struct ether_addr *get_local_link_hw_addr(uint8_t out_port)
-{
- return &link_hw_laddr[out_port];
-}
-
+//static struct ether_addr *get_local_link_hw_addr(uint8_t out_port)
+//{
+// return &link_hw_laddr[out_port];
+//}
+#if 0
static uint8_t local_dest_mac_present(uint8_t out_port)
{
return link_hw_laddr_valid[out_port];
@@ -284,6 +287,7 @@ static void do_local_nh_ipv4_cache(uint32_t dest_if,
}
}
}
+#endif
static uint32_t local_get_nh_ipv6(
uint8_t *ip,
uint32_t *port,
@@ -895,15 +899,11 @@ pkt4_work_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
struct pipeline_vfw *vfw_pipe)
{
- uint32_t ret;
- int ret_mac;
uint8_t i;
- struct ether_addr hw_addr;
struct mbuf_tcp_meta_data *meta_data_addr;
struct ether_hdr *ehdr;
struct rte_mbuf *pkt;
- uint16_t phy_port;
for (i = 0; i < 4; i++) {
uint32_t dest_if = INVALID_DESTIF;
@@ -917,7 +917,6 @@ pkt4_work_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
int must_reverse = ((synproxy_reply_mask & pkt_mask) != 0);
- phy_port = pkt->port;
meta_data_addr = (struct mbuf_tcp_meta_data *)
RTE_MBUF_METADATA_UINT32_PTR(pkt, META_DATA_OFFSET);
ehdr = rte_vfw_get_ether_addr(pkt);
@@ -928,7 +927,9 @@ pkt4_work_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
uint32_t nhip = 0;
uint32_t dest_address = rte_bswap32(ihdr->dst_addr);
-
+ if (must_reverse)
+ rte_sp_exchange_mac_addresses(ehdr);
+#if 0
ret = local_get_nh_ipv4(dest_address, &dest_if,
&nhip, vfw_pipe);
if (must_reverse) {
@@ -993,55 +994,52 @@ pkt4_work_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
ether_addr_copy(get_link_hw_addr(dest_if),
&ehdr->s_addr);
} else {
- ret_mac = get_dest_mac_addr_port(dest_address,
- &dest_if, &hw_addr);
- if (ret_mac == ARP_FOUND) {
+#endif
+ struct arp_entry_data *ret_arp_data = NULL;
+ ret_arp_data = get_dest_mac_addr_port(dest_address,
+ &dest_if, &ehdr->d_addr);
+ meta_data_addr->output_port = vfw_pipe->outport_id[dest_if];
- link_hw_laddr_valid[dest_if] = 1;
- memcpy(&link_hw_laddr[dest_if], &hw_addr,
- sizeof(struct ether_addr));
+ if (arp_cache_dest_mac_present(dest_if)) {
- ether_addr_copy(&hw_addr, &ehdr->d_addr);
- ether_addr_copy(get_link_hw_addr(dest_if),
- &ehdr->s_addr);
+ ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
+ arp_data_ptr[dest_if]->n_last_update = time(NULL);
- if (vfw_debug >= DEBUG_LEVEL_4) {
- char buf[HW_ADDR_SIZE];
+ if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
+
+ printf("sending buffered packets\n");
+ arp_send_buffered_pkts(ret_arp_data,
+ &ehdr->d_addr, vfw_pipe->outport_id[dest_if]);
- ether_format_addr(buf, sizeof(buf),
- &hw_addr);
- printf("MAC found for ip 0x%"
- PRIx32", dest_if %d: %s, ",
- dest_address,
- dest_if, buf);
- ether_format_addr(buf, sizeof(buf),
- &ehdr->s_addr);
- printf("new eth hdr src: %s, ", buf);
- ether_format_addr(buf, sizeof(buf),
- &ehdr->d_addr);
- printf("new eth hdr dst: %s\n", buf);
}
} else {
+ if (unlikely(ret_arp_data == NULL)) {
- if (vfw_debug >= DEBUG_LEVEL_4) {
- char buf[HW_ADDR_SIZE];
+ printf("%s: NHIP Not Found, nhip:%x , "
+ "outport_id: %d\n", __func__, nhip,
+ vfw_pipe->outport_id[dest_if]);
- ether_format_addr(buf, sizeof(buf),
- &hw_addr);
- printf("MAC NOT FOUND for ip 0x%"
- PRIx32", dest_if %"
- PRId16": %s, ",
- dest_address,
- dest_if, buf);
+ /* Drop the pkt */
+ vfw_pipe->counters->
+ pkts_drop_without_arp_entry++;
+ continue;
}
+ if (ret_arp_data->status == INCOMPLETE ||
+ ret_arp_data->status == PROBE) {
+ if (ret_arp_data->num_pkts >= NUM_DESC) {
/* ICMP req sent, drop packet by
* changing the mask */
- *pkts_mask &= ~pkt_mask;
- vfw_pipe->
- counters->pkts_drop_without_arp_entry++;
+ vfw_pipe->counters->
+ pkts_drop_without_arp_entry++;
+ continue;
+ } else {
+ arp_pkts_mask |= pkt_mask;
+ arp_queue_unresolved_packet(ret_arp_data, pkt);
+ continue;
}
}
+ }
}
}
@@ -1072,15 +1070,11 @@ pkt_work_vfw_arp_ipv4_packets(struct rte_mbuf *pkts,
struct pipeline_vfw *vfw_pipe)
{
- uint32_t ret;
uint32_t dest_if = INVALID_DESTIF;
- int ret_mac;
- struct ether_addr hw_addr;
struct mbuf_tcp_meta_data *meta_data_addr;
struct ether_hdr *ehdr;
struct rte_mbuf *pkt;
- uint16_t phy_port;
uint64_t pkt_mask = 1LLU << pkt_num;
pkt = pkts;
@@ -1089,7 +1083,6 @@ pkt_work_vfw_arp_ipv4_packets(struct rte_mbuf *pkts,
int must_reverse = ((synproxy_reply_mask & pkt_mask) != 0);
- phy_port = pkt->port;
meta_data_addr = (struct mbuf_tcp_meta_data *)
RTE_MBUF_METADATA_UINT32_PTR(pkt, META_DATA_OFFSET);
ehdr = rte_vfw_get_ether_addr(pkt);
@@ -1100,7 +1093,10 @@ pkt_work_vfw_arp_ipv4_packets(struct rte_mbuf *pkts,
uint32_t nhip = 0;
uint32_t dest_address = rte_bswap32(ihdr->dst_addr);
+ if (must_reverse)
+ rte_sp_exchange_mac_addresses(ehdr);
+#if 0
ret = local_get_nh_ipv4(dest_address, &dest_if,
&nhip, vfw_pipe);
if (must_reverse) {
@@ -1165,53 +1161,50 @@ pkt_work_vfw_arp_ipv4_packets(struct rte_mbuf *pkts,
ether_addr_copy(get_link_hw_addr(dest_if),
&ehdr->s_addr);
} else {
- ret_mac = get_dest_mac_addr_port(dest_address,
- &dest_if, &hw_addr);
- if (ret_mac) {
- link_hw_laddr_valid[dest_if] = 1;
- memcpy(&link_hw_laddr[dest_if], &hw_addr,
- sizeof(struct ether_addr));
-
- ether_addr_copy(&hw_addr, &ehdr->d_addr);
- ether_addr_copy(get_link_hw_addr(dest_if),
- &ehdr->s_addr);
+#endif
+ struct arp_entry_data *ret_arp_data = NULL;
+ ret_arp_data = get_dest_mac_addr_port(dest_address,
+ &dest_if, &ehdr->d_addr);
+ meta_data_addr->output_port = vfw_pipe->outport_id[dest_if];
+ if (arp_cache_dest_mac_present(dest_if)) {
- if (vfw_debug >= DEBUG_LEVEL_4) {
- char buf[HW_ADDR_SIZE];
+ ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
+ arp_data_ptr[dest_if]->n_last_update = time(NULL);
+
+ if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
+
+ printf("sending buffered packets\n");
+ arp_send_buffered_pkts(ret_arp_data,
+ &ehdr->d_addr, vfw_pipe->outport_id[dest_if]);
- ether_format_addr(buf, sizeof(buf),
- &hw_addr);
- printf("MAC found for ip 0x%"
- PRIx32", dest_if %d: %s, ",
- dest_address,
- dest_if, buf);
- ether_format_addr(buf, sizeof(buf),
- &ehdr->s_addr);
- printf("new eth hdr src: %s, ", buf);
- ether_format_addr(buf, sizeof(buf),
- &ehdr->d_addr);
- printf("new eth hdr dst: %s\n", buf);
}
} else {
- if (vfw_debug >= DEBUG_LEVEL_4) {
- char buf[HW_ADDR_SIZE];
-
- ether_format_addr(buf, sizeof(buf),
- &hw_addr);
- printf("MAC NOT FOUND for ip 0x%"
- PRIx32", dest_if %"
- PRId16": %s, ",
- dest_address,
- dest_if, buf);
+ if (unlikely(ret_arp_data == NULL)) {
+
+ printf("%s: NHIP Not Found, nhip:%x , "
+ "outport_id: %d\n", __func__, nhip,
+ vfw_pipe->outport_id[dest_if]);
+
+ vfw_pipe->counters->
+ pkts_drop_without_arp_entry++;
+ return;
}
+ if (ret_arp_data->status == INCOMPLETE ||
+ ret_arp_data->status == PROBE) {
+ if (ret_arp_data->num_pkts >= NUM_DESC) {
/* ICMP req sent, drop packet by
* changing the mask */
- *pkts_mask &= ~pkt_mask;
- vfw_pipe->
- counters->pkts_drop_without_arp_entry++;
+ vfw_pipe->counters->
+ pkts_drop_without_arp_entry++;
+ return;
+ } else {
+ arp_pkts_mask |= pkt_mask;
+ arp_queue_unresolved_packet(ret_arp_data, pkt);
+ return;
}
}
+ }
}
}
@@ -1567,7 +1560,6 @@ rte_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
uint32_t ret;
uint32_t dest_if = INVALID_DESTIF;
- int ret_mac;
for (; pkts_to_arp;) {
struct ether_addr hw_addr;
struct mbuf_tcp_meta_data *meta_data_addr;
@@ -1594,7 +1586,9 @@ rte_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
uint32_t nhip = 0;
uint32_t dest_address = rte_bswap32(ihdr->dst_addr);
-
+ if (must_reverse)
+ rte_sp_exchange_mac_addresses(ehdr);
+#if 0
ret = local_get_nh_ipv4(dest_address, &dest_if,
&nhip, vfw_pipe);
if (must_reverse) {
@@ -1659,57 +1653,52 @@ rte_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
ether_addr_copy(get_link_hw_addr(dest_if),
&ehdr->s_addr);
} else {
- ret_mac = get_dest_mac_addr_port(dest_address,
- &dest_if, &hw_addr);
- if (ret_mac) {
- link_hw_laddr_valid[dest_if] = 1;
- memcpy(&link_hw_laddr[dest_if], &hw_addr,
- sizeof(struct ether_addr));
-
- ether_addr_copy(&hw_addr, &ehdr->d_addr);
- ether_addr_copy(get_link_hw_addr(dest_if),
- &ehdr->s_addr);
+#endif
+ struct arp_entry_data *ret_arp_data = NULL;
+ ret_arp_data = get_dest_mac_addr_port(dest_address,
+ &dest_if, &ehdr->d_addr);
+ meta_data_addr->output_port = vfw_pipe->outport_id[dest_if];
+ if (arp_cache_dest_mac_present(dest_if)) {
- if (vfw_debug >= DEBUG_LEVEL_4) {
- char buf[HW_ADDR_SIZE];
+ ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
+ arp_data_ptr[dest_if]->n_last_update = time(NULL);
+
+ if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
+
+ printf("sending buffered packets\n");
+ p_nat->naptedPktCount += ret_arp_data->num_pkts;
+ arp_send_buffered_pkts(ret_arp_data,
+ &ehdr->d_addr, vfw_pipe->outport_id[dest_if]);
- ether_format_addr(buf, sizeof(buf),
- &hw_addr);
- printf("MAC found for ip 0x%"
- PRIx32", dest_if %d: %s, ",
- dest_address,
- dest_if, buf);
- ether_format_addr(buf, sizeof(buf),
- &ehdr->s_addr);
- printf("new eth hdr src: %s, ", buf);
- ether_format_addr(buf, sizeof(buf),
- &ehdr->d_addr);
- printf("new eth hdr dst: %s\n", buf);
}
} else {
- if (unlikely(ret_mac == 0))
- request_arp(meta_data_addr->output_port,
- nhip);
+ if (unlikely(ret_arp_data == NULL)) {
- if (vfw_debug >= DEBUG_LEVEL_4) {
- char buf[HW_ADDR_SIZE];
+ printf("%s: NHIP Not Found, nhip:%x , "
+ "outport_id: %d\n", __func__, nhip,
+ vfw_pipe->outport_id[dest_if]);
- ether_format_addr(buf, sizeof(buf),
- &hw_addr);
- printf("MAC NOT FOUND for ip 0x%"
- PRIx32", dest_if %"
- PRId16": %s, ",
- dest_address,
- dest_if, buf);
+ /* Drop the pkt */
+ vfw_pipe->counters->
+ pkts_drop_without_arp_entry++;
+ continue;
}
+ if (ret_arp_data->status == INCOMPLETE ||
+ ret_arp_data->status == PROBE) {
+ if (ret_arp_data->num_pkts >= NUM_DESC) {
/* ICMP req sent, drop packet by
* changing the mask */
- pkts_mask &= ~pkt_mask;
- vfw_pipe->
- counters->pkts_drop_without_arp_entry++;
+ vfw_pipe->counters->
+ pkts_drop_without_arp_entry++;
+ continue;
+ } else {
+ arp_pkts_mask |= pkt_mask;
+ arp_queue_unresolved_packet(ret_arp_data, pkt);
+ continue;
}
}
+ }
}
@@ -2070,6 +2059,7 @@ vfw_port_in_action_ipv4(struct rte_pipeline *p,
uint64_t packet_mask_in = RTE_LEN2MASK(n_pkts, uint64_t);
uint64_t pkts_drop_mask;
uint64_t hijack_mask = 0;
+ arp_pkts_mask = 0;
uint64_t synproxy_reply_mask = 0; /* for synproxy */
uint64_t keep_mask = packet_mask_in;
@@ -2204,6 +2194,9 @@ vfw_port_in_action_ipv4(struct rte_pipeline *p,
}
/* Update mask before returning, so that bad packets are dropped */
+ if (arp_pkts_mask) {
+ rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
+ }
pkts_drop_mask = packet_mask_in & ~keep_mask;