+
+
+ int l34_len =
+ l4_header_offset + sizeof (icmp46_header_t) +
+ offsetof (icmp46_echo_request_t, data);
+ int max_data_len = VLIB_BUFFER_DATA_SIZE - l34_len;
+
+ int first_buf_data_len = data_len < max_data_len ? data_len : max_data_len;
+
+ int payload_offset = 0;
+ for (i = 0; i < first_buf_data_len; i++)
+ icmp46_echo->data[i] = get_icmp_echo_payload_byte (payload_offset++);
+
+ /* inspired by vlib_buffer_add_data */
+ vlib_buffer_t *hb = b0;
+ int remaining_data_len = data_len - first_buf_data_len;
+ while (remaining_data_len)
+ {
+ int this_buf_data_len =
+ remaining_data_len <
+ VLIB_BUFFER_DATA_SIZE ? remaining_data_len : VLIB_BUFFER_DATA_SIZE;
+ int n_alloc = vlib_buffer_alloc_from_free_list (vm, &b0->next_buffer, 1,
+ hb->free_list_index);
+ if (n_alloc < 1)
+ {
+ /* That is how much we have so far - return it... */
+ return (data_len - remaining_data_len);
+ }
+ b0->flags |= VLIB_BUFFER_NEXT_PRESENT;
+ /* move on to the newly acquired buffer */
+ b0 = vlib_get_buffer (vm, b0->next_buffer);
+ /* initialize the data */
+ for (i = 0; i < this_buf_data_len; i++)
+ {
+ b0->data[i] = get_icmp_echo_payload_byte (payload_offset++);
+ }
+ b0->current_length = this_buf_data_len;
+ b0->current_data = 0;
+ remaining_data_len -= this_buf_data_len;
+ }
+ hb->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
+ hb->current_length = l34_len + first_buf_data_len;
+ hb->total_length_not_including_first_buffer = data_len - first_buf_data_len;
+
+ icmp46_echo->time_sent = now;