X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fpunt.c;h=3c46549634a5d6cab8ff9b6ac43dc9d88b823f27;hb=HEAD;hp=ffe0b83d7f45fd3d98821ad96cdd38908ab11f9d;hpb=6e366be38ff4f71d4ad5a24929519dc3c874ed36;p=vpp.git diff --git a/src/vnet/ip/punt.c b/src/vnet/ip/punt.c index ffe0b83d7f4..3c46549634a 100644 --- a/src/vnet/ip/punt.c +++ b/src/vnet/ip/punt.c @@ -148,14 +148,31 @@ punt_socket_register_l4 (vlib_main_t * vm, punt_main_t *pm = &punt_main; punt_client_t *c; - /* For now we only support UDP punt */ - if (protocol != IP_PROTOCOL_UDP) - return clib_error_return (0, - "only UDP protocol (%d) is supported, got %d", - IP_PROTOCOL_UDP, protocol); - if (port == (u16) ~ 0) - return clib_error_return (0, "UDP port number required"); + return clib_error_return (0, "Port number required"); + + u32 node_index; + switch (protocol) + { + case IP_PROTOCOL_UDP: + node_index = (af == AF_IP4 ? udp4_punt_socket_node.index : + udp6_punt_socket_node.index); + udp_register_dst_port (vm, port, node_index, af == AF_IP4); + break; + case IP_PROTOCOL_ICMP6: + if (af != AF_IP6) + return clib_error_return ( + 0, "only UDP or ICMP6 protocol (%d, %d) is supported, got %d", + IP_PROTOCOL_UDP, IP_PROTOCOL_ICMP6, protocol); + + node_index = icmp6_punt_socket_node.index; + icmp6_register_type (vm, port, node_index); + break; + default: + return clib_error_return ( + 0, "only UDP or ICMP6 protocol (%d) is supported, got %d", + IP_PROTOCOL_UDP, protocol); + } c = punt_client_l4_get (af, port); @@ -165,19 +182,14 @@ 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; c->reg.punt.l4.protocol = protocol; c->reg.punt.l4.af = af; - u32 node_index = (af == AF_IP4 ? - udp4_punt_socket_node.index : - udp6_punt_socket_node.index); - - udp_register_dst_port (vm, port, node_index, af == AF_IP4); - return (NULL); } @@ -197,7 +209,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; @@ -227,7 +240,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; @@ -369,6 +383,8 @@ punt_l4_add_del (vlib_main_t * vm, ip_address_family_t af, ip_protocol_t protocol, u16 port, bool is_add) { + 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, @@ -378,19 +394,22 @@ punt_l4_add_del (vlib_main_t * vm, 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); + tcp_punt_unknown (vm, is_ip4, is_add); return 0; } else if (is_add) { + const vlib_node_registration_t *punt_node = + is_ip4 ? &udp4_punt_node : &udp6_punt_node; + if (protocol == IP_PROTOCOL_TCP) return clib_error_return (0, "punt TCP ports is not supported yet"); - udp_register_dst_port (vm, port, udp4_punt_node.index, af == AF_IP4); + udp_register_dst_port (vm, port, punt_node->index, is_ip4); return 0; } @@ -399,12 +418,38 @@ punt_l4_add_del (vlib_main_t * vm, 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) { @@ -414,6 +459,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; } @@ -428,7 +474,6 @@ punt_cli (vlib_main_t * vm, unformat_input_t line_input, *input = &line_input; clib_error_t *error = NULL; bool is_add = true; - /* *INDENT-OFF* */ punt_reg_t pr = { .punt = { .l4 = { @@ -440,7 +485,6 @@ punt_cli (vlib_main_t * vm, .type = PUNT_TYPE_L4, }; u32 port; - /* *INDENT-ON* */ if (!unformat_user (input__, unformat_line_input, input)) return 0; @@ -449,6 +493,9 @@ punt_cli (vlib_main_t * vm, { 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")) @@ -503,13 +550,11 @@ done: * @cliexcmd{set punt udp del all} * @endparblock ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_command, static) = { .path = "set punt", .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, @@ -519,7 +564,6 @@ punt_socket_register_cmd (vlib_main_t * vm, unformat_input_t line_input, *input = &line_input; u8 *socket_name = 0; clib_error_t *error = NULL; - /* *INDENT-OFF* */ punt_reg_t pr = { .punt = { .l4 = { @@ -530,7 +574,6 @@ punt_socket_register_cmd (vlib_main_t * vm, }, .type = PUNT_TYPE_L4, }; - /* *INDENT-ON* */ if (!unformat_user (input__, unformat_line_input, input)) return 0; @@ -551,6 +594,9 @@ punt_socket_register_cmd (vlib_main_t * vm, 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'", @@ -575,7 +621,6 @@ done: * @cliexcmd{punt socket register socket punt_l4_foo.sock} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_socket_register_command, static) = { .path = "punt socket register", @@ -583,7 +628,6 @@ VLIB_CLI_COMMAND (punt_socket_register_command, static) = .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, @@ -592,7 +636,6 @@ punt_socket_deregister_cmd (vlib_main_t * vm, { unformat_input_t line_input, *input = &line_input; clib_error_t *error = NULL; - /* *INDENT-OFF* */ punt_reg_t pr = { .punt = { .l4 = { @@ -603,7 +646,6 @@ punt_socket_deregister_cmd (vlib_main_t * vm, }, .type = PUNT_TYPE_L4, }; - /* *INDENT-ON* */ if (!unformat_user (input__, unformat_line_input, input)) return 0; @@ -622,6 +664,9 @@ punt_socket_deregister_cmd (vlib_main_t * vm, ; 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'", @@ -641,7 +686,6 @@ done: * @cliexpar * @cliexcmd{punt socket register} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_socket_deregister_command, static) = { .path = "punt socket deregister", @@ -649,7 +693,6 @@ VLIB_CLI_COMMAND (punt_socket_deregister_command, static) = .short_help = "punt socket deregister [IPV4|ipv6] [UDP|tcp] [ALL|]", .is_mp_safe = 1, }; -/* *INDENT-ON* */ void punt_client_walk (punt_type_t pt, punt_client_walk_cb_t cb, void *ctx) @@ -662,24 +705,20 @@ punt_client_walk (punt_type_t pt, punt_client_walk_cb_t cb, void *ctx) { u32 pci, key; - /* *INDENT-OFF* */ hash_foreach(key, pci, pm->db.clients_by_l4_port, ({ cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx); })); - /* *INDENT-ON* */ break; } case PUNT_TYPE_IP_PROTO: { u32 pci, key; - /* *INDENT-OFF* */ hash_foreach(key, pci, pm->db.clients_by_ip_proto, ({ cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx); })); - /* *INDENT-ON* */ break; } case PUNT_TYPE_EXCEPTION: @@ -777,7 +816,6 @@ done: * @cliexpar * @cliexcmd{show punt socket ipv4} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_punt_socket_registration_command, static) = { .path = "show punt socket registrations", @@ -785,7 +823,6 @@ VLIB_CLI_COMMAND (show_punt_socket_registration_command, static) = .short_help = "show punt socket registrations [l4|exception]", .is_mp_safe = 1, }; -/* *INDENT-ON* */ clib_error_t * ip_punt_init (vlib_main_t * vm) @@ -809,6 +846,19 @@ ip_punt_init (vlib_main_t * vm) 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 * @@ -869,7 +919,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;