FD.io VPP  v20.01-48-g3e0dafb74
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 */
27 #include <vnet/format_fns.h>
28 #include <mactime/mactime.api_enum.h>
29 #include <mactime/mactime.api_types.h>
30 
31 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
32 
33 #define REPLY_MSG_ID_BASE mm->msg_id_base
35 
37 
39 
40 /** \file time-base src-mac filter device-input feature arc implementation
41  */
42 
43 static void
45 {
46  if (mm->feature_initialized == 0)
47  {
48  /* Create the lookup table */
49  clib_bihash_init_8_8 (&mm->lookup_table, "mactime lookup table",
54  mm->allow_counters.name = "allow";
55  mm->allow_counters.stat_segment_name = "/mactime/allow";
56  mm->drop_counters.name = "drop";
57  mm->drop_counters.stat_segment_name = "/mactime/drop";
58  mm->feature_initialized = 1;
59  }
60 }
61 
62 /** Action function shared between message handler and debug CLI
63 */
64 int
66  int enable_disable)
67 {
69  int rv = 0;
70  static u8 url_init_done;
71 
72  feature_init (mm);
73 
74  /* Utterly wrong? */
76  sw_if_index))
77  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
78 
79  /* Not a physical port? */
80  sw = vnet_get_sw_interface (mm->vnet_main, sw_if_index);
82  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
83 
84  vnet_feature_enable_disable ("device-input", "mactime",
85  sw_if_index, enable_disable, 0, 0);
86  vnet_feature_enable_disable ("interface-output", "mactime-tx",
87  sw_if_index, enable_disable, 0, 0);
88  if (url_init_done == 0)
89  {
91  url_init_done = 1;
92  }
93 
94  return rv;
95 }
96 
97 static clib_error_t *
99  unformat_input_t * input,
100  vlib_cli_command_t * cmd)
101 {
103  u32 sw_if_index = ~0;
104  int enable_disable = 1;
105 
106  int rv;
107 
109  {
110  if (unformat (input, "disable"))
111  enable_disable = 0;
112  else if (unformat (input, "%U", unformat_vnet_sw_interface,
113  mm->vnet_main, &sw_if_index))
114  ;
115  else if (unformat (input, "sw_if_index %d", &sw_if_index))
116  ;
117  else
118  break;
119  }
120 
121  if (sw_if_index == ~0)
122  return clib_error_return (0, "Please specify an interface...");
123 
124  rv = mactime_enable_disable (mm, sw_if_index, enable_disable);
125 
126  switch (rv)
127  {
128  case 0:
129  break;
130 
131  case VNET_API_ERROR_INVALID_SW_IF_INDEX:
132  return clib_error_return
133  (0, "Invalid interface, only works on physical ports");
134  break;
135 
136  default:
137  return clib_error_return (0, "mactime_enable_disable returned %d", rv);
138  }
139  return 0;
140 }
141 
142 /* *INDENT-OFF* */
143 VLIB_CLI_COMMAND (mactime_enable_disable_command, static) =
144 {
145  .path = "mactime enable-disable",
146  .short_help =
147  "mactime enable-disable <interface-name> [disable]",
149 };
150 /* *INDENT-ON* */
151 
152 
153 /** Enable / disable time-base src mac filtration on an interface
154  */
155 
158 {
159  vl_api_mactime_enable_disable_reply_t *rmp;
161  int rv;
162 
164 
165  rv = mactime_enable_disable (mm, ntohl (mp->sw_if_index),
166  (int) (mp->enable_disable));
168  REPLY_MACRO (VL_API_MACTIME_ENABLE_DISABLE_REPLY);
169 }
170 
171 static void
173 {
176  mactime_device_t *dev;
179  int rv = 0, i;
180  u32 his_table_epoch = clib_net_to_host_u32 (mp->my_table_epoch);
181  u32 message_size;
182  u32 name_len;
183  u32 nranges;
184 
186  if (rp == 0)
187  return;
188 
189  if (his_table_epoch == mm->device_table_epoch)
190  {
191  rv = VNET_API_ERROR_NO_CHANGE;
192  goto send_reply;
193  }
194 
195  /* *INDENT-OFF* */
196  pool_foreach (dev, mm->devices,
197  ({
198  message_size = sizeof(*ep) + vec_len(dev->device_name) +
199  vec_len(dev->ranges) * sizeof(ep->ranges[0]);
200 
201  ep = vl_msg_api_alloc (message_size);
202  memset (ep, 0, message_size);
203  ep->_vl_msg_id = clib_host_to_net_u16 (VL_API_MACTIME_DETAILS
204  + mm->msg_id_base);
205  ep->context = mp->context;
206  /* Index is the key for the stats segment combined counters */
207  ep->pool_index = clib_host_to_net_u32 (dev - mm->devices);
208 
209  clib_memcpy_fast (ep->mac_address, dev->mac_address,
210  sizeof (ep->mac_address));
211  ep->data_quota = clib_host_to_net_u64 (dev->data_quota);
212  ep->data_used_in_range = clib_host_to_net_u64 (dev->data_used_in_range);
213  ep->flags = clib_host_to_net_u32 (dev->flags);
214  nranges = vec_len (dev->ranges);
215  ep->nranges = clib_host_to_net_u32 (nranges);
216 
217  for (i = 0; i < vec_len (dev->ranges); i++)
218  {
219  ep->ranges[i].start = dev->ranges[i].start;
220  ep->ranges[i].end = dev->ranges[i].end;
221  }
222 
223  name_len = vec_len (dev->device_name);
224  name_len = (name_len < ARRAY_LEN(ep->device_name)) ?
225  name_len : ARRAY_LEN(ep->device_name) - 1;
226 
228  name_len);
229  ep->device_name [ARRAY_LEN(ep->device_name) -1] = 0;
230  vl_api_send_msg (rp, (u8 *)ep);
231  }));
232  /* *INDENT-OFF* */
233 
234  send_reply:
235  /* *INDENT-OFF* */
236  REPLY_MACRO2 (VL_API_MACTIME_DUMP_REPLY,
237  ({
238  rmp->table_epoch = clib_host_to_net_u32 (mm->device_table_epoch);
239  }));
240  /* *INDENT-ON* */
241 }
242 
243 /** Create a lookup table entry for the indicated mac address
244  */
245 void
247 {
249  api_main_t *am;
250  vl_shmem_hdr_t *shmem_hdr;
251  u8 *name;
253 
254  am = vlibapi_get_main ();
255  shmem_hdr = am->shmem_hdr;
256  mp = vl_msg_api_alloc_as_if_client (sizeof (*mp));
257  clib_memset (mp, 0, sizeof (*mp));
258  mp->_vl_msg_id = ntohs (VL_API_MACTIME_ADD_DEL_RANGE + mm->msg_id_base);
259  name = format (0, "mac-%U", format_mac_address, mac_address);
260 
261  memcpy (mp->device_name, name, vec_len (name));
262  memcpy (mp->mac_address, mac_address, sizeof (mp->mac_address));
263  /* $$$ config: create allow / drop / range */
264  mp->allow = 1;
265  mp->is_add = 1;
266  vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *) & mp);
267 }
268 
269 /** Add or delete static / dynamic accept/drop configuration for a src mac
270  */
271 
274 {
276  vl_api_mactime_add_del_range_reply_t *rmp;
277  mactime_device_t *dp;
279  int found = 1;
280  clib_bihash_8_8_t *lut = &mm->lookup_table;
281  u64 data_quota;
282  int i, rv = 0;
283 
284  feature_init (mm);
285 
286  /*
287  * Change the table epoch. Skip 0 so clients can code my_table_epoch = 0
288  * to receive a full dump.
289  */
290  mm->device_table_epoch++;
291  if (PREDICT_FALSE (mm->device_table_epoch == 0))
292  mm->device_table_epoch++;
293 
294  data_quota = clib_net_to_host_u64 (mp->data_quota);
295 
296  clib_memset (&kv, 0, sizeof (kv));
297  memcpy (&kv.key, mp->mac_address, sizeof (mp->mac_address));
298 
299  /* See if we have a lookup table entry for this src mac address */
300  if (clib_bihash_search_8_8 (lut, &kv, &kv) < 0)
301  found = 0;
302 
303  /* Add an entry? */
304  if (mp->is_add)
305  {
306  /* Create the device entry? */
307  if (found == 0)
308  {
309  pool_get (mm->devices, dp);
310  clib_memset (dp, 0, sizeof (*dp));
312  dp - mm->devices);
315  dp - mm->devices);
317  mp->device_name[ARRAY_LEN (mp->device_name) - 1] = 0;
318  dp->device_name = format (0, "%s%c", mp->device_name, 0);
319  memcpy (dp->mac_address, mp->mac_address, sizeof (mp->mac_address));
320  for (i = 0; i < clib_net_to_host_u32 (mp->count); i++)
321  {
322  clib_timebase_range_t _r, *r = &_r;
323  r->start = mp->ranges[i].start;
324  r->end = mp->ranges[i].end;
325  vec_add1 (dp->ranges, r[0]);
326  }
327  /* If we found some time ranges */
328  if (i)
329  {
330  /* Set allow/drop based on msg flags */
331  if (mp->drop)
333  if (mp->allow)
335  if (mp->allow_quota)
337  }
338  else
339  {
340  /* no ranges, it's a static allow/drop */
341  if (mp->drop)
343  if (mp->allow)
345  }
346  if (mp->no_udp_10001)
348 
349  dp->data_quota = data_quota;
350 
351  /* Add the hash table entry */
352  kv.value = dp - mm->devices;
353  clib_bihash_add_del_8_8 (lut, &kv, 1 /* is_add */ );
354  }
355  else /* add more ranges, flags, etc. */
356  {
357  dp = pool_elt_at_index (mm->devices, kv.value);
358 
359  for (i = 0; i < clib_net_to_host_u32 (mp->count); i++)
360  {
361  clib_timebase_range_t _r, *r = &_r;
362  r->start = mp->ranges[i].start;
363  r->end = mp->ranges[i].end;
364  vec_add1 (dp->ranges, r[0]);
365  }
366 
367  if (vec_len (dp->ranges))
368  {
369  /* Set allow/drop based on msg flags */
370  if (mp->drop)
372  if (mp->allow)
374  if (mp->allow_quota)
376  }
377  else
378  {
379  /* no ranges, it's a static allow/drop */
380  if (mp->drop)
382  if (mp->allow)
384  }
385  if (mp->no_udp_10001)
387 
388  dp->data_quota = data_quota;
389  }
390  }
391  else /* delete case */
392  {
393  if (found == 0)
394  {
395  rv = VNET_API_ERROR_NO_SUCH_ENTRY;
396  goto reply;
397  }
398 
399  /* find the device entry */
400  dp = pool_elt_at_index (mm->devices, kv.value);
401 
402  /* Remove it from the lookup table */
403  clib_bihash_add_del_8_8 (lut, &kv, 0 /* is_add */ );
404  vec_free (dp->ranges);
405  pool_put (mm->devices, dp);
406  }
407 
408 reply:
409  REPLY_MACRO (VL_API_MACTIME_ADD_DEL_RANGE_REPLY);
410 }
411 
412 #include <mactime/mactime.api.c>
413 static clib_error_t *
415 {
417 
418  mm->vlib_main = vm;
419  mm->vnet_main = vnet_get_main ();
420 
421  /* Ask for a correctly-sized block of API message decode slots */
423 
426  mm->timezone_offset = -5; /* US EST / EDT */
427  return 0;
428 }
429 
430 /* *INDENT-OFF* */
432 {
433  .runs_after = VLIB_INITS("ip_neighbor_init"),
434 };
435 /* *INDENT-ON* */
436 
437 static clib_error_t *
439 {
441 
443  {
444  if (unformat (input, "lookup-table-buckets %u",
446  ;
447  else if (unformat (input, "lookup-table-memory %U",
449  ;
450  else if (unformat (input, "timezone_offset %d", &mm->timezone_offset))
451  ;
452  else
453  {
454  return clib_error_return (0, "unknown input '%U'",
455  format_unformat_error, input);
456  }
457  }
458  return 0;
459 }
460 
462 
463 /* *INDENT-OFF* */
464 VNET_FEATURE_INIT (mactime, static) =
465 {
466  .arc_name = "device-input",
467  .node_name = "mactime",
468  .runs_before = VNET_FEATURES ("ethernet-input"),
469 };
470 /* *INDENT-ON */
471 
472 /* *INDENT-OFF* */
473 VNET_FEATURE_INIT (mactime_tx, static) =
474 {
475  .arc_name = "interface-output",
476  .node_name = "mactime-tx",
477  .runs_before = VNET_FEATURES ("interface-tx"),
478 };
479 /* *INDENT-ON */
480 
481 /* *INDENT-OFF* */
483 {
484  .version = VPP_BUILD_VER,
485  .description = "Time-based MAC Source Address Filter",
486 };
487 /* *INDENT-ON* */
488 
489 u8 *
490 format_bytes_with_width (u8 * s, va_list * va)
491 {
492  uword nbytes = va_arg (*va, u64);
493  int width = va_arg (*va, int);
494  f64 nbytes_f64;
495  u8 *fmt;
496  char *suffix = "";
497 
498  if (width > 0)
499  fmt = format (0, "%%%d.3f%%s%c", width, 0);
500  else
501  fmt = format (0, "%%.3f%%s%c", 0);
502 
503  if (nbytes > (1024ULL * 1024ULL * 1024ULL))
504  {
505  nbytes_f64 = ((f64) nbytes) / (1024.0 * 1024.0 * 1024.0);
506  suffix = "G";
507  }
508  else if (nbytes > (1024ULL * 1024ULL))
509  {
510  nbytes_f64 = ((f64) nbytes) / (1024.0 * 1024.0);
511  suffix = "M";
512  }
513  else if (nbytes > 1024ULL)
514  {
515  nbytes_f64 = ((f64) nbytes) / (1024.0);
516  suffix = "K";
517  }
518  else
519  {
520  nbytes_f64 = (f64) nbytes;
521  suffix = "B";
522  }
523 
524  s = format (s, (char *) fmt, nbytes_f64, suffix);
525  vec_free (fmt);
526  return s;
527 }
528 
529 static walk_rc_t
531 {
532  mactime_main_t *mm = ctx;
533 
534  vec_add1 (mm->arp_cache_copy, ipni);
535 
536  return (WALK_CONTINUE);
537 }
538 
539 static clib_error_t *
541  unformat_input_t * input, vlib_cli_command_t * cmd)
542 {
544  mactime_device_t *dp;
545  u8 *macstring = 0;
546  char *status_string;
547  u32 *pool_indices = 0;
548  int verbose = 0;
549  int current_status = 99;
550  int i, j;
551  f64 now;
552  vlib_counter_t allow, drop;
553  ip_neighbor_t *ipn;
554 
556  /* Walk all ip4 neighbours on all interfaces */
558 
559  now = clib_timebase_now (&mm->timebase);
560 
561  if (PREDICT_FALSE ((now - mm->sunday_midnight) > 86400.0 * 7.0))
563 
564  if (unformat (input, "verbose %d", &verbose))
565  ;
566 
567  if (unformat (input, "verbose"))
568  verbose = 1;
569 
570  if (verbose)
571  vlib_cli_output (vm, "Time now: %U", format_clib_timebase_time, now);
572 
573  /* *INDENT-OFF* */
574  pool_foreach (dp, mm->devices,
575  ({
576  vec_add1 (pool_indices, dp - mm->devices);
577  }));
578  /* *INDENT-ON* */
579 
580  vlib_cli_output (vm, "%-15s %18s %14s %10s %11s %13s",
581  "Device Name", "Addresses", "Status",
582  "AllowPkt", "AllowByte", "DropPkt");
583 
584  for (i = 0; i < vec_len (pool_indices); i++)
585  {
586  dp = pool_elt_at_index (mm->devices, pool_indices[i]);
587 
588  /* Check dynamic ranges */
589  for (j = 0; j < vec_len (dp->ranges); j++)
590  {
591  clib_timebase_range_t *r = dp->ranges + j;
592  f64 start0, end0;
593 
594  start0 = r->start + mm->sunday_midnight;
595  end0 = r->end + mm->sunday_midnight;
596  if (verbose > 1)
597  vlib_cli_output (vm, " Range %d: %U - %U", j,
600 
601  if (now >= start0 && now <= end0)
602  {
604  current_status = 3;
606  current_status = 5;
607  else
608  current_status = 2;
609  if (verbose)
610  {
611  vlib_cli_output (vm, " Time in range %d:", j);
612  vlib_cli_output (vm, " %U - %U",
615  }
616  goto print;
617  }
618  }
619  if (verbose && j)
620  vlib_cli_output (vm, " No range match.");
622  current_status = 0;
624  current_status = 1;
626  current_status = 2;
628  current_status = 3;
630  current_status = 4;
631 
632  print:
633  vec_reset_length (macstring);
634  macstring = format (0, "%U", format_mac_address, dp->mac_address);
635  switch (current_status)
636  {
637  case 0:
638  status_string = "static drop";
639  break;
640  case 1:
641  status_string = "static allow";
642  break;
643  case 2:
644  status_string = "dynamic drop";
645  break;
646  case 3:
647  status_string = "dynamic allow";
648  break;
649  case 4:
650  status_string = "d-quota inact";
651  break;
652  case 5:
653  status_string = "d-quota activ";
654  break;
655  default:
656  status_string = "code bug!";
657  break;
658  }
660  &allow);
661  vlib_get_combined_counter (&mm->drop_counters, dp - mm->devices, &drop);
662  vlib_cli_output (vm, "%-15s %18s %14s %10lld %U %13lld",
663  dp->device_name, macstring, status_string,
664  allow.packets, format_bytes_with_width, allow.bytes,
665  10, drop.packets);
666  if (dp->data_quota > 0)
667  vlib_cli_output (vm, "%-54s %s%U %s%U", " ", "Quota ",
669  "Use ", format_bytes_with_width,
670  dp->data_used_in_range, 8);
671  /* This is really only good for small N... */
672  for (j = 0; j < vec_len (mm->arp_cache_copy); j++)
673  {
674  ipn = ip_neighbor_get (mm->arp_cache_copy[j]);
675  if (!memcmp
676  (dp->mac_address, ipn->ipn_mac.bytes, sizeof (ipn->ipn_mac)))
677  {
678  vlib_cli_output (vm, "%17s%U", " ", format_ip46_address,
680  }
681  }
682  }
683  vec_free (macstring);
684  vec_free (pool_indices);
685 
686  return 0;
687 }
688 
689 /* *INDENT-OFF* */
690 VLIB_CLI_COMMAND (show_mactime_command, static) =
691 {
692  .path = "show mactime",
693  .short_help = "show mactime [verbose]",
694  .function = show_mactime_command_fn,
695 };
696 /* *INDENT-ON* */
697 
698 static clib_error_t *
700  unformat_input_t * input, vlib_cli_command_t * cmd)
701 {
703 
704  if (mm->feature_initialized == 0)
705  return clib_error_return (0, "feature not enabled");
706 
709  vlib_cli_output (vm, "Mactime counters cleared...");
710  return 0;
711 }
712 
713 /* *INDENT-OFF* */
714 VLIB_CLI_COMMAND (clear_mactime_command, static) =
715 {
716  .path = "clear mactime",
717  .short_help = "clear mactime counters",
718  .function = clear_mactime_command_fn,
719 };
720 /* *INDENT-ON* */
721 
722 
723 
724 /*
725  * fd.io coding-style-patch-verification: ON
726  *
727  * Local Variables:
728  * eval: (c-set-style "gnu")
729  * End:
730  */
#define MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA
configure per src-mac time ranges
Definition: mactime.api:78
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:273
vlib_combined_counter_main_t drop_counters
Definition: mactime.h:63
u64 data_quota
max bytes this device
Definition: mactime.api:87
static walk_rc_t mactime_ip_neighbor_copy(index_t ipni, void *ctx)
Definition: mactime.c:530
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:94
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:194
string device_name[64]
device name
Definition: mactime.api:89
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
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:65
u16 msg_id_base
Definition: mactime.h:46
static clib_error_t * clear_mactime_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: mactime.c:699
unsigned long u64
Definition: types.h:89
const ip46_address_t * ip_neighbor_get_ip(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:109
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
#define REPLY_MACRO2(t, body)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
clib_timebase_t timebase
Definition: mactime.h:49
dump mactime table
Definition: mactime.api:115
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
#define MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#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_types.h:26
mactime table entry details
Definition: mactime.api:125
int i
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
static void vl_api_mactime_dump_t_handler(vl_api_mactime_dump_t *mp)
Definition: mactime.c:172
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
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:237
unsigned char u8
Definition: types.h:56
#define MACTIME_DEVICE_FLAG_DROP_UDP_10001
#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:540
u32 count
number of time ranges to follow
Definition: mactime.api:90
enum walk_rc_t_ walk_rc_t
Walk return code.
clib_timebase_range_t * ranges
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:61
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
#define MACTIME_MEMORY_SIZE
Definition: mactime.h:84
static f64 clib_timebase_now(clib_timebase_t *tb)
Definition: time_range.h:92
A representation of an IP neighbour/peer.
#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:288
vlib_main_t * vlib_main
Definition: mactime.h:77
unsigned int u32
Definition: types.h:88
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
format_function_t format_clib_timebase_time
Definition: time_range.h:74
#define MACTIME_DEVICE_FLAG_STATIC_ALLOW
vl_api_interface_index_t sw_if_index
the interface handle
Definition: mactime.api:33
VLIB_PLUGIN_REGISTER()
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
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:285
mactime_main_t mactime_main
Definition: mactime.c:38
counter_t packets
packet counter
Definition: counter_types.h:28
vlib_combined_counter_main_t allow_counters
Definition: mactime.h:62
u64 key
the key
Definition: bihash_8_8.h:35
u32 client_index
client index, from api_main
Definition: mactime.api:117
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
u32 lookup_table_num_buckets
Definition: mactime.h:66
u32 my_table_epoch
to suppress dump if no changes
Definition: mactime.api:119
#define MACTIME_DEVICE_FLAG_DYNAMIC_DROP
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
#define PREDICT_FALSE(x)
Definition: clib.h:111
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:182
#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:98
uword lookup_table_memory_size
Definition: mactime.h:67
mac_address_t ipn_mac
The learned MAC address of the neighbour.
vlib_main_t * vm
Definition: in2out_ed.c:1810
static clib_error_t * mactime_config(vlib_main_t *vm, unformat_input_t *input)
Definition: mactime.c:438
api to enable or disable the time-based src mac filter on an interface
Definition: mactime.api:28
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:225
static clib_error_t * mactime_init(vlib_main_t *vm)
Definition: mactime.c:414
format_function_t format_ip46_address
Definition: ip46_address.h:50
An API client registration, only in vpp/vlib.
Definition: api_common.h:46
u64 value
the value
Definition: bihash_8_8.h:36
#define BAD_SW_IF_INDEX_LABEL
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
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:259
dump mactime table reply Includes the vpp table epoch, needed to optimize API traffic ...
Definition: mactime.api:141
f64 sunday_midnight
Definition: mactime.h:52
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
void ip_neighbor_walk(ip46_type_t type, u32 sw_if_index, ip_neighbor_walk_cb_t cb, void *ctx)
Definition: ip_neighbor.c:992
f64 clib_timebase_find_sunday_midnight(f64 start_time)
Definition: time_range.c:213
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:284
8 octet key, 8 octet key value pair
Definition: bihash_8_8.h:33
#define ARRAY_LEN(x)
Definition: clib.h:62
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:57
void mactime_url_init(vlib_main_t *vm)
Definition: builtins.c:160
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
string name[64]
Definition: ip.api:44
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
mactime_device_t * devices
Definition: mactime.h:58
bool enable_disable
enable=1, disable=0
Definition: mactime.api:32
#define MACTIME_DEVICE_FLAG_STATIC_DROP
Always drop packets from this device.
clib_bihash_8_8_t lookup_table
Definition: mactime.h:55
vl_api_time_range_t ranges[count]
time ranges, in seconds since Sunday began
Definition: mactime.api:92
static void feature_init(mactime_main_t *mm)
Definition: mactime.c:44
#define VNET_FEATURES(...)
Definition: feature.h:442
void mactime_send_create_entry_message(u8 *mac_address)
Create a lookup table entry for the indicated mac address.
Definition: mactime.c:246
counter_t bytes
byte counter
Definition: counter_types.h:29
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:157
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u64 uword
Definition: types.h:112
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:854
vl_api_mac_address_t mac_address
src mac address
Definition: mactime.api:88
char * name
The counter collection&#39;s name.
Definition: counter.h:193
int feature_initialized
Definition: mactime.h:71
u8 * format_bytes_with_width(u8 *s, va_list *va)
Definition: mactime.c:490
u8 * format_mac_address(u8 *s, va_list *args)
Definition: format.c:58
index_t * arp_cache_copy
Definition: mactime.h:74
unformat_function_t unformat_memory_size
Definition: format.h:296
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:378
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vnet_sw_interface_type_t type
Definition: interface.h:718
vnet_main_t * vnet_main
Definition: mactime.h:78
ip_neighbor_t * ip_neighbor_get(index_t ipni)
Definition: ip_neighbor.c:88
static void setup_message_id_table(snat_main_t *sm, api_main_t *am)
Definition: nat_api.c:3410
void * vl_msg_api_alloc_as_if_client(int nbytes)
bool is_add
add=1, del=0
Definition: mactime.api:82
manual_print typedef u8 mac_address[6]
#define MACTIME_NUM_BUCKETS
Definition: mactime.h:83
bool no_udp_10001
drop udp to port 10001
Definition: mactime.api:86
u32 device_table_epoch
Definition: mactime.h:59
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
#define VLIB_INITS(...)
Definition: init.h:344
u8 allow_quota
allow subject to quota
Definition: mactime.api:85
i32 timezone_offset
Definition: mactime.h:68
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
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:304
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
#define VALIDATE_SW_IF_INDEX(mp)