- int i;
-
- u32 node_index = is_ip4 ? udp4_punt_socket_node.index :
- udp6_punt_socket_node.index;
-
- for (i = 0; i < n_packets; i++)
- {
- struct iovec *iov;
- vlib_buffer_t *b;
- uword l;
- punt_packetdesc_t packetdesc;
-
- b = vlib_get_buffer (vm, buffers[i]);
-
- /* Reverse UDP Punt advance */
- udp_header_t *udp;
- if (is_ip4)
- {
- vlib_buffer_advance (b, -(sizeof (ip4_header_t) +
- sizeof (udp_header_t)));
- ip4_header_t *ip = vlib_buffer_get_current (b);
- udp = (udp_header_t *) (ip + 1);
- }
- else
- {
- vlib_buffer_advance (b, -(sizeof (ip6_header_t) +
- sizeof (udp_header_t)));
- ip6_header_t *ip = vlib_buffer_get_current (b);
- 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
- */
- struct sockaddr_un *caddr;
- caddr = punt_socket_get (is_ip4, port);
- if (!caddr)
- {
- vlib_node_increment_counter (vm, node_index,
- PUNT_ERROR_SOCKET_TX_ERROR, 1);
- goto error;
- }
-
- punt_client_t *c = NULL;
- if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
- {
- c = punt_client_get (is_ip4, port);
- 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;
-
- /* Add packet descriptor */
- packetdesc.sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
- packetdesc.action = 0;
- vec_add2 (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);
- iov->iov_base = b->data + b->current_data;
- iov->iov_len = l = b->current_length;
-
- if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT))
- {
- do
- {
- b = vlib_get_buffer (vm, b->next_buffer);
- if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
- {
- if (PREDICT_FALSE (!c))
- {
- c = punt_client_get (is_ip4, port);
- }
- udp_punt_trace_t *t;
- t = vlib_add_trace (vm, node, b, sizeof (t[0]));
- clib_memcpy_fast (&t->client, c, sizeof (t->client));
- t->is_midchain = 1;
- }
-
- vec_add2 (iovecs, iov, 1);
-
- iov->iov_base = b->data + b->current_data;
- iov->iov_len = b->current_length;
- l += b->current_length;
- }
- while (b->flags & VLIB_BUFFER_NEXT_PRESENT);
- }
-
- struct msghdr msg = {
- .msg_name = caddr,
- .msg_namelen = sizeof (*caddr),
- .msg_iov = iovecs,
- .msg_iovlen = vec_len (iovecs),
- };
-
- if (sendmsg (pm->socket_fd, &msg, 0) < (ssize_t) l)
- vlib_node_increment_counter (vm, node_index,
- PUNT_ERROR_SOCKET_TX_ERROR, 1);
- else
- vlib_node_increment_counter (vm, node_index, PUNT_ERROR_SOCKET_TX, 1);
-
- }
-
-error:
- vlib_buffer_free (vm, buffers, n_packets);