FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
graph_api.c
Go to the documentation of this file.
1 /* Hey Emacs use -*- mode: C -*- */
2 /*
3  * Copyright 2020 Rubicon Communications, LLC.
4  *
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 <vlibmemory/api.h>
20 
21 #include <tracedump/graph.api_enum.h>
22 #include <tracedump/graph.api_types.h>
23 
24 #define REPLY_MSG_ID_BASE gmp->msg_id_base
26 
27 #include <tracedump/graph.h>
28 
29 
31 
32 
33 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
34 
35 
36 /*
37  * If ever the graph or set of nodes changes, this cache of
38  * nodes in sorted order should be invalidated.
39  */
40 void
42 {
43  graph_main_t *gmp = &graph_main;
44 
46 }
47 
48 
49 static clib_error_t *
51 {
53  return 0;
54 }
55 
57 
58 
59 static void
61  u32 context, u32 retval, u32 cursor)
62 {
63  graph_main_t *gmp = &graph_main;
65 
66  rmp = vl_msg_api_alloc (sizeof (*rmp));
67  rmp->_vl_msg_id = htons (VL_API_GRAPH_NODE_GET_REPLY + gmp->msg_id_base);
68  rmp->context = context;
69  rmp->retval = clib_host_to_net_u32 (retval);
70  rmp->cursor = htonl (cursor);
71 
72  vl_api_send_msg (rp, (u8 *) rmp);
73 }
74 
75 
76 static void
79  u32 context, vlib_node_t * n, bool want_arcs)
80 {
81  graph_main_t *gmp = &graph_main;
83  u32 msg_size;
84 
85  msg_size = sizeof (*mp);
86  if (want_arcs)
87  msg_size += vec_len (n->next_nodes) * sizeof (*n->next_nodes);
88 
89  mp = vl_msg_api_alloc (msg_size);
90  if (!mp)
91  return;
92 
93  clib_memset (mp, 0, msg_size);
94 
95  mp->_vl_msg_id = htons (VL_API_GRAPH_NODE_DETAILS + gmp->msg_id_base);
96  mp->context = context;
97  mp->index = htonl (n->index);
98  mp->flags = htonl (n->flags);
99 
100  clib_strncpy ((char *) mp->name, (char *) n->name,
101  MIN (sizeof (mp->name) - 1, vec_len (n->name)));
102 
103  if (want_arcs)
104  {
105  int i;
106 
107  mp->n_arcs = htonl (vec_len (n->next_nodes));
108  for (i = 0; i < vec_len (n->next_nodes); ++i)
109  {
110  mp->arcs_out[i] = htonl (n->next_nodes[i]);
111  }
112  }
113 
114  vl_api_send_msg (reg, (u8 *) mp);
115 }
116 
117 
118 static int
119 node_cmp (void *a1, void *a2)
120 {
121  vlib_node_t **n1 = a1;
122  vlib_node_t **n2 = a2;
123 
124  return vec_cmp (n1[0]->name, n2[0]->name);
125 }
126 
127 
128 /*
129  * When cursor == ~0, it begins a request:
130  * if index != ~0, dump node with given index
131  * if index == ~0 and name[0] != 0, dump node with given name
132  * if index == ~0 and name[0] == 0, and flag != 0, dump flagged nodes
133  * else
134  * index == ~0 and name[0] == 0 and flag == 0, so dump all nodes.
135  *
136  * When cursor != ~0, it is the middle of a request:
137  * The same (index, name, and flag) parameters are assumed,
138  * The next results resume from cursor.
139  */
140 static void
142 {
144 
146  if (!rp)
147  return;
148 
151  graph_main_t *gmp = &graph_main;
152  vlib_node_t *n;
153  u32 cursor;
154  u32 node_index;
155  bool want_arcs;
156 
157  want_arcs = ! !mp->want_arcs;
158  cursor = ntohl (mp->cursor);
159  n = 0;
160 
161  /*
162  * Return details on a specific node by index?
163  */
164  node_index = ntohl (mp->index);
165  if (cursor == ~0 && node_index != ~0)
166  {
167  if (node_index < vec_len (nm->nodes))
168  n = vlib_get_node (vm, node_index);
169  if (!n)
170  {
172  VNET_API_ERROR_NO_SUCH_ENTRY, ~0);
173  return;
174  }
175  send_graph_node_details (nm, rp, mp->context, n, want_arcs);
176  send_graph_node_reply (rp, mp->context, 0, ~0);
177  return;
178  }
179 
180  /*
181  * Return details on a specific node by name?
182  */
183  if (cursor == ~0 && mp->name[0] != 0)
184  {
185  n = vlib_get_node_by_name (vm, (u8 *) mp->name);
186  if (!n)
187  {
189  VNET_API_ERROR_NO_SUCH_ENTRY, ~0);
190  return;
191  }
192 
193  send_graph_node_details (nm, rp, mp->context, n, want_arcs);
194  send_graph_node_reply (rp, mp->context, 0, ~0);
195  return;
196  }
197 
198  /*
199  * Inspect all nodes, but potentially limit them by flag selection.
200  * As iteration my need to occur over multiple streaming API calls,
201  * determine the API client index and cache a sorted list of nodes.
202  *
203  * First time through, make a sorted node list and cache it.
204  */
205  vlib_node_t **nodes = gmp->sorted_node_vec;
206  if (!nodes)
207  {
208  nodes = vec_dup (nm->nodes);
210  gmp->sorted_node_vec = nodes;
211  }
212 
213  u32 flags = ntohl (mp->flags);
214  u32 first_index = (cursor == ~0) ? 0 : cursor;
215 
216  /* Don't overflow the existing queue space. */
217  svm_queue_t *q = rp->vl_input_queue;
218  u32 queue_slots_available = q->maxsize - q->cursize;
219  int chunk = (queue_slots_available > 0) ? queue_slots_available - 1 : 0;
220  u32 i;
221 
222  for (i = first_index; i < vec_len (nodes); ++i)
223  {
224  if (chunk-- == 0)
225  {
226  /*
227  * Pick up again at cursor = i.
228  */
229  send_graph_node_reply (rp, mp->context, VNET_API_ERROR_EAGAIN, i);
230  return;
231  }
232 
233  n = nodes[i];
234  if (flags == 0 || (n->flags & flags))
235  {
236  send_graph_node_details (nm, rp, mp->context, n, want_arcs);
237  }
238  }
239 
240  send_graph_node_reply (rp, mp->context, 0, ~0);
241 }
242 
243 
244 #include <vnet/format_fns.h>
245 #include <tracedump/graph.api.c>
246 
247 static clib_error_t *
249 {
251  graph_main_t *gmp = &graph_main;
252 
254 
255  am->is_mp_safe[gmp->msg_id_base + VL_API_GRAPH_NODE_GET] = 1;
256 
257  return 0;
258 }
259 
261 
262 /*
263  * fd.io coding-style-patch-verification: ON
264  *
265  * Local Variables:
266  * eval: (c-set-style "gnu")
267  * End:
268  */
clib_strncpy
#define clib_strncpy(d, s, n)
Definition: string.h:992
vl_api_client_index_to_registration
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:79
api.h
vl_api_graph_node_get_t::client_index
u32 client_index
Definition: graph.api:56
vl_api_graph_node_details_t::index
u32 index
Definition: graph.api:83
vl_api_graph_node_get_reply_t::cursor
u32 cursor
Definition: graph.api:70
vl_api_graph_node_details_t
Details for each graph node.
Definition: graph.api:80
send_graph_node_details
static void send_graph_node_details(vlib_node_main_t *nm, vl_api_registration_t *reg, u32 context, vlib_node_t *n, bool want_arcs)
Definition: graph_api.c:77
graph_api_hookup
static clib_error_t * graph_api_hookup(vlib_main_t *vm)
Definition: graph_api.c:248
vl_api_graph_node_details_t::flags
vl_api_node_flag_t flags
Definition: graph.api:85
vl_api_send_msg
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
graph_main_t::sorted_node_vec
vlib_node_t ** sorted_node_vec
Definition: graph.h:23
name
string name[64]
Definition: fib.api:25
vl_api_graph_node_get_reply_t::context
u32 context
Definition: graph.api:68
svm_queue_t
struct _svm_queue svm_queue_t
vlib_node_t::flags
u16 flags
Definition: node.h:278
vlib_main_t::node_main
vlib_node_main_t node_main
Definition: main.h:171
am
app_main_t * am
Definition: application.c:489
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
vl_api_registration_::vl_input_queue
svm_queue_t * vl_input_queue
shared memory only: pointer to client input queue
Definition: api_common.h:63
node_index
node node_index
Definition: interface_output.c:420
graph_main
graph_main_t graph_main
Definition: graph_api.c:30
vec_cmp
#define vec_cmp(v1, v2)
Compare two vectors (only applicable to vectors of signed numbers).
Definition: vec.h:1033
graph_node_invalid_cache
void graph_node_invalid_cache(void)
Definition: graph_api.c:41
vl_api_graph_node_get_reply_t::retval
i32 retval
Definition: graph.api:69
setup_message_id_table
static void setup_message_id_table(api_main_t *am)
Definition: bfd_api.c:451
vl_api_graph_node_get_reply_t
Definition: graph.api:66
VL_MSG_API_REAPER_FUNCTION
VL_MSG_API_REAPER_FUNCTION(graph_node_cache_reaper)
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vlib_node_t::index
u32 index
Definition: node.h:269
graph.h
vl_api_graph_node_get_t::want_arcs
bool want_arcs
Definition: graph.api:62
vec_dup
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:444
vl_api_graph_node_get_t::index
u32 index
Definition: graph.api:59
vl_api_registration_
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
vl_api_graph_node_get_t
graph_node_get - Get nodes of the packet processing graph In order: if index != ~0,...
Definition: graph.api:54
vl_api_graph_node_get_t::cursor
u32 cursor
Definition: graph.api:58
vlibapi_get_main
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:390
vlib_get_node
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:86
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
MIN
#define MIN(x, y)
Definition: graph_api.c:33
send_graph_node_reply
static void send_graph_node_reply(vl_api_registration_t *rp, u32 context, u32 retval, u32 cursor)
Definition: graph_api.c:60
vl_api_graph_node_details_t::arcs_out
u32 arcs_out[n_arcs]
Definition: graph.api:87
api_main_t
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:228
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
vlib_get_node_by_name
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
vl_api_graph_node_get_t_handler
static void vl_api_graph_node_get_t_handler(vl_api_graph_node_get_t *mp)
Definition: graph_api.c:141
format_fns.h
graph_main_t::msg_id_base
u16 msg_id_base
Definition: graph.h:22
vl_api_graph_node_details_t::n_arcs
u32 n_arcs
Definition: graph.api:86
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
node_cmp
static int node_cmp(void *a1, void *a2)
Definition: graph_api.c:119
api_helper_macros.h
vl_api_graph_node_get_t::flags
vl_api_node_flag_t flags
Definition: graph.api:61
nm
nat44_ei_main_t * nm
Definition: nat44_ei_hairpinning.c:413
vl_api_graph_node_details_t::name
string name[64]
Definition: graph.api:84
vec_sort_with_function
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1097
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vl_api_graph_node_get_t::name
string name[64]
Definition: graph.api:60
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
vl_api_graph_node_details_t::context
u32 context
Definition: graph.api:82
graph_main_t
Definition: graph.h:20
context
u32 context
Definition: ip.api:780
vlib_node_t::next_nodes
u32 * next_nodes
Definition: node.h:325
vl_api_graph_node_get_t::context
u32 context
Definition: graph.api:57
vlib_node_main_t
Definition: node.h:665
vnet.h
graph_node_cache_reaper
static clib_error_t * graph_node_cache_reaper(u32 client_index)
Definition: graph_api.c:50
vlib_node_t::name
u8 * name
Definition: node.h:253
vl_msg_api_alloc
void * vl_msg_api_alloc(int nbytes)
Definition: memory_shared.c:199
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105