FD.io VPP  v19.08-24-ge6a5712
Vector Packet Processing
punt_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * punt_api.c - Punt api
4  *
5  * Copyright (c) 2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22 #include <vnet/ip/punt.h>
23 #include <vnet/ip/ip_types_api.h>
24 
25 #include <vnet/vnet_msg_enum.h>
26 
27 #define vl_typedefs /* define message structures */
28 #include <vnet/vnet_all_api_h.h>
29 #undef vl_typedefs
30 
31 #define vl_endianfun /* define message structures */
32 #include <vnet/vnet_all_api_h.h>
33 #undef vl_endianfun
34 
35 /* instantiate all the print functions we know about */
36 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
37 #define vl_printfun
38 #include <vnet/vnet_all_api_h.h>
39 #undef vl_printfun
40 
42 
43 #define foreach_punt_api_msg \
44 _(SET_PUNT, set_punt) \
45 _(PUNT_SOCKET_REGISTER, punt_socket_register) \
46 _(PUNT_SOCKET_DEREGISTER, punt_socket_deregister) \
47 _(PUNT_SOCKET_DUMP, punt_socket_dump) \
48 _(PUNT_REASON_DUMP, punt_reason_dump)
49 
50 static int
51 vl_api_punt_type_decode (vl_api_punt_type_t in, punt_type_t * out)
52 {
53  in = clib_net_to_host_u32 (in);
54 
55  switch (in)
56  {
57 #define _(v, s) \
58  case PUNT_API_TYPE_##v: \
59  *out = PUNT_TYPE_##v; \
60  return (0);
62 #undef _
63  }
64 
65  return (-1);
66 }
67 
68 static vl_api_punt_type_t
70 {
71  vl_api_punt_type_t pt = PUNT_API_TYPE_L4;
72 
73  switch (in)
74  {
75 #define _(v, s) \
76  case PUNT_TYPE_##v: \
77  pt = PUNT_API_TYPE_##v; \
78  break;
80 #undef _
81  }
82 
83  return (clib_host_to_net_u32 (pt));
84 }
85 
86 static int
87 vl_api_punt_l4_decode (const vl_api_punt_l4_t * in, punt_l4_t * out)
88 {
89  int rv;
90 
91  rv = ip_address_family_decode (in->af, &out->af);
92  rv += ip_proto_decode (in->protocol, &out->protocol);
93  out->port = clib_net_to_host_u16 (in->port);
94 
95  return (rv);
96 }
97 
98 static int
99 vl_api_punt_ip_proto_decode (const vl_api_punt_ip_proto_t * in,
100  punt_ip_proto_t * out)
101 {
102  int rv;
103 
104  rv = ip_address_family_decode (in->af, &out->af);
105  rv += ip_proto_decode (in->protocol, &out->protocol);
106 
107  return (rv);
108 }
109 
110 static int
111 vl_api_punt_exception_decode (const vl_api_punt_exception_t * in,
112  punt_exception_t * out)
113 {
114  int rv;
115 
116  out->reason = clib_net_to_host_u32 (in->id);
117  rv = vlib_punt_reason_validate (out->reason);
118 
119  return (rv);
120 }
121 
122 static int
123 vl_api_punt_decode (const vl_api_punt_t * in, punt_reg_t * out)
124 {
125  int rv;
126 
127  rv = vl_api_punt_type_decode (in->type, &out->type);
128 
129  if (rv)
130  return (rv);
131 
132  switch (out->type)
133  {
134  case PUNT_TYPE_L4:
135  return (vl_api_punt_l4_decode (&in->punt.l4, &out->punt.l4));
136  case PUNT_TYPE_EXCEPTION:
137  return (vl_api_punt_exception_decode (&in->punt.exception,
138  &out->punt.exception));
139  case PUNT_TYPE_IP_PROTO:
140  return (vl_api_punt_ip_proto_decode (&in->punt.ip_proto,
141  &out->punt.ip_proto));
142  }
143 
144  return (-1);
145 }
146 
147 static void
148 vl_api_punt_l4_encode (const punt_l4_t * in, vl_api_punt_l4_t * out)
149 {
150  out->af = ip_address_family_encode (in->af);
151  out->protocol = ip_proto_encode (in->protocol);
152  out->port = clib_net_to_host_u16 (in->port);
153 }
154 
155 static void
157  vl_api_punt_ip_proto_t * out)
158 {
159  out->af = ip_address_family_encode (in->af);
160  out->protocol = ip_proto_encode (in->protocol);
161 }
162 
163 static void
165  vl_api_punt_exception_t * out)
166 {
167  out->id = clib_host_to_net_u32 (in->reason);
168 }
169 
170 static void
171 vl_api_punt_encode (const punt_reg_t * in, vl_api_punt_t * out)
172 {
173  out->type = vl_api_punt_type_encode (in->type);
174 
175  switch (in->type)
176  {
177  case PUNT_TYPE_L4:
178  vl_api_punt_l4_encode (&in->punt.l4, &out->punt.l4);
179  break;
180  case PUNT_TYPE_IP_PROTO:
181  vl_api_punt_ip_proto_encode (&in->punt.ip_proto, &out->punt.ip_proto);
182  break;
183  case PUNT_TYPE_EXCEPTION:
185  &out->punt.exception);
186  break;
187  }
188 }
189 
190 static void
192 {
193  vl_api_set_punt_reply_t *rmp;
195  clib_error_t *error;
196  punt_reg_t pr;
197  int rv;
198 
199  rv = vl_api_punt_decode (&mp->punt, &pr);
200 
201  if (rv)
202  goto out;
203 
204  error = vnet_punt_add_del (vm, &pr, mp->is_add);
205  if (error)
206  {
207  rv = -1;
208  clib_error_report (error);
209  }
210 
211 out:
212  REPLY_MACRO (VL_API_SET_PUNT_REPLY);
213 }
214 
215 static void
217 {
220  clib_error_t *error;
221  punt_reg_t pr;
222  int rv;
223 
224  rv = vl_api_punt_decode (&mp->punt, &pr);
225 
226  if (rv)
227  return;
228 
229  error = vnet_punt_socket_add (vm, ntohl (mp->header_version),
230  &pr, (char *) mp->pathname);
231  if (error)
232  {
233  rv = -1;
234  clib_error_report (error);
235  }
236 
237  char *p = vnet_punt_get_server_pathname ();
238 
239  /* *INDENT-OFF* */
240  REPLY_MACRO2 (VL_API_PUNT_SOCKET_REGISTER_REPLY,
241  ({
242  memcpy ((char *) rmp->pathname, p, sizeof (rmp->pathname));
243  }));
244  /* *INDENT-ON* */
245 }
246 
248 {
252 
253 static walk_rc_t
255 {
256  punt_socket_send_ctx_t *ctx = args;
258 
259  mp = vl_msg_api_alloc (sizeof (*mp));
260  if (!mp)
261  return (WALK_STOP);
262 
263  clib_memset (mp, 0, sizeof (*mp));
264  mp->_vl_msg_id = ntohs (VL_API_PUNT_SOCKET_DETAILS);
265  mp->context = ctx->context;
266  vl_api_punt_encode (&pc->reg, &mp->punt);
267  memcpy (mp->pathname, pc->caddr.sun_path, sizeof (pc->caddr.sun_path));
268 
269  vl_api_send_msg (ctx->reg, (u8 *) mp);
270 
271  return (WALK_CONTINUE);
272 }
273 
274 static void
276 {
278  punt_type_t pt;
279 
280  if (0 != vl_api_punt_type_decode (mp->type, &pt))
281  return;
282 
284  if (!reg)
285  return;
286 
288  .reg = reg,
289  .context = mp->context,
290  };
291 
293 }
294 
295 static void
297 {
298  vl_api_punt_socket_deregister_reply_t *rmp;
300  clib_error_t *error;
301  punt_reg_t pr;
302  int rv;
303 
304  rv = vl_api_punt_decode (&mp->punt, &pr);
305 
306  if (rv)
307  goto out;
308 
309  error = vnet_punt_socket_del (vm, &pr);
310  if (error)
311  {
312  rv = -1;
313  clib_error_report (error);
314  }
315 
316 out:
317  REPLY_MACRO (VL_API_PUNT_SOCKET_DEREGISTER_REPLY);
318 }
319 
321 {
326 
327 static int
329 {
332 
333  if (ctx->name)
334  {
335  /* user requested a specific punt-reason */
336  if (vec_cmp (name, ctx->name))
337  /* not the reasonn we're lookgin for */
338  return 1;
339  }
340 
341  mp = vl_msg_api_alloc (sizeof (*mp) + vec_len (name));
342  if (!mp)
343  return (0);
344 
345  clib_memset (mp, 0, sizeof (*mp));
346  mp->_vl_msg_id = ntohs (VL_API_PUNT_REASON_DETAILS);
347 
348  mp->context = ctx->context;
349  mp->reason.id = clib_host_to_net_u32 (id);
350  vl_api_to_api_string (vec_len (name), (char *) name, &mp->reason.name);
351 
352  vl_api_send_msg (ctx->reg, (u8 *) mp);
353 
354  return (1);
355 }
356 
357 static void
359 {
361 
363  if (!reg)
364  return;
365 
367  .reg = reg,
368  .context = mp->context,
369  .name = vl_api_from_api_to_vec (&mp->reason.name),
370  };
371 
373 
374  vec_free (ctx.name);
375 }
376 
377 #define vl_msg_name_crc_list
378 #include <vnet/ip/punt.api.h>
379 #undef vl_msg_name_crc_list
380 
381 static void
383 {
384 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
385  foreach_vl_msg_name_crc_punt;
386 #undef _
387 }
388 
389 static clib_error_t *
391 {
392  api_main_t *am = &api_main;
393 
394 #define _(N,n) \
395  vl_msg_api_set_handlers(VL_API_##N, #n, \
396  vl_api_##n##_t_handler, \
397  vl_noop_handler, \
398  vl_api_##n##_t_endian, \
399  vl_api_##n##_t_print, \
400  sizeof(vl_api_##n##_t), 1);
402 #undef _
403 
404  /*
405  * Set up the (msg_name, crc, message-id) table
406  */
408 
409  return 0;
410 }
411 
413 
414 
415 /*
416  * fd.io coding-style-patch-verification: ON
417  *
418  * Local Variables:
419  * eval: (c-set-style "gnu")
420  * End:
421  */
int vl_api_to_api_string(u32 len, const char *buf, vl_api_string_t *str)
Definition: api_shared.c:1060
enum punt_type_t_ punt_type_t
A registration, by a client, to direct punted traffic to a given node.
Definition: punt.c:66
static int punt_reason_dump_walk_cb(vlib_punt_reason_t id, const u8 *name, void *args)
Definition: punt_api.c:328
ip_protocol_t protocol
Definition: punt.h:49
int vlib_punt_reason_validate(vlib_punt_reason_t reason)
Validate that a punt reason is assigned.
Definition: punt.c:370
struct punt_socket_send_ctx_t_ punt_socket_send_ctx_t
#define REPLY_MACRO2(t, body)
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:34
punt_reg_t reg
Definition: punt.h:103
punt_type_t type
Definition: punt.h:66
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
clib_error_t * vnet_punt_socket_del(vlib_main_t *vm, const punt_reg_t *pr)
Definition: punt.c:330
static void vl_api_punt_ip_proto_encode(const punt_ip_proto_t *in, vl_api_punt_ip_proto_t *out)
Definition: punt_api.c:156
static void vl_api_punt_socket_register_t_handler(vl_api_punt_socket_register_t *mp)
Definition: punt_api.c:216
void * vl_msg_api_alloc(int nbytes)
unsigned char u8
Definition: types.h:56
static int vl_api_punt_exception_decode(const vl_api_punt_exception_t *in, punt_exception_t *out)
Definition: punt_api.c:111
clib_error_t * vnet_punt_socket_add(vlib_main_t *vm, u32 header_version, const punt_reg_t *pr, char *client_pathname)
Definition: punt.c:290
int ip_proto_decode(int _ipp, ip_protocol_t *out)
Definition: ip_types_api.c:66
Dump all or one of the excpetion punt reasons.
Definition: punt.api:144
enum walk_rc_t_ walk_rc_t
Walk return code.
u8 * vl_api_from_api_to_vec(vl_api_string_t *astr)
Definition: api_shared.c:1093
static void vl_api_set_punt_t_handler(vl_api_set_punt_t *mp)
Definition: punt_api.c:191
static void setup_message_id_table(api_main_t *am)
Definition: punt_api.c:382
static walk_rc_t vl_api_punt_socket_send_details(const punt_client_t *pc, void *args)
Definition: punt_api.c:254
static void vl_api_punt_l4_encode(const punt_l4_t *in, vl_api_punt_l4_t *out)
Definition: punt_api.c:148
vl_api_registration_t * reg
Definition: punt_api.c:322
unsigned int u32
Definition: types.h:88
static void vl_api_punt_encode(const punt_reg_t *in, vl_api_punt_t *out)
Definition: punt_api.c:171
vl_api_punt_type_t type
Definition: punt.api:118
vl_api_registration_t * reg
Definition: punt_api.c:249
int ip_address_family_encode(ip_address_family_t af)
Definition: ip_types_api.c:51
static void vl_api_punt_socket_dump_t_handler(vl_api_punt_socket_dump_t *mp)
Definition: punt_api.c:275
punt_ip_proto_t ip_proto
Definition: punt.h:61
static void vl_api_punt_socket_deregister_t_handler(vl_api_punt_socket_deregister_t *mp)
Definition: punt_api.c:296
static vl_api_punt_type_t vl_api_punt_type_encode(punt_type_t in)
Definition: punt_api.c:69
long ctx[MAX_CONNS]
Definition: main.c:144
struct punt_reason_dump_walk_ctx_t_ punt_reason_dump_walk_ctx_t
ip_address_family_t af
Definition: punt.h:41
#define REPLY_MACRO(t)
static void vl_api_punt_reason_dump_t_handler(vl_api_punt_reason_dump_t *mp)
Definition: punt_api.c:358
static void vl_api_punt_exception_encode(const punt_exception_t *in, vl_api_punt_exception_t *out)
Definition: punt_api.c:164
u8 name[64]
Definition: memclnt.api:152
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:203
punt_exception_t exception
Definition: punt.h:59
An API client registration, only in vpp/vlib.
Definition: api_common.h:46
vlib_main_t * vm
Definition: buffer.c:312
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
void punt_reason_walk(punt_reason_walk_cb_t cb, void *ctx)
Definition: punt.c:405
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:56
vl_api_punt_reason_t reason
Definition: punt.api:154
static int vl_api_punt_type_decode(vl_api_punt_type_t in, punt_type_t *out)
Definition: punt_api.c:51
int ip_proto_encode(ip_protocol_t ipp)
Definition: ip_types_api.c:83
VLIB_API_INIT_FUNCTION(punt_api_hookup)
ip_address_family_t af
Definition: punt.h:48
ip_protocol_t protocol
Definition: punt.h:42
static clib_error_t * punt_api_hookup(vlib_main_t *vm)
Definition: punt_api.c:390
punt_l4_t l4
Definition: punt.h:60
#define clib_error_report(e)
Definition: error.h:113
#define vec_cmp(v1, v2)
Compare two vectors (only applicable to vectors of signed numbers).
Definition: vec.h:919
Punt traffic to the host.
Definition: punt.api:86
Punt traffic to the host via socket.
Definition: punt.api:99
#define foreach_punt_api_msg
Definition: punt_api.c:43
static int vl_api_punt_ip_proto_decode(const vl_api_punt_ip_proto_t *in, punt_ip_proto_t *out)
Definition: punt_api.c:99
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
vl_api_punt_t punt
Definition: punt.api:90
static int vl_api_punt_decode(const vl_api_punt_t *in, punt_reg_t *out)
Definition: punt_api.c:123
vl_api_punt_reason_t reason
Definition: punt.api:148
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
punt_union_t punt
Definition: punt.h:67
static int vl_api_punt_l4_decode(const vl_api_punt_l4_t *in, punt_l4_t *out)
Definition: punt_api.c:87
int ip_address_family_decode(int _af, ip_address_family_t *out)
These enum decode/encodes use &#39;int&#39; as the type for the enum becuase one cannot forward declare an en...
Definition: ip_types_api.c:34
clib_error_t * vnet_punt_add_del(vlib_main_t *vm, const punt_reg_t *pr, bool is_add)
Definition: punt.c:410
api_main_t api_main
Definition: api_shared.c:35
vlib_punt_reason_t reason
Definition: punt.h:54
enum vlib_punt_reason_t_ vlib_punt_reason_t
The &#39;syatem&#39; defined punt reasons.
char * vnet_punt_get_server_pathname(void)
Definition: punt.c:42
u16 port
Definition: punt.h:43
void punt_client_walk(punt_type_t pt, punt_client_walk_cb_t cb, void *ctx)
Definition: punt.c:631
struct sockaddr_un caddr
Definition: punt.h:104
Definitions for punt infrastructure.