- if (trace0->ioam_trace_type & BIT_TIMESTAMP)
- {
- /* Send least significant 32 bits */
- f64 time_f64 = (f64)(((f64)hm->unix_time_0) +
- (vlib_time_now(hm->vlib_main) - hm->vlib_time_0));
-
- time_u64.as_u64 =
- time_f64 * trace_tsp_mul[hm->trace_tsp];
- *elt0 = clib_host_to_net_u32(time_u64.as_u32[0]);
- elt0++;
- }
-
- if (trace0->ioam_trace_type & BIT_APPDATA)
- {
- /* $$$ set elt0->app_data */
- *elt0 = clib_host_to_net_u32(hm->app_data);
- elt0++;
- }
- }
-
- opt0 = (ip6_hop_by_hop_option_t *)
- (((u8 *)opt0) + opt0->length
- + sizeof (ip6_hop_by_hop_option_t));
- break;
-
- case HBH_OPTION_TYPE_IOAM_PROOF_OF_WORK:
- pow_profile = scv_profile_find(pow_profile_index);
- if (PREDICT_FALSE(!pow_profile))
- {
- vlib_node_increment_counter (vm,
- ip6_hop_by_hop_node.index,
- IP6_HOP_BY_HOP_ERROR_PROFILE_MISS, 1);
-
- opt0 = (ip6_hop_by_hop_option_t *)
- (((u8 *)opt0) + sizeof (ioam_pow_option_t));
- break;
- }
- pow0 = (ioam_pow_option_t *) opt0;
- pow_encap = (pow0->random == 0);
- if (pow_encap)
- {
- if (PREDICT_FALSE(total_pkts_using_this_profile >=
- pow_profile->validity))
- {
- /* Choose a new profile */
- u16 new_profile_index;
- new_profile_index =
- scv_get_next_profile_id(vm,
- pow_profile_index);
- if (new_profile_index != pow_profile_index)
- {
- /* Got a new profile */
- scv_profile_invalidate(vm, hm,
- pow_profile_index,
- pow_encap);
- pow_profile_index = new_profile_index;
- pow_profile =
- scv_profile_find(pow_profile_index);
- total_pkts_using_this_profile = 0;
- }
- else
- {
- scv_profile_invalidate(vm, hm,
- pow_profile_index,
- pow_encap);
- }
- }
- pow0->reserved_profile_id =
- pow_profile_index & PROFILE_ID_MASK;
- total_pkts_using_this_profile++;
- }
- else
- { /* Non encap node */
- if (PREDICT_FALSE(pow0->reserved_profile_id !=
- pow_profile_index))
- {
- /* New profile announced by encap node. */
- scv_profile *new_profile = 0;
- new_profile =
- scv_profile_find(pow0->reserved_profile_id);
- if (PREDICT_FALSE(new_profile == 0 ||
- new_profile->validity == 0))
- {
- /* Profile is invalid. Use old profile*/
- vlib_node_increment_counter (vm,
- ip6_hop_by_hop_node.index,
- IP6_HOP_BY_HOP_ERROR_PROFILE_MISS, 1);
- scv_profile_invalidate(vm, hm,
- pow0->reserved_profile_id,
- pow_encap);
- }
- else
- {
- scv_profile_invalidate(vm, hm,
- pow_profile_index,
- pow_encap);
- pow_profile_index = pow0->reserved_profile_id;
- pow_profile = new_profile;
- total_pkts_using_this_profile = 0;
- }
- }
- total_pkts_using_this_profile++;
- }
-
- if (pow0->random == 0)
- {
- pow0->random = clib_host_to_net_u64(
- scv_generate_random(pow_profile));
- pow0->cumulative = 0;
- }
- random = clib_net_to_host_u64(pow0->random);
- cumulative = clib_net_to_host_u64(pow0->cumulative);
- pow0->cumulative = clib_host_to_net_u64(
- scv_update_cumulative(pow_profile,
- cumulative,
- random));
- opt0 = (ip6_hop_by_hop_option_t *)
- (((u8 *)opt0) + sizeof (ioam_pow_option_t));
- break;
-
- case 0: /* Pad */
- opt0 = (ip6_hop_by_hop_option_t *) ((u8 *)opt0) + 1;
- goto out0;
-
- default:
- opt0 = (ip6_hop_by_hop_option_t *)
- (((u8 *)opt0) + opt0->length
- + sizeof (ip6_hop_by_hop_option_t));
- unknown_opts++;
- break;
- }
- }
-
- out0:
- next0 = (vnet_buffer(b0)->l2_classify.opaque_index == OI_DECAP) ?
- IP6_HBYH_INPUT_NEXT_IP6_POP_HBYH : IP6_HBYH_INPUT_NEXT_IP6_REWRITE;
- vnet_buffer(b0)->l2_classify.opaque_index = ~0;