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