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.
19 * Gateway packet forwarding Implementation.
21 * Implementation of gateway packet forwarding, next hop IP and
22 * associated processing.
27 #include <rte_malloc.h>
28 #include <rte_ethdev.h>
29 #include <rte_memcpy.h>
32 #include "pipeline_common_fe.h"
34 #define IP_VERSION_4 4
35 #define IP_VERSION_6 6
38 /* Global stats counters used in ARP */
39 extern uint32_t lib_nd_nh_found;
40 extern uint32_t lib_arp_nh_found;
42 struct route_data *p_route_data[MAX_PORTS];
43 struct nd_route_data *p_nd_route_data[MAX_PORTS];
46 * VNF is configured with routing info or not
47 * vnf_gateway = 0: No Routes Added , 1: Routes defined
48 * Flag is part of the ARPICMP config parameter
51 /* Initialized for IP Pkt forwarding */
52 uint32_t vnf_gateway = 0;
54 /* Initialized number of out ports to route */
55 uint32_t num_out_ports = 0;
58 * Initialize the gateway for routing tables
66 void gw_init(uint32_t num_ports)
72 num_out_ports = num_ports;
74 for(i = 0; i < num_ports; i++) {
75 /* IPv4 route table */
76 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct route_data));
77 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
78 p_route_data[i] = (struct route_data *)p;
80 /* IPv6 route touble */
81 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct nd_route_data));
82 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
83 p_nd_route_data[i] = (struct nd_route_data *)p;
87 * Get the the number of ports to route
91 * Number of ports enabled in the VNF
94 uint32_t gw_get_num_ports(void)
101 * Check if the gateway is enabled
106 * 0: No routes, 1: Route entries available
108 uint32_t is_gateway(void)
115 * Get the next hop ip address and port number for IPv4
117 * Destination IPv4 address
119 * A pointer to destination port
121 * A pointer to next hop ip address
124 void gw_get_nh_port_ipv4(uint32_t dst_ip_addr,
125 uint32_t *dst_port, uint32_t *nhip)
132 for(j = 0; j < num_out_ports; j++) {
133 if (gw_get_route_nh_port_ipv4(dst_ip_addr, dst_port, nhip, j))
139 * Get the next hop ip address and port number for IPv6
140 * @param dst_ipv6_addr
141 * Destination IPv6 address
143 * A pointer to destination port
145 * A pointer to next hop ip address
148 void gw_get_nh_port_ipv6(uint8_t *dst_ipv6_addr,
149 uint32_t *dst_port, uint8_t *nhipv6)
154 for(j = 0; j < gw_get_num_ports(); j++){
156 if(p_nd_route_data[j]->nd_route_ent_cnt){
158 memset(nhipv6, 0, IPV6_ADD_SIZE);
161 uint8_t netmask_ipv6[IPV6_ADD_SIZE], netip_nd[IPV6_ADD_SIZE];
162 uint8_t netip_in[IPV6_ADD_SIZE];
163 uint8_t k = 0, depthflags = 0, depthflags1 = 0;
164 memset(netmask_ipv6, 0, sizeof(netmask_ipv6));
165 memset(netip_nd, 0, sizeof(netip_nd));
166 memset(netip_in, 0, sizeof(netip_in));
168 for (i = 0; i < p_nd_route_data[j]->nd_route_ent_cnt; i++) {
170 convert_prefixlen_to_netmask_ipv6(
171 p_nd_route_data[j]->nd_route_table[i].depth, netmask_ipv6);
173 for (k = 0; k < IPV6_ADD_SIZE; k++) {
174 if (p_nd_route_data[j]->nd_route_table[i].nhipv6[k] &
178 netip_nd[k] = p_nd_route_data[j]->nd_route_table[i].nhipv6[k];
181 if (dst_ipv6_addr[k] & netmask_ipv6[k]) {
183 netip_in[k] = dst_ipv6_addr[k];
187 if ((depthflags == depthflags1) &&
188 (memcmp(netip_nd, netip_in, sizeof(netip_nd)) == 0)) {
190 *dst_port = p_nd_route_data[j]->nd_route_table[i].port;
194 rte_mov16(nhipv6, (uint8_t *)
195 &(p_nd_route_data[j]->nd_route_table[i].nhipv6[0]));