X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fpunt_node.c;h=0306d597293651ae7c25cbd9c2bce8f5a79f8871;hb=1adc7e78ad3eb7e800d0ce3ace56f53ab7aebffe;hp=53c8199342b26659130bc8fe88ec948287413ca6;hpb=50f0ac0f097e5495da1f2b1816106e3d420ff34b;p=vpp.git diff --git a/src/vnet/ip/punt_node.c b/src/vnet/ip/punt_node.c index 53c8199342b..0306d597293 100644 --- a/src/vnet/ip/punt_node.c +++ b/src/vnet/ip/punt_node.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -224,6 +223,7 @@ typedef struct { punt_client_t client; u8 is_midchain; + u8 packet_data[64]; } udp_punt_trace_t; static u8 * @@ -239,6 +239,9 @@ format_udp_punt_trace (u8 * s, va_list * args) s = format (s, "\n%U(buffer is part of chain)", format_white_space, indent); } + s = format (s, "\n%U%U", format_white_space, indent, + format_hex_bytes, t->packet_data, sizeof (t->packet_data)); + return s; } @@ -249,13 +252,15 @@ punt_socket_inline (vlib_main_t * vm, punt_type_t pt, ip_address_family_t af) { u32 *buffers = vlib_frame_vector_args (frame); + u32 thread_index = vm->thread_index; uword n_packets = frame->n_vectors; - struct iovec *iovecs = 0; punt_main_t *pm = &punt_main; int i; - u32 node_index = AF_IP4 == af ? udp4_punt_socket_node.index : - udp6_punt_socket_node.index; + punt_thread_data_t *ptd = &pm->thread_data[thread_index]; + u32 node_index = (AF_IP4 == af ? + udp4_punt_socket_node.index : + udp6_punt_socket_node.index); for (i = 0; i < n_packets; i++) { @@ -286,13 +291,29 @@ punt_socket_inline (vlib_main_t * vm, udp = (udp_header_t *) (ip + 1); } - u16 port = clib_net_to_host_u16 (udp->dst_port); - /* * Find registerered client * If no registered client, drop packet and count */ - c = punt_client_l4_get (af, port); + c = punt_client_l4_get (af, clib_net_to_host_u16 (udp->dst_port)); + } + else if (PUNT_TYPE_IP_PROTO == pt) + { + /* Reverse UDP Punt advance */ + ip_protocol_t proto; + + if (AF_IP4 == af) + { + ip4_header_t *ip = vlib_buffer_get_current (b); + proto = ip->protocol; + } + else + { + ip6_header_t *ip = vlib_buffer_get_current (b); + proto = ip->protocol; + } + + c = punt_client_ip_proto_get (af, proto); } else if (PUNT_TYPE_EXCEPTION == pt) { @@ -310,30 +331,32 @@ punt_socket_inline (vlib_main_t * vm, struct sockaddr_un *caddr = &c->caddr; - if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED)) - { - udp_punt_trace_t *t; - t = vlib_add_trace (vm, node, b, sizeof (t[0])); - clib_memcpy_fast (&t->client, c, sizeof (t->client)); - } - - /* Re-set iovecs if present. */ - if (iovecs) - _vec_len (iovecs) = 0; + /* Re-set iovecs */ + vec_reset_length (ptd->iovecs); /* Add packet descriptor */ packetdesc.sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX]; packetdesc.action = 0; - vec_add2 (iovecs, iov, 1); + vec_add2 (ptd->iovecs, iov, 1); iov->iov_base = &packetdesc; iov->iov_len = sizeof (packetdesc); /** VLIB buffer chain -> Unix iovec(s). */ vlib_buffer_advance (b, -(sizeof (ethernet_header_t))); - vec_add2 (iovecs, iov, 1); + vec_add2 (ptd->iovecs, iov, 1); iov->iov_base = b->data + b->current_data; iov->iov_len = l = b->current_length; + if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED)) + { + udp_punt_trace_t *t; + t = vlib_add_trace (vm, node, b, sizeof (t[0])); + clib_memcpy_fast (&t->client, c, sizeof (t->client)); + clib_memcpy_fast (t->packet_data, + vlib_buffer_get_current (b), + sizeof (t->packet_data)); + } + if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT)) { do @@ -347,7 +370,7 @@ punt_socket_inline (vlib_main_t * vm, t->is_midchain = 1; } - vec_add2 (iovecs, iov, 1); + vec_add2 (ptd->iovecs, iov, 1); iov->iov_base = b->data + b->current_data; iov->iov_len = b->current_length; @@ -359,8 +382,8 @@ punt_socket_inline (vlib_main_t * vm, struct msghdr msg = { .msg_name = caddr, .msg_namelen = sizeof (*caddr), - .msg_iov = iovecs, - .msg_iovlen = vec_len (iovecs), + .msg_iov = ptd->iovecs, + .msg_iovlen = vec_len (ptd->iovecs), }; if (sendmsg (pm->socket_fd, &msg, 0) < (ssize_t) l) @@ -390,6 +413,22 @@ udp6_punt_socket (vlib_main_t * vm, return punt_socket_inline (vm, node, from_frame, PUNT_TYPE_L4, AF_IP6); } +static uword +ip4_proto_punt_socket (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return punt_socket_inline (vm, node, from_frame, + PUNT_TYPE_IP_PROTO, AF_IP4); +} + +static uword +ip6_proto_punt_socket (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return punt_socket_inline (vm, node, from_frame, + PUNT_TYPE_IP_PROTO, AF_IP6); +} + static uword exception_punt_socket (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) @@ -419,6 +458,25 @@ VLIB_REGISTER_NODE (udp6_punt_socket_node) = { .n_errors = PUNT_N_ERROR, .error_strings = punt_error_strings, }; +VLIB_REGISTER_NODE (ip4_proto_punt_socket_node) = { + .function = ip4_proto_punt_socket, + .name = "ip4-proto-punt-socket", + .format_trace = format_udp_punt_trace, + .flags = VLIB_NODE_FLAG_IS_DROP, + /* Takes a vector of packets. */ + .vector_size = sizeof (u32), + .n_errors = PUNT_N_ERROR, + .error_strings = punt_error_strings, +}; +VLIB_REGISTER_NODE (ip6_proto_punt_socket_node) = { + .function = ip6_proto_punt_socket, + .name = "ip6-proto-punt-socket", + .format_trace = format_udp_punt_trace, + .flags = VLIB_NODE_FLAG_IS_DROP, + .vector_size = sizeof (u32), + .n_errors = PUNT_N_ERROR, + .error_strings = punt_error_strings, +}; VLIB_REGISTER_NODE (exception_punt_socket_node) = { .function = exception_punt_socket, .name = "exception-punt-socket", @@ -538,6 +596,7 @@ punt_socket_rx_fd (vlib_main_t * vm, vlib_node_runtime_t * node, u32 fd) return 1; error: + vlib_put_next_frame (vm, node, next, n_left_to_next); vlib_node_increment_counter (vm, punt_socket_rx_node.index, error, 1); return 0; } @@ -563,6 +622,7 @@ VLIB_REGISTER_NODE (punt_socket_rx_node) = { .function = punt_socket_rx, .name = "punt-socket-rx", + .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED, .type = VLIB_NODE_TYPE_INPUT, .state = VLIB_NODE_STATE_INTERRUPT, .vector_size = 1,