- if (PREDICT_FALSE (nsm->drop_fraction != 0.0))
- {
- rnd[0] = random_f64 (&nsm->seed);
- rnd[1] = random_f64 (&nsm->seed);
- rnd[2] = random_f64 (&nsm->seed);
- rnd[3] = random_f64 (&nsm->seed);
-
- if (rnd[0] <= nsm->drop_fraction)
- {
- b[0]->error = loss_error;
- is_drop[0] = 1;
- }
- if (rnd[1] <= nsm->drop_fraction)
- {
- b[1]->error = loss_error;
- is_drop[1] = 1;
- }
- if (rnd[2] <= nsm->drop_fraction)
- {
- b[2]->error = loss_error;
- is_drop[2] = 1;
- }
- if (rnd[3] <= nsm->drop_fraction)
- {
- b[3]->error = loss_error;
- is_drop[3] = 1;
- }
- }
-
- if (PREDICT_TRUE (is_drop[0] == 0))
- {
- ep = wp->entries + wp->tail;
- wp->tail++;
- if (wp->tail == wp->wheel_size)
- wp->tail = 0;
- wp->cursize++;
-
- ep->tx_time = expires;
- ep->rx_sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
- if (is_cross_connect)
- {
- ep->tx_sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_TX] =
- (vnet_buffer (b[0])->sw_if_index[VLIB_RX] ==
- nsm->sw_if_index0) ? nsm->sw_if_index1 : nsm->sw_if_index0;
- ep->output_next_index =
- (ep->tx_sw_if_index ==
- nsm->sw_if_index0) ? nsm->
- output_next_index0 : nsm->output_next_index1;
- }
- else /* output feature, even easier... */
- {
- ep->tx_sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
- ep->output_next_index =
- nsm->output_next_index_by_sw_if_index[ep->tx_sw_if_index];
- }
- ep->buffer_index = from[0];
- buffered++;
- }
-
- if (is_trace)
- {
- if (b[1]->flags & VLIB_BUFFER_IS_TRACED)
- {
- nsim_trace_t *t = vlib_add_trace (vm, node, b[1], sizeof (*t));
- t->expires = expires;
- t->is_drop = is_drop[1];
- t->is_lost = b[1]->error == loss_error;
- t->tx_sw_if_index = (is_drop[1] == 0) ? ep->tx_sw_if_index : 0;
- }
- }
-
- if (PREDICT_TRUE (is_drop[1] == 0))
- {
- ep = wp->entries + wp->tail;
- wp->tail++;
- if (wp->tail == wp->wheel_size)
- wp->tail = 0;
- wp->cursize++;
-
- ep->tx_time = expires;
- ep->rx_sw_if_index = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
- if (is_cross_connect)
- {
- ep->tx_sw_if_index = vnet_buffer (b[1])->sw_if_index[VLIB_TX] =
- (vnet_buffer (b[1])->sw_if_index[VLIB_RX] ==
- nsm->sw_if_index0) ? nsm->sw_if_index1 : nsm->sw_if_index0;
- ep->output_next_index =
- (ep->tx_sw_if_index ==
- nsm->sw_if_index0) ? nsm->
- output_next_index0 : nsm->output_next_index1;
- }
- else /* output feature, even easier... */
- {
- ep->tx_sw_if_index = vnet_buffer (b[1])->sw_if_index[VLIB_TX];
- ep->output_next_index =
- nsm->output_next_index_by_sw_if_index[ep->tx_sw_if_index];
- }
- ep->buffer_index = from[1];
- buffered++;
- }
-
- if (is_trace)
- {
- if (b[2]->flags & VLIB_BUFFER_IS_TRACED)
- {
- nsim_trace_t *t = vlib_add_trace (vm, node, b[2], sizeof (*t));
- t->expires = expires;
- t->is_drop = is_drop[2];
- t->is_lost = b[2]->error == loss_error;
- t->tx_sw_if_index = (is_drop[2] == 0) ? ep->tx_sw_if_index : 0;
- }
- }
- if (PREDICT_TRUE (is_drop[2] == 0))
- {
- ep = wp->entries + wp->tail;
- wp->tail++;
- if (wp->tail == wp->wheel_size)
- wp->tail = 0;
- wp->cursize++;
-
- ep->tx_time = expires;
- ep->rx_sw_if_index = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
- if (is_cross_connect)
- {
- ep->tx_sw_if_index = vnet_buffer (b[2])->sw_if_index[VLIB_TX] =
- (vnet_buffer (b[2])->sw_if_index[VLIB_RX] ==
- nsm->sw_if_index0) ? nsm->sw_if_index1 : nsm->sw_if_index0;
- ep->output_next_index =
- (ep->tx_sw_if_index ==
- nsm->sw_if_index0) ? nsm->
- output_next_index0 : nsm->output_next_index1;
- }
- else /* output feature, even easier... */
- {
- ep->tx_sw_if_index = vnet_buffer (b[2])->sw_if_index[VLIB_TX];
- ep->output_next_index =
- nsm->output_next_index_by_sw_if_index[ep->tx_sw_if_index];
- }
- ep->buffer_index = from[2];
- buffered++;
- }
-
- if (is_trace)
- {
- if (b[2]->flags & VLIB_BUFFER_IS_TRACED)
- {
- nsim_trace_t *t = vlib_add_trace (vm, node, b[2], sizeof (*t));
- t->expires = expires;
- t->is_drop = is_drop[2];
- t->is_lost = b[2]->error == loss_error;
- t->tx_sw_if_index = (is_drop[2] == 0) ? ep->tx_sw_if_index : 0;
- }
- }
- if (PREDICT_TRUE (is_drop[3] == 0))
- {
- ep = wp->entries + wp->tail;
- wp->tail++;
- if (wp->tail == wp->wheel_size)
- wp->tail = 0;
- wp->cursize++;
-
- ep->tx_time = expires;
- ep->rx_sw_if_index = vnet_buffer (b[3])->sw_if_index[VLIB_RX];
- if (is_cross_connect)
- {
- ep->tx_sw_if_index = vnet_buffer (b[3])->sw_if_index[VLIB_TX] =
- (vnet_buffer (b[3])->sw_if_index[VLIB_RX] ==
- nsm->sw_if_index0) ? nsm->sw_if_index1 : nsm->sw_if_index0;
- ep->output_next_index =
- (ep->tx_sw_if_index ==
- nsm->sw_if_index0) ? nsm->
- output_next_index0 : nsm->output_next_index1;
- }
- else /* output feature, even easier... */
- {
- ep->tx_sw_if_index = vnet_buffer (b[3])->sw_if_index[VLIB_TX];
- ep->output_next_index =
- nsm->output_next_index_by_sw_if_index[ep->tx_sw_if_index];
- }
- ep->buffer_index = from[3];
- buffered++;
- }