FD.io VPP  v18.07.1-19-g511ce25
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 
181 
182  rv = mactime_enable_disable (mm, ntohl (mp->sw_if_index),
183  (int) (mp->enable_disable));
185  REPLY_MACRO (VL_API_MACTIME_ENABLE_DISABLE_REPLY);
186 }
187 
188 /** Create a lookup table entry for the indicated mac address
189  */
190 void
192 {
194  api_main_t *am;
196  u8 *name;
198 
199  am = &api_main;
200  shmem_hdr = am->shmem_hdr;
201  mp = vl_msg_api_alloc_as_if_client (sizeof (*mp));
202  memset (mp, 0, sizeof (*mp));
203  mp->_vl_msg_id = ntohs (VL_API_MACTIME_ADD_DEL_RANGE + mm->msg_id_base);
204  name = format (0, "mac-%U", format_mac_address, mac_address);
205 
206  memcpy (mp->device_name, name, vec_len (name));
207  memcpy (mp->mac_address, mac_address, sizeof (mp->mac_address));
208  /* $$$ config: create allow / drop / range */
209  mp->allow = 1;
210  mp->is_add = 1;
211  vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *) & mp);
212 }
213 
214 /** Add or delete static / dynamic accept/drop configuration for a src mac
215  */
216 
219 {
221  vl_api_mactime_add_del_range_reply_t *rmp;
222  mactime_device_t *dp;
224  int found = 1;
225  clib_bihash_8_8_t *lut = &mm->lookup_table;
226  int i, rv = 0;
227 
228  feature_init (mm);
229 
230  memset (&kv, 0, sizeof (kv));
231  memcpy (&kv.key, mp->mac_address, sizeof (mp->mac_address));
232 
233  /* See if we have a lookup table entry for this src mac address */
234  if (clib_bihash_search_8_8 (lut, &kv, &kv) < 0)
235  found = 0;
236 
237  /* Add an entry? */
238  if (mp->is_add)
239  {
240  /* Create the device entry? */
241  if (found == 0)
242  {
243  pool_get (mm->devices, dp);
244  memset (dp, 0, sizeof (*dp));
246  dp - mm->devices);
249  dp - mm->devices);
251  mp->device_name[ARRAY_LEN (mp->device_name) - 1] = 0;
252  dp->device_name = format (0, "%s%c", mp->device_name, 0);
253  memcpy (dp->mac_address, mp->mac_address, sizeof (mp->mac_address));
254  for (i = 0; i < clib_net_to_host_u32 (mp->count); i++)
255  {
256  clib_timebase_range_t _r, *r = &_r;
257  r->start = mp->ranges[i].start;
258  r->end = mp->ranges[i].end;
259  vec_add1 (dp->ranges, r[0]);
260  }
261  /* If we found some time ranges */
262  if (i)
263  {
264  /* Set allow/drop based on msg flags */
265  if (mp->drop)
267  if (mp->allow)
269  }
270  else
271  {
272  /* no ranges, it's a static allow/drop */
273  if (mp->drop)
275  if (mp->allow)
277  }
278 
279  /* Add the hash table entry */
280  kv.value = dp - mm->devices;
281  clib_bihash_add_del_8_8 (lut, &kv, 1 /* is_add */ );
282  }
283  else /* add more ranges */
284  {
285  dp = pool_elt_at_index (mm->devices, kv.value);
286  for (i = 0; i < clib_net_to_host_u32 (mp->count); i++)
287  {
288  clib_timebase_range_t _r, *r = &_r;
289  r->start = mp->ranges[i].start;
290  r->end = mp->ranges[i].end;
291  vec_add1 (dp->ranges, r[0]);
292  }
293  }
294  }
295  else /* delete case */
296  {
297  if (found == 0)
298  {
299  rv = VNET_API_ERROR_NO_SUCH_ENTRY;
300  goto reply;
301  }
302 
303  /* find the device entry */
304  dp = pool_elt_at_index (mm->devices, kv.value);
305 
306  /* Remove it from the lookup table */
307  clib_bihash_add_del_8_8 (lut, &kv, 0 /* is_add */ );
308  vec_free (dp->ranges);
309  pool_put (mm->devices, dp);
310  }
311 
312 reply:
313  REPLY_MACRO (VL_API_MACTIME_ADD_DEL_RANGE_REPLY);
314 }
315 
316 /* Set up the API message handling tables */
317 static clib_error_t *
319 {
321 #define _(N,n) \
322  vl_msg_api_set_handlers((VL_API_##N + mm->msg_id_base), \
323  #n, \
324  vl_api_##n##_t_handler, \
325  vl_noop_handler, \
326  vl_api_##n##_t_endian, \
327  vl_api_##n##_t_print, \
328  sizeof(vl_api_##n##_t), 1);
330 #undef _
331 
332  return 0;
333 }
334 
335 #define vl_msg_name_crc_list
337 #undef vl_msg_name_crc_list
338 
339 static void
341 {
342 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n #crc, id + mm->msg_id_base);
343  foreach_vl_msg_name_crc_mactime;
344 #undef _
345 }
346 
347 static clib_error_t *
349 {
351  clib_error_t *error = 0;
352  u8 *name;
353 
354  mm->vlib_main = vm;
355  mm->vnet_main = vnet_get_main ();
356 
357  name = format (0, "mactime_%08x%c", api_version, 0);
358 
359  /* Ask for a correctly-sized block of API message decode slots */
361  ((char *) name, VL_MSG_FIRST_AVAILABLE);
362 
363  error = mactime_plugin_api_hookup (vm);
364 
365  /* Add our API messages to the global name_crc hash table */
367 
368  vec_free (name);
369 
372  mm->timezone_offset = -5; /* US EST / EDT */
373  return error;
374 }
375 
377 
378 static clib_error_t *
380 {
382 
384  {
385  if (unformat (input, "lookup-table-buckets %u",
387  ;
388  else if (unformat (input, "lookup-table-memory %U",
390  ;
391  else if (unformat (input, "timezone_offset %d", &mm->timezone_offset))
392  ;
393  else
394  {
395  return clib_error_return (0, "unknown input '%U'",
396  format_unformat_error, input);
397  }
398  }
399  return 0;
400 }
401 
403 
404 /* *INDENT-OFF* */
405 VNET_FEATURE_INIT (mactime, static) =
406 {
407  .arc_name = "device-input",
408  .node_name = "mactime",
409  .runs_before = VNET_FEATURES ("ethernet-input"),
410 };
411 /* *INDENT-ON */
412 
413 /* *INDENT-OFF* */
414 VNET_FEATURE_INIT (mactime_tx, static) =
415 {
416  .arc_name = "interface-output",
417  .node_name = "mactime-tx",
418  .runs_before = VNET_FEATURES ("interface-tx"),
419 };
420 /* *INDENT-ON */
421 
422 /* *INDENT-OFF* */
424 {
425  .version = VPP_BUILD_VER,
426  .description = "Time-based MAC source-address filter",
427 };
428 /* *INDENT-ON* */
429 
430 static clib_error_t *
432  unformat_input_t * input, vlib_cli_command_t * cmd)
433 {
435  mactime_device_t *dp;
436  u8 *macstring = 0;
437  char *status_string;
438  u32 *pool_indices = 0;
439  int verbose = 0;
440  int current_status = 99;
441  int i, j;
442  f64 now;
443  vlib_counter_t allow, drop;
444  ethernet_arp_ip4_entry_t *n, *pool;
445 
447  pool = ip4_neighbors_pool ();
448 
449  /* *INDENT-OFF* */
450  pool_foreach (n, pool,
451  ({
452  vec_add1 (mm->arp_cache_copy, n[0]);
453  }));
454  /* *INDENT-ON* */
455 
456  now = clib_timebase_now (&mm->timebase);
457 
458  if (PREDICT_FALSE ((now - mm->sunday_midnight) > 86400.0 * 7.0))
460 
461  if (unformat (input, "verbose %d", &verbose))
462  ;
463 
464  if (unformat (input, "verbose"))
465  verbose = 1;
466 
467  if (verbose)
468  vlib_cli_output (vm, "Time now: %U", format_clib_timebase_time, now);
469 
470  /* *INDENT-OFF* */
471  pool_foreach (dp, mm->devices,
472  ({
473  vec_add1 (pool_indices, dp - mm->devices);
474  }));
475  /* *INDENT-ON* */
476 
477  vlib_cli_output (vm, "%-15s %18s %14s %10s %10s %10s",
478  "Device Name", "Addresses", "Status",
479  "AllowPkt", "AllowByte", "DropPkt");
480 
481  for (i = 0; i < vec_len (pool_indices); i++)
482  {
483  dp = pool_elt_at_index (mm->devices, pool_indices[i]);
484 
485  /* Check dynamic ranges */
486  for (j = 0; j < vec_len (dp->ranges); j++)
487  {
488  clib_timebase_range_t *r = dp->ranges + j;
489  f64 start0, end0;
490 
491  start0 = r->start + mm->sunday_midnight;
492  end0 = r->end + mm->sunday_midnight;
493  if (verbose > 1)
494  vlib_cli_output (vm, " Range %d: %U - %U", j,
497 
498  if (now >= start0 && now <= end0)
499  {
501  current_status = 3;
502  else
503  current_status = 2;
504  if (verbose)
505  {
506  vlib_cli_output (vm, " Time in range %d:", j);
507  vlib_cli_output (vm, " %U - %U",
510  }
511  goto print;
512  }
513  }
514  if (verbose && j)
515  vlib_cli_output (vm, " No range match.");
517  current_status = 0;
519  current_status = 1;
521  current_status = 2;
523  current_status = 3;
524 
525  print:
526  vec_reset_length (macstring);
527  macstring = format (0, "%U", format_mac_address, dp->mac_address);
528  switch (current_status)
529  {
530  case 0:
531  status_string = "static drop";
532  break;
533  case 1:
534  status_string = "static allow";
535  break;
536  case 2:
537  status_string = "dynamic drop";
538  break;
539  case 3:
540  status_string = "dynamic allow";
541  break;
542  default:
543  status_string = "code bug!";
544  break;
545  }
547  &allow);
548  vlib_get_combined_counter (&mm->drop_counters, dp - mm->devices, &drop);
549  vlib_cli_output (vm, "%-15s %18s %14s %10lld %10lld %10lld",
550  dp->device_name, macstring, status_string,
551  allow.packets, allow.bytes, drop.packets);
552  /* This is really only good for small N... */
553  for (j = 0; j < vec_len (mm->arp_cache_copy); j++)
554  {
555  n = mm->arp_cache_copy + j;
556  if (!memcmp (dp->mac_address, n->ethernet_address,
557  sizeof (n->ethernet_address)))
558  {
559  vlib_cli_output (vm, "%17s%U", " ", format_ip4_address,
560  &n->ip4_address);
561  }
562  }
563  }
564  vec_free (macstring);
565  vec_free (pool_indices);
566 
567  return 0;
568 }
569 
570 /* *INDENT-OFF* */
571 VLIB_CLI_COMMAND (show_mactime_command, static) =
572 {
573  .path = "show mactime",
574  .short_help = "show mactime [verbose]",
575  .function = show_mactime_command_fn,
576 };
577 /* *INDENT-ON* */
578 
579 static clib_error_t *
581  unformat_input_t * input, vlib_cli_command_t * cmd)
582 {
584 
585  if (mm->feature_initialized == 0)
586  return clib_error_return (0, "feature not enabled");
587 
590  vlib_cli_output (vm, "Mactime counters cleared...");
591  return 0;
592 }
593 
594 /* *INDENT-OFF* */
595 VLIB_CLI_COMMAND (clear_mactime_command, static) =
596 {
597  .path = "clear mactime",
598  .short_help = "clear mactime counters",
599  .function = clear_mactime_command_fn,
600 };
601 /* *INDENT-ON* */
602 
603 
604 
605 /*
606  * fd.io coding-style-patch-verification: ON
607  *
608  * Local Variables:
609  * eval: (c-set-style "gnu")
610  * End:
611  */
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:218
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:580
#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:228
#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:431
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:443
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:464
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:1372
u8 ethernet_address[6]
Definition: arp_packet.h:155
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:274
#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:379
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:348
u64 value
the value
Definition: bihash_8_8.h:36
#define BAD_SW_IF_INDEX_LABEL
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
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:340
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:271
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:318
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:191
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:802
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:295
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:656
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:170
#define VALIDATE_SW_IF_INDEX(mp)
Definition: arp_packet.h:150
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:872