X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fpunt_api.c;h=95fff714b46d89d013f17dc73a2e8e9414ba7b5a;hb=50f0ac0f0;hp=55ab838b167188504e3e67f198bc34bc9af07939;hpb=6c4dae27e75fc668f86c9cca0f3f58273b680621;p=vpp.git diff --git a/src/vnet/ip/punt_api.c b/src/vnet/ip/punt_api.c index 55ab838b167..95fff714b46 100644 --- a/src/vnet/ip/punt_api.c +++ b/src/vnet/ip/punt_api.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -40,27 +41,149 @@ #include #define foreach_punt_api_msg \ -_(PUNT, punt) \ +_(SET_PUNT, set_punt) \ _(PUNT_SOCKET_REGISTER, punt_socket_register) \ -_(PUNT_SOCKET_DEREGISTER, punt_socket_deregister) +_(PUNT_SOCKET_DEREGISTER, punt_socket_deregister) \ +_(PUNT_SOCKET_DUMP, punt_socket_dump) \ +_(PUNT_REASON_DUMP, punt_reason_dump) + +static int +vl_api_punt_type_decode (vl_api_punt_type_t in, punt_type_t * out) +{ + in = clib_net_to_host_u32 (in); + + switch (in) + { +#define _(v, s) \ + case PUNT_API_TYPE_##v: \ + *out = PUNT_TYPE_##v; \ + return (0); + foreach_punt_type +#undef _ + } + + return (-1); +} + +static vl_api_punt_type_t +vl_api_punt_type_encode (punt_type_t in) +{ + vl_api_punt_type_t pt = PUNT_API_TYPE_L4; + + switch (in) + { +#define _(v, s) \ + case PUNT_TYPE_##v: \ + pt = PUNT_API_TYPE_##v; \ + break; + foreach_punt_type +#undef _ + } + + return (clib_host_to_net_u32 (pt)); +} + +static int +vl_api_punt_l4_decode (const vl_api_punt_l4_t * in, punt_l4_t * out) +{ + int rv; + + rv = ip_address_family_decode (in->af, &out->af); + rv += ip_proto_decode (in->protocol, &out->protocol); + out->port = clib_net_to_host_u16 (in->port); + + return (rv); +} + +static int +vl_api_punt_exception_decode (const vl_api_punt_exception_t * in, + punt_exception_t * out) +{ + int rv; + + out->reason = clib_net_to_host_u32 (in->id); + rv = vlib_punt_reason_validate (out->reason); + + return (rv); +} + +static int +vl_api_punt_decode (const vl_api_punt_t * in, punt_reg_t * out) +{ + int rv; + + rv = vl_api_punt_type_decode (in->type, &out->type); + + if (rv) + return (rv); + + switch (out->type) + { + case PUNT_TYPE_L4: + return (vl_api_punt_l4_decode (&in->punt.l4, &out->punt.l4)); + case PUNT_TYPE_EXCEPTION: + return (vl_api_punt_exception_decode (&in->punt.exception, + &out->punt.exception)); + } + + return (-1); +} + +static void +vl_api_punt_l4_encode (const punt_l4_t * in, vl_api_punt_l4_t * out) +{ + out->af = ip_address_family_encode (in->af); + out->protocol = ip_proto_encode (in->protocol); + out->port = clib_net_to_host_u16 (in->port); +} + +static void +vl_api_punt_exception_encode (const punt_exception_t * in, + vl_api_punt_exception_t * out) +{ + out->id = clib_host_to_net_u32 (in->reason); +} + +static void +vl_api_punt_encode (const punt_reg_t * in, vl_api_punt_t * out) +{ + out->type = vl_api_punt_type_encode (in->type); + + switch (in->type) + { + case PUNT_TYPE_L4: + vl_api_punt_l4_encode (&in->punt.l4, &out->punt.l4); + break; + case PUNT_TYPE_EXCEPTION: + vl_api_punt_exception_encode (&in->punt.exception, + &out->punt.exception); + break; + } +} static void -vl_api_punt_t_handler (vl_api_punt_t * mp) +vl_api_set_punt_t_handler (vl_api_set_punt_t * mp) { - vl_api_punt_reply_t *rmp; + vl_api_set_punt_reply_t *rmp; vlib_main_t *vm = vlib_get_main (); - int rv = 0; clib_error_t *error; + punt_reg_t pr; + int rv; - error = vnet_punt_add_del (vm, mp->ipv, mp->l4_protocol, - ntohs (mp->l4_port), mp->is_add); + rv = vl_api_punt_decode (&mp->punt, &pr); + + if (rv) + goto out; + + error = vnet_punt_add_del (vm, &pr, mp->is_add); if (error) { rv = -1; clib_error_report (error); } - REPLY_MACRO (VL_API_PUNT_REPLY); +out: + REPLY_MACRO (VL_API_SET_PUNT_REPLY); } static void @@ -68,31 +191,79 @@ vl_api_punt_socket_register_t_handler (vl_api_punt_socket_register_t * mp) { vl_api_punt_socket_register_reply_t *rmp; vlib_main_t *vm = vlib_get_main (); - int rv = 0; clib_error_t *error; - vl_api_registration_t *reg; + punt_reg_t pr; + int rv; + + rv = vl_api_punt_decode (&mp->punt, &pr); + + if (rv) + return; error = vnet_punt_socket_add (vm, ntohl (mp->header_version), - mp->is_ip4, mp->l4_protocol, - ntohs (mp->l4_port), (char *) mp->pathname); + &pr, (char *) mp->pathname); if (error) { rv = -1; clib_error_report (error); } + char *p = vnet_punt_get_server_pathname (); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_PUNT_SOCKET_REGISTER_REPLY, + ({ + memcpy ((char *) rmp->pathname, p, sizeof (rmp->pathname)); + })); + /* *INDENT-ON* */ +} + +typedef struct punt_socket_send_ctx_t_ +{ + vl_api_registration_t *reg; + u32 context; +} punt_socket_send_ctx_t; + +static walk_rc_t +vl_api_punt_socket_send_details (const punt_client_t * pc, void *args) +{ + punt_socket_send_ctx_t *ctx = args; + vl_api_punt_socket_details_t *mp; + + mp = vl_msg_api_alloc (sizeof (*mp)); + if (!mp) + return (WALK_STOP); + + clib_memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_PUNT_SOCKET_DETAILS); + mp->context = ctx->context; + vl_api_punt_encode (&pc->reg, &mp->punt); + memcpy (mp->pathname, pc->caddr.sun_path, sizeof (pc->caddr.sun_path)); + + vl_api_send_msg (ctx->reg, (u8 *) mp); + + return (WALK_CONTINUE); +} + +static void +vl_api_punt_socket_dump_t_handler (vl_api_punt_socket_dump_t * mp) +{ + vl_api_registration_t *reg; + punt_type_t pt; + + if (0 != vl_api_punt_type_decode (mp->type, &pt)) + return; + reg = vl_api_client_index_to_registration (mp->client_index); if (!reg) return; - rmp = vl_msg_api_alloc (sizeof (*rmp)); - rmp->_vl_msg_id = htons (VL_API_PUNT_SOCKET_REGISTER_REPLY); - rmp->context = mp->context; - rmp->retval = htonl (rv); - char *p = vnet_punt_get_server_pathname (); - /* Abstract pathnames start with \0 */ - memcpy ((char *) rmp->pathname, p, sizeof (rmp->pathname)); - vl_api_send_msg (reg, (u8 *) rmp); + punt_socket_send_ctx_t ctx = { + .reg = reg, + .context = mp->context, + }; + + punt_client_walk (pt, vl_api_punt_socket_send_details, &ctx); } static void @@ -100,27 +271,69 @@ vl_api_punt_socket_deregister_t_handler (vl_api_punt_socket_deregister_t * mp) { vl_api_punt_socket_deregister_reply_t *rmp; vlib_main_t *vm = vlib_get_main (); - int rv = 0; clib_error_t *error; - vl_api_registration_t *reg; + punt_reg_t pr; + int rv; + + rv = vl_api_punt_decode (&mp->punt, &pr); + + if (rv) + goto out; - error = vnet_punt_socket_del (vm, mp->is_ip4, mp->l4_protocol, - ntohs (mp->l4_port)); + error = vnet_punt_socket_del (vm, &pr); if (error) { rv = -1; clib_error_report (error); } +out: + REPLY_MACRO (VL_API_PUNT_SOCKET_DEREGISTER_REPLY); +} + +typedef struct punt_reason_dump_walk_ctx_t_ +{ + vl_api_registration_t *reg; + u32 context; +} punt_reason_dump_walk_ctx_t; + +static int +punt_reason_dump_walk_cb (vlib_punt_reason_t id, const u8 * name, void *args) +{ + punt_reason_dump_walk_ctx_t *ctx = args; + vl_api_punt_reason_details_t *mp; + + mp = vl_msg_api_alloc (sizeof (*mp) + vec_len (name)); + if (!mp) + return (0); + + clib_memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_PUNT_REASON_DETAILS); + + mp->context = ctx->context; + mp->reason.id = clib_host_to_net_u32 (id); + vl_api_to_api_string (vec_len (name), (char *) name, &mp->reason.name); + + vl_api_send_msg (ctx->reg, (u8 *) mp); + + return (1); +} + +static void +vl_api_punt_reason_dump_t_handler (vl_api_punt_reason_dump_t * mp) +{ + vl_api_registration_t *reg; + reg = vl_api_client_index_to_registration (mp->client_index); if (!reg) return; - rmp = vl_msg_api_alloc (sizeof (*rmp)); - rmp->_vl_msg_id = htons (VL_API_PUNT_SOCKET_DEREGISTER_REPLY); - rmp->context = mp->context; - rmp->retval = htonl (rv); - vl_api_send_msg (reg, (u8 *) rmp); + punt_reason_dump_walk_ctx_t ctx = { + .reg = reg, + .context = mp->context, + }; + + punt_reason_walk (punt_reason_dump_walk_cb, &ctx); } #define vl_msg_name_crc_list