lb: remove api boilerplate
[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
20 #include <vppinfra/error.h>
21 #include <lb/lb.h>
22
23 #define __plugin_msg_base lb_test_main.msg_id_base
24 #include <vlibapi/vat_helper_macros.h>
25
26 #include <vnet/format_fns.h>
27 #include <lb/lb.api_enum.h>
28 #include <lb/lb.api_types.h>
29
30 //TODO: Move that to vat/plugin_api.c
31 //////////////////////////
32 uword unformat_ip46_address (unformat_input_t * input, va_list * args)
33 {
34   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
35   ip46_type_t type = va_arg (*args, ip46_type_t);
36   if ((type != IP46_TYPE_IP6) &&
37       unformat(input, "%U", unformat_ip4_address, &ip46->ip4)) {
38     ip46_address_mask_ip4(ip46);
39     return 1;
40   } else if ((type != IP46_TYPE_IP4) &&
41       unformat(input, "%U", unformat_ip6_address, &ip46->ip6)) {
42     return 1;
43   }
44   return 0;
45 }
46 uword unformat_ip46_prefix (unformat_input_t * input, va_list * args)
47 {
48   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
49   u8 *len = va_arg (*args, u8 *);
50   ip46_type_t type = va_arg (*args, ip46_type_t);
51
52   u32 l;
53   if ((type != IP46_TYPE_IP6) && unformat(input, "%U/%u", unformat_ip4_address, &ip46->ip4, &l)) {
54     if (l > 32)
55       return 0;
56     *len = l + 96;
57     ip46->pad[0] = ip46->pad[1] = ip46->pad[2] = 0;
58   } else if ((type != IP46_TYPE_IP4) && unformat(input, "%U/%u", unformat_ip6_address, &ip46->ip6, &l)) {
59     if (l > 128)
60       return 0;
61     *len = l;
62   } else {
63     return 0;
64   }
65   return 1;
66 }
67 /////////////////////////
68
69 typedef struct {
70     /* API message ID base */
71     u16 msg_id_base;
72     vat_main_t *vat_main;
73 } lb_test_main_t;
74
75 lb_test_main_t lb_test_main;
76
77 static int api_lb_conf (vat_main_t * vam)
78 {
79   unformat_input_t *line_input = vam->input;
80   vl_api_lb_conf_t *mp;
81   u32 ip4_src_address = 0xffffffff;
82   ip46_address_t ip6_src_address;
83   u32 sticky_buckets_per_core = LB_DEFAULT_PER_CPU_STICKY_BUCKETS;
84   u32 flow_timeout = LB_DEFAULT_FLOW_TIMEOUT;
85   int ret;
86
87   ip6_src_address.as_u64[0] = 0xffffffffffffffffL;
88   ip6_src_address.as_u64[1] = 0xffffffffffffffffL;
89
90   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
91   {
92     if (unformat(line_input, "ip4-src-address %U", unformat_ip4_address, &ip4_src_address))
93       ;
94     else if (unformat(line_input, "ip6-src-address %U", unformat_ip6_address, &ip6_src_address))
95       ;
96     else if (unformat(line_input, "buckets %d", &sticky_buckets_per_core))
97       ;
98     else if (unformat(line_input, "timeout %d", &flow_timeout))
99       ;
100     else {
101         errmsg ("invalid arguments\n");
102         return -99;
103     }
104   }
105
106   M(LB_CONF, mp);
107   clib_memcpy (&(mp->ip4_src_address), &ip4_src_address, sizeof (ip4_src_address));
108   clib_memcpy (&(mp->ip6_src_address), &ip6_src_address, sizeof (ip6_src_address));
109   mp->sticky_buckets_per_core = htonl (sticky_buckets_per_core);
110   mp->flow_timeout = htonl (flow_timeout);
111
112   S(mp);
113   W (ret);
114   return ret;
115 }
116
117 static int api_lb_add_del_vip (vat_main_t * vam)
118 {
119   unformat_input_t *line_input = vam->input;
120   vl_api_lb_add_del_vip_t *mp;
121   int ret;
122   ip46_address_t ip_prefix;
123   u8 prefix_length = 0;
124   u8 protocol = 0;
125   u32 port = 0;
126   u32 encap = 0;
127   u32 dscp = ~0;
128   u32 srv_type = LB_SRV_TYPE_CLUSTERIP;
129   u32 target_port = 0;
130   u32 new_length = 1024;
131   int is_del = 0;
132
133   if (!unformat(line_input, "%U", unformat_ip46_prefix, &ip_prefix,
134                 &prefix_length, IP46_TYPE_ANY, &prefix_length)) {
135     errmsg ("lb_add_del_vip: invalid vip prefix\n");
136     return -99;
137   }
138
139   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
140   {
141     if (unformat(line_input, "new_len %d", &new_length))
142       ;
143     else if (unformat(line_input, "del"))
144       is_del = 1;
145     else if (unformat(line_input, "protocol tcp"))
146       {
147         protocol = IP_PROTOCOL_TCP;
148       }
149     else if (unformat(line_input, "protocol udp"))
150       {
151         protocol = IP_PROTOCOL_UDP;
152       }
153     else if (unformat(line_input, "port %d", &port))
154       ;
155     else if (unformat(line_input, "encap gre4"))
156       encap = LB_ENCAP_TYPE_GRE4;
157     else if (unformat(line_input, "encap gre6"))
158       encap = LB_ENCAP_TYPE_GRE6;
159     else if (unformat(line_input, "encap l3dsr"))
160       encap = LB_ENCAP_TYPE_L3DSR;
161     else if (unformat(line_input, "encap nat4"))
162       encap = LB_ENCAP_TYPE_NAT4;
163     else if (unformat(line_input, "encap nat6"))
164       encap = LB_ENCAP_TYPE_NAT6;
165     else if (unformat(line_input, "dscp %d", &dscp))
166       ;
167     else if (unformat(line_input, "type clusterip"))
168       srv_type = LB_SRV_TYPE_CLUSTERIP;
169     else if (unformat(line_input, "type nodeport"))
170       srv_type = LB_SRV_TYPE_NODEPORT;
171     else if (unformat(line_input, "target_port %d", &target_port))
172       ;
173     else {
174         errmsg ("invalid arguments\n");
175         return -99;
176     }
177   }
178
179   if ((encap != LB_ENCAP_TYPE_L3DSR) && (dscp != ~0))
180     {
181       errmsg("lb_vip_add error: should not configure dscp for none L3DSR.");
182       return -99;
183     }
184
185   if ((encap == LB_ENCAP_TYPE_L3DSR) && (dscp >= 64))
186     {
187       errmsg("lb_vip_add error: dscp for L3DSR should be less than 64.");
188       return -99;
189     }
190
191   M(LB_ADD_DEL_VIP, mp);
192   clib_memcpy (mp->pfx.address.un.ip6, &ip_prefix.ip6, sizeof (ip_prefix.ip6));
193   mp->pfx.len = prefix_length;
194   mp->protocol = (u8)protocol;
195   mp->port = htons((u16)port);
196   mp->encap = (u8)encap;
197   mp->dscp = (u8)dscp;
198   mp->type = (u8)srv_type;
199   mp->target_port = htons((u16)target_port);
200   mp->node_port = htons((u16)target_port);
201   mp->new_flows_table_length = htonl(new_length);
202   mp->is_del = is_del;
203
204   S(mp);
205   W (ret);
206   return ret;
207 }
208
209 static int api_lb_add_del_as (vat_main_t * vam)
210 {
211
212   unformat_input_t *line_input = vam->input;
213   vl_api_lb_add_del_as_t *mp;
214   int ret;
215   ip46_address_t vip_prefix, as_addr;
216   u8 vip_plen;
217   ip46_address_t *as_array = 0;
218   u32 port = 0;
219   u8 protocol = 0;
220   u8 is_del = 0;
221   u8 is_flush = 0;
222
223   if (!unformat(line_input, "%U", unformat_ip46_prefix,
224                 &vip_prefix, &vip_plen, IP46_TYPE_ANY))
225   {
226       errmsg ("lb_add_del_as: invalid vip prefix\n");
227       return -99;
228   }
229
230   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
231   {
232     if (unformat(line_input, "%U", unformat_ip46_address,
233                  &as_addr, IP46_TYPE_ANY))
234       {
235         vec_add1(as_array, as_addr);
236       }
237     else if (unformat(line_input, "del"))
238       {
239         is_del = 1;
240       }
241     else if (unformat(line_input, "flush"))
242       {
243         is_flush = 1;
244       }
245     else if (unformat(line_input, "protocol tcp"))
246       {
247           protocol = IP_PROTOCOL_TCP;
248       }
249     else if (unformat(line_input, "protocol udp"))
250       {
251           protocol = IP_PROTOCOL_UDP;
252       }
253     else if (unformat(line_input, "port %d", &port))
254       ;
255     else {
256         errmsg ("invalid arguments\n");
257         return -99;
258     }
259   }
260
261   if (!vec_len(as_array)) {
262     errmsg ("No AS address provided \n");
263     return -99;
264   }
265
266   M(LB_ADD_DEL_AS, mp);
267   clib_memcpy (mp->pfx.address.un.ip6, &vip_prefix.ip6, sizeof (vip_prefix.ip6));
268   mp->pfx.len = vip_plen;
269   mp->protocol = (u8)protocol;
270   mp->port = htons((u16)port);
271   clib_memcpy (&mp->as_address, &as_addr, sizeof (as_addr));
272   mp->is_del = is_del;
273   mp->is_flush = is_flush;
274
275   S(mp);
276   W (ret);
277   return ret;
278 }
279
280 static int api_lb_flush_vip (vat_main_t * vam)
281 {
282
283   unformat_input_t *line_input = vam->input;
284   vl_api_lb_flush_vip_t *mp;
285   int ret;
286   ip46_address_t vip_prefix;
287   u8 vip_plen;
288
289   if (!unformat(line_input, "%U", unformat_ip46_prefix,
290                 &vip_prefix, &vip_plen, IP46_TYPE_ANY))
291   {
292       errmsg ("lb_add_del_as: invalid vip prefix\n");
293       return -99;
294   }
295
296   M(LB_FLUSH_VIP, mp);
297   clib_memcpy (mp->pfx.address.un.ip6, &vip_prefix.ip6, sizeof (vip_prefix.ip6));
298   mp->pfx.len = vip_plen;
299   S(mp);
300   W (ret);
301   return ret;
302 }
303 static int api_lb_add_del_intf_nat4 (vat_main_t * vam)
304 {
305   // Not yet implemented
306   return -99;
307 }
308
309 static int api_lb_add_del_intf_nat6 (vat_main_t * vam)
310 {
311   // Not yet implemented
312   return -99;
313 }
314
315 static void vl_api_lb_vip_details_t_handler
316   (vl_api_lb_vip_details_t * mp)
317 {
318   vat_main_t *vam = &vat_main;
319
320   print (vam->ofp, "%24U%14d%14d%18d",
321        format_ip46_address, &mp->vip.pfx.address, IP46_TYPE_ANY,
322        mp->vip.pfx.len,
323        mp->vip.protocol,
324        ntohs (mp->vip.port));
325 /*
326   lb_main_t *lbm = &lb_main;
327   u32 i = 0;
328
329   u32 vip_count = pool_len(lbm->vips);
330
331   print (vam->ofp, "%11d", vip_count);
332
333   for (i=0; i<vip_count; i--)
334     {
335       print (vam->ofp, "%24U%14d%14d%18d",
336            format_ip46_address, &mp->vip.pfx.address, IP46_TYPE_ANY,
337            mp->vip.pfx.len,
338            mp->vip.protocol,
339            ntohs (mp->vip.port));
340     }
341 */
342 }
343
344 static int api_lb_vip_dump (vat_main_t * vam)
345 {
346   vl_api_lb_vip_dump_t *mp;
347   int ret;
348
349   M(LB_VIP_DUMP, mp);
350
351   S(mp);
352   W (ret);
353   return ret;
354 }
355
356 static void vl_api_lb_as_details_t_handler
357   (vl_api_lb_as_details_t * mp)
358 {
359   vat_main_t *vam = &vat_main;
360
361   print (vam->ofp, "%24U%14d%14d%18d%d%d",
362        format_ip46_address, &mp->vip.pfx.address, IP46_TYPE_ANY,
363        mp->vip.pfx.len,
364        mp->vip.protocol,
365        ntohs (mp->vip.port),
366        mp->flags,
367        mp->in_use_since);
368
369   //u32 i = 0;
370
371 /*
372   lb_main_t *lbm = &lb_main;
373   print (vam->ofp, "%11d", pool_len(lbm->ass));
374   for (i=0; i<pool_len(lbm->ass); i--)
375     {
376       print (vam->ofp, "%24U%14d%14d%18d",
377            format_ip46_address, &mp->pfx.address, IP46_TYPE_ANY,
378            mp->pfx.len,
379            mp->pfx.protocol,
380            ntohs (mp->pfx.port),
381            ntohl(mp->app_srv),
382            mp->flags,
383            mp->in_use_;
384     }
385     */
386 }
387
388 static int api_lb_as_dump (vat_main_t * vam)
389 {
390
391   unformat_input_t *line_input = vam->input;
392   vl_api_lb_as_dump_t *mp;
393   int ret;
394   ip46_address_t vip_prefix, as_addr;
395   u8 vip_plen;
396   ip46_address_t *as_array = 0;
397   u32 port = 0;
398   u8 protocol = 0;
399
400   if (!unformat(line_input, "%U", unformat_ip46_prefix,
401                 &vip_prefix, &vip_plen, IP46_TYPE_ANY))
402   {
403       errmsg ("lb_add_del_as: invalid vip prefix\n");
404       return -99;
405   }
406
407   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
408   {
409     if (unformat(line_input, "%U", unformat_ip46_address,
410                  &as_addr, IP46_TYPE_ANY))
411       {
412         vec_add1(as_array, as_addr);
413       }
414     else if (unformat(line_input, "protocol tcp"))
415       {
416           protocol = IP_PROTOCOL_TCP;
417       }
418     else if (unformat(line_input, "protocol udp"))
419       {
420           protocol = IP_PROTOCOL_UDP;
421       }
422     else if (unformat(line_input, "port %d", &port))
423       ;
424     else {
425         errmsg ("invalid arguments\n");
426         return -99;
427     }
428   }
429
430   if (!vec_len(as_array)) {
431     errmsg ("No AS address provided \n");
432     return -99;
433   }
434
435   M(LB_AS_DUMP, mp);
436   clib_memcpy (mp->pfx.address.un.ip6, &vip_prefix.ip6, sizeof (vip_prefix.ip6));
437   mp->pfx.len = vip_plen;
438   mp->protocol = (u8)protocol;
439   mp->port = htons((u16)port);
440
441   S(mp);
442   W (ret);
443   return ret;
444 }
445
446 #include <lb/lb.api_test.c>