2 // Copyright (c) 2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * Filename - l2_proto.c
24 static struct proto_packet_type *proto_list[3];
26 * Function to register the rx functions for different ethertypes. This is maintained in a list.
29 list_add_type(uint16_t type,
30 void (*func) (struct rte_mbuf **, uint16_t, uint64_t,
31 l2_phy_interface_t *))
33 if (type == ETHER_TYPE_IPv4) {
34 proto_list[IPv4_VAL] =
35 rte_malloc(NULL, sizeof(struct proto_packet_type),
37 proto_list[IPv4_VAL]->type = type;
38 proto_list[IPv4_VAL]->func = func;
41 else if (type == ETHER_TYPE_ARP) {
43 rte_malloc(NULL, sizeof(struct proto_packet_type),
45 proto_list[ARP_VAL]->type = type;
46 proto_list[ARP_VAL]->func = func;
47 } else if (type == ETHER_TYPE_IPv6) {
48 proto_list[IPv6_VAL] =
49 rte_malloc(NULL, sizeof(struct proto_packet_type),
51 proto_list[IPv6_VAL]->type = type;
52 proto_list[IPv6_VAL]->func = func;
58 * Check the mac address to see whether it is destined to this host or not.
59 * Call relevant functions registered by other modules when the ethertype matches,
60 * if it is destined to this host. Drop the packet otherwise.
64 l2_check_mac(struct rte_mbuf *m[IFM_BURST_SIZE], l2_phy_interface_t *port,
65 uint8_t i, uint64_t *pkts_mask, uint64_t *arp_pkts_mask,
66 uint64_t *ipv4_pkts_mask, uint64_t *ipv6_pkts_mask)
68 struct ether_hdr *eth=NULL;
73 eth = rte_pktmbuf_mtod(m[i], struct ether_hdr *);
75 ethtype = rte_be_to_cpu_16(eth->ether_type);
77 /*Destination MAC address inside the packet */
78 printf("l2_check_mac: Ethernet Dest Addr NULL !!!\n");
81 ethtype = rte_be_to_cpu_16(eth->ether_type);
83 printf("%s => mbuf pkt dest mac addr: %x:%x:%x:%x:%x:%x\n",
84 __FUNCTION__, eth->d_addr.addr_bytes[0],
85 eth->d_addr.addr_bytes[1], eth->d_addr.addr_bytes[2],
86 eth->d_addr.addr_bytes[3], eth->d_addr.addr_bytes[4],
87 eth->d_addr.addr_bytes[5]);
88 printf("%s => port mac addr: %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
89 port->macaddr[0], port->macaddr[1], port->macaddr[2],
90 port->macaddr[3], port->macaddr[4], port->macaddr[5]);
93 /* Compare the mac addresses */
96 (ð->d_addr, (struct ether_addr *)port->macaddr)
98 ((is_broadcast_ether_addr
99 ((struct ether_addr *)ð->d_addr)
100 && (ethtype == ETHER_TYPE_ARP)))
101 || (ethtype == ETHER_TYPE_IPv6
102 && eth->d_addr.addr_bytes[0] == 0x33
103 && eth->d_addr.addr_bytes[1] == 0x33));
106 uint64_t temp_mask = 1LLU << i;
107 *pkts_mask ^= temp_mask;
108 rte_pktmbuf_free(m[i]);
110 } else if ((ethtype == ETHER_TYPE_IPv4) && same_mac) {
111 uint64_t temp_mask = 1LLU << i;
112 *ipv4_pkts_mask ^= temp_mask;
113 } else if ((ethtype == ETHER_TYPE_ARP) && same_mac) {
114 uint64_t temp_mask = 1LLU << i;
115 *arp_pkts_mask ^= temp_mask;
116 } else if ((ethtype == ETHER_TYPE_IPv6) && same_mac) {
117 uint64_t temp_mask = 1LLU << i;
118 *ipv6_pkts_mask ^= temp_mask;
121 printf("\n%s: arp_pkts_mask = %" PRIu64 ", ipv4_pkts_mask = %" PRIu64
122 ", ipv6_pkts_mask =%" PRIu64 ", pkt-type = %x, sam_mac = %d\n",
123 __FUNCTION__, *arp_pkts_mask, *ipv4_pkts_mask, *ipv6_pkts_mask,
128 protocol_handler_recv(struct rte_mbuf **pkts_burst, uint16_t nb_rx,
129 l2_phy_interface_t *port)
132 uint64_t pkts_mask = 0; //RTE_LEN2MASK(nb_rx, uint64_t);
133 uint64_t arp_pkts_mask = 0; //RTE_LEN2MASK(nb_rx, uint64_t);
134 uint64_t ipv4_pkts_mask = 0; //RTE_LEN2MASK(nb_rx, uint64_t);
135 uint64_t ipv6_pkts_mask = 0; //RTE_LEN2MASK(nb_rx, uint64_t);
137 /*Check the mac address of every single packet and unset the bits in the packet mask
138 *for those packets which are not destined to this host
140 for (i = 0; i < nb_rx; i++) {
141 l2_check_mac(pkts_burst, port, i, &pkts_mask, &arp_pkts_mask,
142 &ipv4_pkts_mask, &ipv6_pkts_mask);
146 proto_list[ARP_VAL]->func(pkts_burst, nb_rx,
147 arp_pkts_mask, port);
149 ("=================After ARP ==================\n");
151 if (ipv4_pkts_mask) {
153 ("=================Calling IPV4 L3 RX ==================\n");
154 printf("====nb_rx:%u, ipv4_pkts_mask: %lu\n\n", nb_rx,
156 proto_list[IPv4_VAL]->func(pkts_burst, nb_rx,
157 ipv4_pkts_mask, port);
159 if (ipv6_pkts_mask) {
161 ("=================Calling IPV6 L3 RX ==================\n");
162 printf("====nb_rx:%u, ipv6_pkts_mask: %lu\n\n", nb_rx,
164 proto_list[IPv6_VAL]->func(pkts_burst, nb_rx,
165 ipv6_pkts_mask, port);
176 ("=====================ENTERED ARP CASE================\n");
177 while (cur->type != ETHER_TYPE_ARP && cur != NULL) {
181 //printf("L2 PROTO TEST-14=================================\n");
183 ("==============\nARPARPARPARP \n=======================\n");
184 cur->func(pkts_burst, nb_rx, pkts_mask, portid);
187 proto_list[ARP_VAL]->func(pkts_burst, nb_rx, arp_pkts_mask,
194 while (cur->type != ETHER_TYPE_IPv4 && cur != NULL) {
198 //printf("L2 PROTO TEST-15=================================\n");
199 //printf("==============\nPkts mask in while calling IPv4 %d \n=======================\n",ipv4_pkts_mask);
200 cur->func(pkts_burst, nb_rx, ipv4_pkts_mask, portid);
204 // printf("=========Inside switch==============\n");
205 proto_list[IPv4_VAL]->func(pkts_burst, nb_rx, ipv4_pkts_mask,
211 while(cur->type != ETHER_TYPE_IPv6 && cur != NULL)
217 cur->func(pkts_burst, nb_rx, ipv6_pkts_mask, portid);
223 rte_exit(EXIT_FAILURE, "Ethertype not found \n");
230 * L2 Stack Init for future