udp: fix csum computation when offload disabled
[vpp.git] / src / plugins / mactime / mactime_test.c
1 /*
2  * mactime.c - skeleton vpp-api-test plug-in
3  *
4  * Copyright (c) <current-year> <your-organization>
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include <vat/vat.h>
18 #include <vlibapi/api.h>
19 #include <vlibmemory/api.h>
20 #include <vppinfra/error.h>
21 #include <vppinfra/time_range.h>
22 #include <vnet/ethernet/ethernet.h>
23 #include <mactime/mactime_device.h>
24 #include <vpp-api/client/stat_client.h>
25
26 /* Declare message IDs */
27 #include <vnet/format_fns.h>
28 #include <mactime/mactime.api_enum.h>
29 #include <mactime/mactime.api_types.h>
30
31 typedef struct
32 {
33   /* device table */
34   mactime_device_t *devices;
35   uword *device_by_device_name;
36   u32 vpp_table_epoch;
37
38   /* time range setup */
39   f64 sunday_midnight;
40   clib_timebase_t timebase;
41   f64 timezone_offset;
42
43   /* API message ID base */
44   u16 msg_id_base;
45   vat_main_t *vat_main;
46 } mactime_test_main_t;
47
48 mactime_test_main_t mactime_test_main;
49
50 #define __plugin_msg_base mactime_test_main.msg_id_base
51 #include <vlibapi/vat_helper_macros.h>
52
53 static int
54 api_mactime_enable_disable (vat_main_t * vam)
55 {
56   unformat_input_t *i = vam->input;
57   int enable_disable = 1;
58   u32 sw_if_index = ~0;
59   vl_api_mactime_enable_disable_t *mp;
60   int ret;
61
62   /* Parse args required to build the message */
63   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
64     {
65       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
66         ;
67       else if (unformat (i, "sw_if_index %d", &sw_if_index))
68         ;
69       else if (unformat (i, "disable"))
70         enable_disable = 0;
71       else
72         break;
73     }
74
75   if (sw_if_index == ~0)
76     {
77       errmsg ("missing interface name / explicit sw_if_index number \n");
78       return -99;
79     }
80
81   /* Construct the API message */
82   M (MACTIME_ENABLE_DISABLE, mp);
83   mp->sw_if_index = ntohl (sw_if_index);
84   mp->enable_disable = enable_disable;
85
86   /* send it... */
87   S (mp);
88
89   /* Wait for a reply... */
90   W (ret);
91   return ret;
92 }
93
94 #if VPP_API_TEST_BUILTIN
95 extern u8 *format_bytes_with_width (u8 * s, va_list * va);
96 #else
97 u8 *
98 format_bytes_with_width (u8 * s, va_list * va)
99 {
100   uword nbytes = va_arg (*va, u64);
101   int width = va_arg (*va, int);
102   f64 nbytes_f64;
103   u8 *fmt;
104   char *suffix = "";
105
106   if (width > 0)
107     fmt = format (0, "%%%d.3f%%s%c", width, 0);
108   else
109     fmt = format (0, "%%.3f%%s%c", 0);
110
111   if (nbytes > (1024ULL * 1024ULL * 1024ULL))
112     {
113       nbytes_f64 = ((f64) nbytes) / (1024.0 * 1024.0 * 1024.0);
114       suffix = "G";
115     }
116   else if (nbytes > (1024ULL * 1024ULL))
117     {
118       nbytes_f64 = ((f64) nbytes) / (1024.0 * 1024.0);
119       suffix = "M";
120     }
121   else if (nbytes > 1024ULL)
122     {
123       nbytes_f64 = ((f64) nbytes) / (1024.0);
124       suffix = "K";
125     }
126   else
127     {
128       nbytes_f64 = (f64) nbytes;
129       suffix = "B";
130     }
131
132   s = format (s, (char *) fmt, nbytes_f64, suffix);
133   vec_free (fmt);
134   return s;
135 }
136 #endif
137
138 static u8 *
139 format_device (u8 * s, va_list * args)
140 {
141   mactime_device_t *dp = va_arg (*args, mactime_device_t *);
142   mactime_test_main_t *mm = &mactime_test_main;
143   int verbose = va_arg (*args, int);
144   int current_status = 99;
145   char *status_string;
146   u8 *macstring = 0;
147   f64 now;
148   int j;
149
150   if (dp == 0)
151     {
152       s = format (s, "%-15s %5s %18s %14s %10s %11s %13s",
153                   "Device Name", "Index", "Addresses", "Status",
154                   "AllowPkt", "AllowByte", "DropPkt");
155       vec_add1 (s, '\n');
156       return s;
157     }
158
159   now = clib_timebase_now (&mm->timebase);
160
161   /* Check dynamic ranges */
162   for (j = 0; j < vec_len (dp->ranges); j++)
163     {
164       clib_timebase_range_t *r = dp->ranges + j;
165       f64 start0, end0;
166
167       start0 = r->start + mm->sunday_midnight;
168       end0 = r->end + mm->sunday_midnight;
169       if (verbose)
170         s = format (s, "  Range %d: %U - %U\n", j,
171                     format_clib_timebase_time, start0,
172                     format_clib_timebase_time, end0);
173
174       if (now >= start0 && now <= end0)
175         {
176           if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW)
177             current_status = 3;
178           else if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA)
179             current_status = 5;
180           else
181             current_status = 2;
182           if (verbose)
183             {
184               s = format (s, "  Time in range %d:", j);
185               s = format (s, "     %U - %U\n",
186                           format_clib_timebase_time, start0,
187                           format_clib_timebase_time, end0);
188             }
189           goto print;
190         }
191     }
192   if (verbose && j)
193     s = format (s, "  No range match.\n");
194   if (dp->flags & MACTIME_DEVICE_FLAG_STATIC_DROP)
195     current_status = 0;
196   if (dp->flags & MACTIME_DEVICE_FLAG_STATIC_ALLOW)
197     current_status = 1;
198   if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW)
199     current_status = 2;
200   if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_DROP)
201     current_status = 3;
202   if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA)
203     current_status = 4;
204
205 print:
206   macstring = format (0, "%U", format_vl_api_mac_address_t, dp->mac_address);
207   switch (current_status)
208     {
209     case 0:
210       status_string = "static drop";
211       break;
212     case 1:
213       status_string = "static allow";
214       break;
215     case 2:
216       status_string = "dynamic drop";
217       break;
218     case 3:
219       status_string = "dynamic allow";
220       break;
221     case 4:
222       status_string = "d-quota inact";
223       break;
224     case 5:
225       status_string = "d-quota activ";
226       break;
227     default:
228       status_string = "code bug!";
229       break;
230     }
231
232   s = format (s, "%-15s %5d %18s %14s\n",
233               dp->device_name, dp->pool_index, macstring, status_string);
234   vec_free (macstring);
235
236   if (dp->data_quota > 0)
237     {
238       s = format (s, "%-59s %s%U %s%U", " ", "Quota ",
239                   format_bytes_with_width, dp->data_quota, 10,
240                   "Use ", format_bytes_with_width, dp->data_used_in_range, 8);
241       vec_add1 (s, '\n');
242     }
243   return s;
244 }
245
246 static int
247 api_mactime_dump (vat_main_t * vam)
248 {
249   mactime_test_main_t *tm = &mactime_test_main;
250   unformat_input_t *i = vam->input;
251   vl_api_mactime_dump_t *mp;
252   int verbose = 0;
253   int ret;
254   f64 now;
255   mactime_device_t *dev;
256
257   now = clib_timebase_now (&tm->timebase);
258
259   if (PREDICT_FALSE ((now - tm->sunday_midnight) > 86400.0 * 7.0))
260     tm->sunday_midnight = clib_timebase_find_sunday_midnight (now);
261
262   /* Parse args required to build the message */
263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
264     {
265       if (unformat (i, "force"))
266         tm->vpp_table_epoch = 0;
267       else if (unformat (i, "verbose"))
268         verbose = 1;
269       else
270         break;
271     }
272
273   /* Construct the API message */
274   M (MACTIME_DUMP, mp);
275   mp->my_table_epoch = clib_host_to_net_u32 (tm->vpp_table_epoch);
276
277   /* send it... */
278   S (mp);
279
280   /* Wait for a reply... */
281   W (ret);
282
283   fformat (vam->ofp, "%U", format_device, 0 /* header */ , 0 /* verbose */ );
284   pool_foreach (dev, tm->devices)
285    {
286     fformat (vam->ofp, "%U", format_device, dev, verbose);
287   }
288
289   return ret;
290 }
291
292 /* These two ought to be in a library somewhere but they aren't */
293 static uword
294 my_unformat_mac_address (unformat_input_t * input, va_list * args)
295 {
296   u8 *a = va_arg (*args, u8 *);
297   return unformat (input, "%x:%x:%x:%x:%x:%x", &a[0], &a[1], &a[2], &a[3],
298                    &a[4], &a[5]);
299 }
300
301 static u8 *
302 my_format_mac_address (u8 * s, va_list * args)
303 {
304   u8 *a = va_arg (*args, u8 *);
305   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
306                  a[0], a[1], a[2], a[3], a[4], a[5]);
307 }
308
309 static int
310 api_mactime_add_del_range (vat_main_t * vam)
311 {
312   unformat_input_t *i = vam->input;
313   vl_api_mactime_add_del_range_t *mp;
314   u8 mac_address[8];
315   u8 *device_name = 0;
316   clib_timebase_range_t *rp = 0;
317   int name_set = 0;
318   int mac_set = 0;
319   u8 is_add = 1;
320   u8 allow = 0;
321   u8 allow_quota = 0;
322   u8 drop = 0;
323   u8 no_udp_10001 = 0;
324   u64 data_quota = 0;
325   int ret;
326   int ii;
327
328   /* Parse args required to build the message */
329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
330     {
331       if (unformat (i, "name %s", &device_name))
332         {
333           vec_add1 (device_name, 0);
334           name_set = 1;
335         }
336       else if (unformat (i, "allow-range %U",
337                          unformat_clib_timebase_range_vector, &rp))
338         allow = 1;
339       else if (unformat (i, "allow-quota-range %U",
340                          unformat_clib_timebase_range_vector, &rp))
341         allow_quota = 1;
342       else if (unformat (i, "drop-range %U",
343                          unformat_clib_timebase_range_vector, &rp))
344         drop = 1;
345       else if (unformat (i, "allow-static"))
346         allow = 1;
347       else if (unformat (i, "drop-static"))
348         drop = 1;
349       else if (unformat (i, "no-udp-10001"))
350         no_udp_10001 = 1;
351       else if (unformat (i, "mac %U", my_unformat_mac_address, mac_address))
352         mac_set = 1;
353       else if (unformat (i, "del"))
354         is_add = 0;
355       else if (unformat (i, "data-quota %lldM", &data_quota))
356         data_quota <<= 20;
357       else if (unformat (i, "data-quota %lldG", &data_quota))
358         data_quota <<= 30;
359       else
360         break;
361     }
362
363   /* Sanity checks */
364   if (mac_set == 0)
365     {
366       vec_free (rp);
367       vec_free (device_name);
368       errmsg ("mac address required, not set\n");
369       return -99;
370     }
371
372   /* allow-range / drop-range parse errors cause this condition */
373   if (is_add && allow == 0 && drop == 0 && allow_quota == 0)
374     {
375       vec_free (rp);
376       vec_free (device_name);
377       errmsg ("parse error...\n");
378       return -99;
379     }
380
381   /* Unlikely, but check anyhow */
382   if (vec_len (device_name) > ARRAY_LEN (mp->device_name))
383     {
384       vec_free (rp);
385       vec_free (device_name);
386       errmsg ("device name too long, max %d\n", ARRAY_LEN (mp->device_name));
387       return -99;
388     }
389
390   /* Cough up a device name if none set */
391   if (name_set == 0)
392     {
393       device_name = format (0, "mac %U%c", my_format_mac_address,
394                             mac_address, 0);
395     }
396
397   /* Construct the API message */
398   M2 (MACTIME_ADD_DEL_RANGE, mp, sizeof (rp[0]) * vec_len (rp));
399   mp->is_add = is_add;
400   mp->drop = drop;
401   mp->allow = allow;
402   mp->allow_quota = allow_quota;
403   mp->no_udp_10001 = no_udp_10001;
404   mp->data_quota = clib_host_to_net_u64 (data_quota);
405   memcpy (mp->mac_address, mac_address, sizeof (mp->mac_address));
406   memcpy (mp->device_name, device_name, vec_len (device_name));
407   mp->count = clib_host_to_net_u32 (vec_len (rp));
408
409   for (ii = 0; ii < vec_len (rp); ii++)
410     {
411       mp->ranges[ii].start = rp[ii].start;
412       mp->ranges[ii].end = rp[ii].end;
413     }
414
415   vec_free (rp);
416   vec_free (device_name);
417
418   /* send it... */
419   S (mp);
420
421   /* Wait for a reply... */
422   W (ret);
423   return ret;
424 }
425
426 /* We shouldn't get these... */
427 static void
428 vl_api_mactime_details_t_handler (vl_api_mactime_details_t * mp)
429 {
430   clib_warning ("WARNING: stub called...");
431 }
432
433 #include <mactime/mactime.api_test.c>
434
435 /*
436  * fd.io coding-style-patch-verification: ON
437  *
438  * Local Variables:
439  * eval: (c-set-style "gnu")
440  * End:
441  */