2 * Copyright (c) 2016 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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <vnet/adj/adj_internal.h>
17 #include <vnet/adj/adj_midchain.h>
20 * @brief Trace data for packets traversing the midchain tx node
22 typedef struct adj_midchain_tx_trace_t_
25 * @brief the midchain adj we are traversing
28 } adj_midchain_tx_trace_t;
31 adj_midchain_tx_inline (vlib_main_t * vm,
32 vlib_node_runtime_t * node,
36 vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
37 u16 nexts[VLIB_FRAME_SIZE], *next;
38 u32 * from, n_left, thread_index;
39 vnet_main_t *vnm = vnet_get_main ();
40 vnet_interface_main_t *im = &vnm->interface_main;
42 thread_index = vm->thread_index;
43 n_left = frame->n_vectors;
44 from = vlib_frame_vector_args (frame);
46 vlib_get_buffers (vm, from, bufs, n_left);
53 u32 adj_index0, adj_index1, adj_index2, adj_index3;
54 const ip_adjacency_t *adj0, *adj1, *adj2, *adj3;
55 const dpo_id_t *dpo0, *dpo1, *dpo2, *dpo3;
57 /* Prefetch next iteration. */
59 vlib_prefetch_buffer_header (b[4], LOAD);
60 vlib_prefetch_buffer_header (b[5], LOAD);
61 vlib_prefetch_buffer_header (b[6], LOAD);
62 vlib_prefetch_buffer_header (b[7], LOAD);
65 /* Follow the DPO on which the midchain is stacked */
66 adj_index0 = vnet_buffer(b[0])->ip.adj_index[VLIB_TX];
67 adj_index1 = vnet_buffer(b[1])->ip.adj_index[VLIB_TX];
68 adj_index2 = vnet_buffer(b[2])->ip.adj_index[VLIB_TX];
69 adj_index3 = vnet_buffer(b[3])->ip.adj_index[VLIB_TX];
71 adj0 = adj_get(adj_index0);
72 adj1 = adj_get(adj_index1);
73 adj2 = adj_get(adj_index2);
74 adj3 = adj_get(adj_index3);
76 dpo0 = &adj0->sub_type.midchain.next_dpo;
77 dpo1 = &adj1->sub_type.midchain.next_dpo;
78 dpo2 = &adj2->sub_type.midchain.next_dpo;
79 dpo3 = &adj3->sub_type.midchain.next_dpo;
81 next[0] = dpo0->dpoi_next_node;
82 next[1] = dpo1->dpoi_next_node;
83 next[2] = dpo2->dpoi_next_node;
84 next[3] = dpo3->dpoi_next_node;
86 vnet_buffer(b[0])->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
87 vnet_buffer(b[1])->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
88 vnet_buffer(b[2])->ip.adj_index[VLIB_TX] = dpo2->dpoi_index;
89 vnet_buffer(b[3])->ip.adj_index[VLIB_TX] = dpo3->dpoi_index;
93 vlib_increment_combined_counter (im->combined_sw_if_counters
94 + VNET_INTERFACE_COUNTER_TX,
96 adj0->rewrite_header.sw_if_index,
98 vlib_buffer_length_in_chain (vm, b[0]));
99 vlib_increment_combined_counter (im->combined_sw_if_counters
100 + VNET_INTERFACE_COUNTER_TX,
102 adj1->rewrite_header.sw_if_index,
104 vlib_buffer_length_in_chain (vm, b[1]));
105 vlib_increment_combined_counter (im->combined_sw_if_counters
106 + VNET_INTERFACE_COUNTER_TX,
108 adj2->rewrite_header.sw_if_index,
110 vlib_buffer_length_in_chain (vm, b[2]));
111 vlib_increment_combined_counter (im->combined_sw_if_counters
112 + VNET_INTERFACE_COUNTER_TX,
114 adj3->rewrite_header.sw_if_index,
116 vlib_buffer_length_in_chain (vm, b[3]));
119 if (PREDICT_FALSE(node->flags & VLIB_NODE_FLAG_TRACE))
121 if (PREDICT_FALSE(b[0]->flags & VLIB_BUFFER_IS_TRACED))
123 adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
127 if (PREDICT_FALSE(b[1]->flags & VLIB_BUFFER_IS_TRACED))
129 adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
133 if (PREDICT_FALSE(b[2]->flags & VLIB_BUFFER_IS_TRACED))
135 adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
139 if (PREDICT_FALSE(b[3]->flags & VLIB_BUFFER_IS_TRACED))
141 adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
153 const ip_adjacency_t * adj0;
154 const dpo_id_t *dpo0;
157 /* Follow the DPO on which the midchain is stacked */
158 adj_index0 = vnet_buffer(b[0])->ip.adj_index[VLIB_TX];
159 adj0 = adj_get(adj_index0);
160 dpo0 = &adj0->sub_type.midchain.next_dpo;
161 next[0] = dpo0->dpoi_next_node;
162 vnet_buffer(b[0])->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
166 vlib_increment_combined_counter (im->combined_sw_if_counters
167 + VNET_INTERFACE_COUNTER_TX,
169 adj0->rewrite_header.sw_if_index,
171 vlib_buffer_length_in_chain (vm, b[0]));
174 if (PREDICT_FALSE(b[0]->flags & VLIB_BUFFER_IS_TRACED))
176 adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
186 vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
188 return frame->n_vectors;
192 format_adj_midchain_tx_trace (u8 * s, va_list * args)
194 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
195 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
196 adj_midchain_tx_trace_t *tr = va_arg (*args, adj_midchain_tx_trace_t*);
198 s = format(s, "adj-midchain:[%d]:%U", tr->ai,
199 format_ip_adjacency, tr->ai,
200 FORMAT_IP_ADJACENCY_NONE);
205 VLIB_NODE_FN (adj_midchain_tx) (vlib_main_t * vm,
206 vlib_node_runtime_t * node,
207 vlib_frame_t * frame)
209 return (adj_midchain_tx_inline(vm, node, frame, 1));
211 VLIB_NODE_FN (tunnel_output) (vlib_main_t * vm,
212 vlib_node_runtime_t * node,
213 vlib_frame_t * frame)
215 return (adj_midchain_tx_inline(vm, node, frame, 1));
218 VLIB_REGISTER_NODE (adj_midchain_tx) = {
219 .name = "adj-midchain-tx",
220 .vector_size = sizeof (u32),
222 .format_trace = format_adj_midchain_tx_trace,
229 VLIB_REGISTER_NODE (tunnel_output) = {
230 .name = "tunnel-output",
231 .vector_size = sizeof (u32),
232 .format_trace = format_adj_midchain_tx_trace,
233 .sibling_of = "adj-midchain-tx",
236 VLIB_NODE_FN (tunnel_output_no_count) (vlib_main_t * vm,
237 vlib_node_runtime_t * node,
238 vlib_frame_t * frame)
240 return (adj_midchain_tx_inline(vm, node, frame, 0));
243 VLIB_REGISTER_NODE (tunnel_output_no_count) = {
244 .name = "tunnel-output-no-count",
245 .vector_size = sizeof (u32),
246 .format_trace = format_adj_midchain_tx_trace,
247 .sibling_of = "adj-midchain-tx",