FD.io VPP  v18.07-rc0-415-g6c78436
Vector Packet Processing
mactime.c
Go to the documentation of this file.
1 /*
2  * mactime.c - time-based src mac address filtration
3  *
4  * Copyright (c) 2018 Cisco and/or its affiliates.
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 
18 #include <vnet/vnet.h>
19 #include <vnet/plugin/plugin.h>
20 #include <mactime/mactime.h>
21 
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vpp/app/version.h>
25 
26 /* define message IDs */
28 
29 /* define message structures */
30 #define vl_typedefs
32 #undef vl_typedefs
33 
34 /* define generated endian-swappers */
35 #define vl_endianfun
37 #undef vl_endianfun
38 
39 /* instantiate all the print functions we know about */
40 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
41 #define vl_printfun
43 #undef vl_printfun
44 
45 /* Get the API version number */
46 #define vl_api_version(n,v) static u32 api_version=(v);
48 #undef vl_api_version
49 
50 #define REPLY_MSG_ID_BASE mm->msg_id_base
52 
54 
55 /** \file time-base src-mac filter device-input feature arc implementation
56  */
57 
58 /* List of message types that this plugin understands */
59 
60 #define foreach_mactime_plugin_api_msg \
61 _(MACTIME_ENABLE_DISABLE, mactime_enable_disable) \
62 _(MACTIME_ADD_DEL_RANGE, mactime_add_del_range)
63 
64 static void
66 {
67  if (mm->feature_initialized == 0)
68  {
69  /* Create the lookup table */
70  clib_bihash_init_8_8 (&mm->lookup_table, "mactime lookup table",
75  mm->allow_counters.name = "allow";
76  mm->allow_counters.stat_segment_name = "/mactime/allow";
77  mm->drop_counters.name = "drop";
78  mm->drop_counters.stat_segment_name = "/mactime/drop";
79  mm->feature_initialized = 1;
80  }
81 }
82 
83 /** Action function shared between message handler and debug CLI
84 */
85 int
87  int enable_disable)
88 {
90  int rv = 0;
91 
92  feature_init (mm);
93 
94  /* Utterly wrong? */
96  sw_if_index))
97  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
98 
99  /* Not a physical port? */
100  sw = vnet_get_sw_interface (mm->vnet_main, sw_if_index);
102  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
103 
104  vnet_feature_enable_disable ("device-input", "mactime",
105  sw_if_index, enable_disable, 0, 0);
106  vnet_feature_enable_disable ("interface-output", "mactime-tx",
107  sw_if_index, enable_disable, 0, 0);
108  return rv;
109 }
110 
111 static clib_error_t *
113  unformat_input_t * input,
114  vlib_cli_command_t * cmd)
115 {
117  u32 sw_if_index = ~0;
118  int enable_disable = 1;
119 
120  int rv;
121 
123  {
124  if (unformat (input, "disable"))
125  enable_disable = 0;
126  else if (unformat (input, "%U", unformat_vnet_sw_interface,
127  mm->vnet_main, &sw_if_index))
128  ;
129  else
130  break;
131  }
132 
133  if (sw_if_index == ~0)
134  return clib_error_return (0, "Please specify an interface...");
135 
136  rv = mactime_enable_disable (mm, sw_if_index, enable_disable);
137 
138  switch (rv)
139  {
140  case 0:
141  break;
142 
143  case VNET_API_ERROR_INVALID_SW_IF_INDEX:
144  return clib_error_return
145  (0, "Invalid interface, only works on physical ports");
146  break;
147 
148  case VNET_API_ERROR_UNIMPLEMENTED:
149  return clib_error_return (0,
150  "Device driver doesn't support redirection");
151  break;
152 
153  default:
154  return clib_error_return (0, "mactime_enable_disable returned %d", rv);
155  }
156  return 0;
157 }
158 
159 /* *INDENT-OFF* */
160 VLIB_CLI_COMMAND (mactime_enable_disable_command, static) =
161 {
162  .path = "mactime enable-disable",
163  .short_help =
164  "mactime enable-disable <interface-name> [disable]",
166 };
167 /* *INDENT-ON* */
168 
169 
170 /** Enable / disable time-base src mac filtration on an interface
171  */
172 
175 {
176  vl_api_mactime_enable_disable_reply_t *rmp;
178  int rv;
179 
180  rv = mactime_enable_disable (mm, ntohl (mp->sw_if_index),
181  (int) (mp->enable_disable));
182 
183  REPLY_MACRO (VL_API_MACTIME_ENABLE_DISABLE_REPLY);
184 }
185 
186 /** Create a lookup table entry for the indicated mac address
187  */
188 void
190 {
192  api_main_t *am;
194  u8 *name;
196 
197  am = &api_main;
198  shmem_hdr = am->shmem_hdr;
199  mp = vl_msg_api_alloc_as_if_client (sizeof (*mp));
200  memset (mp, 0, sizeof (*mp));
201  mp->_vl_msg_id = ntohs (VL_API_MACTIME_ADD_DEL_RANGE + mm->msg_id_base);
202  name = format (0, "mac-%U", format_mac_address, mac_address);
203 
204  memcpy (mp->device_name, name, vec_len (name));
205  memcpy (mp->mac_address, mac_address, sizeof (mp->mac_address));
206  /* $$$ config: create allow / drop / range */
207  mp->allow = 1;
208  mp->is_add = 1;
209  vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *) & mp);
210 }
211 
212 /** Add or delete static / dynamic accept/drop configuration for a src mac
213  */
214 
217 {
219  vl_api_mactime_add_del_range_reply_t *rmp;
220  mactime_device_t *dp;
222  int found = 1;
223  clib_bihash_8_8_t *lut = &mm->lookup_table;
224  int i, rv = 0;
225 
226  feature_init (mm);
227 
228  memset (&kv, 0, sizeof (kv));
229  memcpy (&kv.key, mp->mac_address, sizeof (mp->mac_address));
230 
231  /* See if we have a lookup table entry for this src mac address */
232  if (clib_bihash_search_8_8 (lut, &kv, &kv) < 0)
233  found = 0;
234 
235  /* Add an entry? */
236  if (mp->is_add)
237  {
238  /* Create the device entry? */
239  if (found == 0)
240  {
241  pool_get (mm->devices, dp);
242  memset (dp, 0, sizeof (*dp));
244  dp - mm->devices);
247  dp - mm->devices);
249  mp->device_name[ARRAY_LEN (mp->device_name) - 1] = 0;
250  dp->device_name = format (0, "%s%c", mp->device_name, 0);
251  memcpy (dp->mac_address, mp->mac_address, sizeof (mp->mac_address));
252  for (i = 0; i < clib_net_to_host_u32 (mp->count); i++)
253  {
254  clib_timebase_range_t _r, *r = &_r;
255  r->start = mp->ranges[i].start;
256  r->end = mp->ranges[i].end;
257  vec_add1 (dp->ranges, r[0]);
258  }
259  /* If we found some time ranges */
260  if (i)
261  {
262  /* Set allow/drop based on msg flags */
263  if (mp->drop)
265  if (mp->allow)
267  }
268  else
269  {
270  /* no ranges, it's a static allow/drop */
271  if (mp->drop)
273  if (mp->allow)
275  }
276 
277  /* Add the hash table entry */
278  kv.value = dp - mm->devices;
279  clib_bihash_add_del_8_8 (lut, &kv, 1 /* is_add */ );
280  }
281  else /* add more ranges */
282  {
283  dp = pool_elt_at_index (mm->devices, kv.value);
284  for (i = 0; i < clib_net_to_host_u32 (mp->count); i++)
285  {
286  clib_timebase_range_t _r, *r = &_r;
287  r->start = mp->ranges[i].start;
288  r->end = mp->ranges[i].end;
289  vec_add1 (dp->ranges, r[0]);
290  }
291  }
292  }
293  else /* delete case */
294  {
295  if (found == 0)
296  {
297  rv = VNET_API_ERROR_NO_SUCH_ENTRY;
298  goto reply;
299  }
300 
301  /* find the device entry */
302  dp = pool_elt_at_index (mm->devices, kv.value);
303 
304  /* Remove it from the lookup table */
305  clib_bihash_add_del_8_8 (lut, &kv, 0 /* is_add */ );
306  vec_free (dp->ranges);
307  pool_put (mm->devices, dp);
308  }
309 
310 reply:
311  REPLY_MACRO (VL_API_MACTIME_ADD_DEL_RANGE_REPLY);
312 }
313 
314 /* Set up the API message handling tables */
315 static clib_error_t *
317 {
319 #define _(N,n) \
320  vl_msg_api_set_handlers((VL_API_##N + mm->msg_id_base), \
321  #n, \
322  vl_api_##n##_t_handler, \
323  vl_noop_handler, \
324  vl_api_##n##_t_endian, \
325  vl_api_##n##_t_print, \
326  sizeof(vl_api_##n##_t), 1);
328 #undef _
329 
330  return 0;
331 }
332 
333 #define vl_msg_name_crc_list
335 #undef vl_msg_name_crc_list
336 
337 static void
339 {
340 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n #crc, id + mm->msg_id_base);
341  foreach_vl_msg_name_crc_mactime;
342 #undef _
343 }
344 
345 static clib_error_t *
347 {
349  clib_error_t *error = 0;
350  u8 *name;
351 
352  mm->vlib_main = vm;
353  mm->vnet_main = vnet_get_main ();
354 
355  name = format (0, "mactime_%08x%c", api_version, 0);
356 
357  /* Ask for a correctly-sized block of API message decode slots */
359  ((char *) name, VL_MSG_FIRST_AVAILABLE);
360 
361  error = mactime_plugin_api_hookup (vm);
362 
363  /* Add our API messages to the global name_crc hash table */
365 
366  vec_free (name);
367 
370  mm->timezone_offset = -5; /* US EST / EDT */
371  return error;
372 }
373 
375 
376 static clib_error_t *
378 {
380 
382  {
383  if (unformat (input, "lookup-table-buckets %u",
385  ;
386  else if (unformat (input, "lookup-table-memory %U",
388  ;
389  else if (unformat (input, "timezone_offset %d", &mm->timezone_offset))
390  ;
391  else
392  {
393  return clib_error_return (0, "unknown input '%U'",
394  format_unformat_error, input);
395  }
396  }
397  return 0;
398 }
399 
401 
402 /* *INDENT-OFF* */
403 VNET_FEATURE_INIT (mactime, static) =
404 {
405  .arc_name = "device-input",
406  .node_name = "mactime",
407  .runs_before = VNET_FEATURES ("ethernet-input"),
408 };
409 /* *INDENT-ON */
410 
411 /* *INDENT-OFF* */
412 VNET_FEATURE_INIT (mactime_tx, static) =
413 {
414  .arc_name = "interface-output",
415  .node_name = "mactime-tx",
416  .runs_before = VNET_FEATURES ("interface-tx"),
417 };
418 /* *INDENT-ON */
419 
420 /* *INDENT-OFF* */
422 {
423  .version = VPP_BUILD_VER,
424  .description = "Time-based MAC source-address filter",
425 };
426 /* *INDENT-ON* */
427 
428 static clib_error_t *
430  unformat_input_t * input, vlib_cli_command_t * cmd)
431 {
433  mactime_device_t *dp;
434  u8 *macstring = 0;
435  char *status_string;
436  u32 *pool_indices = 0;
437  int verbose = 0;
438  int current_status = 99;
439  int i, j;
440  f64 now;
441  vlib_counter_t allow, drop;
442  ethernet_arp_ip4_entry_t *n, *pool;
443 
445  pool = ip4_neighbors_pool ();
446 
447  /* *INDENT-OFF* */
448  pool_foreach (n, pool,
449  ({
450  vec_add1 (mm->arp_cache_copy, n[0]);
451  }));
452  /* *INDENT-ON* */
453 
454  now = clib_timebase_now (&mm->timebase);
455 
456  if (PREDICT_FALSE ((now - mm->sunday_midnight) > 86400.0 * 7.0))
458 
459  if (unformat (input, "verbose %d", &verbose))
460  ;
461 
462  if (unformat (input, "verbose"))
463  verbose = 1;
464 
465  if (verbose)
466  vlib_cli_output (vm, "Time now: %U", format_clib_timebase_time, now);
467 
468  /* *INDENT-OFF* */
469  pool_foreach (dp, mm->devices,
470  ({
471  vec_add1 (pool_indices, dp - mm->devices);
472  }));
473  /* *INDENT-ON* */
474 
475  vlib_cli_output (vm, "%-15s %18s %14s %10s %10s %10s",
476  "Device Name", "Addresses", "Status",
477  "AllowPkt", "AllowByte", "DropPkt");
478 
479  for (i = 0; i < vec_len (pool_indices); i++)
480  {
481  dp = pool_elt_at_index (mm->devices, pool_indices[i]);
482 
483  /* Check dynamic ranges */
484  for (j = 0; j < vec_len (dp->ranges); j++)
485  {
486  clib_timebase_range_t *r = dp->ranges + j;
487  f64 start0, end0;
488 
489  start0 = r->start + mm->sunday_midnight;
490  end0 = r->end + mm->sunday_midnight;
491  if (verbose > 1)
492  vlib_cli_output (vm, " Range %d: %U - %U", j,
495 
496  if (now >= start0 && now <= end0)
497  {
499  current_status = 3;
500  else
501  current_status = 2;
502  if (verbose)
503  {
504  vlib_cli_output (vm, " Time in range %d:", j);
505  vlib_cli_output (vm, " %U - %U",
508  }
509  goto print;
510  }
511  }
512  if (verbose && j)
513  vlib_cli_output (vm, " No range match.");
515  current_status = 0;
517  current_status = 1;
519  current_status = 2;
521  current_status = 3;
522 
523  print:
524  vec_reset_length (macstring);
525  macstring = format (0, "%U", format_mac_address, dp->mac_address);
526  switch (current_status)
527  {
528  case 0:
529  status_string = "static drop";
530  break;
531  case 1:
532  status_string = "static allow";
533  break;
534  case 2:
535  status_string = "dynamic drop";
536  break;
537  case 3:
538  status_string = "dynamic allow";
539  break;
540  default:
541  status_string = "code bug!";
542  break;
543  }
545  &allow);
546  vlib_get_combined_counter (&mm->drop_counters, dp - mm->devices, &drop);
547  vlib_cli_output (vm, "%-15s %18s %14s %10lld %10lld %10lld",
548  dp->device_name, macstring, status_string,
549  allow.packets, allow.bytes, drop.packets);
550  /* This is really only good for small N... */
551  for (j = 0; j < vec_len (mm->arp_cache_copy); j++)
552  {
553  n = mm->arp_cache_copy + j;
554  if (!memcmp (dp->mac_address, n->ethernet_address,
555  sizeof (n->ethernet_address)))
556  {
557  vlib_cli_output (vm, "%17s%U", " ", format_ip4_address,
558  &n->ip4_address);
559  }
560  }
561  }
562  vec_free (macstring);
563  vec_free (pool_indices);
564 
565  return 0;
566 }
567 
568 /* *INDENT-OFF* */
569 VLIB_CLI_COMMAND (show_mactime_command, static) =
570 {
571  .path = "show mactime",
572  .short_help = "show mactime [verbose]",
573  .function = show_mactime_command_fn,
574 };
575 /* *INDENT-ON* */
576 
577 static clib_error_t *
579  unformat_input_t * input, vlib_cli_command_t * cmd)
580 {
582 
583  if (mm->feature_initialized == 0)
584  return clib_error_return (0, "feature not enabled");
585 
588  vlib_cli_output (vm, "Mactime counters cleared...");
589  return 0;
590 }
591 
592 /* *INDENT-OFF* */
593 VLIB_CLI_COMMAND (clear_mactime_command, static) =
594 {
595  .path = "clear mactime",
596  .short_help = "clear mactime counters",
597  .function = clear_mactime_command_fn,
598 };
599 /* *INDENT-ON* */
600 
601 
602 
603 /*
604  * fd.io coding-style-patch-verification: ON
605  *
606  * Local Variables:
607  * eval: (c-set-style "gnu")
608  * End:
609  */
configure per src-mac time ranges
Definition: mactime.api:70
static void vl_api_mactime_add_del_range_t_handler(vl_api_mactime_add_del_range_t *mp)
Add or delete static / dynamic accept/drop configuration for a src mac.
Definition: mactime.c:216
vlib_combined_counter_main_t drop_counters
Definition: mactime.h:77
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:106
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:187
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
VNET_FEATURE_INIT(mactime, static)
vnet_interface_main_t interface_main
Definition: vnet.h:56
int mactime_enable_disable(mactime_main_t *mm, u32 sw_if_index, int enable_disable)
Action function shared between message handler and debug CLI.
Definition: mactime.c:86
u16 msg_id_base
Definition: mactime.h:61
static clib_error_t * clear_mactime_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mactime.c:578
#define foreach_mactime_plugin_api_msg
Definition: mactime.c:60
clib_timebase_t timebase
Definition: mactime.h:64
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
Combined counter to hold both packets and byte differences.
Definition: counter.h:140
int i
f64 end
end of the time range
Definition: mactime.api:40
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
unformat_function_t unformat_vnet_sw_interface
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
#define MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW
Definition: mactime.h:47
unsigned char u8
Definition: types.h:56
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
double f64
Definition: types.h:142
static clib_error_t * show_mactime_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mactime.c:429
u32 count
number of time ranges to follow
Definition: mactime.api:79
format_function_t format_ip4_address
Definition: format.h:81
clib_timebase_range_t * ranges
Definition: mactime.h:40
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:60
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
u8 * format_mac_address(u8 *s, va_list *args)
Definition: lisp_types.c:215
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
#define MACTIME_MEMORY_SIZE
Definition: mactime.h:98
static f64 clib_timebase_now(clib_timebase_t *tb)
Definition: time_range.h:92
#define clib_error_return(e, args...)
Definition: error.h:99
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
Definition: api_common.h:264
vlib_main_t * vlib_main
Definition: mactime.h:91
unsigned int u32
Definition: types.h:88
format_function_t format_clib_timebase_time
Definition: time_range.h:74
vl_shmem_hdr_t * shmem_hdr
VLIB_PLUGIN_REGISTER()
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:461
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread counters.
Definition: counter.h:278
ethernet_arp_ip4_entry_t * arp_cache_copy
Definition: mactime.h:88
mactime_main_t mactime_main
Definition: mactime.c:53
counter_t packets
packet counter
Definition: counter.h:142
vlib_combined_counter_main_t allow_counters
Definition: mactime.h:76
u64 key
the key
Definition: bihash_8_8.h:35
ip4_address_t ip4_address
Definition: arp_packet.h:153
struct _unformat_input_t unformat_input_t
u32 lookup_table_num_buckets
Definition: mactime.h:80
ethernet_arp_ip4_entry_t * ip4_neighbors_pool(void)
Definition: arp.c:1365
u8 ethernet_address[6]
Definition: arp_packet.h:155
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:273
#define PREDICT_FALSE(x)
Definition: clib.h:105
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:164
#define REPLY_MACRO(t)
static clib_error_t * mactime_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mactime.c:112
uword lookup_table_memory_size
Definition: mactime.h:81
static clib_error_t * mactime_config(vlib_main_t *vm, unformat_input_t *input)
Definition: mactime.c:377
api to enable or disable the time-based src mac filter on an interface
Definition: mactime.api:25
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:201
static clib_error_t * mactime_init(vlib_main_t *vm)
Definition: mactime.c:346
u64 value
the value
Definition: bihash_8_8.h:36
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
u8 mac_address[6]
src mac address
Definition: mactime.api:77
static void vlib_get_combined_counter(const vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of per-thr...
Definition: counter.h:252
vlib_main_t * vm
Definition: buffer.c:294
f64 sunday_midnight
Definition: mactime.h:67
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
f64 clib_timebase_find_sunday_midnight(f64 start_time)
Definition: time_range.c:213
static void setup_message_id_table(mactime_main_t *mm, api_main_t *am)
Definition: mactime.c:338
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:270
8 octet key, 8 octet key value pair
Definition: bihash_8_8.h:33
#define ARRAY_LEN(x)
Definition: clib.h:59
void clib_timebase_init(clib_timebase_t *tb, i32 timezone_offset_in_hours, clib_timebase_daylight_time_t daylight_type)
Definition: time_range.c:19
svm_queue_t * vl_input_queue
Definition: memory_shared.h:84
#define MACTIME_DEVICE_FLAG_STATIC_DROP
Always drop packets from this device.
Definition: mactime.h:44
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
mactime_device_t * devices
Definition: mactime.h:73
static clib_error_t * mactime_plugin_api_hookup(vlib_main_t *vm)
Definition: mactime.c:316
f64 start
start of the time range
Definition: mactime.api:39
clib_bihash_8_8_t lookup_table
Definition: mactime.h:70
vl_api_time_range_t ranges[count]
time ranges, in seconds since Sunday began
Definition: mactime.api:81
static void feature_init(mactime_main_t *mm)
Definition: mactime.c:65
#define VNET_FEATURES(...)
Definition: feature.h:391
void mactime_send_create_entry_message(u8 *mac_address)
Create a lookup table entry for the indicated mac address.
Definition: mactime.c:189
counter_t bytes
byte counter
Definition: counter.h:143
u32 sw_if_index
the interface handle
Definition: mactime.api:30
static void vl_api_mactime_enable_disable_t_handler(vl_api_mactime_enable_disable_t *mp)
Enable / disable time-base src mac filtration on an interface.
Definition: mactime.c:174
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:801
char * name
The counter collection&#39;s name.
Definition: counter.h:186
#define MACTIME_DEVICE_FLAG_STATIC_ALLOW
Definition: mactime.h:45
int feature_initialized
Definition: mactime.h:85
unformat_function_t unformat_memory_size
Definition: format.h:294
u8 * device_name
Definition: mactime.h:37
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vnet_sw_interface_type_t type
Definition: interface.h:655
vnet_main_t * vnet_main
Definition: mactime.h:92
#define MACTIME_DEVICE_FLAG_DYNAMIC_DROP
Definition: mactime.h:46
u8 enable_disable
enable=1, disable=0
Definition: mactime.api:29
void * vl_msg_api_alloc_as_if_client(int nbytes)
#define MACTIME_NUM_BUCKETS
Definition: mactime.h:97
u8 device_name[64]
device name
Definition: mactime.api:78
u8 mac_address[6]
Definition: mactime.h:38
api_main_t api_main
Definition: api_shared.c:35
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:681
i32 timezone_offset
Definition: mactime.h:82
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:233
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
Definition: arp_packet.h:150
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:872