From 0e51437be874b6831e95639f4c1ad6b0133c2a28 Mon Sep 17 00:00:00 2001 From: Vishwesh M Rudramuni Date: Tue, 6 Jun 2017 04:11:25 +0530 Subject: [l2l3 stack] implements new arp state machine & arp buffering JIRA: SAMPLEVNF-23 This patch implements ~New arp state machine implementing new states like INCOMPLETE, COMPLETE, PROBE, STALE. ~removing unwanted code in arpicmp pipeline ~Implementing arp buffering, when arp is unresolved. ~Integratig the new changes with vCGNAPT ~Integrating the new changes with vACL ~Integrating the new changes with vFW. Change-Id: If467ec035bc8de58463ea50d9e603a97f168c1a2 Signed-off-by: Vishwesh M Rudramuni --- VNFs/vACL/pipeline/pipeline_acl_be.c | 265 ++++++++++++++--------------------- 1 file changed, 109 insertions(+), 156 deletions(-) (limited to 'VNFs/vACL/pipeline') diff --git a/VNFs/vACL/pipeline/pipeline_acl_be.c b/VNFs/vACL/pipeline/pipeline_acl_be.c index 039d6d59..b9386e61 100644 --- a/VNFs/vACL/pipeline/pipeline_acl_be.c +++ b/VNFs/vACL/pipeline/pipeline_acl_be.c @@ -144,6 +144,7 @@ static void *pipeline_acl_msg_req_dbg_handler(struct pipeline *p, void *msg); static pipeline_msg_req_handler custom_handlers[] = { [PIPELINE_ACL_MSG_REQ_DBG] = pipeline_acl_msg_req_dbg_handler, }; +uint64_t arp_pkts_mask; uint8_t ACL_DEBUG; uint32_t local_get_nh_ipv4(uint32_t ip, @@ -154,8 +155,8 @@ uint32_t local_get_nh_ipv4(uint32_t ip, for (i = 0; i < p_acl->local_lib_arp_route_ent_cnt; i++) { if (((p_acl->local_lib_arp_route_table[i].ip & - p_acl->local_lib_arp_route_table[i].mask) == - (ip & p_acl->local_lib_arp_route_table[i].mask))) { + p_acl->local_lib_arp_route_table[i].mask) == + (ip & p_acl->local_lib_arp_route_table[i].mask))) { *port = p_acl->local_lib_arp_route_table[i].port; *nhip = p_acl->local_lib_arp_route_table[i].nh; @@ -175,8 +176,8 @@ static void do_local_nh_ipv4_cache(uint32_t dest_if, struct pipeline_acl *p_acl) if (lib_arp_route_table[i].port == dest_if) { struct lib_arp_route_table_entry *lentry = - &p_acl->local_lib_arp_route_table - [p_acl->local_lib_arp_route_ent_cnt]; + &p_acl->local_lib_arp_route_table + [p_acl->local_lib_arp_route_ent_cnt]; lentry->ip = lib_arp_route_table[i].ip; lentry->mask = lib_arp_route_table[i].mask; @@ -463,6 +464,7 @@ pkt_work_acl_key(struct rte_pipeline *p, uint64_t conntrack_mask = 0; uint64_t connexist_mask = 0; uint32_t dest_address = 0; + arp_pkts_mask = 0; int dest_if = 0; int status; uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t); @@ -918,103 +920,57 @@ pkt_work_acl_key(struct rte_pipeline *p, nhip)); uint32_t packet_length = rte_pktmbuf_pkt_len(pkt); *nhip = 0; - if (is_phy_port_privte(phy_port)) { - dest_address = rte_bswap32(*dst_addr); - ret = - local_get_nh_ipv4(dest_address, &dest_if, - nhip, p_acl); - if (!ret) { - dest_if = - get_prv_to_pub_port(&dest_address, - IP_VERSION_4); - do_local_nh_ipv4_cache(dest_if, p_acl); + struct arp_entry_data *ret_arp_data = NULL; + ret_arp_data = get_dest_mac_addr_port + (dest_address, &dest_if, (struct ether_addr *) eth_dest); + *port_out_id = p_acl->port_out_id[dest_if]; + if (arp_cache_dest_mac_present(dest_if)) { + ether_addr_copy(get_link_hw_addr(dest_if), (struct ether_addr *)eth_src); + 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, + (struct ether_addr *)eth_dest, *port_out_id); + } - *port_out_id = p_acl->port_out_id[dest_if]; } else { - dest_address = rte_bswap32(*dst_addr); - - ret = local_get_nh_ipv4(dest_address, &dest_if, - nhip, p_acl); - if (!ret) { - dest_if = - get_pub_to_prv_port(&dest_address, - IP_VERSION_4); - do_local_nh_ipv4_cache(dest_if, p_acl); - }; - *port_out_id = p_acl->port_out_id[dest_if]; - } - /* port = ACL_PRV_PORT_ID; */ + if (unlikely(ret_arp_data == NULL)) { - int ret_mac = 0; + printf("%s: NHIP Not Found, " + "outport_id: %d\n", __func__, + *port_out_id); - ret_mac = get_dest_mac_addr_port - (dest_address, &dest_if, &hw_addr); - if (ret_mac == ARP_FOUND) { - if (ACL_DEBUG) { - printf("MAC found for ip 0x%x, " - "port %d - %02x:%02x:%02x:%02x:%02x:%02x\n", - dest_address, phy_port, - hw_addr.addr_bytes[0], - hw_addr.addr_bytes[1], - hw_addr.addr_bytes[2], - hw_addr.addr_bytes[3], - hw_addr.addr_bytes[4], - hw_addr.addr_bytes[5]); - printf("Dest MAC before - " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - eth_dest[0], eth_dest[1], - eth_dest[2], eth_dest[3], - eth_dest[4], eth_dest[5]); + /* Drop the pkt */ + pkts_mask &= ~(1LLU << pos); + if (ACL_DEBUG) + printf("ACL after drop pkt_mask " + "%lu, pkt_num %d\n", + pkts_mask, pos); + p_acl->counters->pkts_drop++; + continue; } - memcpy(eth_dest, &hw_addr, - sizeof(struct ether_addr)); - if (ACL_DEBUG) { - printf("PktP %p, dest_macP %p\n", pkt, - eth_dest); - printf("Dest MAC after - " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - eth_dest[0], eth_dest[1], - eth_dest[2], eth_dest[3], - eth_dest[4], eth_dest[5]); + if (ret_arp_data->status == INCOMPLETE || + ret_arp_data->status == PROBE) { + if (ret_arp_data->num_pkts >= NUM_DESC) { + /* Drop the pkt */ + pkts_mask &= ~(1LLU << pos); + if (ACL_DEBUG) + printf("ACL after drop pkt_mask " + "%lu, pkt_num %d\n", + pkts_mask, pos); + p_acl->counters->pkts_drop++; + continue; + } else { + arp_pkts_mask |= pkt_mask; + arp_queue_unresolved_packet(ret_arp_data, pkt); + continue; + } } - if (is_phy_port_privte(phy_port)) - memcpy(eth_src, - get_link_hw_addr(dest_if), - sizeof(struct ether_addr)); - else - memcpy(eth_src, - get_link_hw_addr(dest_if), - sizeof(struct ether_addr)); - p_acl->counters->tpkts_processed++; - p_acl->counters->bytes_processed += - packet_length; } - else { - if (*nhip != 0) { - if (ACL_DEBUG) - printf("ACL requesting ARP for " - "ip %x, port %d\n", - dest_address, phy_port); - if (ret_mac == ARP_NOT_FOUND) - request_arp(dest_if, *nhip); - - /* request_arp(p_acl->links_map[phy_port], *nhip); */ - } - /* Drop packet by changing the mask */ - if (ACL_DEBUG) - printf("ACL before drop pkt_mask " - "%lu, pkt_num %d\n", - pkts_mask, pos); - pkts_mask &= ~(1LLU << pos); - if (ACL_DEBUG) - printf("ACL after drop pkt_mask " - "%lu, pkt_num %d\n", - pkts_mask, pos); - p_acl->counters->pkts_drop++; - } - } + } /* end of if (hdr_chk == IPv4_HDR_VERSION) */ if (hdr_chk == IPv6_HDR_VERSION) { @@ -1053,7 +1009,7 @@ pkt_work_acl_key(struct rte_pipeline *p, uint8_t nhip[16]; nhip[0] = - RTE_MBUF_METADATA_UINT8(pkt, + RTE_MBUF_METADATA_UINT8(pkt, META_DATA_OFFSET + offsetof(struct mbuf_acl_meta_data, @@ -1176,6 +1132,11 @@ pkt_work_acl_key(struct rte_pipeline *p, rte_pipeline_ah_packet_drop(p, pkts_drop_mask); keep_mask = pkts_mask; + if (arp_pkts_mask) { + keep_mask &= ~(arp_pkts_mask); + rte_pipeline_ah_packet_hijack(p, arp_pkts_mask); + } + /* don't bother measuring if traffic very low, might skew stats */ uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask); @@ -1238,6 +1199,7 @@ pkt_work_acl_ipv4_key(struct rte_pipeline *p, uint64_t conntrack_mask = 0; uint64_t connexist_mask = 0; uint32_t dest_address = 0; + arp_pkts_mask = 0; int dest_if = 0; int status; uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t); @@ -1711,76 +1673,56 @@ pkt_work_acl_ipv4_key(struct rte_pipeline *p, *port_out_id = p_acl->port_out_id[dest_if]; } /* port = ACL_PRV_PORT_ID; */ - int ret_mac = 0; - ret_mac = get_dest_mac_addr_port - (dest_address, &dest_if, &hw_addr); + struct arp_entry_data *ret_arp_data = NULL; + ret_arp_data = get_dest_mac_addr_port + (dest_address, &dest_if, (struct ether_addr *)eth_dest); + *port_out_id = p_acl->port_out_id[dest_if]; - if (ret_mac == ARP_FOUND) { - if (ACL_DEBUG) { - printf("MAC found for ip 0x%x, port " - "%d - %02x:%02x:%02x:%02x:%02x:%02x\n", - dest_address, phy_port, - hw_addr.addr_bytes[0], - hw_addr.addr_bytes[1], - hw_addr.addr_bytes[2], - hw_addr.addr_bytes[3], - hw_addr.addr_bytes[4], - hw_addr.addr_bytes[5]); - printf("Dest MAC before - " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - eth_dest[0], eth_dest[1], - eth_dest[2], eth_dest[3], - eth_dest[4], eth_dest[5]); - } + if (arp_cache_dest_mac_present(dest_if)) { + ether_addr_copy(get_link_hw_addr(dest_if), (struct ether_addr *)eth_src); + 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, + (struct ether_addr *)eth_dest, *port_out_id); - memcpy(eth_dest, &hw_addr, - sizeof(struct ether_addr)); - if (ACL_DEBUG) { - printf("PktP %p, dest_macP %p\n", pkt, - eth_dest); - printf("Dest MAC after - " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - eth_dest[0], eth_dest[1], - eth_dest[2], eth_dest[3], - eth_dest[4], eth_dest[5]); } - if (is_phy_port_privte(phy_port)) - memcpy(eth_src, - get_link_hw_addr(dest_if), - sizeof(struct ether_addr)); - else - memcpy(eth_src, - get_link_hw_addr(dest_if), - sizeof(struct ether_addr)); - p_acl->counters->tpkts_processed++; - p_acl->counters->bytes_processed += - packet_length; - } + } else { + if (unlikely(ret_arp_data == NULL)) { - else { - if (*nhip != 0) { - if (ACL_DEBUG) - printf("ACL requesting ARP for " - "ip %x, port %d\n", - dest_address, phy_port); - if (ret_mac == ARP_NOT_FOUND) - request_arp(dest_if, *nhip); + printf("%s: NHIP Not Found, " + "outport_id: %d\n", __func__, + *port_out_id); - /* request_arp(p_acl->links_map[phy_port], *nhip); */ + /* Drop the pkt */ + pkts_mask &= ~(1LLU << pos); + if (ACL_DEBUG) + printf("ACL after drop pkt_mask " + "%lu, pkt_num %d\n", + pkts_mask, pos); + p_acl->counters->pkts_drop++; + continue; } - /* Drop packet by changing the mask */ - if (ACL_DEBUG) - printf - ("ACL before drop pkt_mask " - "%lu, pkt_num %d\n", - pkts_mask, pos); - pkts_mask &= ~(1LLU << pos); - if (ACL_DEBUG) - printf("ACL after drop pkt_mask " + + if (ret_arp_data->status == INCOMPLETE || + ret_arp_data->status == PROBE) { + if (ret_arp_data->num_pkts >= NUM_DESC) { + /* Drop the pkt */ + pkts_mask &= ~(1LLU << pos); + if (ACL_DEBUG) + printf("ACL after drop pkt_mask " "%lu, pkt_num %d\n", - pkts_mask, pos); - p_acl->counters->pkts_drop++; + pkts_mask, pos); + p_acl->counters->pkts_drop++; + continue; + } else { + arp_pkts_mask |= pkt_mask; + arp_queue_unresolved_packet(ret_arp_data, pkt); + continue; + } + } } } #if 0 @@ -1923,6 +1865,11 @@ pkt_work_acl_ipv4_key(struct rte_pipeline *p, rte_pipeline_ah_packet_drop(p, pkts_drop_mask); keep_mask = pkts_mask; + if (arp_pkts_mask) { + keep_mask &= ~(arp_pkts_mask); + rte_pipeline_ah_packet_hijack(p, arp_pkts_mask); + } + /* don't bother measuring if traffic very low, might skew stats */ uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask); @@ -1934,7 +1881,7 @@ pkt_work_acl_ipv4_key(struct rte_pipeline *p, } if (ACL_DEBUG) printf("Leaving pkt_work_acl_key pkts_mask = %p\n", - (void *)pkts_mask); + (void *)pkts_mask); return 0; } @@ -1983,6 +1930,7 @@ pkt_work_acl_ipv6_key(struct rte_pipeline *p, uint64_t conntrack_mask = 0; uint64_t connexist_mask = 0; uint32_t dest_address = 0; + arp_pkts_mask = 0; int dest_if = 0; int status; uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t); @@ -2691,6 +2639,11 @@ pkt_work_acl_ipv6_key(struct rte_pipeline *p, rte_pipeline_ah_packet_drop(p, pkts_drop_mask); keep_mask = pkts_mask; + if (arp_pkts_mask) { + keep_mask &= ~(arp_pkts_mask); + rte_pipeline_ah_packet_hijack(p, arp_pkts_mask); + } + /* don't bother measuring if traffic very low, might skew stats */ uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask); -- cgit 1.2.3-korg