common: Adding common library for sample vnf
[samplevnf.git] / common / VIL / l2l3_stack / l3fwd_lpm6.h
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 * L3fwd lpm6 header file is for IPv6 specific declarations
20 */
21
22 #ifndef L3FWD_LPM6_H
23 #define L3FWD_LPM6_H
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdint.h>
28 #include <inttypes.h>
29 #include <sys/types.h>
30 #include <string.h>
31 #include <sys/queue.h>
32 #include <stdarg.h>
33 #include <errno.h>
34 #include <getopt.h>
35 #include <stdbool.h>
36
37 #include <rte_debug.h>
38 #include <rte_ether.h>
39 #include <rte_ethdev.h>
40 #include <rte_ring.h>
41 #include <rte_mempool.h>
42 #include <rte_cycles.h>
43 #include <rte_mbuf.h>
44 #include <rte_ip.h>
45 #include <rte_tcp.h>
46 #include <rte_udp.h>
47 #include <rte_lpm.h>
48 #include <rte_lpm6.h>
49 #include <rte_table_lpm_ipv6.h>
50 #include "l3fwd_common.h"
51 #include "l3fwd_lpm4.h"
52 #include "interface.h"
53
54 /**
55 * Define all RTE MBUF offset size
56 */
57
58 #define MBUF_HDR_ROOM 256                       /**< MBUF HEADER ROOM OFFSET */
59 /* IPv6 */
60 #define IP_HDR_SIZE_IPV6  40                    /**< IPv6 HEADER OFFSET */
61 #define IP_HDR_SRC_ADR_OFST_IPV6 8  /**< IPv6 HEADER SRC IP ADDRESS OFFSET */
62 #define IP_HDR_DST_ADR_OFST_IPV6 24 /**< IPv6 HEADER DST IP ADDRESS OFFSET */
63
64 /* IPV6 Rules and Tables8s */
65 #define IPV6_L3FWD_LPM_MAX_RULES         1024  /**< Number of LPM6 Rules*/
66 #define IPV6_L3FWD_LPM_NUMBER_TBL8S (1 << 16)  /**< Number of Table 8 for LPM6 */
67
68 #define MAX_FIB_PATHS 8 /**< MAX FIB PATH, If ECMP feature is enabled */
69
70 /**
71 * A structure used to define the routing information for IPv6
72 * This structure is used as input parameters for route ADD
73 */
74 struct ipv6_routing_info {
75         uint8_t dst_ipv6[RTE_LPM_IPV6_ADDR_SIZE];  /**< DST IPv6 Address */
76         uint8_t depth;                                   /**< Depth */
77         uint32_t metric;                                 /**< Metrics */
78         uint32_t fib_nh_size; /**< num of fib paths, greater than if Multipath(ECMP) feature is supported*/
79         uint8_t nh_ipv6[MAX_FIB_PATHS][RTE_LPM_IPV6_ADDR_SIZE];         /**< NextHop IP Address */
80         uint8_t out_port[MAX_FIB_PATHS];                                /**< OUTGOING PORT */
81 } __rte_cache_aligned;                                   /**< RTE CACHE ALIGNED */
82
83 /**
84 * A structure used to define the fib path for Destination IPv6 Address
85 * This fib path is shared accross different fib_info.
86 */
87 struct ipv6_fib_path {
88         uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE];  /**< Next hop IP address (only valid for remote routes) */
89         uint32_t refcount;                              /**< Refcount, greater then 1 if multiple fib_info has same fib_path*/
90         uint8_t out_port;                               /**< Output port */
91         struct l2_adj_ipv6_entry *l2_adj_ipv6_ptr;/**< Address of the L2 ADJ table entry */
92 } __rte_cache_aligned;                                  /**< RTE CACHE ALIGNED */
93
94 /**
95 * A structure used to define the fib info (Route info)
96 * This fib info structure can have multiple fib paths.
97 */
98 struct ipv6_fib_info {
99         uint8_t dst_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< DST IPv6 Address */
100         uint8_t depth;                                  /**< Depth */
101         uint32_t metric;                                /**< Metric */
102         uint32_t fib_nh_size;                   /**< num of fib paths, greater than if Multipath(ECMP) feature is supported*/
103         struct ipv6_fib_path *path[MAX_FIB_PATHS]; /**< Array of pointers to the fib_path */
104 } __rte_cache_aligned;                                  /**< RTE CACHE ALIGNED */
105
106 /**
107 * A structure used to define the L2 Adjacency table
108 */
109 struct l2_adj_ipv6_entry {
110         struct ether_addr eth_addr;              /**< Ether address */
111         uint8_t out_port_id;                     /**< Outgoing port */
112         uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< Next hop IP address (only valid for remote routes) */
113         uint32_t refcount;                      /**< Refcount, greater then 1 if multiple fib_path has same L2_adj_entry*/
114         uint8_t l2_string[256];                  /**< L2 string, to rewrite the packet before transmission */
115         l2_phy_interface_t *phy_port;  /**<  Address of the L2 physical interface structure */
116         uint8_t flags;                  /**< flags for marking this entry as resolved or unresolved. */
117 } __rte_cache_aligned;                                          /**< RTE CACHE ALIGNED */
118
119 /**
120 * A structure used to define the L2 Adjacency table
121 */
122 struct l2_adj_key_ipv6 {
123         /*128 Bit of IPv6 Address */
124         /*<48bit Network> <16bit Subnet> <64bit Interface> */
125         uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< Next hop IPv6 address */
126         uint8_t out_port_id;                     /**< Outgoing port */
127         uint8_t filler1;    /**< Filler 1, for better hash key */
128         uint8_t filler2;    /**< Filler2, for better hash key*/
129         uint8_t filler3;    /**< Filler3, for better hash Key */
130 };
131
132 /**
133 * A structure used to define the fib path key for hash table
134 */
135 struct fib_path_key_ipv6 {
136         /*128 Bit of IPv6 Address */
137         /*<48bit Network> <16bit Subnet> <64bit Interface> */
138         uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE];  /**< Next hop IPv6 address */
139         uint8_t out_port;                               /**< Outgoing port */
140         uint8_t filler1;    /**< Filler 1, for better hash key */
141         uint8_t filler2;    /**< Filler2, for better hash key*/
142         uint8_t filler3;    /**< Filler3, for better hash Key */
143 };
144
145 struct ipv6_protocol_type {
146         uint8_t protocol_type;          /**< Protocol Type */
147         void (*func) (struct rte_mbuf **, uint16_t, uint64_t,
148                                         l2_phy_interface_t *);
149 } __rte_cache_aligned;
150
151 /* Function Declarations */
152 /**
153  * To creare LPM6 table, Cuckoo hash table for fib_path and l2_adj_entry tables
154  * @return
155  * 0 for failure, 1 for success
156  */
157 int lpm6_init(void);
158
159 /**
160  * To add a route in LPM6 table by populating fib_path and L2 Adjacency.
161  * @param data
162  * To add the route based on ipv6_routing_info stucture.
163  * @return
164  * 0 for failure, 1 for success
165  */
166 int lpm6_table_route_add(struct ipv6_routing_info *data);
167
168 /**
169  * To Delete the IP route and corresponding fib_path and L2 Adjacency entries.
170  * @param dst_ipv6
171  * Destionation IPv6 for which the route need to deleted
172  * @param depth
173  * netmask for the Destination IP
174  * @return
175  * 0 for failure, 1 for success
176  */
177 int lpm6_table_route_delete(uint8_t dst_ipv6[RTE_LPM_IPV6_ADDR_SIZE],
178                                         uint8_t depth);
179
180 /**
181  * To perform a LPM6 table lookup
182  * @param pkts_burst
183  * Burst of packets that needs to be lookup in LPM6 table
184  * @param nb_pkts
185  * Number of valid L3 packets
186  * @param pkts_mask
187  * number of valid pkts mask that needs to be lookup in LPM6 table
188  * @return
189  * 0 for failure, 1 for success
190  */
191 int lpm6_table_lookup(struct rte_mbuf **pkts_burst, uint16_t nb_pkts,
192                                         uint64_t pkts_mask,
193                                         l2_phy_interface_t *port_ptr[RTE_PORT_IN_BURST_SIZE_MAX],
194                                         uint64_t *hit_mask);
195
196 /**
197  * To forward the valid L3 packets for LMP6 table lookup and forward ICMP Pkts to ICMP module
198  * @param m
199  * packet burst of type rte_mbuf
200  * @param nb_pkts
201  * Number of valid L3 packets
202  * @param valid_pkts_mask
203  * Valid IPv6 packets mask that needs to be processed
204  * @param in_port
205  * IPv6 Pkt received form the input port.
206  * @return
207  * None
208  */
209 void l3fwd_rx_ipv6_packets(struct rte_mbuf **m, uint16_t nb_pkts,
210                                  uint64_t valid_pkts_mask,
211                                  l2_phy_interface_t *in_port);
212
213 /**
214  * To populate the fib_path for the nexthop IPv6 and outgoing port
215  * @param nh_ipv6
216  * NextHop Ip Address for which L2_adj_entry needs to be populated
217  * @param out_port
218  * outgong port ID
219  * @return
220  * NULL if lookup fails, Address of the type ipv6_fib_path if lookup success
221 */
222 struct ipv6_fib_path *populate_ipv6_fib_path(uint8_t
223                                                          nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE],
224                                                          uint8_t out_port);
225
226 /**
227  * To retrieve the fib_path entry for the nexthop IP and outgoing port
228  * This queries with cuckoo hash table based on the fib_path_key_ipv4
229  * @param path_key
230  * Key which is required for Cuckook hash table lookup
231  * @return
232  * NULL if lookup fails, Address of type ipv6_fib_path if lookup success
233 */
234 struct ipv6_fib_path *retrieve_ipv6_fib_path_entry(struct fib_path_key_ipv6
235                                                          path_key);
236
237 /**
238  * To retrieve the l2_adj_entry for the nexthop IP and outgoing port
239  * This queries with cuckoo hash table based on the l2_adj_key_ipv6
240  * @param l2_adj_key
241  * Key which is required for Cuckook hash table lookup
242  * @return
243  * NULL if lookup fails, Address of type l2_adj_ipv6_entry if lookup success
244 */
245 struct l2_adj_ipv6_entry *retrieve_ipv6_l2_adj_entry(struct l2_adj_key_ipv6
246                                                                  l2_adj_key);
247
248 /**
249  * To populate the l2_adj_entry for the nexthop IP and outgoing port
250  * @param nh_ip
251  * NextHop Ip Address for which L2_adj_entry needs to be populated
252  * @param portid
253  * outgong port ID
254  * @return
255  * NULL if lookup fails, Address of the L2_adj_ipv6_entry if lookup success
256 */
257 struct l2_adj_ipv6_entry *populate_ipv6_l2_adj(uint8_t
258                                                                  nh_ip[RTE_LPM_IPV6_ADDR_SIZE],
259                                                                  uint8_t portid);
260
261 /**
262  * To get the destination MAC Address for the nexthop IP and outgoing port
263  * @param nh_ipv6
264  * Next HOP IP Address for which MAC address is needed
265  * @param out_phy_port
266  * Outgoing physical port
267  * @param hw_addr
268  * pointet to the ether_add, This gets update with valid MAC address based on nh_ip and out port
269  * @return
270  * 0 if failure, 1 if success
271  */
272 int get_dest_mac_for_nexthop_ipv6(uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE],
273                                         uint32_t out_phy_port,
274                                         struct ether_addr *hw_addr);
275
276 /**
277  * To delete the ipv6 fib path and l2 adjacency entry from the cuckoo hash table
278  * @return
279  * None
280 */
281 void remove_ipv6_fib_l2_adj_entry(void *entry);
282
283 void
284 ipv6_l3_protocol_type_add(uint8_t protocol_type,
285                                 void (*func) (struct rte_mbuf **, uint16_t, uint64_t,
286                                         l2_phy_interface_t *));
287
288 void
289 ipv6_local_deliver(struct rte_mbuf **, uint16_t, uint64_t,
290                          l2_phy_interface_t *);
291
292 void
293 ipv6_forward_deliver(struct rte_mbuf **, uint16_t, uint64_t,
294                                  l2_phy_interface_t *);
295
296 int is_valid_ipv6_pkt(struct ipv6_hdr *pkt, uint32_t link_len);
297 uint8_t ipv6_hash_load_balance(struct rte_mbuf *mbuf);
298
299 /**
300  * To resolve l2_adj_entry based on nexthop IP, outgoing port and ether hw address.
301  * @param nh_ip
302  * NextHop Ip Address for which L2_adj_entry needs to be resolved
303  * @param portid
304  * outgong port ID
305  * @hw_addr
306  * Ethernet hardware address for the above nexthop IP and out port ID.
307  * @return
308  * Return is void.
309 */
310
311 void resolve_ipv6_l2_adj(uint8_t nh_ip[RTE_LPM_IPV6_ADDR_SIZE], uint8_t portid,
312                          struct ether_addr *hw_addr);
313
314 void ipv6_iterate__hash_table(void);
315 #endif                          /* L3FWD_LPM_H */