[l2l3 stack] implements new arp state machine & arp buffering
[samplevnf.git] / common / VIL / pipeline_loadb / pipeline_loadb.c
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 #include <cmdline_parse.h>
18 #include <cmdline_parse_num.h>
19 #include <cmdline_parse_string.h>
20 #include <cmdline_parse_ipaddr.h>
21 #include <cmdline_parse_etheraddr.h>
22
23 #include "app.h"
24 #include "pipeline_common_fe.h"
25 #include "pipeline_loadb.h"
26 #include "vnf_common.h"
27 //#include "lib_arp.h"
28 #include "pipeline_arpicmp_be.h"
29 //#include "lib_arp.h"
30 //#include "interface.h"
31 static int
32 app_pipeline_loadb_entry_dbg(struct app_params *app,
33                                          uint32_t pipeline_id, uint8_t *msg)
34 {
35         struct pipeline_loadb_entry_dbg_msg_req *req;
36         struct pipeline_loadb_entry_dbg_msg_rsp *rsp;
37
38         /* Check input arguments */
39         if (app == NULL)
40                 return -1;
41
42         /* Allocate and write request */
43         req = app_msg_alloc(app);
44         if (req == NULL)
45                 return -1;
46
47         req->type = PIPELINE_MSG_REQ_CUSTOM;
48         req->subtype = PIPELINE_LOADB_MSG_REQ_ENTRY_DBG;
49         req->data[0] = msg[0];
50         req->data[1] = msg[1];
51
52         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
53         if (rsp == NULL)
54                 return -1;
55
56         /* Read response */
57         if (rsp->status) {
58                 app_msg_free(app, rsp);
59                 printf("Error rsp->status %d\n", rsp->status);
60                 return -1;
61         }
62
63         /* Free response */
64         app_msg_free(app, rsp);
65
66         return 0;
67 }
68
69 /*
70  * entry dbg
71  */
72
73 struct cmd_entry_dbg_result {
74         cmdline_fixed_string_t p_string;
75         uint32_t p;
76         cmdline_fixed_string_t entry_string;
77         cmdline_fixed_string_t dbg_string;
78         uint8_t cmd;
79         uint8_t d1;
80 };
81
82 static void
83 cmd_entry_dbg_parsed(void *parsed_result,
84                                  __rte_unused struct cmdline *cl, void *data)
85 {
86         struct cmd_entry_dbg_result *params = parsed_result;
87         struct app_params *app = data;
88         uint8_t msg[2];
89         int status;
90
91         msg[0] = params->cmd;
92         msg[1] = params->d1;
93         status = app_pipeline_loadb_entry_dbg(app, params->p, msg);
94
95         if (status != 0) {
96                 printf("Dbg Command failed\n");
97                 return;
98         }
99 }
100
101 static cmdline_parse_token_string_t lb_cmd_entry_dbg_p_string =
102 TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result, p_string, "p");
103
104 static cmdline_parse_token_num_t lb_cmd_entry_dbg_p =
105 TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, p, UINT32);
106
107 static cmdline_parse_token_string_t lb_cmd_entry_dbg_entry_string =
108 TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result,
109                          entry_string, "lbentry");
110
111 static cmdline_parse_token_string_t lb_cmd_entry_dbg_dbg_string =
112 TOKEN_STRING_INITIALIZER(struct cmd_entry_dbg_result, dbg_string,
113                          "dbg");
114
115 static cmdline_parse_token_num_t lb_cmd_entry_dbg_cmd =
116 TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, cmd, UINT8);
117
118 static cmdline_parse_token_num_t lb_cmd_entry_dbg_d1 =
119 TOKEN_NUM_INITIALIZER(struct cmd_entry_dbg_result, d1, UINT8);
120
121 static cmdline_parse_inst_t lb_cmd_entry_dbg = {
122         .f = cmd_entry_dbg_parsed,
123         .data = NULL,
124         .help_str = "LOADB dbg cmd",
125         .tokens = {
126                          (void *)&lb_cmd_entry_dbg_p_string,
127                          (void *)&lb_cmd_entry_dbg_p,
128                          (void *)&lb_cmd_entry_dbg_entry_string,
129                          (void *)&lb_cmd_entry_dbg_dbg_string,
130                          (void *)&lb_cmd_entry_dbg_cmd,
131                          (void *)&lb_cmd_entry_dbg_d1,
132                          NULL,
133                          },
134 };
135
136 /*static void*/
137 /*print_arp_entry(const struct app_pipeline_arp_icmp_arp_entry *entry)*/
138 /*{*/
139 /*      printf("(Port = %" PRIu32 ", IP = %" PRIu32 ".%" PRIu32*/
140 /*              ".%" PRIu32 ".%" PRIu32 ") => "*/
141 /*              "HWaddress = %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32*/
142 /*              ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",*/
143 /*              entry->key.key.ipv4.port_id,*/
144 /*              (entry->key.key.ipv4.ip >> 24) & 0xFF,*/
145 /*              (entry->key.key.ipv4.ip >> 16) & 0xFF,*/
146 /*              (entry->key.key.ipv4.ip >> 8) & 0xFF,*/
147 /*              entry->key.key.ipv4.ip & 0xFF,*/
148
149 /*              entry->macaddr.addr_bytes[0],*/
150 /*              entry->macaddr.addr_bytes[1],*/
151 /*              entry->macaddr.addr_bytes[2],*/
152 /*              entry->macaddr.addr_bytes[3],*/
153 /*              entry->macaddr.addr_bytes[4],*/
154 /*              entry->macaddr.addr_bytes[5]);*/
155 /*}*/
156
157 #if 0
158 /*
159  * arp add
160  */
161
162 struct cmd_arp_add_result {
163         cmdline_fixed_string_t p_string;
164         uint32_t p;
165         cmdline_fixed_string_t arpadd_string;
166         uint32_t port_id;
167         cmdline_ipaddr_t ip;
168         struct ether_addr macaddr;
169
170 };
171
172 static void
173 cmd_arp_add_parsed(void *parsed_result,
174                          __rte_unused struct cmdline *cl, __rte_unused void *data)
175 {
176         struct cmd_arp_add_result *params = parsed_result;
177         uint8_t ipv6[16];
178
179 /*      struct pipeline_arp_icmp_arp_key key;*/
180 /*      key.type = PIPELINE_ARP_ICMP_ARP_IPV4;*/
181 /*      key.key.ipv4.port_id = params->port_id;*/
182 /*      key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);*/
183 /*      populate_arp_entry(&req->macaddr, rte_bswap32(req->key.key.ipv4.ip),
184  * req->key.key.ipv4.port_id);
185  */
186         if (params->ip.family == AF_INET) {
187                 populate_arp_entry(&params->macaddr,
188                                          rte_cpu_to_be_32(params->ip.addr.
189                                                                 ipv4.s_addr),
190                                          params->port_id, STATIC_ARP);
191         } else {
192                 memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
193                 populate_nd_entry(&params->macaddr, ipv6, params->port_id, STATIC_ND);
194         }
195 }
196
197 static cmdline_parse_token_string_t cmd_arp_add_p_string =
198 TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, p_string,
199                          "p");
200
201 static cmdline_parse_token_num_t cmd_arp_add_p =
202 TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, p, UINT32);
203
204 static cmdline_parse_token_string_t cmd_arp_add_arp_string =
205 TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, arpadd_string, "arpadd");
206
207 static cmdline_parse_token_num_t cmd_arp_add_port_id =
208 TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, port_id, UINT32);
209
210 static cmdline_parse_token_ipaddr_t cmd_arp_add_ip =
211 TOKEN_IPADDR_INITIALIZER(struct cmd_arp_add_result, ip);
212
213 static cmdline_parse_token_etheraddr_t cmd_arp_add_macaddr =
214 TOKEN_ETHERADDR_INITIALIZER(struct cmd_arp_add_result, macaddr);
215
216 static cmdline_parse_inst_t cmd_arp_add = {
217         .f = cmd_arp_add_parsed,
218         .data = NULL,
219         .help_str = "ARP add",
220         .tokens = {
221                          (void *)&cmd_arp_add_p_string,
222                          (void *)&cmd_arp_add_p,
223                          (void *)&cmd_arp_add_arp_string,
224                          (void *)&cmd_arp_add_port_id,
225                          (void *)&cmd_arp_add_ip,
226                          (void *)&cmd_arp_add_macaddr,
227                          NULL,
228                          },
229 };
230
231 /*
232  * arp del
233  */
234
235 struct cmd_arp_del_result {
236         cmdline_fixed_string_t p_string;
237         uint32_t p;
238         cmdline_fixed_string_t arp_string;
239         uint32_t port_id;
240         cmdline_ipaddr_t ip;
241 };
242
243 static void
244 cmd_arp_del_parsed(void *parsed_result,
245                          __rte_unused struct cmdline *cl, __rte_unused void *data)
246 {
247         struct cmd_arp_del_result *params = parsed_result;
248         uint8_t ipv6[16];
249
250 /*      struct pipeline_arp_icmp_arp_key key;*/
251 /*      key.type = PIPELINE_ARP_ICMP_ARP_IPV4;*/
252 /*      key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);*/
253 /*      key.key.ipv4.port_id = params->port_id;*/
254 /*      remove_arp_entry(rte_bswap32(req->key.key.ipv4.ip),
255  * req->key.key.ipv4.port_id);
256  */
257         if (params->ip.family == AF_INET) {
258                 remove_arp_entry(rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr),
259                                  params->port_id, NULL);
260         } else {
261                 memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
262                 remove_nd_entry_ipv6(ipv6, params->port_id);
263         }
264 }
265
266 static cmdline_parse_token_string_t cmd_arp_del_p_string =
267 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, p_string,
268                          "p");
269
270 static cmdline_parse_token_num_t cmd_arp_del_p =
271 TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, p, UINT32);
272
273 static cmdline_parse_token_string_t cmd_arp_del_arp_string =
274 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arpdel");
275
276 static cmdline_parse_token_num_t cmd_arp_del_port_id =
277 TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, port_id, UINT32);
278
279 static cmdline_parse_token_ipaddr_t cmd_arp_del_ip =
280 TOKEN_IPADDR_INITIALIZER(struct cmd_arp_del_result, ip);
281
282 static cmdline_parse_inst_t cmd_arp_del = {
283         .f = cmd_arp_del_parsed,
284         .data = NULL,
285         .help_str = "ARP delete",
286         .tokens = {
287                          (void *)&cmd_arp_del_p_string,
288                          (void *)&cmd_arp_del_p,
289                          (void *)&cmd_arp_del_arp_string,
290                          (void *)&cmd_arp_del_port_id,
291                          (void *)&cmd_arp_del_ip,
292                          NULL,
293                          },
294 };
295
296 /*
297  * arp req
298  */
299
300 /*Re-uses delete structures*/
301
302 static void
303 cmd_arp_req_parsed(void *parsed_result,
304                          __rte_unused struct cmdline *cl, __rte_unused void *data)
305 {
306         struct cmd_arp_del_result *params = parsed_result;
307         /*struct app_params *app = data;*/
308
309         struct arp_key_ipv4 key;
310 /*      int status;*/
311
312 /*      key.type = ARP_IPV4;*/
313 /*      key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);*/
314 /*      key.key.ipv4.port_id = params->port_id;*/
315         key.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
316         key.port_id = params->port_id;
317         key.filler1 = 0;
318         key.filler2 = 0;
319         key.filler3 = 0;
320
321         struct arp_entry_data *arp_data = retrieve_arp_entry(key, STATIC_ARP);
322
323         if (arp_data) {
324                 if (ARPICMP_DEBUG)
325                         printf("ARP entry exists for ip 0x%x, port %d\n",
326                                                  params->ip.addr.ipv4.s_addr, params->port_id);
327                 return;
328         }
329         /* else request an arp*/
330         if (ARPICMP_DEBUG)
331                 printf("ARP - requesting arp for ip 0x%x, port %d\n",
332                                          params->ip.addr.ipv4.s_addr, params->port_id);
333         request_arp(params->port_id, params->ip.addr.ipv4.s_addr);
334         /*give pipeline number too*/
335 }
336
337 static cmdline_parse_token_string_t cmd_arp_req_string =
338 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arpreq");
339
340 static cmdline_parse_inst_t cmd_arp_req = {
341         .f = cmd_arp_req_parsed,
342         .data = NULL,
343         .help_str = "ARP request",
344         .tokens = {
345                          (void *)&cmd_arp_del_p_string,
346                          (void *)&cmd_arp_del_p,
347                          (void *)&cmd_arp_req_string,
348                          (void *)&cmd_arp_del_port_id,
349                          (void *)&cmd_arp_del_ip,
350                          NULL,
351                          },
352 };
353
354 /*
355  * arpicmp echo req
356  */
357
358 /*Re-uses delete structures*/
359
360 static void
361 cmd_icmp_echo_req_parsed(void *parsed_result,
362                          __rte_unused struct cmdline *cl,
363                          __rte_unused void *data)
364 {
365         struct cmd_arp_del_result *params = parsed_result;
366         struct rte_mbuf *pkt;
367         l2_phy_interface_t *port = (l2_phy_interface_t *) ifm_get_port((uint8_t)params->port_id);
368
369         if (ARPICMP_DEBUG)
370                 printf("Echo Req Handler ip %x, port %d\n",
371                                          params->ip.addr.ipv4.s_addr, params->port_id);
372
373         pkt = request_echo(params->port_id, params->ip.addr.ipv4.s_addr);
374         port->transmit_single_pkt(port, pkt);
375 }
376
377 static cmdline_parse_token_string_t cmd_icmp_echo_req_string =
378 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "icmpecho");
379
380 static cmdline_parse_inst_t cmd_icmp_echo_req = {
381         .f = cmd_icmp_echo_req_parsed,
382         .data = NULL,
383         .help_str = "ICMP echo request",
384         .tokens = {
385                          (void *)&cmd_arp_del_p_string,
386                          (void *)&cmd_arp_del_p,
387                          (void *)&cmd_icmp_echo_req_string,
388                          (void *)&cmd_arp_del_port_id,
389                          (void *)&cmd_arp_del_ip,
390                          NULL,
391                          },
392 };
393
394 /*
395  * arp ls
396  */
397
398 struct cmd_arp_ls_result {
399         cmdline_fixed_string_t p_string;
400         uint32_t p;
401         cmdline_fixed_string_t arp_string;
402         uint32_t ip_type;
403 };
404
405 static void
406 cmd_arp_ls_parsed(void *parsed_result,
407                         __rte_unused struct cmdline *cl, __rte_unused void *data)
408 {
409         struct cmd_arp_ls_result *params = parsed_result;
410
411         if (!params->ip_type) {
412                 printf("\nARP table ...\n");
413                 printf("-------------\n");
414                 print_arp_table();
415         } else {
416                 printf("\nND IPv6 table:\n");
417                 printf("--------------\n");
418                 print_nd_table();
419         }
420 }
421
422 static cmdline_parse_token_string_t cmd_arp_ls_p_string =
423 TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, p_string,
424                          "p");
425
426 static cmdline_parse_token_num_t cmd_arp_ls_p =
427 TOKEN_NUM_INITIALIZER(struct cmd_arp_ls_result, p, UINT32);
428
429 static cmdline_parse_token_string_t cmd_arp_ls_arp_string =
430 TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, arp_string,
431                          "arpls");
432
433 static cmdline_parse_token_num_t cmd_arp_ls_ip_type =
434 TOKEN_NUM_INITIALIZER(struct cmd_arp_ls_result, ip_type, UINT32);
435
436 static cmdline_parse_inst_t cmd_arp_ls = {
437         .f = cmd_arp_ls_parsed,
438         .data = NULL,
439         .help_str = "ARP list",
440         .tokens = {
441                          (void *)&cmd_arp_ls_p_string,
442                          (void *)&cmd_arp_ls_p,
443                          (void *)&cmd_arp_ls_arp_string,
444                          (void *)&cmd_arp_ls_ip_type,
445                          NULL,
446                          },
447 };
448
449 /*
450  * show ports info
451  */
452
453 struct cmd_show_ports_info_result {
454         cmdline_fixed_string_t p_string;
455         uint32_t p;
456         cmdline_fixed_string_t arp_string;
457 };
458
459 static void
460 cmd_show_ports_info_parsed(__rte_unused void *parsed_result,
461                                  __rte_unused struct cmdline *cl,
462                                  __rte_unused void *data)
463 {
464         show_ports_info();
465 }
466
467 static cmdline_parse_token_string_t cmd_show_ports_info_string =
468 TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, arp_string,
469                          "showPortsInfo");
470
471 static cmdline_parse_inst_t cmd_show_ports_info = {
472         .f = cmd_show_ports_info_parsed,
473         .data = NULL,
474         .help_str = "show ports info",
475         .tokens = {
476                          (void *)&cmd_arp_ls_p_string,
477                          (void *)&cmd_arp_ls_p,
478                          (void *)&cmd_show_ports_info_string,
479                          NULL,
480                          },
481 };
482 #endif
483
484 static cmdline_parse_ctx_t pipeline_cmds[] = {
485         (cmdline_parse_inst_t *) &lb_cmd_entry_dbg,
486         NULL,
487 };
488
489 static struct pipeline_fe_ops pipeline_loadb_fe_ops = {
490         .f_init = NULL,
491         .f_free = NULL,
492         .cmds = pipeline_cmds,
493 };
494
495 struct pipeline_type pipeline_loadb = {
496         .name = "LOADB",
497         .be_ops = &pipeline_loadb_be_ops,
498         .fe_ops = &pipeline_loadb_fe_ops,
499 };