Line data Source code
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 0 : 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 0 : nsh_main_t *hm = &nsh_main; 47 : nsh_option_map_t *nsh_option; 48 : 49 : /* Populate the iOAM header */ 50 0 : ip0 = vlib_buffer_get_current (b0); 51 0 : udp_hdr0 = (udp_header_t *) (ip0 + 1); 52 0 : lisp_gpe_hdr0 = (lisp_gpe_header_t *) (udp_hdr0 + 1); 53 0 : nsh_hdr = (nsh_base_header_t *) (lisp_gpe_hdr0 + 1); 54 0 : opt0 = (nsh_tlv_header_t *) (nsh_hdr + 1); 55 0 : limit0 = 56 0 : (nsh_tlv_header_t *) ((u8 *) opt0 + (nsh_hdr->length * 4) - 57 : sizeof (nsh_base_header_t)); 58 : 59 : /* 60 : * Basic validity checks 61 : */ 62 0 : if ((nsh_hdr->length * 4) > clib_net_to_host_u16 (ip0->length)) 63 : { 64 0 : *next0 = drop_node_val; 65 0 : return; 66 : } 67 : 68 0 : if (nsh_hdr->md_type != 2) 69 : { 70 0 : *next0 = drop_node_val; 71 0 : return; 72 : } 73 : 74 : /* Scan the set of h-b-h options, process ones that we understand */ 75 0 : while (opt0 < limit0) 76 : { 77 : u8 type0; 78 0 : type0 = opt0->type; 79 0 : switch (type0) 80 : { 81 0 : case 0: /* Pad1 */ 82 0 : opt0 = (nsh_tlv_header_t *) ((u8 *) opt0) + 1; 83 0 : continue; 84 0 : case 1: /* PadN */ 85 0 : break; 86 0 : default: 87 0 : nsh_option = nsh_md2_lookup_option (opt0->class, opt0->type); 88 0 : if ((nsh_option != NULL) && (hm->options[nsh_option->option_id])) 89 : { 90 0 : if ((*hm->options[nsh_option->option_id]) (b0, opt0) < 0) 91 : { 92 0 : *next0 = drop_node_val; 93 0 : return; 94 : } 95 : } 96 0 : break; 97 : } 98 0 : opt0 = 99 0 : (nsh_tlv_header_t *) (((u8 *) opt0) + opt0->length + 100 : sizeof (nsh_tlv_header_t)); 101 : } 102 : 103 : 104 0 : if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) 105 : { 106 0 : nsh_transit_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); 107 0 : clib_memcpy_fast (&(tr->trace_data), nsh_hdr, (nsh_hdr->length * 4)); 108 : } 109 0 : 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 : */