+ 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));