Line data Source code
1 : /* 2 : * Copyright (c) 2015 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_vxlan_gpe_ioam_util_h__ 16 : #define __included_vxlan_gpe_ioam_util_h__ 17 : 18 : #include <vnet/vxlan-gpe/vxlan_gpe.h> 19 : #include <vnet/vxlan-gpe/vxlan_gpe_packet.h> 20 : #include <vnet/ip/ip.h> 21 : 22 : 23 : typedef struct 24 : { 25 : u32 tunnel_index; 26 : ioam_trace_t fmt_trace; 27 : } vxlan_gpe_ioam_v4_trace_t; 28 : 29 : 30 : static u8 * 31 0 : format_vxlan_gpe_ioam_v4_trace (u8 * s, va_list * args) 32 : { 33 0 : CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); 34 0 : CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); 35 0 : vxlan_gpe_ioam_v4_trace_t *t1 = va_arg (*args, vxlan_gpe_ioam_v4_trace_t *); 36 0 : ioam_trace_t *t = &(t1->fmt_trace); 37 : vxlan_gpe_ioam_option_t *fmt_trace0; 38 : vxlan_gpe_ioam_option_t *opt0, *limit0; 39 0 : vxlan_gpe_ioam_main_t *hm = &vxlan_gpe_ioam_main; 40 : 41 : u8 type0; 42 : 43 0 : fmt_trace0 = (vxlan_gpe_ioam_option_t *) t->option_data; 44 : 45 0 : s = format (s, "VXLAN-GPE-IOAM: next_index %d len %d traced %d", 46 0 : t->next_index, fmt_trace0->length, t->trace_len); 47 : 48 0 : opt0 = (vxlan_gpe_ioam_option_t *) (fmt_trace0 + 1); 49 0 : limit0 = (vxlan_gpe_ioam_option_t *) ((u8 *) fmt_trace0) + t->trace_len; 50 : 51 0 : while (opt0 < limit0) 52 : { 53 0 : type0 = opt0->type; 54 0 : switch (type0) 55 : { 56 0 : case 0: /* Pad, just stop */ 57 0 : opt0 = (vxlan_gpe_ioam_option_t *) ((u8 *) opt0) + 1; 58 0 : break; 59 : 60 0 : default: 61 0 : if (hm->trace[type0]) 62 : { 63 0 : s = (*hm->trace[type0]) (s, opt0); 64 : } 65 : else 66 : { 67 : s = 68 0 : format (s, "\n unrecognized option %d length %d", type0, 69 0 : opt0->length); 70 : } 71 0 : opt0 = 72 0 : (vxlan_gpe_ioam_option_t *) (((u8 *) opt0) + opt0->length + 73 : sizeof (vxlan_gpe_ioam_option_t)); 74 0 : break; 75 : } 76 : } 77 : 78 0 : s = format (s, "VXLAN-GPE-IOAM: tunnel %d", t1->tunnel_index); 79 0 : return s; 80 : } 81 : 82 : 83 : always_inline void 84 0 : vxlan_gpe_encap_decap_ioam_v4_one_inline (vlib_main_t * vm, 85 : vlib_node_runtime_t * node, 86 : vlib_buffer_t * b0, 87 : u32 * next0, u32 drop_node_val, 88 : u8 use_adj) 89 : { 90 : ip4_header_t *ip0; 91 : udp_header_t *udp_hdr0; 92 : vxlan_gpe_header_t *gpe_hdr0; 93 : vxlan_gpe_ioam_hdr_t *gpe_ioam0; 94 : vxlan_gpe_ioam_option_t *opt0; 95 : vxlan_gpe_ioam_option_t *limit0; 96 0 : vxlan_gpe_ioam_main_t *hm = &vxlan_gpe_ioam_main; 97 : 98 : /* Populate the iOAM header */ 99 0 : ip0 = vlib_buffer_get_current (b0); 100 0 : udp_hdr0 = (udp_header_t *) (ip0 + 1); 101 0 : gpe_hdr0 = (vxlan_gpe_header_t *) (udp_hdr0 + 1); 102 0 : gpe_ioam0 = (vxlan_gpe_ioam_hdr_t *) (gpe_hdr0 + 1); 103 0 : opt0 = (vxlan_gpe_ioam_option_t *) (gpe_ioam0 + 1); 104 0 : limit0 = (vxlan_gpe_ioam_option_t *) ((u8 *) gpe_ioam0 + gpe_ioam0->length); 105 : 106 : /* 107 : * Basic validity checks 108 : */ 109 0 : if (gpe_ioam0->length > clib_net_to_host_u16 (ip0->length)) 110 : { 111 0 : *next0 = drop_node_val; 112 0 : return; 113 : } 114 : 115 : /* Scan the set of h-b-h options, process ones that we understand */ 116 0 : while (opt0 < limit0) 117 : { 118 : u8 type0; 119 0 : type0 = opt0->type; 120 0 : switch (type0) 121 : { 122 0 : case 0: /* Pad1 */ 123 0 : opt0 = (vxlan_gpe_ioam_option_t *) ((u8 *) opt0) + 1; 124 0 : continue; 125 0 : case 1: /* PadN */ 126 0 : break; 127 0 : default: 128 0 : if (hm->options[type0]) 129 : { 130 0 : if ((*hm->options[type0]) (b0, opt0, 1 /* is_ipv4 */ , 131 : use_adj) < 0) 132 : { 133 0 : *next0 = drop_node_val; 134 0 : return; 135 : } 136 : } 137 0 : break; 138 : } 139 0 : opt0 = 140 0 : (vxlan_gpe_ioam_option_t *) (((u8 *) opt0) + opt0->length + 141 : sizeof (vxlan_gpe_ioam_hdr_t)); 142 : } 143 : 144 : 145 0 : if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) 146 : { 147 : vxlan_gpe_ioam_v4_trace_t *t = 148 0 : vlib_add_trace (vm, node, b0, sizeof (*t)); 149 0 : u32 trace_len = gpe_ioam0->length; 150 0 : t->fmt_trace.next_index = *next0; 151 : /* Capture the ioam option verbatim */ 152 0 : trace_len = 153 : trace_len < 154 : ARRAY_LEN (t->fmt_trace. 155 : option_data) ? trace_len : ARRAY_LEN (t->fmt_trace. 156 : option_data); 157 0 : t->fmt_trace.trace_len = trace_len; 158 0 : clib_memcpy (&(t->fmt_trace.option_data), gpe_ioam0, trace_len); 159 : } 160 0 : return; 161 : } 162 : 163 : 164 : #endif 165 : 166 : /* 167 : * fd.io coding-style-patch-verification: ON 168 : * 169 : * Local Variables: 170 : * eval: (c-set-style "gnu") 171 : * End: 172 : */