Temp Fix for vFW perf issue
[samplevnf.git] / common / VIL / gateway / gateway.c
1 /*
2 // Copyright (c) 2017 Intel Corporation
3 //
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
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 */
16
17 /**
18  * @file
19  * Gateway packet forwarding Implementation.
20  *
21  * Implementation of gateway packet forwarding, next hop IP and
22  * associated processing.
23  *
24  */
25
26 #include <rte_mbuf.h>
27 #include <rte_malloc.h>
28 #include <rte_ethdev.h>
29 #include <rte_memcpy.h>
30
31 #include "gateway.h"
32 #include "pipeline_common_fe.h"
33
34 #define IP_VERSION_4 4
35 #define IP_VERSION_6 6
36 #define MAX_PORTS 32
37
38 /* Global stats counters used in ARP */
39 extern uint32_t lib_nd_nh_found;
40 extern uint32_t lib_arp_nh_found;
41
42 struct route_data *p_route_data[MAX_PORTS];
43 struct nd_route_data *p_nd_route_data[MAX_PORTS];
44
45 /**
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
49 */
50
51 /* Initialized for IP Pkt forwarding */
52 uint32_t vnf_gateway = 0;
53
54 /* Initialized number of out ports to route */
55 uint32_t num_out_ports = 0;
56
57 /**
58  * Initialize the gateway for routing tables
59  *
60  * @param void
61  *  None
62  * @return uint32_t
63  * 1 to MAX_PORTS
64  */
65
66 void gw_init(uint32_t num_ports)
67 {
68      void *p;
69      uint32_t size;
70      uint32_t i;
71
72      num_out_ports = num_ports;
73
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;
79
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;
84    }
85 }
86 /*
87  * Get the the number of ports to route
88  * @param void
89  *  None
90  * @return uint32_t
91  *  Number of ports enabled in the VNF
92 */
93
94 uint32_t gw_get_num_ports(void)
95 {
96         return num_out_ports;
97 }
98
99
100 /**
101  * Check if the gateway is enabled
102  *
103  * @param void
104  *  None
105  * @return uint32_t
106  *  0: No routes, 1: Route entries available
107  */
108 uint32_t is_gateway(void)
109 {
110         return vnf_gateway;
111 }
112
113
114 /**
115  * Get the next hop ip address and port number for IPv4
116  * @param dst_ip_addr
117  *  Destination IPv4 address
118  * @param dst_port
119  *  A pointer to destination port
120  * @param nhip
121  *  A pointer to next hop ip address
122  */
123
124 void gw_get_nh_port_ipv4(uint32_t dst_ip_addr,
125                          uint32_t *dst_port, uint32_t *nhip)
126 {
127         uint32_t j;
128
129         *nhip = 0;
130         *dst_port = 0xff;
131
132         for(j = 0; j < num_out_ports; j++) {
133            if (gw_get_route_nh_port_ipv4(dst_ip_addr, dst_port, nhip, j))
134                return;
135         }
136 }
137
138 /**
139  * Get the next hop ip address and port number for IPv6
140  * @param dst_ipv6_addr
141  *  Destination IPv6 address
142  * @param dst_port
143  *  A pointer to destination port
144  * @param nhipv6
145  *  A pointer to next hop ip address
146  */
147
148 void gw_get_nh_port_ipv6(uint8_t *dst_ipv6_addr,
149                                         uint32_t *dst_port, uint8_t *nhipv6)
150 {
151     if (!dst_ipv6_addr)
152             return;
153     uint32_t j;
154     for(j = 0; j < gw_get_num_ports(); j++){
155
156             if(p_nd_route_data[j]->nd_route_ent_cnt){
157
158                     memset(nhipv6, 0, IPV6_ADD_SIZE);
159
160                     int i=0;
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));
167
168                      for (i = 0; i < p_nd_route_data[j]->nd_route_ent_cnt; i++) {
169
170                              convert_prefixlen_to_netmask_ipv6(
171                                              p_nd_route_data[j]->nd_route_table[i].depth, netmask_ipv6);
172
173                              for (k = 0; k < IPV6_ADD_SIZE; k++) {
174                                      if (p_nd_route_data[j]->nd_route_table[i].nhipv6[k] &
175                                                      netmask_ipv6[k]) {
176
177                                              depthflags++;
178                                              netip_nd[k] = p_nd_route_data[j]->nd_route_table[i].nhipv6[k];
179                                      }
180
181                                      if (dst_ipv6_addr[k] & netmask_ipv6[k]) {
182                                              depthflags1++;
183                                              netip_in[k] = dst_ipv6_addr[k];
184                                      }
185                              }
186
187                              if ((depthflags == depthflags1) &&
188                                              (memcmp(netip_nd, netip_in, sizeof(netip_nd)) == 0)) {
189
190                                      *dst_port = p_nd_route_data[j]->nd_route_table[i].port;
191
192                                      lib_nd_nh_found++;
193
194                                      rte_mov16(nhipv6, (uint8_t *)
195                                                      &(p_nd_route_data[j]->nd_route_table[i].nhipv6[0]));
196
197                                      return;
198                              }
199
200                      }
201
202             }
203     }
204 }
205