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 * L3fwd lpm4 header file is for IPv4 specific declarations
28 #include <sys/types.h>
30 #include <sys/queue.h>
36 #include <rte_debug.h>
37 #include <rte_memory.h>
38 #include <rte_ether.h>
39 #include <rte_ethdev.h>
41 #include <rte_mempool.h>
42 #include <rte_cycles.h>
49 #include "l3fwd_common.h"
50 #include "l3fwd_lpm6.h"
51 #include "interface.h"
54 * Define all RTE MBUF offset size
57 #define MBUF_HDR_ROOM 256 /**< MBUF HEADER ROOM OFFSET */
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 */
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 */
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 */
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 */
80 * A structure used to define the routing information for IPv4
81 * This structure is used as input parameters for route ADD
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;
93 * A structure used to define the fib path for Destination IP Address
94 * This fib path is shared accross different fib_info.
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 */
104 * A structure used to define the fib info (Route info)
105 * This fib info structure can have multiple fib paths.
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 */
116 * A structure used to define the L2 Adjacency table
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 */
129 * A structure used to define the fib path key for hash table
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 */
140 * A structure used to define the fib path key for hash table
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 */
151 * A structure used to hold the fib info after LPM Lookup
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 */
160 * A structure used to define the L3 counter statistics
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*/
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;
182 /* Function Declarations */
185 * To creare LPM table, Cuckoo hash table for fib_path and l2_adj_entry tables
187 * 0 for failure, 1 for success
192 * To add a route in LPM table by populating fib_path and L2 Adjacency.
194 * To add the route based on routing_info stucture.
196 * 0 for failure, 1 for success
198 int lpm4_table_route_add(struct routing_info *input_array);
201 * To Delete the IP route and corresponding fib_path and L2 Adjacency entries.
203 * Destionation IP for which the route need to deleted
205 * netmask for the Destination IP
207 * 0 for failure, 1 for success
209 int lpm4_table_route_delete(uint32_t ip, uint8_t depth);
212 * To perform a LPM table lookup
214 * Burst of packets that needs to be lookup in LPM table
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
220 * 0 for failure, 1 for success
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],
228 * To Verify whether the received IPv4 Packet is valid or not
230 * packet pointing to IPv4 header that needs to be verifed
232 * length of the IPv4 Pkt
234 * 0 for failure, 1 for success
236 int is_valid_ipv4_pkt(struct ipv4_hdr *pkt, uint32_t link_len);
239 * To forward the valid L3 packets for LMP table lookup and forward ICMP Pkts to ICMP module
241 * packet burst of type rte_mbuf
243 * Number of valid L3 packets
245 * Valid IPv4 packets mask that needs to be processed
247 * IPv4 Pkt received form the input port structure.
249 * 0 for failure, 1 for success
251 void l3fwd_rx_ipv4_packets(struct rte_mbuf **m, uint16_t nb_pkts,
252 uint64_t pkt_mask, l2_phy_interface_t *port);
255 * To get the destination MAC Address for the nexthop IP and outgoing port
257 * Next HOP IP Address for which MAC address is needed
258 * @param out_phy_port
259 * Outgoing physical port
261 * pointer to the ether_add, This gets update with valid MAC address based on nh_ip and out port
263 * 0 if failure, 1 if success
265 int get_dest_mac_for_nexthop(uint32_t next_hop_ip,
266 uint8_t out_phy_port, struct ether_addr *hw_addr);
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
271 * Key which is required for Cuckook hash table lookup
273 * NULL if lookup fails, Address of the L2_adj_entry if lookup success
276 struct l2_adj_entry *retrieve_l2_adj_entry(struct l2_adj_key_ipv4 l2_adj_key);
279 * To populate the l2_adj_entry for the nexthop IP and outgoing port
281 * NextHop Ip Address for which L2_adj_entry needs to be populated
285 * NULL if lookup fails, Address of the L2_adj_entry if lookup success
288 struct l2_adj_entry *populate_l2_adj(uint32_t ipaddr, uint8_t portid);
291 * To populate the fib_path for the nexthop IP and outgoing port
293 * NextHop Ip Address for which L2_adj_entry needs to be populated
297 * NULL if lookup fails, Address of the type fib_path if lookup success
299 struct fib_path *populate_fib_path(uint32_t nh_ip, uint8_t portid);
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
305 * Key which is required for Cuckook hash table lookup
307 * NULL if lookup fails, Address of type fib_path if lookup success
310 struct fib_path *retrieve_fib_path_entry(struct fib_path_key_ipv4 path_key);
313 * To delete the fib path and l2 adjacency entry from the cuckoo hash table
317 void remove_fib_l2_adj_entry(void *);
320 * To iterate the cuckoo hash table for fib_path and l2_adj_entry and print the table contents
324 void iterate_cuckoo_hash_table(void);
327 * To print the l3 counter statitics
331 void print_l3_stats(void);
334 * To get the hash resultant value based on SRC IP and DST IP
336 * packet of type rte_mbuf
338 * It returns a result of type uint8_t
341 uint8_t ip_hash_load_balance(struct rte_mbuf *mbuf);
344 * Rotates the count number of bits from the value
348 * rotates a count number of bits from integer value
350 * It returns a result.
353 uint32_t rotr32(uint32_t value, unsigned int count);
356 resolve_l2_adj(uint32_t nexthop_ip, uint8_t out_port_id,
357 const struct ether_addr *hw_addr);
360 l3_protocol_type_add(uint8_t protocol_type,
361 void (*func) (struct rte_mbuf **, uint16_t, uint64_t,
362 l2_phy_interface_t *));
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 *);
371 ip_forward_deliver(struct rte_mbuf **, uint16_t, uint64_t,
372 l2_phy_interface_t *);
374 #endif /* L3FWD_LPM_H */