ip-neighbor: show age instead of time in cli
[vpp.git] / src / plugins / lb / lb_test.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vat/vat.h>
17 #include <vlibapi/api.h>
18 #include <vlibmemory/api.h>
19 #include <vnet/ip/ip_types_api.h>
20
21 #include <vppinfra/error.h>
22 #include <lb/lb.h>
23
24 #define __plugin_msg_base lb_test_main.msg_id_base
25 #include <vlibapi/vat_helper_macros.h>
26
27 #include <vnet/format_fns.h>
28 #include <lb/lb.api_enum.h>
29 #include <lb/lb.api_types.h>
30
31 //TODO: Move that to vat/plugin_api.c
32 //////////////////////////
33 uword unformat_ip46_address (unformat_input_t * input, va_list * args)
34 {
35   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
36   ip46_type_t type = va_arg (*args, ip46_type_t);
37   if ((type != IP46_TYPE_IP6) &&
38       unformat(input, "%U", unformat_ip4_address, &ip46->ip4)) {
39     ip46_address_mask_ip4(ip46);
40     return 1;
41   } else if ((type != IP46_TYPE_IP4) &&
42       unformat(input, "%U", unformat_ip6_address, &ip46->ip6)) {
43     return 1;
44   }
45   return 0;
46 }
47 uword unformat_ip46_prefix (unformat_input_t * input, va_list * args)
48 {
49   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
50   u8 *len = va_arg (*args, u8 *);
51   ip46_type_t type = va_arg (*args, ip46_type_t);
52
53   u32 l;
54   if ((type != IP46_TYPE_IP6) && unformat(input, "%U/%u", unformat_ip4_address, &ip46->ip4, &l)) {
55     if (l > 32)
56       return 0;
57     *len = l + 96;
58     ip46->pad[0] = ip46->pad[1] = ip46->pad[2] = 0;
59   } else if ((type != IP46_TYPE_IP4) && unformat(input, "%U/%u", unformat_ip6_address, &ip46->ip6, &l)) {
60     if (l > 128)
61       return 0;
62     *len = l;
63   } else {
64     return 0;
65   }
66   return 1;
67 }
68 /////////////////////////
69
70 typedef struct {
71     /* API message ID base */
72     u16 msg_id_base;
73     vat_main_t *vat_main;
74 } lb_test_main_t;
75
76 lb_test_main_t lb_test_main;
77
78 static int api_lb_conf (vat_main_t * vam)
79 {
80   unformat_input_t *line_input = vam->input;
81   vl_api_lb_conf_t *mp;
82   u32 ip4_src_address = 0xffffffff;
83   ip46_address_t ip6_src_address;
84   u32 sticky_buckets_per_core = LB_DEFAULT_PER_CPU_STICKY_BUCKETS;
85   u32 flow_timeout = LB_DEFAULT_FLOW_TIMEOUT;
86   int ret;
87
88   ip6_src_address.as_u64[0] = 0xffffffffffffffffL;
89   ip6_src_address.as_u64[1] = 0xffffffffffffffffL;
90
91   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
92   {
93     if (unformat(line_input, "ip4-src-address %U", unformat_ip4_address, &ip4_src_address))
94       ;
95     else if (unformat(line_input, "ip6-src-address %U", unformat_ip6_address, &ip6_src_address))
96       ;
97     else if (unformat(line_input, "buckets %d", &sticky_buckets_per_core))
98       ;
99     else if (unformat(line_input, "timeout %d", &flow_timeout))
100       ;
101     else {
102         errmsg ("invalid arguments\n");
103         return -99;
104     }
105   }
106
107   M(LB_CONF, mp);
108   clib_memcpy (&(mp->ip4_src_address), &ip4_src_address, sizeof (ip4_src_address));
109   clib_memcpy (&(mp->ip6_src_address), &ip6_src_address, sizeof (ip6_src_address));
110   mp->sticky_buckets_per_core = htonl (sticky_buckets_per_core);
111   mp->flow_timeout = htonl (flow_timeout);
112
113   S(mp);
114   W (ret);
115   return ret;
116 }
117
118 static int api_lb_add_del_vip (vat_main_t * vam)
119 {
120   unformat_input_t *line_input = vam->input;
121   vl_api_lb_add_del_vip_t *mp;
122   int ret;
123   ip46_address_t ip_prefix;
124   u8 prefix_length = 0;
125   u8 protocol = 0;
126   u32 port = 0;
127   u32 encap = 0;
128   u32 dscp = ~0;
129   u32 srv_type = LB_SRV_TYPE_CLUSTERIP;
130   u32 target_port = 0;
131   u32 new_length = 1024;
132   int is_del = 0;
133
134   if (!unformat(line_input, "%U", unformat_ip46_prefix, &ip_prefix,
135                 &prefix_length, IP46_TYPE_ANY, &prefix_length)) {
136     errmsg ("lb_add_del_vip: invalid vip prefix\n");
137     return -99;
138   }
139
140   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
141   {
142     if (unformat(line_input, "new_len %d", &new_length))
143       ;
144     else if (unformat(line_input, "del"))
145       is_del = 1;
146     else if (unformat(line_input, "protocol tcp"))
147       {
148         protocol = IP_PROTOCOL_TCP;
149       }
150     else if (unformat(line_input, "protocol udp"))
151       {
152         protocol = IP_PROTOCOL_UDP;
153       }
154     else if (unformat(line_input, "port %d", &port))
155       ;
156     else if (unformat(line_input, "encap gre4"))
157       encap = LB_ENCAP_TYPE_GRE4;
158     else if (unformat(line_input, "encap gre6"))
159       encap = LB_ENCAP_TYPE_GRE6;
160     else if (unformat(line_input, "encap l3dsr"))
161       encap = LB_ENCAP_TYPE_L3DSR;
162     else if (unformat(line_input, "encap nat4"))
163       encap = LB_ENCAP_TYPE_NAT4;
164     else if (unformat(line_input, "encap nat6"))
165       encap = LB_ENCAP_TYPE_NAT6;
166     else if (unformat(line_input, "dscp %d", &dscp))
167       ;
168     else if (unformat(line_input, "type clusterip"))
169       srv_type = LB_SRV_TYPE_CLUSTERIP;
170     else if (unformat(line_input, "type nodeport"))
171       srv_type = LB_SRV_TYPE_NODEPORT;
172     else if (unformat(line_input, "target_port %d", &target_port))
173       ;
174     else {
175         errmsg ("invalid arguments\n");
176         return -99;
177     }
178   }
179
180   if ((encap != LB_ENCAP_TYPE_L3DSR) && (dscp != ~0))
181     {
182       errmsg("lb_vip_add error: should not configure dscp for none L3DSR.");
183       return -99;
184     }
185
186   if ((encap == LB_ENCAP_TYPE_L3DSR) && (dscp >= 64))
187     {
188       errmsg("lb_vip_add error: dscp for L3DSR should be less than 64.");
189       return -99;
190     }
191
192   M(LB_ADD_DEL_VIP, mp);
193   ip_address_encode(&ip_prefix, IP46_TYPE_ANY, &mp->pfx.address);
194   mp->pfx.len = prefix_length;
195   mp->protocol = (u8)protocol;
196   mp->port = htons((u16)port);
197   mp->encap = (u8)encap;
198   mp->dscp = (u8)dscp;
199   mp->type = (u8)srv_type;
200   mp->target_port = htons((u16)target_port);
201   mp->node_port = htons((u16)target_port);
202   mp->new_flows_table_length = htonl(new_length);
203   mp->is_del = is_del;
204
205   S(mp);
206   W (ret);
207   return ret;
208 }
209
210 static int
211 api_lb_add_del_vip_v2 (vat_main_t *vam)
212 {
213   unformat_input_t *line_input = vam->input;
214   vl_api_lb_add_del_vip_v2_t *mp;
215   int ret;
216   ip46_address_t ip_prefix;
217   u8 prefix_length = 0;
218   u8 protocol = 0;
219   u32 port = 0;
220   u32 encap = 0;
221   u32 dscp = ~0;
222   u32 srv_type = LB_SRV_TYPE_CLUSTERIP;
223   u32 target_port = 0;
224   u32 new_length = 1024;
225   u8 src_ip_sticky = 0;
226   int is_del = 0;
227
228   if (!unformat (line_input, "%U", unformat_ip46_prefix, &ip_prefix,
229                  &prefix_length, IP46_TYPE_ANY, &prefix_length))
230     {
231       errmsg ("lb_add_del_vip: invalid vip prefix\n");
232       return -99;
233     }
234
235   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
236     {
237       if (unformat (line_input, "new_len %d", &new_length))
238         ;
239       else if (unformat (line_input, "del"))
240         is_del = 1;
241       else if (unformat (line_input, "src_ip_sticky"))
242         src_ip_sticky = 1;
243       else if (unformat (line_input, "protocol tcp"))
244         {
245           protocol = IP_PROTOCOL_TCP;
246         }
247       else if (unformat (line_input, "protocol udp"))
248         {
249           protocol = IP_PROTOCOL_UDP;
250         }
251       else if (unformat (line_input, "port %d", &port))
252         ;
253       else if (unformat (line_input, "encap gre4"))
254         encap = LB_ENCAP_TYPE_GRE4;
255       else if (unformat (line_input, "encap gre6"))
256         encap = LB_ENCAP_TYPE_GRE6;
257       else if (unformat (line_input, "encap l3dsr"))
258         encap = LB_ENCAP_TYPE_L3DSR;
259       else if (unformat (line_input, "encap nat4"))
260         encap = LB_ENCAP_TYPE_NAT4;
261       else if (unformat (line_input, "encap nat6"))
262         encap = LB_ENCAP_TYPE_NAT6;
263       else if (unformat (line_input, "dscp %d", &dscp))
264         ;
265       else if (unformat (line_input, "type clusterip"))
266         srv_type = LB_SRV_TYPE_CLUSTERIP;
267       else if (unformat (line_input, "type nodeport"))
268         srv_type = LB_SRV_TYPE_NODEPORT;
269       else if (unformat (line_input, "target_port %d", &target_port))
270         ;
271       else
272         {
273           errmsg ("invalid arguments\n");
274           return -99;
275         }
276     }
277
278   if ((encap != LB_ENCAP_TYPE_L3DSR) && (dscp != ~0))
279     {
280       errmsg ("lb_vip_add error: should not configure dscp for none L3DSR.");
281       return -99;
282     }
283
284   if ((encap == LB_ENCAP_TYPE_L3DSR) && (dscp >= 64))
285     {
286       errmsg ("lb_vip_add error: dscp for L3DSR should be less than 64.");
287       return -99;
288     }
289
290   M (LB_ADD_DEL_VIP, mp);
291   ip_address_encode (&ip_prefix, IP46_TYPE_ANY, &mp->pfx.address);
292   mp->pfx.len = prefix_length;
293   mp->protocol = (u8) protocol;
294   mp->port = htons ((u16) port);
295   mp->encap = (u8) encap;
296   mp->dscp = (u8) dscp;
297   mp->type = (u8) srv_type;
298   mp->target_port = htons ((u16) target_port);
299   mp->node_port = htons ((u16) target_port);
300   mp->new_flows_table_length = htonl (new_length);
301   mp->is_del = is_del;
302   mp->src_ip_sticky = src_ip_sticky;
303
304   S (mp);
305   W (ret);
306   return ret;
307 }
308
309 static int api_lb_add_del_as (vat_main_t * vam)
310 {
311
312   unformat_input_t *line_input = vam->input;
313   vl_api_lb_add_del_as_t *mp;
314   int ret;
315   ip46_address_t vip_prefix, as_addr;
316   u8 vip_plen;
317   ip46_address_t *as_array = 0;
318   u32 port = 0;
319   u8 protocol = 0;
320   u8 is_del = 0;
321   u8 is_flush = 0;
322
323   if (!unformat(line_input, "%U", unformat_ip46_prefix,
324                 &vip_prefix, &vip_plen, IP46_TYPE_ANY))
325   {
326       errmsg ("lb_add_del_as: invalid vip prefix\n");
327       return -99;
328   }
329
330   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
331   {
332     if (unformat(line_input, "%U", unformat_ip46_address,
333                  &as_addr, IP46_TYPE_ANY))
334       {
335         vec_add1(as_array, as_addr);
336       }
337     else if (unformat(line_input, "del"))
338       {
339         is_del = 1;
340       }
341     else if (unformat(line_input, "flush"))
342       {
343         is_flush = 1;
344       }
345     else if (unformat(line_input, "protocol tcp"))
346       {
347           protocol = IP_PROTOCOL_TCP;
348       }
349     else if (unformat(line_input, "protocol udp"))
350       {
351           protocol = IP_PROTOCOL_UDP;
352       }
353     else if (unformat(line_input, "port %d", &port))
354       ;
355     else {
356         errmsg ("invalid arguments\n");
357         return -99;
358     }
359   }
360
361   if (!vec_len(as_array)) {
362     errmsg ("No AS address provided \n");
363     return -99;
364   }
365
366   M(LB_ADD_DEL_AS, mp);
367   ip_address_encode(&vip_prefix, IP46_TYPE_ANY, &mp->pfx.address);
368   mp->pfx.len = vip_plen;
369   mp->protocol = (u8)protocol;
370   mp->port = htons((u16)port);
371   ip_address_encode(&as_addr, IP46_TYPE_ANY, &mp->as_address);
372   mp->is_del = is_del;
373   mp->is_flush = is_flush;
374
375   S(mp);
376   W (ret);
377   return ret;
378 }
379
380 static int api_lb_flush_vip (vat_main_t * vam)
381 {
382
383   unformat_input_t *line_input = vam->input;
384   vl_api_lb_flush_vip_t *mp;
385   int ret;
386   ip46_address_t vip_prefix;
387   u8 vip_plen;
388
389   if (!unformat(line_input, "%U", unformat_ip46_prefix,
390                 &vip_prefix, &vip_plen, IP46_TYPE_ANY))
391   {
392       errmsg ("lb_add_del_as: invalid vip prefix\n");
393       return -99;
394   }
395
396   M(LB_FLUSH_VIP, mp);
397   clib_memcpy (mp->pfx.address.un.ip6, &vip_prefix.ip6, sizeof (vip_prefix.ip6));
398   mp->pfx.len = vip_plen;
399   S(mp);
400   W (ret);
401   return ret;
402 }
403 static int api_lb_add_del_intf_nat4 (vat_main_t * vam)
404 {
405   // Not yet implemented
406   return -99;
407 }
408
409 static int api_lb_add_del_intf_nat6 (vat_main_t * vam)
410 {
411   // Not yet implemented
412   return -99;
413 }
414
415 static void vl_api_lb_vip_details_t_handler
416   (vl_api_lb_vip_details_t * mp)
417 {
418   vat_main_t *vam = &vat_main;
419
420   print (vam->ofp, "%24U%14d%14d%18d",
421        format_ip46_address, &mp->vip.pfx.address, IP46_TYPE_ANY,
422        mp->vip.pfx.len,
423        mp->vip.protocol,
424        ntohs (mp->vip.port));
425 /*
426   lb_main_t *lbm = &lb_main;
427   u32 i = 0;
428
429   u32 vip_count = pool_len(lbm->vips);
430
431   print (vam->ofp, "%11d", vip_count);
432
433   for (i=0; i<vip_count; i--)
434     {
435       print (vam->ofp, "%24U%14d%14d%18d",
436            format_ip46_address, &mp->vip.pfx.address, IP46_TYPE_ANY,
437            mp->vip.pfx.len,
438            mp->vip.protocol,
439            ntohs (mp->vip.port));
440     }
441 */
442 }
443
444 static int api_lb_vip_dump (vat_main_t * vam)
445 {
446   vl_api_lb_vip_dump_t *mp;
447   int ret;
448
449   M(LB_VIP_DUMP, mp);
450
451   S(mp);
452   W (ret);
453   return ret;
454 }
455
456 static void vl_api_lb_as_details_t_handler
457   (vl_api_lb_as_details_t * mp)
458 {
459   vat_main_t *vam = &vat_main;
460
461   print (vam->ofp, "%24U%14d%14d%18d%d%d",
462        format_ip46_address, &mp->vip.pfx.address, IP46_TYPE_ANY,
463        mp->vip.pfx.len,
464        mp->vip.protocol,
465        ntohs (mp->vip.port),
466        mp->flags,
467        mp->in_use_since);
468
469   //u32 i = 0;
470
471 /*
472   lb_main_t *lbm = &lb_main;
473   print (vam->ofp, "%11d", pool_len(lbm->ass));
474   for (i=0; i<pool_len(lbm->ass); i--)
475     {
476       print (vam->ofp, "%24U%14d%14d%18d",
477            format_ip46_address, &mp->pfx.address, IP46_TYPE_ANY,
478            mp->pfx.len,
479            mp->pfx.protocol,
480            ntohs (mp->pfx.port),
481            ntohl(mp->app_srv),
482            mp->flags,
483            mp->in_use_;
484     }
485     */
486 }
487
488 static int api_lb_as_dump (vat_main_t * vam)
489 {
490
491   unformat_input_t *line_input = vam->input;
492   vl_api_lb_as_dump_t *mp;
493   int ret;
494   ip46_address_t vip_prefix, as_addr;
495   u8 vip_plen;
496   ip46_address_t *as_array = 0;
497   u32 port = 0;
498   u8 protocol = 0;
499
500   if (!unformat(line_input, "%U", unformat_ip46_prefix,
501                 &vip_prefix, &vip_plen, IP46_TYPE_ANY))
502   {
503       errmsg ("lb_add_del_as: invalid vip prefix\n");
504       return -99;
505   }
506
507   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
508   {
509     if (unformat(line_input, "%U", unformat_ip46_address,
510                  &as_addr, IP46_TYPE_ANY))
511       {
512         vec_add1(as_array, as_addr);
513       }
514     else if (unformat(line_input, "protocol tcp"))
515       {
516           protocol = IP_PROTOCOL_TCP;
517       }
518     else if (unformat(line_input, "protocol udp"))
519       {
520           protocol = IP_PROTOCOL_UDP;
521       }
522     else if (unformat(line_input, "port %d", &port))
523       ;
524     else {
525         errmsg ("invalid arguments\n");
526         return -99;
527     }
528   }
529
530   if (!vec_len(as_array)) {
531     errmsg ("No AS address provided \n");
532     return -99;
533   }
534
535   M(LB_AS_DUMP, mp);
536   clib_memcpy (mp->pfx.address.un.ip6, &vip_prefix.ip6, sizeof (vip_prefix.ip6));
537   mp->pfx.len = vip_plen;
538   mp->protocol = (u8)protocol;
539   mp->port = htons((u16)port);
540
541   S(mp);
542   W (ret);
543   return ret;
544 }
545
546 #include <lb/lb.api_test.c>