X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fpunt.c;h=10deb2e88491fe83eaaa65374ce54278a5387cdd;hb=e8d8d47dca42113706abc05663b436d2664e1612;hp=b057a53306e0a93ff6a7ffbadb7f93261a316ac8;hpb=4f3c1042667a77e9c19dfbd51d3922cb5d37ea18;p=vpp.git diff --git a/src/vnet/ip/punt.c b/src/vnet/ip/punt.c index b057a53306e..10deb2e8849 100644 --- a/src/vnet/ip/punt.c +++ b/src/vnet/ip/punt.c @@ -24,10 +24,8 @@ #include #include -#include #include #include -#include #include #include @@ -167,7 +165,8 @@ punt_socket_register_l4 (vlib_main_t * vm, punt_client_l4_db_add (af, port, c - pm->punt_client_pool); } - memcpy (c->caddr.sun_path, client_pathname, sizeof (c->caddr.sun_path)); + snprintf (c->caddr.sun_path, sizeof (c->caddr.sun_path), "%s", + client_pathname); c->caddr.sun_family = AF_UNIX; c->reg.type = PUNT_TYPE_L4; c->reg.punt.l4.port = port; @@ -199,7 +198,8 @@ punt_socket_register_ip_proto (vlib_main_t * vm, punt_client_ip_proto_db_add (af, proto, c - pm->punt_client_pool); } - memcpy (c->caddr.sun_path, client_pathname, sizeof (c->caddr.sun_path)); + snprintf (c->caddr.sun_path, sizeof (c->caddr.sun_path), "%s", + client_pathname); c->caddr.sun_family = AF_UNIX; c->reg.type = PUNT_TYPE_IP_PROTO; c->reg.punt.ip_proto.protocol = proto; @@ -229,7 +229,8 @@ punt_socket_register_exception (vlib_main_t * vm, punt_client_exception_db_add (reason, pc - pm->punt_client_pool); } - memcpy (pc->caddr.sun_path, client_pathname, sizeof (pc->caddr.sun_path)); + snprintf (pc->caddr.sun_path, sizeof (pc->caddr.sun_path), "%s", + client_pathname); pc->caddr.sun_family = AF_UNIX; pc->reg.type = PUNT_TYPE_EXCEPTION; pc->reg.punt.exception.reason = reason; @@ -352,10 +353,10 @@ vnet_punt_socket_del (vlib_main_t * vm, const punt_reg_t * pr) } /** - * @brief Request IP traffic punt to the local TCP/IP stack. + * @brief Request IP L4 traffic punt to the local TCP/IP stack. * * @em Note - * - UDP, TCP and SCTP are the only protocols supported in the current implementation + * - UDP is the only protocol supported in the current implementation * * @param vm vlib_main_t corresponding to the current thread * @param af IP address family. @@ -371,48 +372,73 @@ punt_l4_add_del (vlib_main_t * vm, ip_address_family_t af, ip_protocol_t protocol, u16 port, bool is_add) { - /* For now we only support TCP, UDP and SCTP punt */ - if (protocol != IP_PROTOCOL_UDP && - protocol != IP_PROTOCOL_TCP && protocol != IP_PROTOCOL_SCTP) + int is_ip4 = af == AF_IP4; + + /* For now we only support TCP and UDP punt */ + if (protocol != IP_PROTOCOL_UDP && protocol != IP_PROTOCOL_TCP) return clib_error_return (0, - "only UDP (%d), TCP (%d) and SCTP (%d) protocols are supported, got %d", - IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, - IP_PROTOCOL_SCTP, protocol); + "only UDP (%d) and TCP (%d) protocols are supported, got %d", + IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, protocol); if (port == (u16) ~ 0) { if (protocol == IP_PROTOCOL_UDP) - udp_punt_unknown (vm, af == AF_IP4, is_add); + udp_punt_unknown (vm, is_ip4, is_add); else if (protocol == IP_PROTOCOL_TCP) - tcp_punt_unknown (vm, af == AF_IP4, is_add); - else if (protocol == IP_PROTOCOL_SCTP) - sctp_punt_unknown (vm, af == AF_IP4, is_add); + tcp_punt_unknown (vm, is_ip4, is_add); return 0; } else if (is_add) { - if (protocol == IP_PROTOCOL_TCP || protocol == IP_PROTOCOL_SCTP) - return clib_error_return (0, - "punt TCP/SCTP ports is not supported yet"); + const vlib_node_registration_t *punt_node = + is_ip4 ? &udp4_punt_node : &udp6_punt_node; - udp_register_dst_port (vm, port, udp4_punt_node.index, af == AF_IP4); + if (protocol == IP_PROTOCOL_TCP) + return clib_error_return (0, "punt TCP ports is not supported yet"); + + udp_register_dst_port (vm, port, punt_node->index, is_ip4); return 0; } else { - if (protocol == IP_PROTOCOL_TCP || protocol == IP_PROTOCOL_SCTP) - return clib_error_return (0, - "punt TCP/SCTP ports is not supported yet"); + if (protocol == IP_PROTOCOL_TCP) + return clib_error_return (0, "punt TCP ports is not supported yet"); - udp_unregister_dst_port (vm, port, af == AF_IP4); + udp_unregister_dst_port (vm, port, is_ip4); return 0; } } +/** + * @brief Request exception traffic punt. + * + * @param reason Punting reason + * + * @returns 0 on success, non-zero value otherwise + */ +static clib_error_t * +punt_exception_add_del (vlib_punt_reason_t reason, bool is_add) +{ + punt_main_t *pm = &punt_main; + int rv = 0; + vnet_punt_reason_flag_t flag = vlib_punt_reason_get_flags (reason); + const char *node_name = + vnet_punt_reason_flag_is_IP6_PACKET (flag) ? "ip6-punt" : "ip4-punt"; + if (is_add) + rv = vlib_punt_register (pm->hdl, reason, node_name); + else + rv = vlib_punt_unregister (pm->hdl, reason, node_name); + if (!rv) + return 0; + else + return clib_error_return (0, is_add ? "Existing punting registration..." : + "Punting registration not found..."); +} + clib_error_t * vnet_punt_add_del (vlib_main_t * vm, const punt_reg_t * pr, bool is_add) { @@ -422,6 +448,7 @@ vnet_punt_add_del (vlib_main_t * vm, const punt_reg_t * pr, bool is_add) return (punt_l4_add_del (vm, pr->punt.l4.af, pr->punt.l4.protocol, pr->punt.l4.port, is_add)); case PUNT_TYPE_EXCEPTION: + return punt_exception_add_del (pr->punt.exception.reason, is_add); case PUNT_TYPE_IP_PROTO: break; } @@ -431,8 +458,9 @@ vnet_punt_add_del (vlib_main_t * vm, const punt_reg_t * pr, bool is_add) static clib_error_t * punt_cli (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) + unformat_input_t * input__, vlib_cli_command_t * cmd) { + unformat_input_t line_input, *input = &line_input; clib_error_t *error = NULL; bool is_add = true; /* *INDENT-OFF* */ @@ -441,7 +469,7 @@ punt_cli (vlib_main_t * vm, .l4 = { .af = AF_IP4, .port = ~0, - .protocol = ~0, + .protocol = IP_PROTOCOL_UDP, }, }, .type = PUNT_TYPE_L4, @@ -449,16 +477,26 @@ punt_cli (vlib_main_t * vm, u32 port; /* *INDENT-ON* */ + if (!unformat_user (input__, unformat_line_input, input)) + return 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "del")) is_add = false; + else if (unformat (input, "reason %U", unformat_punt_reason, + &pr.punt.exception.reason)) + pr.type = PUNT_TYPE_EXCEPTION; + else if (unformat (input, "ipv4")) + pr.punt.l4.af = AF_IP4; else if (unformat (input, "ipv6")) pr.punt.l4.af = AF_IP6; else if (unformat (input, "ip6")) pr.punt.l4.af = AF_IP6; else if (unformat (input, "%d", &port)) pr.punt.l4.port = port; + else if (unformat (input, "all")) + pr.punt.l4.port = ~0; else if (unformat (input, "udp")) pr.punt.l4.protocol = IP_PROTOCOL_UDP; else if (unformat (input, "tcp")) @@ -479,6 +517,7 @@ punt_cli (vlib_main_t * vm, } done: + unformat_free (input); return error; } @@ -505,15 +544,17 @@ done: /* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_command, static) = { .path = "set punt", - .short_help = "set punt [udp|tcp] [del] ", + .short_help = "set punt [IPV4|ip6|ipv6] [UDP|tcp] [del] [ALL|]", .function = punt_cli, }; /* *INDENT-ON* */ static clib_error_t * punt_socket_register_cmd (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) + unformat_input_t * input__, + vlib_cli_command_t * cmd) { + unformat_input_t line_input, *input = &line_input; u8 *socket_name = 0; clib_error_t *error = NULL; /* *INDENT-OFF* */ @@ -522,17 +563,20 @@ punt_socket_register_cmd (vlib_main_t * vm, .l4 = { .af = AF_IP4, .port = ~0, - .protocol = ~0, + .protocol = IP_PROTOCOL_UDP, }, }, .type = PUNT_TYPE_L4, }; /* *INDENT-ON* */ + if (!unformat_user (input__, unformat_line_input, input)) + return 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "ipv4")) - ; + pr.punt.l4.af = AF_IP4; else if (unformat (input, "ipv6")) pr.punt.l4.af = AF_IP6; else if (unformat (input, "udp")) @@ -541,8 +585,13 @@ punt_socket_register_cmd (vlib_main_t * vm, pr.punt.l4.protocol = IP_PROTOCOL_TCP; else if (unformat (input, "%d", &pr.punt.l4.port)) ; + else if (unformat (input, "all")) + pr.punt.l4.port = ~0; else if (unformat (input, "socket %s", &socket_name)) ; + else if (unformat (input, "reason %U", unformat_punt_reason, + &pr.punt.exception.reason)) + pr.type = PUNT_TYPE_EXCEPTION; else { error = clib_error_return (0, "parse error: '%U'", @@ -557,29 +606,32 @@ punt_socket_register_cmd (vlib_main_t * vm, error = vnet_punt_socket_add (vm, 1, &pr, (char *) socket_name); done: + unformat_free (input); return error; } /*? * * @cliexpar - * @cliexcmd{punt socket register} + * @cliexcmd{punt socket register socket punt_l4_foo.sock} + ?*/ /* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_socket_register_command, static) = { .path = "punt socket register", .function = punt_socket_register_cmd, - .short_help = "punt socket register [ipv4|ipv6] [udp|tcp]> ", + .short_help = "punt socket register [IPV4|ipv6] [UDP|tcp] [ALL|] socket ", .is_mp_safe = 1, }; /* *INDENT-ON* */ static clib_error_t * punt_socket_deregister_cmd (vlib_main_t * vm, - unformat_input_t * input, + unformat_input_t * input__, vlib_cli_command_t * cmd) { + unformat_input_t line_input, *input = &line_input; clib_error_t *error = NULL; /* *INDENT-OFF* */ punt_reg_t pr = { @@ -587,17 +639,20 @@ punt_socket_deregister_cmd (vlib_main_t * vm, .l4 = { .af = AF_IP4, .port = ~0, - .protocol = ~0, + .protocol = IP_PROTOCOL_UDP, }, }, .type = PUNT_TYPE_L4, }; /* *INDENT-ON* */ + if (!unformat_user (input__, unformat_line_input, input)) + return 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "ipv4")) - ; + pr.punt.l4.af = AF_IP4; else if (unformat (input, "ipv6")) pr.punt.l4.af = AF_IP6; else if (unformat (input, "udp")) @@ -606,6 +661,11 @@ punt_socket_deregister_cmd (vlib_main_t * vm, pr.punt.l4.protocol = IP_PROTOCOL_TCP; else if (unformat (input, "%d", &pr.punt.l4.port)) ; + else if (unformat (input, "all")) + pr.punt.l4.port = ~0; + else if (unformat (input, "reason %U", unformat_punt_reason, + &pr.punt.exception.reason)) + pr.type = PUNT_TYPE_EXCEPTION; else { error = clib_error_return (0, "parse error: '%U'", @@ -616,6 +676,7 @@ punt_socket_deregister_cmd (vlib_main_t * vm, error = vnet_punt_socket_del (vm, &pr); done: + unformat_free (input); return error; } @@ -629,7 +690,7 @@ VLIB_CLI_COMMAND (punt_socket_deregister_command, static) = { .path = "punt socket deregister", .function = punt_socket_deregister_cmd, - .short_help = "punt socket deregister [ipv4|ipv6] [udp|tcp]> ", + .short_help = "punt socket deregister [IPV4|ipv6] [UDP|tcp] [ALL|]", .is_mp_safe = 1, }; /* *INDENT-ON* */ @@ -721,13 +782,17 @@ punt_client_show_one (const punt_client_t * pc, void *ctx) static clib_error_t * punt_socket_show_cmd (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) + unformat_input_t * input__, vlib_cli_command_t * cmd) { + unformat_input_t line_input, *input = &line_input; clib_error_t *error = NULL; punt_type_t pt; pt = PUNT_TYPE_L4; + if (!unformat_user (input__, unformat_line_input, input)) + return 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "exception")) @@ -747,6 +812,7 @@ punt_socket_show_cmd (vlib_main_t * vm, punt_client_walk (pt, punt_client_show_one, vm); done: + unformat_free (input); return (error); } @@ -770,6 +836,7 @@ ip_punt_init (vlib_main_t * vm) { clib_error_t *error = NULL; punt_main_t *pm = &punt_main; + vlib_thread_main_t *tm = vlib_get_thread_main (); pm->is_configured = false; pm->interface_output_node = @@ -780,9 +847,25 @@ ip_punt_init (vlib_main_t * vm) pm->hdl = vlib_punt_client_register ("ip-punt"); + vec_validate_aligned (pm->thread_data, tm->n_vlib_mains, + CLIB_CACHE_LINE_BYTES); + return (error); } +u8 * +format_vnet_punt_reason_flags (u8 *s, va_list *args) +{ + vnet_punt_reason_flag_t flag = va_arg (*args, int); +#define _(pos, len, value, name, str) \ + if (vnet_punt_reason_flag_is_##name (flag)) \ + s = format (s, "%s ", str); + + foreach_vnet_punt_reason_flag +#undef _ + return (s); +} + VLIB_INIT_FUNCTION (ip_punt_init); static clib_error_t * @@ -843,7 +926,7 @@ punt_config (vlib_main_t * vm, unformat_input_t * input) clib_file_t template = { 0 }; template.read_function = punt_socket_read_ready; template.file_descriptor = pm->socket_fd; - template.description = format (0, "%s", socket_path); + template.description = format (0, "punt socket %s", socket_path); pm->clib_file_index = clib_file_add (fm, &template); pm->is_configured = true;