+ if (is_ip4)
+ {
+ ip4_header_t *ip4;
+
+ /* TODO: must fix once udp_local does ip options correctly */
+ ip4 = (ip4_header_t *) (((u8 *) udp) - sizeof (*ip4));
+ ip_set (&hdr->lcl_ip, &ip4->dst_address, 1);
+ ip_set (&hdr->rmt_ip, &ip4->src_address, 1);
+ hdr->data_length = clib_net_to_host_u16 (ip4->length);
+ hdr->data_length -= sizeof (ip4_header_t) + sizeof (udp_header_t);
+ s = session_lookup_safe4 (fib_index, &ip4->dst_address,
+ &ip4->src_address, udp->dst_port,
+ udp->src_port, TRANSPORT_PROTO_UDP);
+ }
+ else
+ {
+ ip6_header_t *ip60;
+
+ ip60 = (ip6_header_t *) (((u8 *) udp) - sizeof (*ip60));
+ ip_set (&hdr->lcl_ip, &ip60->dst_address, 0);
+ ip_set (&hdr->rmt_ip, &ip60->src_address, 0);
+ hdr->data_length = clib_net_to_host_u16 (ip60->payload_length);
+ hdr->data_length -= sizeof (udp_header_t);
+ s = session_lookup_safe6 (fib_index, &ip60->dst_address,
+ &ip60->src_address, udp->dst_port,
+ udp->src_port, TRANSPORT_PROTO_UDP);
+ }
+
+ if (PREDICT_TRUE (!(b->flags & VLIB_BUFFER_NEXT_PRESENT)))
+ b->current_length = hdr->data_length;
+ else
+ b->total_length_not_including_first_buffer = hdr->data_length
+ - b->current_length;
+
+ return s;
+}
+
+always_inline uword
+udp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame, u8 is_ip4)
+{
+ u32 n_left_from, *from, errors, *first_buffer;
+ vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
+ u16 err_counters[UDP_N_ERROR] = { 0 };
+ u32 thread_index = vm->thread_index;
+
+ from = first_buffer = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+ vlib_get_buffers (vm, from, bufs, n_left_from);
+
+ b = bufs;
+
+ while (n_left_from > 0)
+ {
+ u32 error0 = UDP_ERROR_ENQUEUED;
+ session_dgram_hdr_t hdr0;
+ udp_connection_t *uc0;
+ session_t *s0;
+
+ s0 = udp_parse_and_lookup_buffer (b[0], &hdr0, is_ip4);
+ if (PREDICT_FALSE (!s0))
+ {
+ error0 = UDP_ERROR_NO_LISTENER;
+ goto done;
+ }
+
+ /*
+ * If session exists pool peeker lock is taken at this point unless
+ * the session is already on the right thread or is a listener
+ */
+
+ if (s0->session_state == SESSION_STATE_OPENED)
+ {
+ u8 queue_event = 1;
+ uc0 = udp_connection_from_transport (session_get_transport (s0));
+ if (uc0->flags & UDP_CONN_F_CONNECTED)