Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 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 | #include <vlib/vlib.h> |
| 16 | #include <vnet/pg/pg.h> |
| 17 | #include <vnet/ethernet/ethernet.h> |
| 18 | #include <vppinfra/error.h> |
| 19 | #include <vnet/devices/pci/ige.h> |
| 20 | #include <vnet/devices/pci/ixge.h> |
| 21 | #include <vnet/devices/pci/ixgev.h> |
| 22 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 23 | typedef struct |
| 24 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 25 | u32 cached_next_index; |
| 26 | u32 cached_sw_if_index; |
| 27 | |
| 28 | /* Hash table to map sw_if_index to next node index */ |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 29 | uword *next_node_index_by_sw_if_index; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 30 | |
| 31 | /* convenience */ |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 32 | vlib_main_t *vlib_main; |
| 33 | vnet_main_t *vnet_main; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 34 | } mac_swap_main_t; |
| 35 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 36 | typedef struct |
| 37 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 38 | u8 src[6]; |
| 39 | u8 dst[6]; |
| 40 | u32 sw_if_index; |
| 41 | u32 next_index; |
| 42 | } swap_trace_t; |
| 43 | |
| 44 | /* packet trace format function */ |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 45 | static u8 * |
| 46 | format_swap_trace (u8 * s, va_list * args) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 47 | { |
| 48 | CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); |
| 49 | CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 50 | swap_trace_t *t = va_arg (*args, swap_trace_t *); |
| 51 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 52 | s = format (s, "SWAP: dst now %U src now %U sw_if_index %d next_index %d", |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 53 | format_ethernet_address, t->dst, |
| 54 | format_ethernet_address, t->src, t->sw_if_index, t->next_index); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 55 | return s; |
| 56 | } |
| 57 | |
| 58 | #define foreach_hw_driver_next \ |
| 59 | _(IP4) \ |
| 60 | _(IP6) \ |
| 61 | _(ETHERNET) |
| 62 | |
| 63 | mac_swap_main_t mac_swap_main; |
| 64 | |
| 65 | static vlib_node_registration_t mac_swap_node; |
| 66 | |
| 67 | #define foreach_mac_swap_error \ |
| 68 | _(SWAPS, "mac addresses swapped") |
| 69 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 70 | typedef enum |
| 71 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 72 | #define _(sym,str) MAC_SWAP_ERROR_##sym, |
| 73 | foreach_mac_swap_error |
| 74 | #undef _ |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 75 | MAC_SWAP_N_ERROR, |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 76 | } mac_swap_error_t; |
| 77 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 78 | static char *mac_swap_error_strings[] = { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 79 | #define _(sym,string) string, |
| 80 | foreach_mac_swap_error |
| 81 | #undef _ |
| 82 | }; |
| 83 | |
Damjan Marion | 607de1a | 2016-08-16 22:53:54 +0200 | [diff] [blame] | 84 | /* |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 85 | * To drop a pkt and increment one of the previous counters: |
Damjan Marion | 607de1a | 2016-08-16 22:53:54 +0200 | [diff] [blame] | 86 | * |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 87 | * set b0->error = error_node->errors[RANDOM_ERROR_SAMPLE]; |
| 88 | * set next0 to a disposition index bound to "error-drop". |
| 89 | * |
| 90 | * To manually increment the specific counter MAC_SWAP_ERROR_SAMPLE: |
| 91 | * |
| 92 | * vlib_node_t *n = vlib_get_node (vm, mac_swap.index); |
| 93 | * u32 node_counter_base_index = n->error_heap_index; |
| 94 | * vlib_error_main_t * em = &vm->error_main; |
| 95 | * em->counters[node_counter_base_index + MAC_SWAP_ERROR_SAMPLE] += 1; |
Damjan Marion | 607de1a | 2016-08-16 22:53:54 +0200 | [diff] [blame] | 96 | * |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 97 | */ |
| 98 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 99 | typedef enum |
| 100 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 101 | MAC_SWAP_NEXT_DROP, |
| 102 | MAC_SWAP_N_NEXT, |
| 103 | } mac_swap_next_t; |
| 104 | |
| 105 | static uword |
| 106 | mac_swap_node_fn (vlib_main_t * vm, |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 107 | vlib_node_runtime_t * node, vlib_frame_t * frame) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 108 | { |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 109 | u32 n_left_from, *from, *to_next; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 110 | mac_swap_next_t next_index; |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 111 | mac_swap_main_t *msm = &mac_swap_main; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 112 | vlib_node_t *n = vlib_get_node (vm, mac_swap_node.index); |
| 113 | u32 node_counter_base_index = n->error_heap_index; |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 114 | vlib_error_main_t *em = &vm->error_main; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 115 | |
| 116 | from = vlib_frame_vector_args (frame); |
| 117 | n_left_from = frame->n_vectors; |
| 118 | next_index = node->cached_next_index; |
| 119 | |
| 120 | while (n_left_from > 0) |
| 121 | { |
| 122 | u32 n_left_to_next; |
| 123 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 124 | vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 125 | |
| 126 | while (n_left_from >= 4 && n_left_to_next >= 2) |
| 127 | { |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 128 | u32 bi0, bi1; |
| 129 | vlib_buffer_t *b0, *b1; |
| 130 | u32 next0, next1; |
| 131 | u32 sw_if_index0, sw_if_index1; |
| 132 | uword *p0, *p1; |
| 133 | u64 tmp0a, tmp0b; |
| 134 | u64 tmp1a, tmp1b; |
| 135 | ethernet_header_t *h0, *h1; |
| 136 | |
| 137 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 138 | /* Prefetch next iteration. */ |
| 139 | { |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 140 | vlib_buffer_t *p2, *p3; |
| 141 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 142 | p2 = vlib_get_buffer (vm, from[2]); |
| 143 | p3 = vlib_get_buffer (vm, from[3]); |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 144 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 145 | vlib_prefetch_buffer_header (p2, LOAD); |
| 146 | vlib_prefetch_buffer_header (p3, LOAD); |
| 147 | |
| 148 | CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE); |
| 149 | CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE); |
| 150 | } |
| 151 | |
| 152 | to_next[0] = bi0 = from[0]; |
| 153 | to_next[1] = bi1 = from[1]; |
| 154 | from += 2; |
| 155 | to_next += 2; |
| 156 | n_left_from -= 2; |
| 157 | n_left_to_next -= 2; |
| 158 | |
| 159 | b0 = vlib_get_buffer (vm, bi0); |
| 160 | b1 = vlib_get_buffer (vm, bi1); |
| 161 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 162 | sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; |
| 163 | next0 = msm->cached_next_index; |
| 164 | sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; |
| 165 | next1 = msm->cached_next_index; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 166 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 167 | if (PREDICT_FALSE (msm->cached_sw_if_index != sw_if_index0)) |
| 168 | { |
| 169 | p0 = |
| 170 | hash_get (msm->next_node_index_by_sw_if_index, sw_if_index0); |
| 171 | if (p0 == 0) |
| 172 | { |
| 173 | vnet_hw_interface_t *hw0; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 174 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 175 | hw0 = vnet_get_sup_hw_interface (msm->vnet_main, |
| 176 | sw_if_index0); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 177 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 178 | next0 = vlib_node_add_next (msm->vlib_main, |
| 179 | mac_swap_node.index, |
| 180 | hw0->output_node_index); |
| 181 | hash_set (msm->next_node_index_by_sw_if_index, |
| 182 | sw_if_index0, next0); |
| 183 | } |
| 184 | else |
| 185 | next0 = p0[0]; |
| 186 | msm->cached_sw_if_index = sw_if_index0; |
| 187 | msm->cached_next_index = next0; |
| 188 | next1 = next0; |
| 189 | } |
| 190 | if (PREDICT_FALSE (msm->cached_sw_if_index != sw_if_index1)) |
| 191 | { |
| 192 | p1 = |
| 193 | hash_get (msm->next_node_index_by_sw_if_index, sw_if_index1); |
| 194 | if (p1 == 0) |
| 195 | { |
| 196 | vnet_hw_interface_t *hw1; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 197 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 198 | hw1 = vnet_get_sup_hw_interface (msm->vnet_main, |
| 199 | sw_if_index1); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 200 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 201 | next1 = vlib_node_add_next (msm->vlib_main, |
| 202 | mac_swap_node.index, |
| 203 | hw1->output_node_index); |
| 204 | hash_set (msm->next_node_index_by_sw_if_index, |
| 205 | sw_if_index1, next1); |
| 206 | } |
| 207 | else |
| 208 | next1 = p1[0]; |
| 209 | msm->cached_sw_if_index = sw_if_index1; |
| 210 | msm->cached_next_index = next1; |
| 211 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 212 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 213 | em->counters[node_counter_base_index + MAC_SWAP_ERROR_SWAPS] += 2; |
| 214 | |
| 215 | /* reset buffer so we always point at the MAC hdr */ |
| 216 | vlib_buffer_reset (b0); |
| 217 | vlib_buffer_reset (b1); |
| 218 | h0 = vlib_buffer_get_current (b0); |
| 219 | h1 = vlib_buffer_get_current (b1); |
| 220 | |
| 221 | /* Swap 2 x src and dst mac addresses using 8-byte load/stores */ |
| 222 | tmp0a = clib_net_to_host_u64 (((u64 *) (h0->dst_address))[0]); |
| 223 | tmp1a = clib_net_to_host_u64 (((u64 *) (h1->dst_address))[0]); |
| 224 | tmp0b = clib_net_to_host_u64 (((u64 *) (h0->src_address))[0]); |
| 225 | tmp1b = clib_net_to_host_u64 (((u64 *) (h1->src_address))[0]); |
| 226 | ((u64 *) (h0->dst_address))[0] = clib_host_to_net_u64 (tmp0b); |
| 227 | ((u64 *) (h1->dst_address))[0] = clib_host_to_net_u64 (tmp1b); |
| 228 | /* Move the ethertype from "b" to "a" */ |
| 229 | tmp0a &= ~(0xFFFF); |
| 230 | tmp1a &= ~(0xFFFF); |
| 231 | tmp0a |= tmp0b & 0xFFFF; |
| 232 | ((u64 *) (h0->src_address))[0] = clib_host_to_net_u64 (tmp0a); |
| 233 | tmp1a |= tmp1b & 0xFFFF; |
| 234 | ((u64 *) (h1->src_address))[0] = clib_host_to_net_u64 (tmp1a); |
| 235 | |
| 236 | if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE))) |
| 237 | { |
| 238 | if (b0->flags & VLIB_BUFFER_IS_TRACED) |
| 239 | { |
| 240 | swap_trace_t *t = |
| 241 | vlib_add_trace (vm, node, b0, sizeof (*t)); |
| 242 | clib_memcpy (t->src, h0->src_address, 6); |
| 243 | clib_memcpy (t->dst, h0->dst_address, 6); |
| 244 | t->sw_if_index = sw_if_index0; |
| 245 | t->next_index = next0; |
| 246 | } |
| 247 | if (b1->flags & VLIB_BUFFER_IS_TRACED) |
| 248 | { |
| 249 | swap_trace_t *t = |
| 250 | vlib_add_trace (vm, node, b1, sizeof (*t)); |
| 251 | clib_memcpy (t->src, h1->src_address, 6); |
| 252 | clib_memcpy (t->dst, h1->dst_address, 6); |
| 253 | t->sw_if_index = sw_if_index1; |
| 254 | t->next_index = next1; |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | vlib_validate_buffer_enqueue_x2 (vm, node, next_index, |
| 259 | to_next, n_left_to_next, |
| 260 | bi0, bi1, next0, next1); |
| 261 | } |
| 262 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 263 | while (n_left_from > 0 && n_left_to_next > 0) |
| 264 | { |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 265 | u32 bi0; |
| 266 | vlib_buffer_t *b0; |
| 267 | u32 next0; |
| 268 | u32 sw_if_index0; |
| 269 | uword *p0; |
| 270 | u64 tmp0a, tmp0b; |
| 271 | ethernet_header_t *h0; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 272 | |
| 273 | bi0 = from[0]; |
| 274 | to_next[0] = bi0; |
| 275 | from += 1; |
| 276 | to_next += 1; |
| 277 | n_left_from -= 1; |
| 278 | n_left_to_next -= 1; |
| 279 | |
| 280 | b0 = vlib_get_buffer (vm, bi0); |
| 281 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 282 | sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; |
| 283 | next0 = msm->cached_next_index; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 284 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 285 | if (PREDICT_FALSE (msm->cached_sw_if_index != sw_if_index0)) |
| 286 | { |
| 287 | p0 = |
| 288 | hash_get (msm->next_node_index_by_sw_if_index, sw_if_index0); |
| 289 | if (p0 == 0) |
| 290 | { |
| 291 | vnet_hw_interface_t *hw0; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 292 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 293 | hw0 = vnet_get_sup_hw_interface (msm->vnet_main, |
| 294 | sw_if_index0); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 295 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 296 | next0 = vlib_node_add_next (msm->vlib_main, |
| 297 | mac_swap_node.index, |
| 298 | hw0->output_node_index); |
| 299 | hash_set (msm->next_node_index_by_sw_if_index, |
| 300 | sw_if_index0, next0); |
| 301 | } |
| 302 | else |
| 303 | next0 = p0[0]; |
| 304 | msm->cached_sw_if_index = sw_if_index0; |
| 305 | msm->cached_next_index = next0; |
| 306 | } |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 307 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 308 | em->counters[node_counter_base_index + MAC_SWAP_ERROR_SWAPS] += 1; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 309 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 310 | /* reset buffer so we always point at the MAC hdr */ |
| 311 | vlib_buffer_reset (b0); |
| 312 | h0 = vlib_buffer_get_current (b0); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 313 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 314 | /* Exchange src and dst, preserve the ethertype */ |
| 315 | tmp0a = clib_net_to_host_u64 (((u64 *) (h0->dst_address))[0]); |
| 316 | tmp0b = clib_net_to_host_u64 (((u64 *) (h0->src_address))[0]); |
| 317 | ((u64 *) (h0->dst_address))[0] = clib_host_to_net_u64 (tmp0b); |
| 318 | tmp0a &= ~(0xFFFF); |
| 319 | tmp0a |= tmp0b & 0xFFFF; |
| 320 | ((u64 *) (h0->src_address))[0] = clib_host_to_net_u64 (tmp0a); |
| 321 | |
| 322 | /* ship it */ |
| 323 | if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) |
| 324 | && (b0->flags & VLIB_BUFFER_IS_TRACED))) |
| 325 | { |
| 326 | swap_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); |
| 327 | clib_memcpy (t->src, h0->src_address, 6); |
| 328 | clib_memcpy (t->dst, h0->dst_address, 6); |
| 329 | t->sw_if_index = sw_if_index0; |
| 330 | t->next_index = next0; |
| 331 | } |
| 332 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 333 | vlib_validate_buffer_enqueue_x1 (vm, node, next_index, |
| 334 | to_next, n_left_to_next, |
| 335 | bi0, next0); |
| 336 | } |
| 337 | |
| 338 | vlib_put_next_frame (vm, node, next_index, n_left_to_next); |
| 339 | } |
| 340 | |
| 341 | return frame->n_vectors; |
| 342 | } |
| 343 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 344 | /* *INDENT-OFF* */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 345 | VLIB_REGISTER_NODE (mac_swap_node,static) = { |
| 346 | .function = mac_swap_node_fn, |
| 347 | .name = "mac-swap", |
| 348 | .vector_size = sizeof (u32), |
| 349 | .format_trace = format_swap_trace, |
| 350 | .type = VLIB_NODE_TYPE_INTERNAL, |
Damjan Marion | 607de1a | 2016-08-16 22:53:54 +0200 | [diff] [blame] | 351 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 352 | .n_errors = ARRAY_LEN(mac_swap_error_strings), |
| 353 | .error_strings = mac_swap_error_strings, |
| 354 | |
| 355 | .n_next_nodes = MAC_SWAP_N_NEXT, |
| 356 | |
| 357 | /* edit / add dispositions here */ |
| 358 | .next_nodes = { |
| 359 | [MAC_SWAP_NEXT_DROP] = "error-drop", |
| 360 | }, |
| 361 | }; |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 362 | /* *INDENT-ON* */ |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 363 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 364 | clib_error_t * |
| 365 | mac_swap_init (vlib_main_t * vm) |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 366 | { |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 367 | mac_swap_main_t *msm = &mac_swap_main; |
| 368 | |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 369 | msm->next_node_index_by_sw_if_index = hash_create (0, sizeof (uword)); |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 370 | msm->cached_next_index = (u32) ~ 0; |
| 371 | msm->cached_sw_if_index = (u32) ~ 0; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 372 | msm->vlib_main = vm; |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 373 | msm->vnet_main = vnet_get_main (); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 374 | |
| 375 | /* Driver RX nodes send pkts here... */ |
| 376 | #define _(a) ixge_set_next_node (IXGE_RX_NEXT_##a##_INPUT, "mac-swap"); |
| 377 | foreach_hw_driver_next |
| 378 | #undef _ |
| 379 | #define _(a) ixgev_set_next_node (IXGEV_RX_NEXT_##a##_INPUT, "mac-swap"); |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 380 | foreach_hw_driver_next |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 381 | #undef _ |
| 382 | #define _(a) ige_set_next_node (IGE_RX_NEXT_##a##_INPUT, "mac-swap"); |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 383 | foreach_hw_driver_next |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 384 | #undef _ |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 385 | return 0; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 386 | } |
| 387 | |
| 388 | VLIB_INIT_FUNCTION (mac_swap_init); |
| 389 | |
Keith Burns (alagalah) | e70dcc8 | 2016-08-15 18:33:19 -0700 | [diff] [blame] | 390 | |
| 391 | /* |
| 392 | * fd.io coding-style-patch-verification: ON |
| 393 | * |
| 394 | * Local Variables: |
| 395 | * eval: (c-set-style "gnu") |
| 396 | * End: |
| 397 | */ |