nsh_md2_ioam_util.h revision f126e1c3
1/*
2 * Copyright (c) 2017 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef __included_nsh_md2_ioam_util_h__
16#define __included_nsh_md2_ioam_util_h__
17
18#include <vnet/lisp-gpe/lisp_gpe.h>
19#include <vnet/lisp-gpe/lisp_gpe_packet.h>
20#include <vnet/ip/ip.h>
21#include <nsh/nsh.h>
22#include <nsh-md2-ioam/nsh_md2_ioam.h>
23#include <nsh/nsh_packet.h>
24
25
26extern nsh_option_map_t * nsh_md2_lookup_option (u16 class, u8 type);
27
28
29typedef struct {
30   u8 trace_data[256];
31} nsh_transit_trace_t;
32
33always_inline void
34nsh_md2_ioam_encap_decap_ioam_v4_one_inline (vlib_main_t * vm,
35					  vlib_node_runtime_t * node,
36					  vlib_buffer_t * b0,
37					  u32 * next0, u32 drop_node_val,
38					  u8 use_adj)
39{
40  ip4_header_t *ip0;
41  udp_header_t *udp_hdr0;
42  lisp_gpe_header_t *lisp_gpe_hdr0;
43  nsh_base_header_t *nsh_hdr;
44  nsh_tlv_header_t *opt0;
45  nsh_tlv_header_t *limit0;
46  nsh_main_t *hm = &nsh_main;
47  nsh_option_map_t *nsh_option;
48
49  /* Populate the iOAM header */
50  ip0 = vlib_buffer_get_current (b0);
51  udp_hdr0 = (udp_header_t *) (ip0 + 1);
52  lisp_gpe_hdr0 = (lisp_gpe_header_t *) (udp_hdr0 + 1);
53  nsh_hdr = (nsh_base_header_t *)(lisp_gpe_hdr0 + 1);
54  opt0 = (nsh_tlv_header_t *) (nsh_hdr + 1);
55  limit0 = (nsh_tlv_header_t *) ((u8 *) opt0 + (nsh_hdr->length *4) - sizeof(nsh_base_header_t));
56
57  /*
58   * Basic validity checks
59   */
60  if ((nsh_hdr->length*4) > clib_net_to_host_u16 (ip0->length))
61    {
62      *next0 = drop_node_val;
63      return;
64    }
65
66  if (nsh_hdr->md_type != 2)
67    {
68      *next0 = drop_node_val;
69      return;
70    }
71
72  /* Scan the set of h-b-h options, process ones that we understand */
73  while (opt0 < limit0)
74    {
75      u8 type0;
76      type0 = opt0->type;
77      switch (type0)
78	{
79	case 0:		/* Pad1 */
80	  opt0 = (nsh_tlv_header_t *) ((u8 *) opt0) + 1;
81	  continue;
82	case 1:		/* PadN */
83	  break;
84	default:
85          nsh_option = nsh_md2_lookup_option(opt0->class, opt0->type);
86          if(( nsh_option != NULL) && (hm->options[nsh_option->option_id]))
87	    {
88	       if ((*hm->options[nsh_option->option_id]) (b0, opt0) < 0)
89		  {
90		     *next0 = drop_node_val;
91		     return;
92		  }
93	    }
94	  break;
95	}
96      opt0 =
97	(nsh_tlv_header_t *) (((u8 *) opt0) + opt0->length +
98				     sizeof (nsh_tlv_header_t));
99    }
100
101
102  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
103    {
104      nsh_transit_trace_t *tr = vlib_add_trace(vm, node, b0, sizeof(*tr));
105      clib_memcpy ( &(tr->trace_data), nsh_hdr, (nsh_hdr->length*4) );
106    }
107  return;
108}
109
110
111#endif
112
113/*
114 * fd.io coding-style-patch-verification: ON
115 *
116 * Local Variables:
117 * eval: (c-set-style "gnu")
118 * End:
119 */
120