X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fpunt.c;h=eb191da1394403e92825dbf841229d4dead7e529;hb=d3915dc1b5201956578eb900a2d936d94fc09b90;hp=7cdb5fcc084e1e3a991afc9769fc056fe0489d13;hpb=5481ad4eb7fbbf32ff30450525c935de63ffcf0f;p=vpp.git diff --git a/src/vnet/ip/punt.c b/src/vnet/ip/punt.c index 7cdb5fcc084..eb191da1394 100644 --- a/src/vnet/ip/punt.c +++ b/src/vnet/ip/punt.c @@ -369,6 +369,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 +380,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 +404,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 +445,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; } @@ -449,6 +481,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")) @@ -551,6 +586,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'", @@ -622,6 +660,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'", @@ -809,6 +850,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 *