Merge "[l2l3 stack] implements new nd state machine & nd buffering"
[samplevnf.git] / common / VIL / l2l3_stack / lib_arp.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 #ifndef __INCLUDE_LIB_ARP_H__
18 #define __INCLUDE_LIB_ARP_H__
19
20 #include <rte_pipeline.h>
21 #include "rte_ether.h"
22 #include "l2_proto.h"
23 #include "app.h"
24
25 #define ND_IPV6_ADDR_SIZE 16    /**< 16 Byte of IPv6 Address. */
26 #define ND_IPV6_TIMER_EXPIRY 300  /**< in Seconds, Timer for ND IPv6 Expiry */
27 #define ARP_TIMER_EXPIRY 20      /**< in Seconds, TIMER for ARP Expiry */
28 #define TIMER_MILLISECOND 1
29 #define RTE_LOGTYPE_LIBARP RTE_LOGTYPE_USER1
30 #define MAX_ND_RT_ENTRY 32
31 #define MAX_ARP_RT_ENTRY 32
32 #define NUM_DESC                (get_arp_buf())
33 #define ARP_BUF_DEFAULT                30000
34 #define PROBE_TIME             50
35 #undef L3_STACK_SUPPORT
36
37 /**
38 * A structure for Route table entries of IPv4
39 */
40
41 struct lib_arp_route_table_entry {
42         uint32_t ip;    /**< Ipv4 address*/
43         uint32_t mask;  /**< mask */
44         uint32_t port;  /**< Physical port */
45         uint32_t nh;    /**< next hop */
46         uint32_t nh_mask;
47 };
48
49 #define MAX_LOCAL_MAC_ADDRESS          32
50 #define MAX_PORTS                      32
51 struct arp_cache {
52         uint32_t nhip[MAX_LOCAL_MAC_ADDRESS];
53         struct ether_addr link_hw_laddr[MAX_LOCAL_MAC_ADDRESS];
54         uint32_t num_nhip;
55 };
56
57 struct nd_cache {
58         uint8_t nhip[MAX_LOCAL_MAC_ADDRESS][16];
59         struct ether_addr link_hw_laddr[MAX_LOCAL_MAC_ADDRESS];
60         uint32_t num_nhip;
61 };
62
63 /**
64 * A structure for Route table entires of IPv6
65 *
66 */
67 struct lib_nd_route_table_entry {
68         uint8_t ipv6[16];       /**< Ipv6 address */
69         uint8_t depth;          /**< Depth */
70         uint32_t port;          /**< Port */
71         uint8_t nhipv6[16];     /**< next hop Ipv6 */
72 };
73
74 uint8_t arp_cache_dest_mac_present(uint32_t out_port);
75 uint8_t nd_cache_dest_mac_present(uint32_t out_port);
76 extern struct lib_nd_route_table_entry lib_nd_route_table[MAX_ND_RT_ENTRY];
77 extern struct lib_arp_route_table_entry lib_arp_route_table[MAX_ARP_RT_ENTRY];
78 extern struct ether_addr *get_local_link_hw_addr(uint8_t out_port, uint32_t nhip);
79 extern struct ether_addr *get_nd_local_link_hw_addr(uint8_t out_port, uint8_t nhip[]);
80 extern struct arp_cache arp_local_cache[MAX_PORTS];
81 extern void prefetch(void);
82 extern void update_nhip_access(uint8_t);
83 uint32_t get_arp_buf(void);
84 uint32_t get_nd_buf(void);
85
86 enum {
87         ARP_FOUND,
88         ARP_NOT_FOUND,
89         NH_NOT_FOUND,
90 };
91
92 enum arp_key_type {
93         ARP_IPV4,
94         ND_IPV6,
95 };
96
97 struct arp_key_ipv4 {
98         uint32_t ip;     /**< IP address */
99         uint8_t port_id; /**< Port id */
100         uint8_t filler1; /**< filler 1, for better hash key */
101         uint8_t filler2; /**< filler 2, for better hash key */
102         uint8_t filler3; /**< filler 3, for better hash key */
103 };
104
105 /**
106 * IPv6
107 */
108 struct nd_key_ipv6 {
109         uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< 128 Bit of IPv6 Address*/
110         uint8_t port_id;                 /**< Port id */
111         uint8_t filler1;
112         uint8_t filler2;
113         uint8_t filler3;
114 };
115
116 /**
117 * Arp Key
118 */
119 struct arp_key {
120         enum arp_key_type type;
121         union {
122                 struct arp_key_ipv4 ipv4;
123         } key;  /**< Key of type arp key Ipv4 */
124 };
125
126 /**
127 * call back function parameter pair remove nd entry
128 *
129 */
130
131 struct nd_timer_key {
132         uint8_t ipv6[ND_IPV6_ADDR_SIZE];   /**< IPv6 address */
133         uint8_t port_id;                 /**< Port id */
134 } __rte_cache_aligned;
135
136 /**
137 * call back function parameter remove arp entry
138 *
139 */
140 struct arp_timer_key {
141         uint32_t ip;     /**< Ip address */
142         uint8_t port_id; /**< Port id */
143 } __rte_cache_aligned;
144
145 extern uint32_t ARPICMP_DEBUG;
146
147 enum {
148         INCOMPLETE,
149         COMPLETE,
150         PROBE,
151         STALE
152 };
153 #define USED_TIME       5
154
155 extern uint32_t NDIPV6_DEBUG;  /**< ND IPv6 */
156
157 #define ICMPv6_COMPLETE   1 /**< ICMPv6 entry populated and echo reply recieved. */
158 #define ICMPv6_INCOMPLETE 0 /**< ICMPv6 entry populated and either awaiting echo reply or stale entry. */
159 #define STATIC_ARP 1                    /**< Static ARP Entry. */
160 #define DYNAMIC_ARP 0                   /**< Dynamic ARP Entry. */
161 #define STATIC_ND 1                     /**< Static ND Entry. */
162 #define DYNAMIC_ND 0                    /**< Dynamic ND Entry. */
163
164 /**
165 * A structure is used to defined the ARP entry data
166 * This structure is used as a input parameters for entry of ARP data
167 */
168
169 struct arp_entry_data {
170         struct ether_addr eth_addr; /**< ethernet address */
171         uint32_t ip;                            /**< IP address */
172         uint8_t port;                           /**< Port */
173         uint8_t status;                         /**< Status of entry */
174         uint8_t mode;                           /**< Mode */
175         uint8_t retry_count;                    /**< retry count for ARP*/
176         struct rte_timer *timer;    /**< Timer Associated with ARP*/
177         struct arp_timer_key *timer_key;
178         rte_rwlock_t queue_lock;    /** queue lock */
179         struct rte_mbuf **buf_pkts;
180         uint32_t num_pkts;
181         uint64_t n_confirmed;
182 } __attribute__ ((packed));
183
184 /**
185 * A structure is used to defined the table for arp entry data
186 * This structure is used to maintain the arp entry data
187 */
188
189 struct table_arp_entry_data {
190         uint8_t eth_addr[6];     /**< Ethernet address */
191         uint8_t port;            /**< port */
192         uint8_t status;          /**< status of entry */
193         uint32_t ip;             /**< Ip address */
194 } __attribute__ ((packed));
195
196 /**
197 * A structure is used to define the ND entry data for IPV6
198 * This structure is used as a input parameters  for ND entry data
199 */
200
201 struct nd_entry_data {
202         struct ether_addr eth_addr;             /**< Ethernet address */
203         uint8_t port;                           /**< port */
204         uint8_t status;                         /**< statusof the entry */
205         uint8_t mode;                           /**< Mode */
206         uint8_t ipv6[ND_IPV6_ADDR_SIZE];  /**< Ipv6 address */
207         uint8_t retry_count;                    /**< retry count for ARP*/
208         struct rte_timer *timer;                /**< Timer */
209         struct nd_timer_key *timer_key;
210         rte_rwlock_t queue_lock;    /** queue lock */
211         struct rte_mbuf **buf_pkts;
212         uint32_t num_pkts;
213         uint64_t n_confirmed;
214 } __attribute__ ((packed));
215
216 /**
217 * A structure is used to define the table for ND entry data
218 * This structure is used to maintain ND entry data
219 *
220 */
221
222 struct table_nd_entry_data {
223         uint8_t eth_addr[6];             /**< Ethernet address */
224         uint8_t port;                    /**< Port */
225         uint8_t status;                  /**< status of Entry */
226         uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< IPv6 address */
227         struct rte_timer *timer;         /**< Timer */
228 } __attribute__ ((packed));
229
230 struct arp_data {
231         struct lib_arp_route_table_entry
232             lib_arp_route_table[MAX_ARP_RT_ENTRY];
233         uint8_t lib_arp_route_ent_cnt;
234         struct lib_nd_route_table_entry
235             lib_nd_route_table[MAX_ARP_RT_ENTRY];
236         uint8_t lib_nd_route_ent_cnt;
237         struct arp_cache arp_local_cache[MAX_PORTS];
238         struct nd_cache nd_local_cache[MAX_PORTS];
239         struct ether_addr link_hw_addr[MAX_LOCAL_MAC_ADDRESS];
240         uint32_t link_hw_addr_array_idx;
241         uint8_t arp_cache_hw_laddr_valid[MAX_LOCAL_MAC_ADDRESS];
242         uint8_t nd_cache_hw_laddr_valid[MAX_LOCAL_MAC_ADDRESS];
243         uint64_t update_tsc[MAX_LOCAL_MAC_ADDRESS];
244 } __rte_cache_aligned;
245
246 /**
247 * To get the destination MAC address andnext hop for the ip address  and outgoing port
248 * @param1 ip addr
249 * IP address for which MAC address is needed.
250 * @param2 phy_port
251 *  Physical Port
252 * @param3 ether_addr
253 * pointer to the ether_addr, This gets update with valid MAC addresss
254 * @Param4 next nhip
255 * Gets the next hop IP by Ip address and physical port
256 * @return
257 * 0 if failure, and 1 if success
258 */
259 struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
260                                  uint32_t *phy_port, struct ether_addr *hw_addr);
261
262 /**
263 * To get the destination mac address for IPV6 address
264 * @param ipv6addr
265 * IPv6 address which need the destination mac adress
266 * @param Phy_Port
267 * physical prt
268 * @param ether_addr
269 * pointer to the ether_address, This gets update with valid mac address
270 * @param Nhipv6[]
271 * Gets the next hop ipv6 address by ipv6 address and physical port
272 * @return
273 * 0 if failure, 1 ifsuccess
274 */
275
276 struct nd_entry_data *get_dest_mac_address_ipv6_port(uint8_t ipv6addr[], uint32_t *phy_port,
277                                          struct ether_addr *hw_addr,
278                                          uint8_t nhipv6[]);
279 int arp_queue_unresolved_packet(struct arp_entry_data * arp_data,
280                         struct rte_mbuf * m);
281 extern void arp_send_buffered_pkts(struct arp_entry_data *ret_arp_data,struct ether_addr *hw_addr, uint8_t port_id);
282
283 int nd_queue_unresolved_packet(struct nd_entry_data *nd_data,
284                         struct rte_mbuf * m);
285 extern void nd_send_buffered_pkts(struct nd_entry_data *ret_nd_data,struct ether_addr *hw_addr, uint8_t port_id);
286
287 /**
288 * To get hardware link address
289 * @param out_port
290 * out going  port
291 */
292
293 struct ether_addr *get_link_hw_addr(uint8_t out_port);
294
295 /**
296 * This prints the Arp Table
297 * @param void
298 *
299 */
300 void print_arp_table(void);
301
302 /**
303 * This prints the ND table
304 * @param void
305 *
306 */
307 void print_nd_table(void);
308
309 /**
310 * This removes arp entry from Table
311 * @param ipaddr
312 * Ipv4 address
313 * @param portid
314 * Port id
315 */
316 void remove_arp_entry(struct arp_entry_data *ret_arp_data, void *arg);
317
318 /**
319 * Removes ND entry from Nd Table
320 * @Param ipv6addr[]
321 * Ipv6 address
322 * @Param portid
323 * Port id
324 */
325
326 void remove_nd_entry_ipv6(struct nd_entry_data *ret_nd_data, void *arg);
327
328 /**
329 * Populate arp entry in arp Table
330 * @param ether_addr
331 * Ethernet address
332 * @param ipaddr
333 * Ipv4 adress
334 * @Param portid
335 * port id
336 * @Param mode
337 * Mode
338 */
339 void populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
340                         uint8_t portid, uint8_t mode);
341
342 /**
343 * Populate ND entry in ND Table
344 * @param ether_addr
345 * Ethernet address
346 * @param ip[]
347 * Ipv6 adress
348 * @Param portid
349 * port id
350 * @Param mode
351 * Mode
352 */
353
354 void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ip[],
355                                          uint8_t portid, uint8_t mode);
356
357 /**
358 * To send ARp request
359 * @Param port_id
360 * port id
361 @ Param IP
362 * Ip address
363 */
364
365 void request_arp(uint8_t port_id, uint32_t ip);
366
367 /**
368 * TO send echo request
369 * @param port_id
370 * Port id
371 * @Param ip
372 * Ip address
373 */
374 struct rte_mbuf *request_echo(uint32_t port_id, uint32_t ip);
375
376 /**
377 * To send icmpv6 echo request
378 * @Param port_id
379 * Port id
380 * @Param ipv6
381 * ipv6 address
382 */
383 struct rte_mbuf *request_icmpv6_echo(uint8_t ipv6[], l2_phy_interface_t *port);
384
385 /**
386 * To request ND
387 * @Param ipv6
388 * ipv6 address
389 * @Param port
390 * pointer to port
391 */
392 struct rte_mbuf *request_nd(uint8_t ipv6[], l2_phy_interface_t *port);
393
394 /**
395 * To process te ARP and ICMP packets
396 * @Param Pkt
397 * Packets to be processed
398 * @Param pkt_num
399 * packet number
400 * @Param portid
401 * port id
402 */
403 void process_arpicmp_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port);
404
405 /**
406 * IPv4
407 * Validate if key-value pair already exists in the hash table for given key - IPv4
408 * @Param arp_key
409 * Arp key to validate entry
410 */
411 struct arp_entry_data *retrieve_arp_entry(const struct arp_key_ipv4 arp_key, uint8_t mode);
412
413 /**
414 * ND IPv6
415 * Validate if key-value pair already exists in the hash table for given key - ND IPv6
416 * @Param nd_key
417 * Nd key to validate Nd entry
418 */
419
420 struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key, uint8_t mode);
421
422 /**
423 * Setsup Arp Initilization
424 */
425 //void lib_arp_init(void);
426 void lib_arp_init(struct pipeline_params *params, struct app_params *app);
427 #if 0
428 void set_port_to_loadb_map(uint8_t pipeline_num);
429
430 /**
431 * Acts on port_to_loadb_map
432 */
433 uint8_t get_port_to_loadb_map(uint8_t phy_port_id);
434
435 void set_phy_inport_map(uint8_t pipeline_num, uint8_t *map);
436 void set_phy_outport_map(uint8_t pipeline_num, uint8_t *map);
437
438 /**
439 * Acts on lb_outport_id
440 */
441
442 uint8_t get_loadb_outport_id(uint8_t actual_phy_port);
443 uint8_t get_vnf_set_num(uint8_t pipeline_num);
444
445 void pipelines_port_info(void);
446 void pipelines_map_info(void);
447 #endif
448 /**
449 * A callback for arp Timer
450 * @Param rte_timer
451 * timer pointer
452 * @Param arg
453 * arguments to timer
454 */
455 void arp_timer_callback(struct rte_timer *, void *arg);
456
457 /**
458 * A callback for ND timer
459 * @Param rte_timer
460 * timer pointer
461 * @Param arg
462 * arguments to timer
463 */
464 void nd_timer_callback(struct rte_timer *timer, void *arg);
465
466 /**
467 * To create Arp Table
468 * @param void
469 */
470 void create_arp_table(void);
471 /**
472 * To create ND Table
473 * @param void
474 */
475 void create_nd_table(void);
476
477 /**
478 * To parse and process the Arp and icmp packets
479 * @Param pkt
480 * pkt to process
481 * @Param pkt_num
482 * pkt number
483 * @Param pkt_mask
484 * packet mask
485 * @Param port
486 * pointer to port
487 */
488 void process_arpicmp_pkt_parse(struct rte_mbuf **pkt, uint16_t pkt_num,
489                                                  uint64_t pkt_mask, l2_phy_interface_t *port);
490
491 /**
492 * Sends garp packet
493 * @Param port
494 * pointer to port
495 */
496 void send_gratuitous_arp(l2_phy_interface_t *port);
497 /**
498 * To set arp debug
499 * @Param flag
500 * set 1 unset 0
501 */
502 void set_arpdebug(int flag);
503 /**
504 * To set timer for arp entry
505 * @Param timeout_val
506 * timer val for arp entry
507 */
508 void set_arptimeout(uint32_t timeout_val);
509 /**
510 * To get nexthop for ipv4
511 * @Param ipv4
512 * ipv4 address
513 * @Param
514 * timeout_val to set
515 */
516 uint32_t get_nh(uint32_t, uint32_t *, struct ether_addr *addr);
517 /**
518 * To get nexthop for ipv6
519 * @Param ipv6
520 * ipv6 address
521 * @Param port
522 * pointer to port
523 * @Param nhipv6
524 * next hop ipv6
525 */
526 void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[], struct ether_addr *hw_addr);
527 #endif