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
35 #define ARP_RETRY_COUNT 100
36 #undef L3_STACK_SUPPORT
38 #define MAX_LOCAL_MAC_ADDRESS 32
41 uint32_t nhip[MAX_LOCAL_MAC_ADDRESS];
42 struct ether_addr link_hw_laddr[MAX_LOCAL_MAC_ADDRESS];
47 uint8_t nhip[MAX_LOCAL_MAC_ADDRESS][16];
48 struct ether_addr link_hw_laddr[MAX_LOCAL_MAC_ADDRESS];
52 uint8_t arp_cache_dest_mac_present(uint32_t out_port);
53 uint8_t nd_cache_dest_mac_present(uint32_t out_port);
54 extern struct ether_addr *get_local_cache_hw_addr(uint8_t out_port, uint32_t nhip);
55 extern struct ether_addr *get_nd_local_link_hw_addr(uint8_t out_port, uint8_t nhip[]);
56 extern struct arp_cache arp_local_cache[MAX_PORTS];
57 extern void prefetch(void);
58 extern void update_nhip_access(uint8_t);
59 uint32_t get_arp_buf(void);
60 uint32_t get_nd_buf(void);
74 uint32_t ip; /**< IP address */
75 uint8_t port_id; /**< Port id */
76 uint8_t filler1; /**< filler 1, for better hash key */
77 uint8_t filler2; /**< filler 2, for better hash key */
78 uint8_t filler3; /**< filler 3, for better hash key */
85 uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< 128 Bit of IPv6 Address*/
86 uint8_t port_id; /**< Port id */
96 enum arp_key_type type;
98 struct arp_key_ipv4 ipv4;
99 } key; /**< Key of type arp key Ipv4 */
103 * call back function parameter pair remove nd entry
107 struct nd_timer_key {
108 uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< IPv6 address */
109 uint8_t port_id; /**< Port id */
110 } __rte_cache_aligned;
113 * call back function parameter remove arp entry
116 struct arp_timer_key {
117 uint32_t ip; /**< Ip address */
118 uint8_t port_id; /**< Port id */
119 } __rte_cache_aligned;
121 extern uint32_t ARPICMP_DEBUG;
131 extern uint32_t NDIPV6_DEBUG; /**< ND IPv6 */
133 #define ICMPv6_COMPLETE 1 /**< ICMPv6 entry populated and echo reply recieved. */
134 #define ICMPv6_INCOMPLETE 0 /**< ICMPv6 entry populated and either awaiting echo reply or stale entry. */
135 #define STATIC_ARP 1 /**< Static ARP Entry. */
136 #define DYNAMIC_ARP 0 /**< Dynamic ARP Entry. */
137 #define STATIC_ND 1 /**< Static ND Entry. */
138 #define DYNAMIC_ND 0 /**< Dynamic ND Entry. */
141 * A structure is used to defined the ARP entry data
142 * This structure is used as a input parameters for entry of ARP data
145 struct arp_entry_data {
146 struct ether_addr eth_addr; /**< ethernet address */
147 uint32_t ip; /**< IP address */
148 uint8_t port; /**< Port */
149 uint8_t status; /**< Status of entry */
150 uint8_t mode; /**< Mode */
151 uint8_t retry_count; /**< retry count for ARP*/
152 struct rte_timer *timer; /**< Timer Associated with ARP*/
153 struct arp_timer_key *timer_key;
154 rte_rwlock_t queue_lock; /** queue lock */
155 struct rte_mbuf **buf_pkts;
157 uint64_t n_confirmed;
158 } __attribute__ ((packed));
161 * A structure is used to defined the table for arp entry data
162 * This structure is used to maintain the arp entry data
165 struct table_arp_entry_data {
166 uint8_t eth_addr[6]; /**< Ethernet address */
167 uint8_t port; /**< port */
168 uint8_t status; /**< status of entry */
169 uint32_t ip; /**< Ip address */
170 } __attribute__ ((packed));
173 * A structure is used to define the ND entry data for IPV6
174 * This structure is used as a input parameters for ND entry data
177 struct nd_entry_data {
178 struct ether_addr eth_addr; /**< Ethernet address */
179 uint8_t port; /**< port */
180 uint8_t status; /**< statusof the entry */
181 uint8_t mode; /**< Mode */
182 uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< Ipv6 address */
183 uint8_t retry_count; /**< retry count for ARP*/
184 struct rte_timer *timer; /**< Timer */
185 struct nd_timer_key *timer_key;
186 rte_rwlock_t queue_lock; /** queue lock */
187 struct rte_mbuf **buf_pkts;
189 uint64_t n_confirmed;
190 } __attribute__ ((packed));
193 * A structure is used to define the table for ND entry data
194 * This structure is used to maintain ND entry data
198 struct table_nd_entry_data {
199 uint8_t eth_addr[6]; /**< Ethernet address */
200 uint8_t port; /**< Port */
201 uint8_t status; /**< status of Entry */
202 uint8_t ipv6[ND_IPV6_ADDR_SIZE]; /**< IPv6 address */
203 struct rte_timer *timer; /**< Timer */
204 } __attribute__ ((packed));
207 struct arp_cache arp_local_cache[MAX_PORTS];
208 struct nd_cache nd_local_cache[MAX_PORTS];
209 struct ether_addr link_hw_addr[MAX_LOCAL_MAC_ADDRESS];
210 uint32_t link_hw_addr_array_idx;
211 uint8_t arp_cache_hw_laddr_valid[MAX_LOCAL_MAC_ADDRESS];
212 uint8_t nd_cache_hw_laddr_valid[MAX_LOCAL_MAC_ADDRESS];
213 uint64_t update_tsc[MAX_LOCAL_MAC_ADDRESS];
214 } __rte_cache_aligned;
217 * To get the destination MAC address andnext hop for the ip address and outgoing port
219 * IP address for which MAC address is needed.
223 * pointer to the ether_addr, This gets update with valid MAC addresss
225 * Gets the next hop IP by Ip address and physical port
227 * 0 if failure, and 1 if success
229 struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
230 uint32_t phy_port, struct ether_addr *hw_addr);
233 * To get the destination mac address for IPV6 address
235 * IPv6 address which need the destination mac adress
239 * pointer to the ether_address, This gets update with valid mac address
241 * Gets the next hop ipv6 address by ipv6 address and physical port
243 * 0 if failure, 1 ifsuccess
245 int arp_queue_unresolved_packet(struct arp_entry_data * arp_data,
246 struct rte_mbuf * m);
247 extern void arp_send_buffered_pkts(struct arp_entry_data *ret_arp_data,struct ether_addr *hw_addr, uint8_t port_id);
249 int nd_queue_unresolved_packet(struct nd_entry_data *nd_data,
250 struct rte_mbuf * m);
251 extern void nd_send_buffered_pkts(struct nd_entry_data *ret_nd_data,struct ether_addr *hw_addr, uint8_t port_id);
254 * To get hardware link address
259 struct ether_addr *get_link_hw_addr(uint8_t out_port);
262 * This prints the Arp Table
266 void print_arp_table(void);
269 * This prints the ND table
273 void print_nd_table(void);
276 * This removes arp entry from Table
282 void remove_arp_entry(struct arp_entry_data *ret_arp_data, void *arg);
285 * Removes ND entry from Nd Table
292 void remove_nd_entry_ipv6(struct nd_entry_data *ret_nd_data, void *arg);
295 * Populate arp entry in arp Table
305 void populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
306 uint8_t portid, uint8_t mode);
309 * Populate ND entry in ND Table
320 void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ip[],
321 uint8_t portid, uint8_t mode);
324 * To send ARp request
331 void request_arp(uint8_t port_id, uint32_t ip);
334 * TO send echo request
340 struct rte_mbuf *request_echo(uint32_t port_id, uint32_t ip);
343 * To send icmpv6 echo request
349 struct rte_mbuf *request_icmpv6_echo(uint8_t ipv6[], l2_phy_interface_t *port);
358 struct rte_mbuf *request_nd(uint8_t ipv6[], l2_phy_interface_t *port);
361 * To process te ARP and ICMP packets
363 * Packets to be processed
369 void process_arpicmp_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port);
373 * Validate if key-value pair already exists in the hash table for given key - IPv4
375 * Arp key to validate entry
377 struct arp_entry_data *retrieve_arp_entry(const struct arp_key_ipv4 arp_key, uint8_t mode);
381 * Validate if key-value pair already exists in the hash table for given key - ND IPv6
383 * Nd key to validate Nd entry
386 struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key, uint8_t mode);
389 * Setsup Arp Initilization
391 //void lib_arp_init(void);
392 void lib_arp_init(struct pipeline_params *params, struct app_params *app);
394 void set_port_to_loadb_map(uint8_t pipeline_num);
397 * Acts on port_to_loadb_map
399 uint8_t get_port_to_loadb_map(uint8_t phy_port_id);
401 void set_phy_inport_map(uint8_t pipeline_num, uint8_t *map);
402 void set_phy_outport_map(uint8_t pipeline_num, uint8_t *map);
405 * Acts on lb_outport_id
408 uint8_t get_loadb_outport_id(uint8_t actual_phy_port);
409 uint8_t get_vnf_set_num(uint8_t pipeline_num);
411 void pipelines_port_info(void);
412 void pipelines_map_info(void);
415 * A callback for arp Timer
421 void arp_timer_callback(struct rte_timer *, void *arg);
424 * A callback for ND timer
430 void nd_timer_callback(struct rte_timer *timer, void *arg);
433 * To create Arp Table
436 void create_arp_table(void);
441 void create_nd_table(void);
444 * To parse and process the Arp and icmp packets
454 void process_arpicmp_pkt_parse(struct rte_mbuf **pkt, uint16_t pkt_num,
455 uint64_t pkt_mask, l2_phy_interface_t *port);
462 void send_gratuitous_arp(l2_phy_interface_t *port);
468 void set_arpdebug(int flag);
470 * To set timer for arp entry
472 * timer val for arp entry
474 void set_arptimeout(uint32_t timeout_val);
476 * To get nexthop for ipv4
482 uint32_t get_nh(uint32_t, uint32_t *, struct ether_addr *addr);
484 * To get nexthop for ipv6
492 void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[], struct ether_addr *hw_addr);
494 struct arp_entry_data *get_dest_mac_addr_ipv4(const uint32_t nhip,
495 uint32_t phy_port, struct ether_addr *hw_addr);
496 struct nd_entry_data *get_dest_mac_addr_ipv6(uint8_t nhipv6[],
497 uint32_t phy_port, struct ether_addr *hw_addr);