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.
17 #ifndef __INCLUDE_LIB_ARP_H__
18 #define __INCLUDE_LIB_ARP_H__
20 #include <rte_pipeline.h>
21 #include "rte_ether.h"
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 500
35 #undef L3_STACK_SUPPORT
38 * A structure for Route table entries of IPv4
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 */
49 #define MAX_LOCAL_MAC_ADDRESS 32
52 uint32_t nhip[MAX_LOCAL_MAC_ADDRESS];
53 struct ether_addr link_hw_laddr[MAX_LOCAL_MAC_ADDRESS];
58 * A structure for Route table entires of IPv6
61 struct lib_nd_route_table_entry {
62 uint8_t ipv6[16]; /**< Ipv6 address */
63 uint8_t depth; /**< Depth */
64 uint32_t port; /**< Port */
65 uint8_t nhipv6[16]; /**< next hop Ipv6 */
69 struct lib_arp_route_table_entry
70 lib_arp_route_table[MAX_ARP_RT_ENTRY];
71 uint8_t lib_arp_route_ent_cnt;
72 struct lib_nd_route_table_entry
73 lib_nd_route_table[MAX_ARP_RT_ENTRY];
74 uint8_t lib_nd_route_ent_cnt;
75 struct arp_cache arp_local_cache[MAX_PORTS];
76 struct ether_addr link_hw_addr[MAX_LOCAL_MAC_ADDRESS];
77 uint32_t link_hw_addr_array_idx;
78 uint8_t arp_cache_hw_laddr_valid[MAX_LOCAL_MAC_ADDRESS];
79 } __rte_cache_aligned;
81 uint8_t arp_cache_dest_mac_present(uint32_t out_port);
83 extern struct lib_nd_route_table_entry lib_nd_route_table[MAX_ND_RT_ENTRY];
84 extern struct lib_arp_route_table_entry lib_arp_route_table[MAX_ARP_RT_ENTRY];
85 extern struct ether_addr *get_local_link_hw_addr(uint8_t out_port, uint32_t nhip);
86 extern struct arp_cache arp_local_cache[MAX_PORTS];
87 extern void prefetch(void);
88 extern struct arp_entry_data *arp_data_ptr[16];
89 uint32_t get_arp_buf(void);
102 struct arp_key_ipv4 {
103 uint32_t ip; /**< IP address */
104 uint8_t port_id; /**< Port id */
105 uint8_t filler1; /**< filler 1, for better hash key */
106 uint8_t filler2; /**< filler 2, for better hash key */
107 uint8_t filler3; /**< filler 3, for better hash key */
114 uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< 128 Bit of IPv6 Address*/
115 uint8_t port_id; /**< Port id */
125 enum arp_key_type type;
127 struct arp_key_ipv4 ipv4;
128 } key; /**< Key of type arp key Ipv4 */
132 * call back function parameter pair remove nd entry
136 struct nd_timer_key {
137 uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< IPv6 address */
138 uint8_t port_id; /**< Port id */
139 } __rte_cache_aligned;
142 * call back function parameter remove arp entry
145 struct arp_timer_key {
146 uint32_t ip; /**< Ip address */
147 uint8_t port_id; /**< Port id */
148 } __rte_cache_aligned;
150 extern uint32_t ARPICMP_DEBUG;
159 //#define COMPLETE 1 /**< ARP entry populated and echo reply recieved. */
160 //#define INCOMPLETE 0 /**< ARP entry populated and either awaiting echo reply or stale entry. */
162 extern uint32_t NDIPV6_DEBUG; /**< ND IPv6 */
164 #define ICMPv6_COMPLETE 1 /**< ICMPv6 entry populated and echo reply recieved. */
165 #define ICMPv6_INCOMPLETE 0 /**< ICMPv6 entry populated and either awaiting echo reply or stale entry. */
166 #define STATIC_ARP 1 /**< Static ARP Entry. */
167 #define DYNAMIC_ARP 0 /**< Dynamic ARP Entry. */
168 #define STATIC_ND 1 /**< Static ND Entry. */
169 #define DYNAMIC_ND 0 /**< Dynamic ND Entry. */
172 * A structure is used to defined the ARP entry data
173 * This structure is used as a input parameters for entry of ARP data
176 struct arp_entry_data {
177 struct ether_addr eth_addr; /**< ethernet address */
178 uint32_t ip; /**< IP address */
179 uint8_t port; /**< Port */
180 uint8_t status; /**< Status of entry */
181 uint8_t mode; /**< Mode */
182 uint8_t retry_count; /**< retry count for ARP*/
183 struct rte_timer *timer; /**< Timer Associated with ARP*/
184 struct arp_timer_key *timer_key;
185 struct rte_ring *queue; /** pkts queued */
186 rte_rwlock_t queue_lock; /** queue lock */
187 struct rte_mbuf **buf_pkts;
188 struct rte_mbuf *buffered_pkt_list_head;
189 struct rte_mbuf *buffered_pkt_list_tail;
191 uint32_t n_confirmed;
192 uint32_t n_last_update;
193 } __attribute__ ((packed));
196 * A structure is used to defined the table for arp entry data
197 * This structure is used to maintain the arp entry data
200 struct table_arp_entry_data {
201 uint8_t eth_addr[6]; /**< Ethernet address */
202 uint8_t port; /**< port */
203 uint8_t status; /**< status of entry */
204 uint32_t ip; /**< Ip address */
205 } __attribute__ ((packed));
208 * A structure is used to define the ND entry data for IPV6
209 * This structure is used as a input parameters for ND entry data
212 struct nd_entry_data {
213 struct ether_addr eth_addr; /**< Ethernet address */
214 uint8_t port; /**< port */
215 uint8_t status; /**< statusof the entry */
216 uint8_t mode; /**< Mode */
217 uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< Ipv6 address */
218 struct rte_timer *timer; /**< Timer */
219 } __attribute__ ((packed));
222 * A structure is used to define the table for ND entry data
223 * This structure is used to maintain ND entry data
227 struct table_nd_entry_data {
228 uint8_t eth_addr[6]; /**< Ethernet address */
229 uint8_t port; /**< Port */
230 uint8_t status; /**< status of Entry */
231 uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< IPv6 address */
232 struct rte_timer *timer; /**< Timer */
233 } __attribute__ ((packed));
236 * To get the destination MAC address andnext hop for the ip address and outgoing port
238 * IP address for which MAC address is needed.
242 * pointer to the ether_addr, This gets update with valid MAC addresss
244 * Gets the next hop IP by Ip address and physical port
246 * 0 if failure, and 1 if success
249 struct arp_entry_data *get_dest_mac_address(const uint32_t ipaddr, uint32_t *phy_port, struct ether_addr *hw_addr, uint32_t *nhip);
251 * To get the destination MAC address andnext hop for the ip address and outgoing port
253 * IP address for which MAC address is needed.
257 * pointer to the ether_addr, This gets update with valid MAC addresss
259 * Gets the next hop IP by Ip address and physical port
261 * 0 if failure, and 1 if success
263 struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
264 uint32_t *phy_port, struct ether_addr *hw_addr);
267 * To get the destination mac address for IPv4 address
269 * IP address which need the destination mac address
273 * pointer to the ether_addr, This gets update with valid mac address
275 * 0 if failure, 1 if success
277 int get_dest_mac_addr(const uint32_t ipaddr, uint32_t *phy_port,
278 struct ether_addr *hw_addr);
281 * To get the destination mac address for IPV6 address
283 * IPv6 address which need the destination mac adress
287 * pointer to the ether_address, This gets update with valid mac address
289 * Gets the next hop ipv6 address by ipv6 address and physical port
291 * 0 if failure, 1 ifsuccess
293 int get_dest_mac_address_ipv6(uint8_t ipv6addr[], uint32_t *phy_port,
294 struct ether_addr *hw_addr, uint8_t nhipv6[]);
296 * To get the destination mac address for IPV6 address
298 * IPv6 address which need the destination mac adress
302 * pointer to the ether_address, This gets update with valid mac address
304 * Gets the next hop ipv6 address by ipv6 address and physical port
306 * 0 if failure, 1 ifsuccess
309 int get_dest_mac_address_ipv6_port(uint8_t ipv6addr[], uint32_t *phy_port,
310 struct ether_addr *hw_addr,
312 int arp_queue_unresolved_packet(struct arp_entry_data * arp_data,
313 struct rte_mbuf * m);
314 extern void arp_send_buffered_pkts(struct arp_entry_data *ret_arp_data,struct ether_addr *hw_addr, uint8_t port_id);
317 * To get hardware link address
322 struct ether_addr *get_link_hw_addr(uint8_t out_port);
325 * This prints the Arp Table
329 void print_arp_table(void);
332 * This prints the ND table
336 void print_nd_table(void);
339 * This removes arp entry from Table
345 void remove_arp_entry(struct arp_entry_data *ret_arp_data, void *arg);
348 * Removes ND entry from Nd Table
355 void remove_nd_entry_ipv6(uint8_t ipv6addr[], uint8_t portid);
358 * Populate arp entry in arp Table
368 void populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
369 uint8_t portid, uint8_t mode);
372 * Populate ND entry in ND Table
383 void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ip[],
384 uint8_t portid, uint8_t mode);
387 * To send ARp request
394 void request_arp(uint8_t port_id, uint32_t ip);
397 * TO send echo request
403 struct rte_mbuf *request_echo(uint32_t port_id, uint32_t ip);
406 * To send icmpv6 echo request
412 struct rte_mbuf *request_icmpv6_echo(uint8_t ipv6[], l2_phy_interface_t *port);
421 struct rte_mbuf *request_nd(uint8_t ipv6[], l2_phy_interface_t *port);
424 * To process te ARP and ICMP packets
426 * Packets to be processed
432 void process_arpicmp_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port);
436 * Validate if key-value pair already exists in the hash table for given key - IPv4
438 * Arp key to validate entry
440 struct arp_entry_data *retrieve_arp_entry(const struct arp_key_ipv4 arp_key, uint8_t mode);
444 * Validate if key-value pair already exists in the hash table for given key - ND IPv6
446 * Nd key to validate Nd entry
449 struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key);
452 * Setsup Arp Initilization
454 //void lib_arp_init(void);
455 void lib_arp_init(struct pipeline_params *params, struct app_params *app);
457 void set_port_to_loadb_map(uint8_t pipeline_num);
460 * Acts on port_to_loadb_map
462 uint8_t get_port_to_loadb_map(uint8_t phy_port_id);
464 void set_phy_inport_map(uint8_t pipeline_num, uint8_t *map);
465 void set_phy_outport_map(uint8_t pipeline_num, uint8_t *map);
468 * Acts on lb_outport_id
471 uint8_t get_loadb_outport_id(uint8_t actual_phy_port);
472 uint8_t get_vnf_set_num(uint8_t pipeline_num);
474 void pipelines_port_info(void);
475 void pipelines_map_info(void);
478 * A callback for arp Timer
484 void arp_timer_callback(struct rte_timer *, void *arg);
487 * A callback for ND timer
493 void nd_timer_callback(struct rte_timer *timer, void *arg);
496 * To create Arp Table
499 void create_arp_table(void);
504 void create_nd_table(void);
507 * To parse and process the Arp and icmp packets
517 void process_arpicmp_pkt_parse(struct rte_mbuf **pkt, uint16_t pkt_num,
518 uint64_t pkt_mask, l2_phy_interface_t *port);
525 void send_gratuitous_arp(l2_phy_interface_t *port);
531 void set_arpdebug(int flag);
533 * To set timer for arp entry
535 * timer val for arp entry
537 void set_arptimeout(uint32_t timeout_val);
539 * To get nexthop for ipv4
545 uint32_t get_nh(uint32_t, uint32_t *, struct ether_addr *addr);
547 * To get nexthop for ipv6
555 void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[]);