Support packets in flight
[samplevnf.git] / common / VIL / l2l3_stack / l3fwd_lpm4.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 lpm4 header file is for IPv4 specific declarations
20 */
21 #ifndef L3FWD_LPM_H
22 #define L3FWD_LPM_H
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdint.h>
27 #include <inttypes.h>
28 #include <sys/types.h>
29 #include <string.h>
30 #include <sys/queue.h>
31 #include <stdarg.h>
32 #include <errno.h>
33 #include <getopt.h>
34 #include <stdbool.h>
35
36 #include <rte_debug.h>
37 #include <rte_memory.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 "l3fwd_common.h"
50 #include "l3fwd_lpm6.h"
51 #include "interface.h"
52
53 /**
54 * Define all RTE MBUF offset size
55 */
56
57 #define MBUF_HDR_ROOM 256 /**< MBUF HEADER ROOM OFFSET */
58
59 /* IPv4 */
60 #define ETH_HDR_SIZE  14 /**< ETHER HEADER OFFSET */
61 #define IP_HDR_SIZE  20 /**< IP HEADER OFFSET */
62 #define IP_HDR_DST_ADR_OFST 16 /**< IP HEADER DST IP ADDRESS OFFSET */
63 #define IP_HDR_SRC_ADR_OFST 12 /**< IP HEADER SRC IP ADDRESS OFFSET */
64
65 /* Rules and Tables8s */
66 #define IPV4_L3FWD_LPM_MAX_RULES      256  /**< Number of LPM RULES */
67 #define IPV4_L3FWD_LPM_NUMBER_TBL8S (1 <<  8) /**< Number of TABLE 8s for LPM */
68 #define MAX_FIB_PATHS 8 /**< MAX FIB PATH, If ECMP feature is enabled */
69 #define IP_LOCAL 0 /**< for ICMP Packet destined to Local */
70 #define IP_REMOTE 1 /**< for ICMP Packet destined to Local */
71
72 /* ECMP MACROS */
73 #define MAX_SUPPORTED_FIB_PATHS 8 /**< for ECMP max supported FIB Paths */
74 #define HASH_BUCKET_SIZE 64  /**< size of HASH bucket for ECMP */
75
76 /* L2 Adjacency Macro */
77 #define L2_ADJ_RESOLVED   0x00  /** <MACRO to define a flag as Resolved*/
78 #define L2_ADJ_UNRESOLVED 0x01  /** <MacrO to define a flag as Unresolved */
79 /**
80 * A structure used to define the routing information for IPv4
81 * This structure is used as input parameters for route ADD
82 */
83 struct routing_info {
84         uint32_t dst_ip_addr;  /**< DST IP Address */
85         uint8_t depth;                           /**< Depth */
86         uint32_t metric;       /**< Metrics */
87         uint32_t fib_nh_size; /**< num of fib paths, greater than if Multipath(ECMP) feature is supported*/
88         uint32_t nh_ip_addr[MAX_FIB_PATHS];   /**< NextHop IP Address */
89         uint8_t out_port[MAX_FIB_PATHS];      /**< OUTGOING PORT */
90 } __rte_cache_aligned;
91
92 /**
93 * A structure used to define the fib path for Destination IP Address
94 * This fib path is shared accross different fib_info.
95 */
96 struct fib_path {
97         uint32_t nh_ip;         /**< Next hop IP address (only valid for remote routes) */
98         uint8_t out_port;       /**< Output port */
99         uint32_t refcount;      /**< Refcount, greater then 1 if multiple fib_info has same fib_path*/
100         struct l2_adj_entry *l2_adj_ptr; /**< Address of the L2 ADJ table entry */
101 } __rte_cache_aligned;                           /**< RTE CACHE ALIGNED */
102
103 /**
104 * A structure used to define the fib info (Route info)
105 * This fib info structure can have multiple fib paths.
106 */
107 struct fib_info {
108         uint32_t dst_ip_addr; /**< DST IP Address */
109         uint32_t metric;      /**< Metrics */
110         uint32_t fib_nh_size; /**< num of fib paths, greater than if Multipath(ECMP) feature is supported*/
111         uint8_t depth;                          /**< Depth */
112         struct fib_path *path[MAX_FIB_PATHS]; /**< Array of pointers to the fib_path */
113 } __rte_cache_aligned;                          /**< RTE CACHE ALIGNED */
114
115 /**
116 * A structure used to define the L2 Adjacency table
117 */
118 struct l2_adj_entry {
119         struct ether_addr eth_addr;    /**< Ether address */
120         uint32_t Next_hop_ip;                            /**< Next hop IP address (only valid for remote routes) */
121         uint8_t out_port_id;                             /**< Output port */
122         uint32_t refcount;                               /**< Refcount, greater then 1 if multiple fib_path has same L2_adj_entry*/
123         uint8_t l2_string[256];                          /**< L2 string, to rewrite the packet before transmission */
124         l2_phy_interface_t *phy_port;  /**<  Address of the L2 physical interface structure */
125         uint8_t flags;                                   /**< Set to unresolved, when ARP entry not available. Set to resolved, when ARP is available */
126 } __rte_cache_aligned;                                   /**< RTE CACHE ALIGNED */
127
128 /**
129 * A structure used to define the fib path key for hash table
130 */
131 struct fib_path_key_ipv4 {
132         uint32_t nh_ip;                 /**< Next hop IP address */
133         uint8_t out_port;   /**< Output port */
134         uint8_t filler1;    /**< Filler 1, for better hash key */
135         uint8_t filler2;    /**< Filler2, for better hash key*/
136         uint8_t filler3;    /**< Filler3, for better hash Key */
137 };
138
139 /**
140 * A structure used to define the fib path key for hash table
141 */
142 struct l2_adj_key_ipv4 {
143         uint32_t Next_hop_ip;   /**< Next hop IP address */
144         uint8_t out_port_id;    /**< Output port */
145         uint8_t filler1;        /**< Filler 1, for better hash key */
146         uint8_t filler2;        /**< Filler2, for better hash key*/
147         uint8_t filler3;        /**< Filler3, for better hash Key */
148 };
149
150 /**
151 * A structure used to hold the fib info after LPM Lookup
152 */
153 struct routing_table_entry {
154         uint32_t ip;                     /**< Next hop IP address (only valid for remote routes) */
155         uint8_t port_id;                 /**< Output port ID */
156         struct l2_adj_entry *l2_adj_ptr; /**< Address of L2 Adjacency table entry */
157 } __rte_cache_aligned;                   /**< RTE CACHE ALIGNED */
158
159 /**
160 * A structure used to define the L3 counter statistics
161 */
162 typedef struct l3fwd_stats {
163         uint64_t nb_rx_l3_pkt;          /**< Num of L3 pkts Received */
164         uint64_t nb_tx_l3_pkt;          /**< Num of L3 pkts Transmitted */
165         uint64_t nb_rx_l3_icmp_pkt;
166                                         /**< Num of ICMP pkts Received at L3*/
167         uint64_t nb_tx_l3_icmp_pkt;
168                                         /**< Num of ICMP pkts Transmitted at L3*/
169         uint64_t nb_l3_drop_pkt;  /**< Num of L3 Packets Dropped*/
170         uint64_t total_nb_rx_l3_pkt;
171                                         /**< Total Num of L3 Packets received, includes ICMP Pkt*/
172         uint64_t total_nb_tx_l3_pkt;
173                                         /**< Total Num of L3 Packets Transmitted, includes ICMP Pkt*/
174 } l3_stats_t;
175
176 struct ip_protocol_type {
177         uint8_t protocol_type;          /**< Protocol Type */
178         void (*func) (struct rte_mbuf **, uint16_t, uint64_t,
179                                         l2_phy_interface_t *);
180 } __rte_cache_aligned;
181
182 /* Function Declarations */
183
184 /**
185  * To creare LPM table, Cuckoo hash table for fib_path and l2_adj_entry tables
186  * @return
187  * 0 for failure, 1 for success
188  */
189 int lpm_init(void);
190
191 /**
192  * To add a route in LPM table by populating fib_path and L2 Adjacency.
193  * @param input_array
194  * To add the route based on routing_info stucture.
195  * @return
196  * 0 for failure, 1 for success
197  */
198 int lpm4_table_route_add(struct routing_info *input_array);
199
200 /**
201  * To Delete the IP route and corresponding fib_path and L2 Adjacency entries.
202  * @param ip
203  * Destionation IP for which the route need to deleted
204  * @param depth
205  * netmask for the Destination IP
206  * @return
207  * 0 for failure, 1 for success
208  */
209 int lpm4_table_route_delete(uint32_t ip, uint8_t depth);
210
211 /**
212  * To perform a LPM table lookup
213  * @param pkts_burst
214  * Burst of packets that needs to be lookup in LPM table
215  * @param nb_pkts
216  * number of packets that needs to be lookup in LPM table
217  * @param valid_pkts_mask
218  * lookup of the valid IPv4 Pkt mask
219  * @return
220  * 0 for failure, 1 for success
221  */
222 int lpm4_table_lookup(struct rte_mbuf **pkts_burst, uint16_t nb_pkts,
223                                         uint64_t valid_pkts_mask,
224                                         l2_phy_interface_t *port[RTE_PORT_IN_BURST_SIZE_MAX],
225                                         uint64_t *hit_mask);
226
227 /**
228  * To Verify whether the received IPv4 Packet is valid or not
229  * @param pkt
230  * packet pointing to IPv4 header that needs to be verifed
231  * @param link_len
232  * length of the IPv4 Pkt
233  * @return
234  * 0 for failure, 1 for success
235 */
236 int is_valid_ipv4_pkt(struct ipv4_hdr *pkt, uint32_t link_len);
237
238 /**
239  * To forward the valid L3 packets for LMP table lookup and forward ICMP Pkts to ICMP module
240  * @param m
241  * packet burst of type rte_mbuf
242  * @param nb_pkts
243  * Number of valid L3 packets
244  * @param pkt_mask
245  * Valid IPv4 packets mask that needs to be processed
246  * @param port
247  * IPv4 Pkt received form the input port structure.
248  * @return
249  * 0 for failure, 1 for success
250 */
251 void l3fwd_rx_ipv4_packets(struct rte_mbuf **m, uint16_t nb_pkts,
252                                  uint64_t pkt_mask, l2_phy_interface_t *port);
253
254 /**
255  * To get the destination MAC Address for the nexthop IP and outgoing port
256  * @param next_hop_ip
257  * Next HOP IP Address for which MAC address is needed
258  * @param out_phy_port
259  * Outgoing physical port
260  * @param hw_addr
261  * pointer to the ether_add, This gets update with valid MAC address based on nh_ip and out port
262  * @return
263  * 0 if failure, 1 if success
264  */
265 int get_dest_mac_for_nexthop(uint32_t next_hop_ip,
266                                          uint8_t out_phy_port, struct ether_addr *hw_addr);
267 /**
268  * To retrieve the l2_adj_entry for the nexthop IP and outgoing port
269  * This queries with cuckoo hash table based on the l2_adj_key_ipv4
270  * @param l2_adj_key
271  * Key which is required for Cuckook hash table lookup
272  * @return
273  * NULL if lookup fails, Address of the L2_adj_entry if lookup success
274 */
275
276 struct l2_adj_entry *retrieve_l2_adj_entry(struct l2_adj_key_ipv4 l2_adj_key);
277
278 /**
279  * To populate the l2_adj_entry for the nexthop IP and outgoing port
280  * @param ipaddr
281  * NextHop Ip Address for which L2_adj_entry needs to be populated
282  * @param portid
283  * outgong port ID
284  * @return
285  * NULL if lookup fails, Address of the L2_adj_entry if lookup success
286 */
287
288 struct l2_adj_entry *populate_l2_adj(uint32_t ipaddr, uint8_t portid);
289
290 /**
291  * To populate the fib_path for the nexthop IP and outgoing port
292  * @param nh_ip
293  * NextHop Ip Address for which L2_adj_entry needs to be populated
294  * @param portid
295  * outgong port ID
296  * @return
297  * NULL if lookup fails, Address of the type fib_path if lookup success
298 */
299 struct fib_path *populate_fib_path(uint32_t nh_ip, uint8_t portid);
300
301 /**
302  * To retrieve the fib_path entry for the nexthop IP and outgoing port
303  * This queries with cuckoo hash table based on the fib_path_key_ipv4
304  * @param path_key
305  * Key which is required for Cuckook hash table lookup
306  * @return
307  * NULL if lookup fails, Address of type fib_path if lookup success
308 */
309
310 struct fib_path *retrieve_fib_path_entry(struct fib_path_key_ipv4 path_key);
311
312 /**
313  * To delete the fib path and l2 adjacency entry from the cuckoo hash table
314  * @return
315  * None
316 */
317 void remove_fib_l2_adj_entry(void *);
318
319 /**
320  * To iterate the cuckoo hash table for fib_path and l2_adj_entry and print the table contents
321  * @return
322  * None
323 */
324 void iterate_cuckoo_hash_table(void);
325
326 /**
327  * To print the l3 counter statitics
328  * @return
329  * None
330 */
331 void print_l3_stats(void);
332
333 /**
334  * To get the hash resultant value based on SRC IP and DST IP
335  * @param mbuf
336  * packet of type rte_mbuf
337  * @return
338  * It returns a result of type uint8_t
339  */
340
341 uint8_t ip_hash_load_balance(struct rte_mbuf *mbuf);
342
343 /**
344  * Rotates the count number of bits from the value
345  * @param value
346  * an integer value
347  * @param count
348  * rotates a count number of bits from integer value
349  * @return
350  * It returns a result.
351  */
352
353 uint32_t rotr32(uint32_t value, unsigned int count);
354
355 void
356 resolve_l2_adj(uint32_t nexthop_ip, uint8_t out_port_id,
357                                  const struct ether_addr *hw_addr);
358
359 void
360 l3_protocol_type_add(uint8_t protocol_type,
361                                  void (*func) (struct rte_mbuf **, uint16_t, uint64_t,
362                                          l2_phy_interface_t *));
363
364 void
365 ip_local_packets_process(struct rte_mbuf **, uint16_t, uint64_t,
366                          l2_phy_interface_t *);
367 void ip_local_out_deliver(struct rte_mbuf **, uint16_t, uint64_t,
368                                 l2_phy_interface_t *);
369
370 void
371 ip_forward_deliver(struct rte_mbuf **, uint16_t, uint64_t,
372                          l2_phy_interface_t *);
373
374 #endif                          /* L3FWD_LPM_H */