X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fexamples%2Fsrv6-sample-localsid%2Fnode.c;h=3ac7108bb08f3a5d09aae920fbbf939e7708b187;hb=5f5d50ee9b342964caeeee10612cd002497fb40c;hp=7bae9cd7c55dc94ef382893ba94f7ea74e20c4de;hpb=4521afa9a643983c789b6b3a77b14c0a95d5e0b2;p=vpp.git diff --git a/src/examples/srv6-sample-localsid/node.c b/src/examples/srv6-sample-localsid/node.c index 7bae9cd7c55..3ac7108bb08 100644 --- a/src/examples/srv6-sample-localsid/node.c +++ b/src/examples/srv6-sample-localsid/node.c @@ -59,43 +59,102 @@ typedef enum { } srv6_localsid_sample_next_t; /** - * @brief Function doing End processing. + * @brief Function doing End processing. */ -//Fixme: support OAM (hop-by-hop header) here! static_always_inline void end_srh_processing (vlib_node_runtime_t * node, - vlib_buffer_t * b0, - ip6_header_t * ip0, - ip6_sr_header_t * sr0, - u32 * next0) + vlib_buffer_t * b0, + ip6_header_t * ip0, + ip6_sr_header_t * sr0, + ip6_sr_localsid_t * ls0, + u32 * next0, + u8 psp, + ip6_ext_header_t * prev0) { ip6_address_t *new_dst0; - if(PREDICT_TRUE(ip0->protocol == IP_PROTOCOL_IPV6_ROUTE)) + if (PREDICT_TRUE (sr0->type == ROUTING_HEADER_TYPE_SR)) { - if(PREDICT_TRUE(sr0->type == ROUTING_HEADER_TYPE_SR)) + if (sr0->segments_left == 1 && psp) { - if(PREDICT_TRUE(sr0->segments_left != 0)) + u32 new_l0, sr_len; + u64 *copy_dst0, *copy_src0; + u32 copy_len_u64s0 = 0; + + ip0->dst_address.as_u64[0] = sr0->segments->as_u64[0]; + ip0->dst_address.as_u64[1] = sr0->segments->as_u64[1]; + + /* Remove the SRH taking care of the rest of IPv6 ext header */ + if (prev0) + prev0->next_hdr = sr0->protocol; + else + ip0->protocol = sr0->protocol; + + sr_len = ip6_ext_header_len (sr0); + vlib_buffer_advance (b0, sr_len); + new_l0 = clib_net_to_host_u16 (ip0->payload_length) - sr_len; + ip0->payload_length = clib_host_to_net_u16 (new_l0); + copy_src0 = (u64 *) ip0; + copy_dst0 = copy_src0 + (sr0->length + 1); + /* number of 8 octet units to copy + * By default in absence of extension headers it is equal to length of ip6 header + * With extension headers it number of 8 octet units of ext headers preceding + * SR header + */ + copy_len_u64s0 = + (((u8 *) sr0 - (u8 *) ip0) - sizeof (ip6_header_t)) >> 3; + copy_dst0[4 + copy_len_u64s0] = copy_src0[4 + copy_len_u64s0]; + copy_dst0[3 + copy_len_u64s0] = copy_src0[3 + copy_len_u64s0]; + copy_dst0[2 + copy_len_u64s0] = copy_src0[2 + copy_len_u64s0]; + copy_dst0[1 + copy_len_u64s0] = copy_src0[1 + copy_len_u64s0]; + copy_dst0[0 + copy_len_u64s0] = copy_src0[0 + copy_len_u64s0]; + + int i; + for (i = copy_len_u64s0 - 1; i >= 0; i--) { - sr0->segments_left -= 1; - new_dst0 = (ip6_address_t *)(sr0->segments); - new_dst0 += sr0->segments_left; - ip0->dst_address.as_u64[0] = new_dst0->as_u64[0]; - ip0->dst_address.as_u64[1] = new_dst0->as_u64[1]; + copy_dst0[i] = copy_src0[i]; } - else + + if (ls0->behavior == SR_BEHAVIOR_X) + { + vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0->nh_adj; + *next0 = SR_LOCALSID_NEXT_IP6_REWRITE; + } + else if(ls0->behavior == SR_BEHAVIOR_T) { - *next0 = SRV6_SAMPLE_LOCALSID_NEXT_ERROR; - b0->error = node->errors[SRV6_LOCALSID_COUNTER_NO_SRH]; + vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->vrf_index; + } + } + else if (PREDICT_TRUE(sr0->segments_left > 0)) + { + sr0->segments_left -= 1; + new_dst0 = (ip6_address_t *) (sr0->segments); + new_dst0 += sr0->segments_left; + ip0->dst_address.as_u64[0] = new_dst0->as_u64[0]; + ip0->dst_address.as_u64[1] = new_dst0->as_u64[1]; + + if (ls0->behavior == SR_BEHAVIOR_X) + { + vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0->nh_adj; + *next0 = SR_LOCALSID_NEXT_IP6_REWRITE; + } + else if(ls0->behavior == SR_BEHAVIOR_T) + { + vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->vrf_index; } } else { - /* Error. Routing header of type != SR */ - *next0 = SRV6_SAMPLE_LOCALSID_NEXT_ERROR; - b0->error = node->errors[SRV6_LOCALSID_COUNTER_NO_SRH]; + *next0 = SR_LOCALSID_NEXT_ERROR; + b0->error = node->errors[SR_LOCALSID_ERROR_NO_MORE_SEGMENTS]; } } + else + { + /* Error. Routing header of type != SR */ + *next0 = SR_LOCALSID_NEXT_ERROR; + b0->error = node->errors[SR_LOCALSID_ERROR_NO_SRH]; + } } /* @@ -114,7 +173,7 @@ srv6_localsid_sample_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_fram from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; next_index = node->cached_next_index; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vlib_get_thread_index (); while (n_left_from > 0) { @@ -129,6 +188,7 @@ srv6_localsid_sample_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_fram vlib_buffer_t * b0; ip6_header_t * ip0 = 0; ip6_sr_header_t * sr0; + ip6_ext_header_t *prev0 u32 next0 = SRV6_SAMPLE_LOCALSID_NEXT_IP6LOOKUP; ip6_sr_localsid_t *ls0; srv6_localsid_sample_per_sid_memory_t *ls0_mem; @@ -149,7 +209,8 @@ srv6_localsid_sample_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_fram ls0_mem = ls0->plugin_mem; /* SRH processing */ - end_srh_processing (node, b0, ip0, sr0, &next0); + ip6_ext_header_find_t (ip0, prev0, sr0, IP_PROTOCOL_IPV6_ROUTE); + end_decaps_srh_processing (node, b0, ip0, sr0, ls0, &next0); /* ==================================================================== */ /* INSERT CODE HERE */ @@ -168,7 +229,7 @@ srv6_localsid_sample_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_fram /* This increments the SRv6 per LocalSID counters.*/ vlib_increment_combined_counter (((next0 == SRV6_SAMPLE_LOCALSID_NEXT_ERROR) ? &(sm->sr_ls_invalid_counters) : &(sm->sr_ls_valid_counters)), - cpu_index, + thread_index, ls0 - sm->localsids, 1, vlib_buffer_length_in_chain (vm, b0));