ip: Protocol Independent IP Neighbors
[vpp.git] / src / plugins / mactime / builtins.c
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
8 static walk_rc_t
9 mactime_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
18 static int
19 handle_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
159 void
160 mactime_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  */