FD.io VPP  v20.09-64-g4f7b92f0a
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 mactime.c
41  * time-base src-mac filter device-input feature arc implementation
42  */
43 
44 static void
46 {
47  if (mm->feature_initialized == 0)
48  {
49  /* Create the lookup table */
50  clib_bihash_init_8_8 (&mm->lookup_table, "mactime lookup table",
55  &(mm->vlib_main->clib_time));
56  mm->allow_counters.name = "allow";
57  mm->allow_counters.stat_segment_name = "/mactime/allow";
58  mm->drop_counters.name = "drop";
59  mm->drop_counters.stat_segment_name = "/mactime/drop";
60  mm->feature_initialized = 1;
61  }
62 }
63 
64 /** Action function shared between message handler and debug CLI
65 */
66 int
68  int enable_disable)
69 {
71  int rv = 0;
72  static u8 url_init_done;
73 
74  feature_init (mm);
75 
76  /* Utterly wrong? */
78  sw_if_index))
79  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
80 
81  /* Not a physical port? */
82  sw = vnet_get_sw_interface (mm->vnet_main, sw_if_index);
84  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
85 
86  vnet_feature_enable_disable ("device-input", "mactime",
87  sw_if_index, enable_disable, 0, 0);
88  vnet_feature_enable_disable ("interface-output", "mactime-tx",
89  sw_if_index, enable_disable, 0, 0);
90  if (url_init_done == 0)
91  {
93  url_init_done = 1;
94  }
95 
96  return rv;
97 }
98 
99 static clib_error_t *
101  unformat_input_t * input,
102  vlib_cli_command_t * cmd)
103 {
105  u32 sw_if_index = ~0;
106  int enable_disable = 1;
107 
108  int rv;
109 
111  {
112  if (unformat (input, "disable"))
113  enable_disable = 0;
114  else if (unformat (input, "%U", unformat_vnet_sw_interface,
115  mm->vnet_main, &sw_if_index))
116  ;
117  else if (unformat (input, "sw_if_index %d", &sw_if_index))
118  ;
119  else
120  break;
121  }
122 
123  if (sw_if_index == ~0)
124  return clib_error_return (0, "Please specify an interface...");
125 
126  rv = mactime_enable_disable (mm, sw_if_index, enable_disable);
127 
128  switch (rv)
129  {
130  case 0:
131  break;
132 
133  case VNET_API_ERROR_INVALID_SW_IF_INDEX:
134  return clib_error_return
135  (0, "Invalid interface, only works on physical ports");
136  break;
137 
138  default:
139  return clib_error_return (0, "mactime_enable_disable returned %d", rv);
140  }
141  return 0;
142 }
143 
144 /* *INDENT-OFF* */
145 VLIB_CLI_COMMAND (mactime_enable_disable_command, static) =
146 {
147  .path = "mactime enable-disable",
148  .short_help =
149  "mactime enable-disable <interface-name> [disable]",
151 };
152 /* *INDENT-ON* */
153 
154 
155 /** Enable / disable time-base src mac filtration on an interface
156  */
157 
160 {
161  vl_api_mactime_enable_disable_reply_t *rmp;
163  int rv;
164 
166 
167  rv = mactime_enable_disable (mm, ntohl (mp->sw_if_index),
168  (int) (mp->enable_disable));
170  REPLY_MACRO (VL_API_MACTIME_ENABLE_DISABLE_REPLY);
171 }
172 
173 static void
175 {
178  mactime_device_t *dev;
181  int rv = 0, i;
182  u32 his_table_epoch = clib_net_to_host_u32 (mp->my_table_epoch);
183  u32 message_size;
184  u32 name_len;
185  u32 nranges;
186 
188  if (rp == 0)
189  return;
190 
191  if (his_table_epoch == mm->device_table_epoch)
192  {
193  rv = VNET_API_ERROR_NO_CHANGE;
194  goto send_reply;
195  }
196 
197  /* *INDENT-OFF* */
198  pool_foreach (dev, mm->devices,
199  ({
200  message_size = sizeof(*ep) + vec_len(dev->device_name) +
201  vec_len(dev->ranges) * sizeof(ep->ranges[0]);
202 
203  ep = vl_msg_api_alloc (message_size);
204  memset (ep, 0, message_size);
205  ep->_vl_msg_id = clib_host_to_net_u16 (VL_API_MACTIME_DETAILS
206  + mm->msg_id_base);
207  ep->context = mp->context;
208  /* Index is the key for the stats segment combined counters */
209  ep->pool_index = clib_host_to_net_u32 (dev - mm->devices);
210 
211  clib_memcpy_fast (ep->mac_address, dev->mac_address,
212  sizeof (ep->mac_address));
213  ep->data_quota = clib_host_to_net_u64 (dev->data_quota);
214  ep->data_used_in_range = clib_host_to_net_u64 (dev->data_used_in_range);
215  ep->flags = clib_host_to_net_u32 (dev->flags);
216  nranges = vec_len (dev->ranges);
217  ep->nranges = clib_host_to_net_u32 (nranges);
218 
219  for (i = 0; i < vec_len (dev->ranges); i++)
220  {
221  ep->ranges[i].start = dev->ranges[i].start;
222  ep->ranges[i].end = dev->ranges[i].end;
223  }
224 
225  name_len = vec_len (dev->device_name);
226  name_len = (name_len < ARRAY_LEN(ep->device_name)) ?
227  name_len : ARRAY_LEN(ep->device_name) - 1;
228 
230  name_len);
231  ep->device_name [ARRAY_LEN(ep->device_name) -1] = 0;
232  vl_api_send_msg (rp, (u8 *)ep);
233  }));
234  /* *INDENT-OFF* */
235 
236  send_reply:
237  /* *INDENT-OFF* */
238  REPLY_MACRO2 (VL_API_MACTIME_DUMP_REPLY,
239  ({
240  rmp->table_epoch = clib_host_to_net_u32 (mm->device_table_epoch);
241  }));
242  /* *INDENT-ON* */
243 }
244 
245 /** Create a lookup table entry for the indicated mac address
246  */
247 void
249 {
251  api_main_t *am;
252  vl_shmem_hdr_t *shmem_hdr;
253  u8 *name;
255 
256  am = vlibapi_get_main ();
257  shmem_hdr = am->shmem_hdr;
258  mp = vl_msg_api_alloc_as_if_client (sizeof (*mp));
259  clib_memset (mp, 0, sizeof (*mp));
260  mp->_vl_msg_id = ntohs (VL_API_MACTIME_ADD_DEL_RANGE + mm->msg_id_base);
261  name = format (0, "mac-%U", format_mac_address, mac_address);
262 
263  memcpy (mp->device_name, name, vec_len (name));
264  memcpy (mp->mac_address, mac_address, sizeof (mp->mac_address));
265  /* $$$ config: create allow / drop / range */
266  mp->allow = 1;
267  mp->is_add = 1;
268  vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *) & mp);
269 }
270 
271 /** Add or delete static / dynamic accept/drop configuration for a src mac
272  */
273 
276 {
278  vl_api_mactime_add_del_range_reply_t *rmp;
279  mactime_device_t *dp;
281  int found = 1;
282  clib_bihash_8_8_t *lut = &mm->lookup_table;
283  u64 data_quota;
284  int i, rv = 0;
285 
286  feature_init (mm);
287 
288  /*
289  * Change the table epoch. Skip 0 so clients can code my_table_epoch = 0
290  * to receive a full dump.
291  */
292  mm->device_table_epoch++;
293  if (PREDICT_FALSE (mm->device_table_epoch == 0))
294  mm->device_table_epoch++;
295 
296  data_quota = clib_net_to_host_u64 (mp->data_quota);
297 
298  clib_memset (&kv, 0, sizeof (kv));
299  memcpy (&kv.key, mp->mac_address, sizeof (mp->mac_address));
300 
301  /* See if we have a lookup table entry for this src mac address */
302  if (clib_bihash_search_8_8 (lut, &kv, &kv) < 0)
303  found = 0;
304 
305  /* Add an entry? */
306  if (mp->is_add)
307  {
308  /* Create the device entry? */
309  if (found == 0)
310  {
311  pool_get (mm->devices, dp);
312  clib_memset (dp, 0, sizeof (*dp));
314  dp - mm->devices);
317  dp - mm->devices);
319  mp->device_name[ARRAY_LEN (mp->device_name) - 1] = 0;
320  dp->device_name = format (0, "%s%c", mp->device_name, 0);
321  memcpy (dp->mac_address, mp->mac_address, sizeof (mp->mac_address));
322  for (i = 0; i < clib_net_to_host_u32 (mp->count); i++)
323  {
324  clib_timebase_range_t _r, *r = &_r;
325  r->start = mp->ranges[i].start;
326  r->end = mp->ranges[i].end;
327  vec_add1 (dp->ranges, r[0]);
328  }
329  /* If we found some time ranges */
330  if (i)
331  {
332  /* Set allow/drop based on msg flags */
333  if (mp->drop)
335  if (mp->allow)
337  if (mp->allow_quota)
339  }
340  else
341  {
342  /* no ranges, it's a static allow/drop */
343  if (mp->drop)
345  if (mp->allow)
347  }
348  if (mp->no_udp_10001)
350 
351  dp->data_quota = data_quota;
352 
353  /* Add the hash table entry */
354  kv.value = dp - mm->devices;
355  clib_bihash_add_del_8_8 (lut, &kv, 1 /* is_add */ );
356  }
357  else /* add more ranges, flags, etc. */
358  {
359  dp = pool_elt_at_index (mm->devices, kv.value);
360 
361  for (i = 0; i < clib_net_to_host_u32 (mp->count); i++)
362  {
363  clib_timebase_range_t _r, *r = &_r;
364  r->start = mp->ranges[i].start;
365  r->end = mp->ranges[i].end;
366  vec_add1 (dp->ranges, r[0]);
367  }
368 
369  if (vec_len (dp->ranges))
370  {
371  /* Set allow/drop based on msg flags */
372  if (mp->drop)
374  if (mp->allow)
376  if (mp->allow_quota)
378  }
379  else
380  {
381  /* no ranges, it's a static allow/drop */
382  if (mp->drop)
384  if (mp->allow)
386  }
387  if (mp->no_udp_10001)
389 
390  dp->data_quota = data_quota;
391  }
392  }
393  else /* delete case */
394  {
395  if (found == 0)
396  {
397  rv = VNET_API_ERROR_NO_SUCH_ENTRY;
398  goto reply;
399  }
400 
401  /* find the device entry */
402  dp = pool_elt_at_index (mm->devices, kv.value);
403 
404  /* Remove it from the lookup table */
405  clib_bihash_add_del_8_8 (lut, &kv, 0 /* is_add */ );
406  vec_free (dp->ranges);
407  pool_put (mm->devices, dp);
408  }
409 
410 reply:
411  REPLY_MACRO (VL_API_MACTIME_ADD_DEL_RANGE_REPLY);
412 }
413 
414 #include <mactime/mactime.api.c>
415 static clib_error_t *
417 {
419 
420  mm->vlib_main = vm;
421  mm->vnet_main = vnet_get_main ();
422 
423  /* Ask for a correctly-sized block of API message decode slots */
425 
428  mm->timezone_offset = -5; /* US EST / EDT */
429  return 0;
430 }
431 
432 /* *INDENT-OFF* */
434 {
435  .runs_after = VLIB_INITS("ip_neighbor_init"),
436 };
437 /* *INDENT-ON* */
438 
439 static clib_error_t *
441 {
443 
445  {
446  if (unformat (input, "lookup-table-buckets %u",
448  ;
449  else if (unformat (input, "lookup-table-memory %U",
451  ;
452  else if (unformat (input, "timezone_offset %d", &mm->timezone_offset))
453  ;
454  else
455  {
456  return clib_error_return (0, "unknown input '%U'",
457  format_unformat_error, input);
458  }
459  }
460  return 0;
461 }
462 
464 
465 /* *INDENT-OFF* */
466 VNET_FEATURE_INIT (mactime, static) =
467 {
468  .arc_name = "device-input",
469  .node_name = "mactime",
470  .runs_before = VNET_FEATURES ("ethernet-input"),
471 };
472 /* *INDENT-ON */
473 
474 /* *INDENT-OFF* */
475 VNET_FEATURE_INIT (mactime_tx, static) =
476 {
477  .arc_name = "interface-output",
478  .node_name = "mactime-tx",
479  .runs_before = VNET_FEATURES ("interface-tx"),
480 };
481 /* *INDENT-ON */
482 
483 /* *INDENT-OFF* */
485 {
486  .version = VPP_BUILD_VER,
487  .description = "Time-based MAC Source Address Filter",
488 };
489 /* *INDENT-ON* */
490 
491 u8 *
492 format_bytes_with_width (u8 * s, va_list * va)
493 {
494  uword nbytes = va_arg (*va, u64);
495  int width = va_arg (*va, int);
496  f64 nbytes_f64;
497  u8 *fmt;
498  char *suffix = "";
499 
500  if (width > 0)
501  fmt = format (0, "%%%d.3f%%s%c", width, 0);
502  else
503  fmt = format (0, "%%.3f%%s%c", 0);
504 
505  if (nbytes > (1024ULL * 1024ULL * 1024ULL))
506  {
507  nbytes_f64 = ((f64) nbytes) / (1024.0 * 1024.0 * 1024.0);
508  suffix = "G";
509  }
510  else if (nbytes > (1024ULL * 1024ULL))
511  {
512  nbytes_f64 = ((f64) nbytes) / (1024.0 * 1024.0);
513  suffix = "M";
514  }
515  else if (nbytes > 1024ULL)
516  {
517  nbytes_f64 = ((f64) nbytes) / (1024.0);
518  suffix = "K";
519  }
520  else
521  {
522  nbytes_f64 = (f64) nbytes;
523  suffix = "B";
524  }
525 
526  s = format (s, (char *) fmt, nbytes_f64, suffix);
527  vec_free (fmt);
528  return s;
529 }
530 
531 static walk_rc_t
533 {
534  mactime_main_t *mm = ctx;
535 
536  vec_add1 (mm->arp_cache_copy, ipni);
537 
538  return (WALK_CONTINUE);
539 }
540 
541 static clib_error_t *
543  unformat_input_t * input, vlib_cli_command_t * cmd)
544 {
546  mactime_device_t *dp;
547  u8 *macstring = 0;
548  char *status_string;
549  u32 *pool_indices = 0;
550  int verbose = 0;
551  int current_status = 99;
552  int i, j;
553  f64 now;
554  vlib_counter_t allow, drop;
555  ip_neighbor_t *ipn;
556 
557  if (mm->feature_initialized == 0)
558  return clib_error_return
559  (0,
560  "Feature not initialized, suggest 'help mactime enable-disable'...");
561 
563  /* Walk all ip4 neighbours on all interfaces */
565 
566  now = clib_timebase_now (&mm->timebase);
567 
568  if (PREDICT_FALSE ((now - mm->sunday_midnight) > 86400.0 * 7.0))
570 
571  if (unformat (input, "verbose %d", &verbose))
572  ;
573 
574  if (unformat (input, "verbose"))
575  verbose = 1;
576 
577  if (verbose)
578  vlib_cli_output (vm, "Time now: %U", format_clib_timebase_time, now);
579 
580  /* *INDENT-OFF* */
581  pool_foreach (dp, mm->devices,
582  ({
583  vec_add1 (pool_indices, dp - mm->devices);
584  }));
585  /* *INDENT-ON* */
586 
587  vlib_cli_output (vm, "%-15s %18s %14s %10s %11s %13s",
588  "Device Name", "Addresses", "Status",
589  "AllowPkt", "AllowByte", "DropPkt");
590 
591  for (i = 0; i < vec_len (pool_indices); i++)
592  {
593  dp = pool_elt_at_index (mm->devices, pool_indices[i]);
594 
595  /* Check dynamic ranges */
596  for (j = 0; j < vec_len (dp->ranges); j++)
597  {
598  clib_timebase_range_t *r = dp->ranges + j;
599  f64 start0, end0;
600 
601  start0 = r->start + mm->sunday_midnight;
602  end0 = r->end + mm->sunday_midnight;
603  if (verbose > 1)
604  vlib_cli_output (vm, " Range %d: %U - %U", j,
607 
608  if (now >= start0 && now <= end0)
609  {
611  current_status = 3;
613  current_status = 5;
614  else
615  current_status = 2;
616  if (verbose)
617  {
618  vlib_cli_output (vm, " Time in range %d:", j);
619  vlib_cli_output (vm, " %U - %U",
622  }
623  goto print;
624  }
625  }
626  if (verbose && j)
627  vlib_cli_output (vm, " No range match.");
629  current_status = 0;
631  current_status = 1;
633  current_status = 2;
635  current_status = 3;
637  current_status = 4;
638 
639  print:
640  vec_reset_length (macstring);
641  macstring = format (0, "%U", format_mac_address, dp->mac_address);
642  switch (current_status)
643  {
644  case 0:
645  status_string = "static drop";
646  break;
647  case 1:
648  status_string = "static allow";
649  break;
650  case 2:
651  status_string = "dynamic drop";
652  break;
653  case 3:
654  status_string = "dynamic allow";
655  break;
656  case 4:
657  status_string = "d-quota inact";
658  break;
659  case 5:
660  status_string = "d-quota activ";
661  break;
662  default:
663  status_string = "code bug!";
664  break;
665  }
667  &allow);
668  vlib_get_combined_counter (&mm->drop_counters, dp - mm->devices, &drop);
669  vlib_cli_output (vm, "%-15s %18s %14s %10lld %U %13lld",
670  dp->device_name, macstring, status_string,
671  allow.packets, format_bytes_with_width, allow.bytes,
672  10, drop.packets);
673  if (dp->data_quota > 0)
674  vlib_cli_output (vm, "%-54s %s%U %s%U", " ", "Quota ",
676  "Use ", format_bytes_with_width,
677  dp->data_used_in_range, 8);
678  /* This is really only good for small N... */
679  for (j = 0; j < vec_len (mm->arp_cache_copy); j++)
680  {
681  ipn = ip_neighbor_get (mm->arp_cache_copy[j]);
682  if (!memcmp
683  (dp->mac_address, ipn->ipn_mac.bytes, sizeof (ipn->ipn_mac)))
684  {
685  vlib_cli_output (vm, "%17s%U", " ", format_ip46_address,
687  }
688  }
689  }
690  vec_free (macstring);
691  vec_free (pool_indices);
692 
693  return 0;
694 }
695 
696 /* *INDENT-OFF* */
697 VLIB_CLI_COMMAND (show_mactime_command, static) =
698 {
699  .path = "show mactime",
700  .short_help = "show mactime [verbose]",
701  .function = show_mactime_command_fn,
702 };
703 /* *INDENT-ON* */
704 
705 static clib_error_t *
707  unformat_input_t * input, vlib_cli_command_t * cmd)
708 {
710 
711  if (mm->feature_initialized == 0)
712  return clib_error_return
713  (0,
714  "Feature not initialized, suggest 'help mactime enable-disable'...");
715 
718  vlib_cli_output (vm, "Mactime counters cleared...");
719  return 0;
720 }
721 
722 /* *INDENT-OFF* */
723 VLIB_CLI_COMMAND (clear_mactime_command, static) =
724 {
725  .path = "clear mactime",
726  .short_help = "clear mactime counters",
727  .function = clear_mactime_command_fn,
728 };
729 /* *INDENT-ON* */
730 
731 
732 
733 /*
734  * fd.io coding-style-patch-verification: ON
735  *
736  * Local Variables:
737  * eval: (c-set-style "gnu")
738  * End:
739  */
#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:275
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:532
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:108
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:194
#define ntohs(x)
Definition: af_xdp.bpf.c:29
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:59
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:67
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:706
unsigned long u64
Definition: types.h:89
const ip46_address_t * ip_neighbor_get_ip(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:115
#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:592
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
mactime table entry details
Definition: mactime.api:125
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
vlib_main_t * vm
Definition: in2out_ed.c:1582
static void vl_api_mactime_dump_t_handler(vl_api_mactime_dump_t *mp)
Definition: mactime.c:174
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unformat_function_t unformat_vnet_sw_interface
clib_time_t clib_time
Definition: main.h:124
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
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:542
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:513
#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:88
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:293
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:70
#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:534
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:41
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:302
#define PREDICT_FALSE(x)
Definition: clib.h:120
#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:100
uword lookup_table_memory_size
Definition: mactime.h:67
mac_address_t ipn_mac
The learned MAC address of the neighbour.
static clib_error_t * mactime_config(vlib_main_t *vm, unformat_input_t *input)
Definition: mactime.c:440
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:227
static clib_error_t * mactime_init(vlib_main_t *vm)
Definition: mactime.c:416
format_function_t format_ip46_address
Definition: ip46_address.h:50
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
u64 value
the value
Definition: bihash_8_8.h:42
#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
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
f64 sunday_midnight
Definition: mactime.h:52
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
void ip_neighbor_walk(ip46_type_t type, u32 sw_if_index, ip_neighbor_walk_cb_t cb, void *ctx)
Definition: ip_neighbor.c:1040
f64 clib_timebase_find_sunday_midnight(f64 start_time)
Definition: time_range.c:221
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:299
8 octet key, 8 octet key value pair
Definition: bihash_8_8.h:39
#define ARRAY_LEN(x)
Definition: clib.h:67
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:79
void mactime_url_init(vlib_main_t *vm)
Definition: builtins.c:160
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:158
mactime_device_t * devices
Definition: mactime.h:58
bool enable_disable
enable=1, disable=0
Definition: mactime.api:32
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
void clib_timebase_init(clib_timebase_t *tb, i32 timezone_offset_in_hours, clib_timebase_daylight_time_t daylight_type, clib_time_t *clib_time)
Definition: time_range.c:19
#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:45
#define VNET_FEATURES(...)
Definition: feature.h:470
void mactime_send_create_entry_message(u8 *mac_address)
Create a lookup table entry for the indicated mac address.
Definition: mactime.c:248
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:159
#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:872
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:492
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:389
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vnet_sw_interface_type_t type
Definition: interface.h:736
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:2804
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
#define VLIB_INITS(...)
Definition: init.h:357
u8 allow_quota
allow subject to quota
Definition: mactime.api:85
i32 timezone_offset
Definition: mactime.h:68
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
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:303
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
#define VALIDATE_SW_IF_INDEX(mp)