FD.io VPP  v20.05-21-gb1500e9ff
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  if (rv < 0)
93  return (rv);
94  rv = ip_proto_decode (in->protocol, &out->protocol);
95  if (rv < 0)
96  return (rv);
97  out->port = clib_net_to_host_u16 (in->port);
98 
99  return (rv);
100 }
101 
102 static int
103 vl_api_punt_ip_proto_decode (const vl_api_punt_ip_proto_t * in,
104  punt_ip_proto_t * out)
105 {
106  int rv;
107 
108  rv = ip_address_family_decode (in->af, &out->af);
109  if (rv < 0)
110  return (rv);
111  rv = ip_proto_decode (in->protocol, &out->protocol);
112 
113  return (rv);
114 }
115 
116 static int
117 vl_api_punt_exception_decode (const vl_api_punt_exception_t * in,
118  punt_exception_t * out)
119 {
120  int rv;
121 
122  out->reason = clib_net_to_host_u32 (in->id);
123  rv = vlib_punt_reason_validate (out->reason);
124 
125  return (rv);
126 }
127 
128 static int
129 vl_api_punt_decode (const vl_api_punt_t * in, punt_reg_t * out)
130 {
131  int rv;
132 
133  rv = vl_api_punt_type_decode (in->type, &out->type);
134 
135  if (rv)
136  return (rv);
137 
138  switch (out->type)
139  {
140  case PUNT_TYPE_L4:
141  return (vl_api_punt_l4_decode (&in->punt.l4, &out->punt.l4));
142  case PUNT_TYPE_EXCEPTION:
143  return (vl_api_punt_exception_decode (&in->punt.exception,
144  &out->punt.exception));
145  case PUNT_TYPE_IP_PROTO:
146  return (vl_api_punt_ip_proto_decode (&in->punt.ip_proto,
147  &out->punt.ip_proto));
148  }
149 
150  return (-1);
151 }
152 
153 static void
154 vl_api_punt_l4_encode (const punt_l4_t * in, vl_api_punt_l4_t * out)
155 {
156  out->af = ip_address_family_encode (in->af);
157  out->protocol = ip_proto_encode (in->protocol);
158  out->port = clib_net_to_host_u16 (in->port);
159 }
160 
161 static void
163  vl_api_punt_ip_proto_t * out)
164 {
165  out->af = ip_address_family_encode (in->af);
166  out->protocol = ip_proto_encode (in->protocol);
167 }
168 
169 static void
171  vl_api_punt_exception_t * out)
172 {
173  out->id = clib_host_to_net_u32 (in->reason);
174 }
175 
176 static void
177 vl_api_punt_encode (const punt_reg_t * in, vl_api_punt_t * out)
178 {
179  out->type = vl_api_punt_type_encode (in->type);
180 
181  switch (in->type)
182  {
183  case PUNT_TYPE_L4:
184  vl_api_punt_l4_encode (&in->punt.l4, &out->punt.l4);
185  break;
186  case PUNT_TYPE_IP_PROTO:
187  vl_api_punt_ip_proto_encode (&in->punt.ip_proto, &out->punt.ip_proto);
188  break;
189  case PUNT_TYPE_EXCEPTION:
191  &out->punt.exception);
192  break;
193  }
194 }
195 
196 static void
198 {
199  vl_api_set_punt_reply_t *rmp;
201  clib_error_t *error;
202  punt_reg_t pr;
203  int rv;
204 
205  rv = vl_api_punt_decode (&mp->punt, &pr);
206 
207  if (rv)
208  goto out;
209 
210  error = vnet_punt_add_del (vm, &pr, mp->is_add);
211  if (error)
212  {
213  rv = -1;
214  clib_error_report (error);
215  }
216 
217 out:
218  REPLY_MACRO (VL_API_SET_PUNT_REPLY);
219 }
220 
221 static void
223 {
226  clib_error_t *error;
227  punt_reg_t pr;
228  int rv;
229 
230  rv = vl_api_punt_decode (&mp->punt, &pr);
231 
232  if (rv)
233  return;
234 
235  error = vnet_punt_socket_add (vm, ntohl (mp->header_version),
236  &pr, (char *) mp->pathname);
237  if (error)
238  {
239  rv = -1;
240  clib_error_report (error);
241  }
242 
243  char *p = vnet_punt_get_server_pathname ();
244 
245  /* *INDENT-OFF* */
246  REPLY_MACRO2 (VL_API_PUNT_SOCKET_REGISTER_REPLY,
247  ({
248  memcpy ((char *) rmp->pathname, p, sizeof (rmp->pathname));
249  }));
250  /* *INDENT-ON* */
251 }
252 
254 {
258 
259 static walk_rc_t
261 {
262  punt_socket_send_ctx_t *ctx = args;
264 
265  mp = vl_msg_api_alloc (sizeof (*mp));
266  if (!mp)
267  return (WALK_STOP);
268 
269  clib_memset (mp, 0, sizeof (*mp));
270  mp->_vl_msg_id = ntohs (VL_API_PUNT_SOCKET_DETAILS);
271  mp->context = ctx->context;
272  vl_api_punt_encode (&pc->reg, &mp->punt);
273  memcpy (mp->pathname, pc->caddr.sun_path, sizeof (pc->caddr.sun_path));
274 
275  vl_api_send_msg (ctx->reg, (u8 *) mp);
276 
277  return (WALK_CONTINUE);
278 }
279 
280 static void
282 {
284  punt_type_t pt;
285 
286  if (0 != vl_api_punt_type_decode (mp->type, &pt))
287  return;
288 
290  if (!reg)
291  return;
292 
294  .reg = reg,
295  .context = mp->context,
296  };
297 
299 }
300 
301 static void
303 {
304  vl_api_punt_socket_deregister_reply_t *rmp;
306  clib_error_t *error;
307  punt_reg_t pr;
308  int rv;
309 
310  rv = vl_api_punt_decode (&mp->punt, &pr);
311 
312  if (rv)
313  goto out;
314 
315  error = vnet_punt_socket_del (vm, &pr);
316  if (error)
317  {
318  rv = -1;
319  clib_error_report (error);
320  }
321 
322 out:
323  REPLY_MACRO (VL_API_PUNT_SOCKET_DEREGISTER_REPLY);
324 }
325 
327 {
332 
333 static int
335 {
338 
339  if (ctx->name)
340  {
341  /* user requested a specific punt-reason */
342  if (vec_cmp (name, ctx->name))
343  /* not the reasonn we're lookgin for */
344  return 1;
345  }
346 
347  mp = vl_msg_api_alloc (sizeof (*mp) + vec_len (name));
348  if (!mp)
349  return (0);
350 
351  clib_memset (mp, 0, sizeof (*mp));
352  mp->_vl_msg_id = ntohs (VL_API_PUNT_REASON_DETAILS);
353 
354  mp->context = ctx->context;
355  mp->reason.id = clib_host_to_net_u32 (id);
356  vl_api_vec_to_api_string (name, &mp->reason.name);
357 
358  vl_api_send_msg (ctx->reg, (u8 *) mp);
359 
360  return (1);
361 }
362 
363 static void
365 {
367 
369  if (!reg)
370  return;
371 
373  .reg = reg,
374  .context = mp->context,
375  .name = vl_api_from_api_to_new_vec (mp, &mp->reason.name),
376  };
377 
379 
380  vec_free (ctx.name);
381 }
382 
383 #define vl_msg_name_crc_list
384 #include <vnet/ip/punt.api.h>
385 #undef vl_msg_name_crc_list
386 
387 static void
389 {
390 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
391  foreach_vl_msg_name_crc_punt;
392 #undef _
393 }
394 
395 static clib_error_t *
397 {
398  api_main_t *am = vlibapi_get_main ();
399 
400 #define _(N,n) \
401  vl_msg_api_set_handlers(VL_API_##N, #n, \
402  vl_api_##n##_t_handler, \
403  vl_noop_handler, \
404  vl_api_##n##_t_endian, \
405  vl_api_##n##_t_print, \
406  sizeof(vl_api_##n##_t), 1);
408 #undef _
409 
410  /*
411  * Set up the (msg_name, crc, message-id) table
412  */
414 
415  return 0;
416 }
417 
419 
420 
421 /*
422  * fd.io coding-style-patch-verification: ON
423  *
424  * Local Variables:
425  * eval: (c-set-style "gnu")
426  * End:
427  */
int ip_address_family_decode(vl_api_address_family_t af, ip_address_family_t *out)
Conversion functions to/from (decode/encode) API types to VPP internal types.
Definition: ip_types_api.c:34
enum punt_type_t_ punt_type_t
A registration, by a client, to direct punted traffic to a given node.
Definition: punt.h:64
static int punt_reason_dump_walk_cb(vlib_punt_reason_t id, const u8 *name, void *args)
Definition: punt_api.c:334
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:394
struct punt_socket_send_ctx_t_ punt_socket_send_ctx_t
#define REPLY_MACRO2(t, body)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
punt_reg_t reg
Definition: punt.h:103
punt_type_t type
Definition: punt.h:66
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:162
static void vl_api_punt_socket_register_t_handler(vl_api_punt_socket_register_t *mp)
Definition: punt_api.c:222
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:117
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
Dump all or one of the exception punt reasons.
Definition: punt.api:144
enum walk_rc_t_ walk_rc_t
Walk return code.
static void vl_api_set_punt_t_handler(vl_api_set_punt_t *mp)
Definition: punt_api.c:197
static void setup_message_id_table(api_main_t *am)
Definition: punt_api.c:388
static walk_rc_t vl_api_punt_socket_send_details(const punt_client_t *pc, void *args)
Definition: punt_api.c:260
static void vl_api_punt_l4_encode(const punt_l4_t *in, vl_api_punt_l4_t *out)
Definition: punt_api.c:154
vl_api_registration_t * reg
Definition: punt_api.c:328
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:177
vl_api_punt_type_t type
Definition: punt.api:118
vl_api_registration_t * reg
Definition: punt_api.c:255
static void vl_api_punt_socket_dump_t_handler(vl_api_punt_socket_dump_t *mp)
Definition: punt_api.c:281
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:302
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:364
static void vl_api_punt_exception_encode(const punt_exception_t *in, vl_api_punt_exception_t *out)
Definition: punt_api.c:170
vlib_main_t * vm
Definition: in2out_ed.c:1599
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:226
punt_exception_t exception
Definition: punt.h:59
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
vl_api_ip_proto_t ip_proto_encode(ip_protocol_t ipp)
Definition: ip_types_api.c:83
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
vl_api_address_family_t ip_address_family_encode(ip_address_family_t af)
Definition: ip_types_api.c:50
void punt_reason_walk(punt_reason_walk_cb_t cb, void *ctx)
Definition: punt.c:433
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:57
string name[64]
Definition: ip.api:44
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
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:396
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:989
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:103
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:129
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
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:379
clib_error_t * vnet_punt_add_del(vlib_main_t *vm, const punt_reg_t *pr, bool is_add)
Definition: punt.c:410
int ip_proto_decode(vl_api_ip_proto_t ipp, ip_protocol_t *out)
Definition: ip_types_api.c:65
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
u8 * vl_api_from_api_to_new_vec(void *mp, vl_api_string_t *astr)
Definition: api_shared.c:1156
int vl_api_vec_to_api_string(const u8 *vec, vl_api_string_t *str)
Definition: api_shared.c:1129
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:640
struct sockaddr_un caddr
Definition: punt.h:104
Definitions for punt infrastructure.