lisp: Move to plugin
[vpp.git] / src / plugins / nsh / nsh-md2-ioam / nsh_md2_ioam_util.h
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 <lisp/lisp-gpe/lisp_gpe_packet.h>
19 #include <vnet/ip/ip.h>
20 #include <nsh/nsh.h>
21 #include <nsh/nsh-md2-ioam/nsh_md2_ioam.h>
22 #include <nsh/nsh_packet.h>
23
24
25 extern nsh_option_map_t *nsh_md2_lookup_option (u16 class, u8 type);
26
27
28 typedef struct
29 {
30   u8 trace_data[256];
31 } nsh_transit_trace_t;
32
33 always_inline void
34 nsh_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 =
56     (nsh_tlv_header_t *) ((u8 *) opt0 + (nsh_hdr->length * 4) -
57                           sizeof (nsh_base_header_t));
58
59   /*
60    * Basic validity checks
61    */
62   if ((nsh_hdr->length * 4) > clib_net_to_host_u16 (ip0->length))
63     {
64       *next0 = drop_node_val;
65       return;
66     }
67
68   if (nsh_hdr->md_type != 2)
69     {
70       *next0 = drop_node_val;
71       return;
72     }
73
74   /* Scan the set of h-b-h options, process ones that we understand */
75   while (opt0 < limit0)
76     {
77       u8 type0;
78       type0 = opt0->type;
79       switch (type0)
80         {
81         case 0:         /* Pad1 */
82           opt0 = (nsh_tlv_header_t *) ((u8 *) opt0) + 1;
83           continue;
84         case 1:         /* PadN */
85           break;
86         default:
87           nsh_option = nsh_md2_lookup_option (opt0->class, opt0->type);
88           if ((nsh_option != NULL) && (hm->options[nsh_option->option_id]))
89             {
90               if ((*hm->options[nsh_option->option_id]) (b0, opt0) < 0)
91                 {
92                   *next0 = drop_node_val;
93                   return;
94                 }
95             }
96           break;
97         }
98       opt0 =
99         (nsh_tlv_header_t *) (((u8 *) opt0) + opt0->length +
100                               sizeof (nsh_tlv_header_t));
101     }
102
103
104   if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
105     {
106       nsh_transit_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
107       clib_memcpy_fast (&(tr->trace_data), nsh_hdr, (nsh_hdr->length * 4));
108     }
109   return;
110 }
111
112
113 #endif
114
115 /*
116  * fd.io coding-style-patch-verification: ON
117  *
118  * Local Variables:
119  * eval: (c-set-style "gnu")
120  * End:
121  */