builtins.c revision cbe25aab
1#include <vnet/vnet.h>
2#include <builtinurl/builtinurl.h>
3#include <http_static/http_static.h>
4#include <mactime/mactime.h>
5#include <vlib/unix/plugin.h>
6#include <vnet/ip-neighbor/ip_neighbor.h>
7
8static walk_rc_t
9mactime_ip_neighbor_copy (index_t ipni, void *ctx)
10{
11  mactime_main_t *mm = ctx;
12
13  vec_add1 (mm->arp_cache_copy, ipni);
14
15  return (WALK_CONTINUE);
16}
17
18static int
19handle_get_mactime (http_builtin_method_type_t reqtype,
20		    u8 * request, http_session_t * hs)
21{
22  mactime_main_t *mm = &mactime_main;
23  mactime_device_t *dp;
24  u8 *macstring = 0;
25  char *status_string;
26  u32 *pool_indices = 0;
27  int current_status = 99;
28  int i, j;
29  f64 now;
30  vlib_counter_t allow, drop;
31  ip_neighbor_t *n;
32  char *q = "\"";
33  u8 *s = 0;
34  int need_comma = 0;
35
36  /* Walk all ip4 neighbours on all interfaces */
37  vec_reset_length (mm->arp_cache_copy);
38  ip_neighbor_walk (IP46_TYPE_IP4, ~0, mactime_ip_neighbor_copy, mm);
39
40  now = clib_timebase_now (&mm->timebase);
41
42  if (PREDICT_FALSE ((now - mm->sunday_midnight) > 86400.0 * 7.0))
43    mm->sunday_midnight = clib_timebase_find_sunday_midnight (now);
44
45    /* *INDENT-OFF* */
46    pool_foreach (dp, mm->devices,
47    ({
48        vec_add1 (pool_indices, dp - mm->devices);
49    }));
50    /* *INDENT-ON* */
51
52  s = format (s, "{%smactime%s: [\n", q, q);
53
54  for (i = 0; i < vec_len (pool_indices); i++)
55    {
56      dp = pool_elt_at_index (mm->devices, pool_indices[i]);
57
58      /* Check dynamic ranges */
59      for (j = 0; j < vec_len (dp->ranges); j++)
60	{
61	  clib_timebase_range_t *r = dp->ranges + j;
62	  f64 start0, end0;
63
64	  start0 = r->start + mm->sunday_midnight;
65	  end0 = r->end + mm->sunday_midnight;
66
67	  if (now >= start0 && now <= end0)
68	    {
69	      if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW)
70		current_status = 3;
71	      else if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA)
72		current_status = 5;
73	      else
74		current_status = 2;
75	      goto print;
76	    }
77	}
78      if (dp->flags & MACTIME_DEVICE_FLAG_STATIC_DROP)
79	current_status = 0;
80      if (dp->flags & MACTIME_DEVICE_FLAG_STATIC_ALLOW)
81	current_status = 1;
82      if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW)
83	current_status = 2;
84      if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_DROP)
85	current_status = 3;
86      if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA)
87	current_status = 4;
88
89    print:
90      vec_reset_length (macstring);
91
92      macstring = format (0, "%U", format_mac_address, dp->mac_address);
93
94      if (need_comma)
95	s = format (s, "},\n");
96
97      need_comma = 1;
98      s = format (s, "{%smac_address%s: %s%s%s, ", q, q, q, macstring, q);
99
100      switch (current_status)
101	{
102	case 0:
103	  status_string = "static drop";
104	  break;
105	case 1:
106	  status_string = "static allow";
107	  break;
108	case 2:
109	  status_string = "dynamic drop";
110	  break;
111	case 3:
112	  status_string = "dynamic allow";
113	  break;
114	case 4:
115	  status_string = "d-quota inact";
116	  break;
117	case 5:
118	  status_string = "d-quota activ";
119	  break;
120	default:
121	  status_string = "code bug!";
122	  break;
123	}
124      vlib_get_combined_counter (&mm->allow_counters, dp - mm->devices,
125				 &allow);
126      vlib_get_combined_counter (&mm->drop_counters, dp - mm->devices, &drop);
127      s = format (s, "%sname%s: %s%s%s, %sstatus%s: %s%s%s,",
128		  q, q, q, dp->device_name, q, q, q, q, status_string, q);
129      s = format (s, "%sallow_pkts%s: %lld,", q, q, allow.packets);
130      s = format (s, "%sallow_bytes%s: %lld,", q, q, allow.bytes);
131      s = format (s, "%sdrop_pkts%s: %lld", q, q, drop.packets);
132
133      for (j = 0; j < vec_len (mm->arp_cache_copy); j++)
134	{
135	  n = ip_neighbor_get (mm->arp_cache_copy[j]);
136	  if (!memcmp (dp->mac_address,
137		       ip_neighbor_get_mac (n), sizeof (mac_address_t)))
138	    {
139	      s = format (s, ", %sip4_address%s: %s%U%s", q, q,
140			  q, format_ip46_address,
141			  ip_neighbor_get_ip (n), IP46_TYPE_IP4, q);
142	      break;
143	    }
144	}
145    }
146  if (need_comma)
147    s = format (s, "}\n");
148  s = format (s, "]}\n");
149  vec_free (macstring);
150  vec_free (pool_indices);
151
152  hs->data = s;
153  hs->data_offset = 0;
154  hs->cache_pool_index = ~0;
155  hs->free_data = 1;
156  return 0;
157}
158
159void
160mactime_url_init (vlib_main_t * vm)
161{
162  void (*fp) (void *, char *, int);
163
164  /* Look up the builtin URL registration handler */
165  fp = vlib_get_plugin_symbol ("http_static_plugin.so",
166			       "http_static_server_register_builtin_handler");
167
168  if (fp == 0)
169    {
170      clib_warning ("http_static_plugin.so not loaded...");
171      return;
172    }
173
174  (*fp) (handle_get_mactime, "mactime.json", HTTP_BUILTIN_METHOD_GET);
175}
176
177/*
178 * fd.io coding-style-patch-verification: ON
179 *
180 * Local Variables:
181 * eval: (c-set-style "gnu")
182 * End:
183 */
184