diff options
author | Vishwesh M Rudramuni <vishweshmr@gmail.com> | 2017-04-18 19:41:40 +0530 |
---|---|---|
committer | Deepak S <deepak.s@linux.intel.com> | 2017-04-18 02:59:07 -0700 |
commit | 51cd08d9a3f2826088d122e2a5683315c77a2786 (patch) | |
tree | 3fac17a8f7bf362f0c77f1003615b2063d900d35 /common/VIL/l2l3_stack/l2_proto.c | |
parent | 03aef84e240c5be8813634735d825420129f1460 (diff) |
common: Adding common library for sample vnf
JIRA: SAMPLEVNF-3
This patch adds common libraries required as part of the
sample vnf.
This includes the following libraries
1. ACL library
2. SIP
3. FTP
4. Connection tracker
5. L2l3 stack
- Interface Manager
- ARP & ICMPv4
- ND & ICMPv6
and other common libraries needed for ip pipeline framework
Change-Id: I117690b6b63fbcd76974cd7274518484e60980ab
Signed-off-by: Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>
[Push patch to gerrit]
Signed-off-by: Deepak S <deepak.s@linux.intel.com>
Diffstat (limited to 'common/VIL/l2l3_stack/l2_proto.c')
-rw-r--r-- | common/VIL/l2l3_stack/l2_proto.c | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/common/VIL/l2l3_stack/l2_proto.c b/common/VIL/l2l3_stack/l2_proto.c new file mode 100644 index 00000000..44c50b08 --- /dev/null +++ b/common/VIL/l2l3_stack/l2_proto.c @@ -0,0 +1,239 @@ +/* +// Copyright (c) 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. +*/ + +/* + * Filename - l2_proto.c + * L2 Protocol Handler + */ + +#include "l2_proto.h" + +static struct proto_packet_type *proto_list[3]; +/* + * Function to register the rx functions for different ethertypes. This is maintained in a list. + */ +void +list_add_type(uint16_t type, + void (*func) (struct rte_mbuf **, uint16_t, uint64_t, + l2_phy_interface_t *)) +{ + if (type == ETHER_TYPE_IPv4) { + proto_list[IPv4_VAL] = + rte_malloc(NULL, sizeof(struct proto_packet_type), + RTE_CACHE_LINE_SIZE); + proto_list[IPv4_VAL]->type = type; + proto_list[IPv4_VAL]->func = func; + } + + else if (type == ETHER_TYPE_ARP) { + proto_list[ARP_VAL] = + rte_malloc(NULL, sizeof(struct proto_packet_type), + RTE_CACHE_LINE_SIZE); + proto_list[ARP_VAL]->type = type; + proto_list[ARP_VAL]->func = func; + } else if (type == ETHER_TYPE_IPv6) { + proto_list[IPv6_VAL] = + rte_malloc(NULL, sizeof(struct proto_packet_type), + RTE_CACHE_LINE_SIZE); + proto_list[IPv6_VAL]->type = type; + proto_list[IPv6_VAL]->func = func; + } + +} + +/* + * Check the mac address to see whether it is destined to this host or not. + * Call relevant functions registered by other modules when the ethertype matches, + * if it is destined to this host. Drop the packet otherwise. + */ + +void +l2_check_mac(struct rte_mbuf *m[IFM_BURST_SIZE], l2_phy_interface_t *port, + uint8_t i, uint64_t *pkts_mask, uint64_t *arp_pkts_mask, + uint64_t *ipv4_pkts_mask, uint64_t *ipv6_pkts_mask) +{ + struct ether_hdr *eth=NULL; + uint16_t same_mac=0; + uint16_t ethtype = 0; + + if (m[i] != NULL) { + eth = rte_pktmbuf_mtod(m[i], struct ether_hdr *); + if(eth) + ethtype = rte_be_to_cpu_16(eth->ether_type); + if (eth == NULL) { + /*Destination MAC address inside the packet */ + printf("l2_check_mac: Ethernet Dest Addr NULL !!!\n"); + return; + } + ethtype = rte_be_to_cpu_16(eth->ether_type); +#if L2_PROTO_DBG + printf("%s => mbuf pkt dest mac addr: %x:%x:%x:%x:%x:%x\n", + __FUNCTION__, eth->d_addr.addr_bytes[0], + eth->d_addr.addr_bytes[1], eth->d_addr.addr_bytes[2], + eth->d_addr.addr_bytes[3], eth->d_addr.addr_bytes[4], + eth->d_addr.addr_bytes[5]); + printf("%s => port mac addr: %x:%x:%x:%x:%x:%x\n", __FUNCTION__, + port->macaddr[0], port->macaddr[1], port->macaddr[2], + port->macaddr[3], port->macaddr[4], port->macaddr[5]); + +#endif + /* Compare the mac addresses */ + same_mac = + (is_same_ether_addr + (ð->d_addr, (struct ether_addr *)port->macaddr) + || + ((is_broadcast_ether_addr + ((struct ether_addr *)ð->d_addr) + && (ethtype == ETHER_TYPE_ARP))) + || (ethtype == ETHER_TYPE_IPv6 + && eth->d_addr.addr_bytes[0] == 0x33 + && eth->d_addr.addr_bytes[1] == 0x33)); + + if (!same_mac) { + uint64_t temp_mask = 1LLU << i; + *pkts_mask ^= temp_mask; + rte_pktmbuf_free(m[i]); + m[i] = NULL; + } else if ((ethtype == ETHER_TYPE_IPv4) && same_mac) { + uint64_t temp_mask = 1LLU << i; + *ipv4_pkts_mask ^= temp_mask; + } else if ((ethtype == ETHER_TYPE_ARP) && same_mac) { + uint64_t temp_mask = 1LLU << i; + *arp_pkts_mask ^= temp_mask; + } else if ((ethtype == ETHER_TYPE_IPv6) && same_mac) { + uint64_t temp_mask = 1LLU << i; + *ipv6_pkts_mask ^= temp_mask; + } + } + printf("\n%s: arp_pkts_mask = %" PRIu64 ", ipv4_pkts_mask = %" PRIu64 + ", ipv6_pkts_mask =%" PRIu64 ", pkt-type = %x, sam_mac = %d\n", + __FUNCTION__, *arp_pkts_mask, *ipv4_pkts_mask, *ipv6_pkts_mask, + ethtype, same_mac); +} + +void +protocol_handler_recv(struct rte_mbuf **pkts_burst, uint16_t nb_rx, + l2_phy_interface_t *port) +{ + uint8_t i; + uint64_t pkts_mask = 0; //RTE_LEN2MASK(nb_rx, uint64_t); + uint64_t arp_pkts_mask = 0; //RTE_LEN2MASK(nb_rx, uint64_t); + uint64_t ipv4_pkts_mask = 0; //RTE_LEN2MASK(nb_rx, uint64_t); + uint64_t ipv6_pkts_mask = 0; //RTE_LEN2MASK(nb_rx, uint64_t); + + /*Check the mac address of every single packet and unset the bits in the packet mask + *for those packets which are not destined to this host + */ + for (i = 0; i < nb_rx; i++) { + l2_check_mac(pkts_burst, port, i, &pkts_mask, &arp_pkts_mask, + &ipv4_pkts_mask, &ipv6_pkts_mask); + } + if (nb_rx) { + if (arp_pkts_mask) { + proto_list[ARP_VAL]->func(pkts_burst, nb_rx, + arp_pkts_mask, port); + printf + ("=================After ARP ==================\n"); + } + if (ipv4_pkts_mask) { + printf + ("=================Calling IPV4 L3 RX ==================\n"); + printf("====nb_rx:%u, ipv4_pkts_mask: %lu\n\n", nb_rx, + ipv4_pkts_mask); + proto_list[IPv4_VAL]->func(pkts_burst, nb_rx, + ipv4_pkts_mask, port); + } + if (ipv6_pkts_mask) { + printf + ("=================Calling IPV6 L3 RX ==================\n"); + printf("====nb_rx:%u, ipv6_pkts_mask: %lu\n\n", nb_rx, + ipv6_pkts_mask); + proto_list[IPv6_VAL]->func(pkts_burst, nb_rx, + ipv6_pkts_mask, port); + } + } +} + +#if 0 +switch (qid) { +case 1: + { +#if 0 + printf + ("=====================ENTERED ARP CASE================\n"); + while (cur->type != ETHER_TYPE_ARP && cur != NULL) { + cur = cur->next; + } + if (cur != NULL) { + //printf("L2 PROTO TEST-14=================================\n"); + printf + ("==============\nARPARPARPARP \n=======================\n"); + cur->func(pkts_burst, nb_rx, pkts_mask, portid); + } +#endif + proto_list[ARP_VAL]->func(pkts_burst, nb_rx, arp_pkts_mask, + portid); + break; + } +case 0: + { +#if 0 + while (cur->type != ETHER_TYPE_IPv4 && cur != NULL) { + cur = cur->next; + } + if (cur != NULL) { + //printf("L2 PROTO TEST-15=================================\n"); + //printf("==============\nPkts mask in while calling IPv4 %d \n=======================\n",ipv4_pkts_mask); + cur->func(pkts_burst, nb_rx, ipv4_pkts_mask, portid); + } + break; +#endif + // printf("=========Inside switch==============\n"); + proto_list[IPv4_VAL]->func(pkts_burst, nb_rx, ipv4_pkts_mask, + portid); + break; + } + /* case 2: + { + while(cur->type != ETHER_TYPE_IPv6 && cur != NULL) + { + cur = cur->next; + } + if(cur != NULL) + { + cur->func(pkts_burst, nb_rx, ipv6_pkts_mask, portid); + } + break; + } */ +default: + { + rte_exit(EXIT_FAILURE, "Ethertype not found \n"); + break; + } +} +#endif + +/* + * L2 Stack Init for future + + + void +l2_stack_init(void) +{ + +} + +*/ |