-// Function for SRv6 GTP6.DT function
-VLIB_NODE_FN (srv6_end_m_gtp6_dt) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- srv6_end_main_v6_dt_t *sm = &srv6_end_main_v6_dt;
- ip6_sr_main_t *sm2 = &sr_main;
- u32 n_left_from, next_index, *from, *to_next;
- u32 thread_index = vm->thread_index;
-
- u32 good_n = 0, bad_n = 0;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 bi0;
- vlib_buffer_t *b0;
- srv6_end_gtp6_dt_param_t *ls_param;
- ip6_sr_localsid_t *ls0;
-
- ip6_gtpu_header_t *hdr0 = NULL;
- ip4_header_t *ip4 = NULL;
- ip6_header_t *ip6 = NULL;
- ip6_address_t src, dst;
- u32 teid;
- u32 hdrlen;
- u32 len0;
-
- u32 next0 = SRV6_END_M_GTP6_DT_NEXT_DROP;
-
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
- ls0 =
- pool_elt_at_index (sm2->localsids,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
-
- ls_param = (srv6_end_gtp6_dt_param_t *) ls0->plugin_mem;
-
- hdr0 = vlib_buffer_get_current (b0);
-
- hdrlen = sizeof (ip6_gtpu_header_t);
-
- len0 = vlib_buffer_length_in_chain (vm, b0);
-
- if ((hdr0->ip6.protocol != IP_PROTOCOL_UDP)
- || (hdr0->udp.dst_port !=
- clib_host_to_net_u16 (SRV6_GTP_UDP_DST_PORT))
- || (len0 < sizeof (ip6_gtpu_header_t)))
- {
- next0 = SRV6_END_M_GTP6_DT_NEXT_DROP;
-
- bad_n++;
- }
- else
- {
- clib_memcpy_fast (src.as_u8, hdr0->ip6.src_address.as_u8,
- sizeof (ip6_address_t));
- clib_memcpy_fast (dst.as_u8, hdr0->ip6.dst_address.as_u8,
- sizeof (ip6_address_t));
-
- teid = hdr0->gtpu.teid;
-
- if (hdr0->gtpu.ver_flags & GTPU_EXTHDR_FLAG)
- {
- hdrlen += sizeof (gtpu_exthdr_t);
- if (hdr0->gtpu.ext->nextexthdr == GTPU_EXTHDR_PDU_SESSION)
- {
- gtpu_pdu_session_t *sess;
-
- sess =
- (gtpu_pdu_session_t *) (((char *) hdr0) +
- sizeof (ip6_gtpu_header_t) +
- sizeof (gtpu_exthdr_t));
-
- hdrlen += sizeof (gtpu_pdu_session_t);
- if (sess->u.val & GTPU_PDU_SESSION_P_BIT_MASK)
- {
- hdrlen += sizeof (gtpu_paging_policy_t);
- }
- }
- }
-
- if (ls_param->type == SRV6_GTP6_DT4)
- {
- vlib_buffer_advance (b0, (word) hdrlen);
- ip4 = vlib_buffer_get_current (b0);
- if ((ip4->ip_version_and_header_length & 0xf0) != 0x40)
- {
- next0 = SRV6_END_M_GTP6_DT_NEXT_DROP;
- bad_n++;
- goto DONE;
- }
-
- next0 = SRV6_END_M_GTP6_DT_NEXT_LOOKUP4;
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->fib4_index;
- }
- else if (ls_param->type == SRV6_GTP6_DT6)
- {
- ip6 = (ip6_header_t *) ((u8 *) hdr0 + hdrlen);
- if ((clib_net_to_host_u32
- (ip6->ip_version_traffic_class_and_flow_label) >> 28)
- != 6)
- {
- next0 = SRV6_END_M_GTP6_DT_NEXT_DROP;
- bad_n++;
- goto DONE;
- }
-
- next0 = SRV6_END_M_GTP6_DT_NEXT_LOOKUP6;
- if ((ip6->dst_address.as_u8[0] == 0xfe)
- && ((ip6->dst_address.as_u8[1] & 0xc0) == 0x80))
- {
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->local_fib_index;
- }
- else
- {
- vlib_buffer_advance (b0, (word) hdrlen);
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->fib6_index;
- }
- }
- else if (ls_param->type == SRV6_GTP6_DT46)
- {
- ip6 = (ip6_header_t *) ((u8 *) hdr0 + hdrlen);
- if ((clib_net_to_host_u32
- (ip6->ip_version_traffic_class_and_flow_label) >> 28)
- == 6)
- {
- next0 = SRV6_END_M_GTP6_DT_NEXT_LOOKUP6;
- if ((ip6->dst_address.as_u8[0] == 0xfe)
- && ((ip6->dst_address.as_u8[1] & 0xc0) == 0x80))
- {
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->local_fib_index;
- }
- else
- {
- vlib_buffer_advance (b0, (word) hdrlen);
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->fib6_index;
- }
- }
- else
- if ((clib_net_to_host_u32
- (ip6->ip_version_traffic_class_and_flow_label) >> 28)
- == 4)
- {
- vlib_buffer_advance (b0, (word) hdrlen);
- next0 = SRV6_END_M_GTP6_DT_NEXT_LOOKUP4;
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->fib4_index;
- }
- else
- {
- next0 = SRV6_END_M_GTP6_DT_NEXT_DROP;
- bad_n++;
- goto DONE;
- }
- }
- else
- {
- next0 = SRV6_END_M_GTP6_DT_NEXT_DROP;
- bad_n++;
- goto DONE;
- }
-
- good_n++;
-
- if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
- PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- srv6_end_rewrite_trace_t *tr =
- vlib_add_trace (vm, node, b0, sizeof (*tr));
- clib_memcpy (tr->src.as_u8, src.as_u8,
- sizeof (ip6_address_t));
- clib_memcpy (tr->dst.as_u8, dst.as_u8,
- sizeof (ip6_address_t));
- tr->teid = teid;
- }
- }
-
- DONE:
- vlib_increment_combined_counter
- (((next0 ==
- SRV6_END_M_GTP6_DT_NEXT_DROP) ? &(sm2->sr_ls_invalid_counters)
- : &(sm2->sr_ls_valid_counters)), thread_index,
- ls0 - sm2->localsids, 1, vlib_buffer_length_in_chain (vm, b0));
-
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
- n_left_to_next, bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, sm->end_m_gtp6_dt_node_index,
- SRV6_END_ERROR_M_GTP6_DT_BAD_PACKETS, bad_n);
-
- vlib_node_increment_counter (vm, sm->end_m_gtp6_dt_node_index,
- SRV6_END_ERROR_M_GTP6_DT_PACKETS, good_n);
-
- return frame->n_vectors;
-}
-
-// Function for SRv6 GTP4.DT function
-VLIB_NODE_FN (srv6_t_m_gtp4_dt) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- srv6_t_main_v4_dt_t *sm = &srv6_t_main_v4_dt;
- ip6_sr_main_t *sm2 = &sr_main;
- u32 n_left_from, next_index, *from, *to_next;
-
- u32 good_n = 0, bad_n = 0;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 bi0;
- vlib_buffer_t *b0;
- srv6_t_gtp4_dt_param_t *ls_param;
- ip6_sr_sl_t *ls0;
-
- ip4_gtpu_header_t *hdr0 = NULL;
- ip4_header_t *ip4 = NULL;
- ip6_header_t *ip6 = NULL;
- ip6_address_t src, dst;
- u32 teid;
- u32 hdrlen;
- u32 len0;
-
- u32 next0 = SRV6_T_M_GTP4_DT_NEXT_DROP;
-
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
- ls0 =
- pool_elt_at_index (sm2->sid_lists,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
-
- ls_param = (srv6_t_gtp4_dt_param_t *) ls0->plugin_mem;
-
- hdr0 = vlib_buffer_get_current (b0);
-
- hdrlen = sizeof (ip4_gtpu_header_t);
-
- len0 = vlib_buffer_length_in_chain (vm, b0);
-
- if ((hdr0->ip4.protocol != IP_PROTOCOL_UDP)
- || (hdr0->udp.dst_port !=
- clib_host_to_net_u16 (SRV6_GTP_UDP_DST_PORT))
- || (len0 < sizeof (ip4_gtpu_header_t)))
- {
- next0 = SRV6_T_M_GTP4_DT_NEXT_DROP;
-
- bad_n++;
- }
- else
- {
- clib_memcpy_fast (src.as_u8, hdr0->ip4.src_address.as_u8,
- sizeof (ip4_address_t));
- clib_memcpy_fast (dst.as_u8, hdr0->ip4.dst_address.as_u8,
- sizeof (ip4_address_t));
-
- teid = hdr0->gtpu.teid;
-
- if (hdr0->gtpu.ver_flags & GTPU_EXTHDR_FLAG)
- {
- hdrlen += sizeof (gtpu_exthdr_t);
- if (hdr0->gtpu.ext->nextexthdr == GTPU_EXTHDR_PDU_SESSION)
- {
- gtpu_pdu_session_t *sess;
-
- sess =
- (gtpu_pdu_session_t *) (((char *) hdr0) +
- sizeof (ip6_gtpu_header_t) +
- sizeof (gtpu_exthdr_t));
-
- hdrlen += sizeof (gtpu_pdu_session_t);
- if (sess->u.val & GTPU_PDU_SESSION_P_BIT_MASK)
- {
- hdrlen += sizeof (gtpu_paging_policy_t);
- }
- }
- }
-
- if (ls_param->type == SRV6_GTP4_DT4)
- {
- vlib_buffer_advance (b0, (word) hdrlen);
- ip4 = vlib_buffer_get_current (b0);
- if ((ip4->ip_version_and_header_length & 0xf0) != 0x40)
- {
- next0 = SRV6_T_M_GTP4_DT_NEXT_DROP;
- bad_n++;
- goto DONE;
- }
-
- next0 = SRV6_T_M_GTP4_DT_NEXT_LOOKUP4;
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->fib4_index;
- }
- else if (ls_param->type == SRV6_GTP4_DT6)
- {
- ip6 = (ip6_header_t *) ((u8 *) hdr0 + hdrlen);
- if ((clib_net_to_host_u32
- (ip6->ip_version_traffic_class_and_flow_label) >> 28)
- != 6)
- {
- next0 = SRV6_T_M_GTP4_DT_NEXT_DROP;
- bad_n++;
- goto DONE;
- }
-
- next0 = SRV6_T_M_GTP4_DT_NEXT_LOOKUP6;
- if ((ip6->dst_address.as_u8[0] == 0xfe)
- && ((ip6->dst_address.as_u8[1] & 0xc0) == 0x80))
- {
- next0 = SRV6_T_M_GTP4_DT_NEXT_LOOKUP4;
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->local_fib_index;
- }
- else
- {
- vlib_buffer_advance (b0, (word) hdrlen);
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->fib6_index;
- }
- }
- else if (ls_param->type == SRV6_GTP4_DT46)
- {
- ip6 = (ip6_header_t *) ((u8 *) hdr0 + hdrlen);
- if ((clib_net_to_host_u32
- (ip6->ip_version_traffic_class_and_flow_label) >> 28)
- == 6)
- {
- next0 = SRV6_T_M_GTP4_DT_NEXT_LOOKUP6;
- if ((ip6->dst_address.as_u8[0] == 0xfe)
- && ((ip6->dst_address.as_u8[1] & 0xc0) == 0x80))
- {
- next0 = SRV6_T_M_GTP4_DT_NEXT_LOOKUP4;
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->local_fib_index;
- }
- else
- {
- vlib_buffer_advance (b0, (word) hdrlen);
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->fib6_index;
- }
- }
- else
- if ((clib_net_to_host_u32
- (ip6->ip_version_traffic_class_and_flow_label) >> 28)
- == 4)
- {
- vlib_buffer_advance (b0, (word) hdrlen);
- next0 = SRV6_T_M_GTP4_DT_NEXT_LOOKUP4;
- vnet_buffer (b0)->sw_if_index[VLIB_TX] =
- ls_param->fib4_index;
- }
- else
- {
- next0 = SRV6_T_M_GTP4_DT_NEXT_DROP;
- bad_n++;
- goto DONE;
- }
- }
- else
- {
- next0 = SRV6_T_M_GTP4_DT_NEXT_DROP;
- bad_n++;
- goto DONE;
- }
-
- good_n++;
-
- if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
- PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- srv6_end_rewrite_trace_t *tr =
- vlib_add_trace (vm, node, b0, sizeof (*tr));
- clib_memcpy (tr->src.as_u8, src.as_u8,
- sizeof (ip6_address_t));
- clib_memcpy (tr->dst.as_u8, dst.as_u8,
- sizeof (ip6_address_t));
- tr->teid = teid;
- }
- }
-
- DONE:
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
- n_left_to_next, bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, sm->t_m_gtp4_dt_node_index,
- SRV6_T_ERROR_M_GTP4_DT_BAD_PACKETS, bad_n);
-
- vlib_node_increment_counter (vm, sm->t_m_gtp4_dt_node_index,
- SRV6_T_ERROR_M_GTP4_DT_PACKETS, good_n);
-
- return frame->n_vectors;
-}
-