FD.io VPP  v19.08.1-401-g8e4ed521a
Vector Packet Processing
qos_record_node.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 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 
16 #include <vnet/qos/qos_record.h>
17 #include <vnet/ip/ip.h>
18 #include <vnet/ip/ip6_to_ip4.h>
19 #include <vnet/feature/feature.h>
20 #include <vnet/qos/qos_types.h>
21 #include <vnet/l2/l2_input.h>
22 #include <vnet/l2/feat_bitmap.h>
23 
26 
27 /**
28  * per-packet trace data
29  */
30 typedef struct qos_record_trace_t_
31 {
32  /* per-pkt trace data */
35 
36 /* packet trace format function */
37 static u8 *
38 format_qos_record_trace (u8 * s, va_list * args)
39 {
40  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
41  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
42  qos_record_trace_t *t = va_arg (*args, qos_record_trace_t *);
43 
44  s = format (s, "qos:%d", t->bits);
45 
46  return s;
47 }
48 
49 static inline uword
51  vlib_node_runtime_t * node,
52  vlib_frame_t * frame,
53  qos_source_t qos_src, dpo_proto_t dproto, int is_l2)
54 {
55  u32 n_left_from, *from, *to_next, next_index;
56 
57  next_index = 0;
58  n_left_from = frame->n_vectors;
59  from = vlib_frame_vector_args (frame);
60 
61  while (n_left_from > 0)
62  {
63  u32 n_left_to_next;
64 
65  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
66 
67  while (n_left_from > 0 && n_left_to_next > 0)
68  {
69  ip4_header_t *ip4_0;
70  ip6_header_t *ip6_0;
71  vlib_buffer_t *b0;
72  u32 next0, bi0;
73  qos_bits_t qos0;
74  u8 l2_len;
75 
76  next0 = 0;
77  bi0 = from[0];
78  to_next[0] = bi0;
79  from += 1;
80  to_next += 1;
81  n_left_from -= 1;
82  n_left_to_next -= 1;
83 
84  b0 = vlib_get_buffer (vm, bi0);
85 
86  if (is_l2)
87  {
88  l2_len = vnet_buffer (b0)->l2.l2_len;
89  u8 *l3h;
90  u16 ethertype;
91 
92  vlib_buffer_advance (b0, l2_len);
93 
94  l3h = vlib_buffer_get_current (b0);
95  ethertype = clib_net_to_host_u16 (*(u16 *) (l3h - 2));
96 
97  if (ethertype == ETHERNET_TYPE_IP4)
98  dproto = DPO_PROTO_IP4;
99  else if (ethertype == ETHERNET_TYPE_IP6)
100  dproto = DPO_PROTO_IP6;
101  else if (ethertype == ETHERNET_TYPE_MPLS)
102  dproto = DPO_PROTO_MPLS;
103  else
104  goto non_ip;
105  }
106 
107  if (DPO_PROTO_IP6 == dproto)
108  {
109  ip6_0 = vlib_buffer_get_current (b0);
110  qos0 = ip6_traffic_class_network_order (ip6_0);
111  }
112  else if (DPO_PROTO_IP4 == dproto)
113  {
114  ip4_0 = vlib_buffer_get_current (b0);
115  qos0 = ip4_0->tos;
116  }
117  else if (DPO_PROTO_ETHERNET == dproto)
118  {
119  ethernet_vlan_header_t *vlan0;
120 
121  vlan0 = (vlib_buffer_get_current (b0) -
122  sizeof (ethernet_vlan_header_t));
123 
125  }
126  else if (DPO_PROTO_MPLS)
127  {
129 
130  mh = vlib_buffer_get_current (b0);
132  }
133 
134  vnet_buffer2 (b0)->qos.bits = qos0;
135  vnet_buffer2 (b0)->qos.source = qos_src;
136  b0->flags |= VNET_BUFFER_F_QOS_DATA_VALID;
137 
138  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
139  (b0->flags & VLIB_BUFFER_IS_TRACED)))
140  {
141  qos_record_trace_t *t =
142  vlib_add_trace (vm, node, b0, sizeof (*t));
143  t->bits = qos0;
144  }
145 
146  non_ip:
147  if (is_l2)
148  {
149  vlib_buffer_advance (b0, -l2_len);
150  next0 = vnet_l2_feature_next (b0,
151  l2_qos_input_next[qos_src],
152  L2INPUT_FEAT_L2_IP_QOS_RECORD);
153  }
154  else
155  vnet_feature_next (&next0, b0);
156 
157  /* verify speculative enqueue, maybe switch current next frame */
158  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
159  to_next, n_left_to_next,
160  bi0, next0);
161  }
162 
163  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
164  }
165 
166  return frame->n_vectors;
167 }
168 
169 
171  vlib_node_runtime_t * node,
172  vlib_frame_t * frame)
173 {
174  return (qos_record_inline (vm, node, frame, QOS_SOURCE_IP,
175  DPO_PROTO_IP4, 0));
176 }
177 
179  vlib_node_runtime_t * node,
180  vlib_frame_t * frame)
181 {
182  return (qos_record_inline (vm, node, frame, QOS_SOURCE_IP,
183  DPO_PROTO_IP6, 0));
184 }
185 
187  vlib_node_runtime_t * node,
188  vlib_frame_t * frame)
189 {
190  return (qos_record_inline (vm, node, frame, QOS_SOURCE_MPLS,
191  DPO_PROTO_MPLS, 0));
192 }
193 
195  vlib_node_runtime_t * node,
196  vlib_frame_t * frame)
197 {
198  return (qos_record_inline (vm, node, frame, QOS_SOURCE_VLAN,
199  DPO_PROTO_ETHERNET, 0));
200 }
201 
203  vlib_node_runtime_t * node,
204  vlib_frame_t * frame)
205 {
206  return (qos_record_inline (vm, node, frame, QOS_SOURCE_VLAN,
207  DPO_PROTO_ETHERNET, 0));
208 }
209 
211  vlib_node_runtime_t * node,
212  vlib_frame_t * frame)
213 {
214  return (qos_record_inline (vm, node, frame, QOS_SOURCE_VLAN,
215  DPO_PROTO_ETHERNET, 0));
216 }
217 
219  vlib_node_runtime_t * node,
220  vlib_frame_t * frame)
221 {
222  return (qos_record_inline (vm, node, frame, QOS_SOURCE_VLAN, 0, 1));
223 }
224 
225 /* *INDENT-OFF* */
227  .name = "ip4-qos-record",
228  .vector_size = sizeof (u32),
229  .format_trace = format_qos_record_trace,
231 
232  .n_errors = 0,
233  .n_next_nodes = 1,
234 
235  .next_nodes = {
236  [0] = "ip4-drop",
237  },
238 };
239 
241  .arc_name = "ip4-unicast",
242  .node_name = "ip4-qos-record",
243 };
244 VNET_FEATURE_INIT (ip4m_qos_record_node, static) = {
245  .arc_name = "ip4-multicast",
246  .node_name = "ip4-qos-record",
247 };
248 
250  .name = "ip6-qos-record",
251  .vector_size = sizeof (u32),
252  .format_trace = format_qos_record_trace,
254 
255  .n_errors = 0,
256  .n_next_nodes = 1,
257 
258  .next_nodes = {
259  [0] = "ip6-drop",
260  },
261 };
262 
264  .arc_name = "ip6-unicast",
265  .node_name = "ip6-qos-record",
266 };
267 VNET_FEATURE_INIT (ip6m_qos_record_node, static) = {
268  .arc_name = "ip6-multicast",
269  .node_name = "ip6-qos-record",
270 };
271 
273  .name = "mpls-qos-record",
274  .vector_size = sizeof (u32),
275  .format_trace = format_qos_record_trace,
277 
278  .n_errors = 0,
279  .n_next_nodes = 1,
280 
281  .next_nodes = {
282  [0] = "mpls-drop",
283  },
284 };
285 
287  .arc_name = "mpls-input",
288  .node_name = "mpls-qos-record",
289 };
290 
292  .name = "vlan-mpls-qos-record",
293  .vector_size = sizeof (u32),
294  .format_trace = format_qos_record_trace,
296 
297  .n_errors = 0,
298  .n_next_nodes = 1,
299 
300  .next_nodes = {
301  [0] = "mpls-drop",
302  },
303 };
304 
306  .arc_name = "mpls-input",
307  .node_name = "vlan-mpls-qos-record",
308  .runs_before = VNET_FEATURES ("mpls-qos-record"),
309 };
310 
312  .name = "vlan-ip4-qos-record",
313  .vector_size = sizeof (u32),
314  .format_trace = format_qos_record_trace,
316 
317  .n_errors = 0,
318  .n_next_nodes = 1,
319 
320  .next_nodes = {
321  [0] = "ip4-drop",
322  },
323 };
324 
326  .arc_name = "ip4-unicast",
327  .node_name = "vlan-ip4-qos-record",
328  .runs_before = VNET_FEATURES ("ip4-qos-record"),
329 };
330 VNET_FEATURE_INIT (vlan_ip4m_qos_record_node, static) = {
331  .arc_name = "ip4-multicast",
332  .node_name = "vlan-ip4-qos-record",
333  .runs_before = VNET_FEATURES ("ip4-qos-record"),
334 };
335 
337  .name = "vlan-ip6-qos-record",
338  .vector_size = sizeof (u32),
339  .format_trace = format_qos_record_trace,
341 
342  .n_errors = 0,
343  .n_next_nodes = 1,
344 
345  .next_nodes = {
346  [0] = "ip6-drop",
347  },
348 };
349 
351  .arc_name = "ip6-unicast",
352  .node_name = "vlan-ip6-qos-record",
353  .runs_before = VNET_FEATURES ("ip6-qos-record"),
354 };
355 VNET_FEATURE_INIT (vlan_ip6m_qos_record_node, static) = {
356  .arc_name = "ip6-multicast",
357  .node_name = "vlan-ip6-qos-record",
358  .runs_before = VNET_FEATURES ("ip6-qos-record"),
359 };
360 
362  .name = "l2-ip-qos-record",
363  .vector_size = sizeof (u32),
364  .format_trace = format_qos_record_trace,
366 
367  .n_errors = 0,
368  .n_next_nodes = 1,
369 
370  /* Consider adding error "no IP after L2, no recording" */
371  .next_nodes = {
372  [0] = "error-drop",
373  },
374 };
375 /* *INDENT-ON* */
376 
377 /*
378  * fd.io coding-style-patch-verification: ON
379  *
380  * Local Variables:
381  * eval: (c-set-style "gnu")
382  * End:
383  */
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
vlib_node_registration_t mpls_qos_record_node
(constructor) VLIB_REGISTER_NODE (mpls_qos_record_node)
vlib_node_registration_t l2_ip_qos_record_node
(constructor) VLIB_REGISTER_NODE (l2_ip_qos_record_node)
#define CLIB_UNUSED(x)
Definition: clib.h:82
static u8 * format_qos_record_trace(u8 *s, va_list *args)
#define vnet_buffer2(b)
Definition: buffer.h:424
static uword qos_record_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, qos_source_t qos_src, dpo_proto_t dproto, int is_l2)
static_always_inline ip_dscp_t ip6_traffic_class_network_order(const ip6_header_t *ip6)
Definition: ip6_packet.h:393
VNET_FEATURE_INIT(ip4_qos_record_node, static)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define VLIB_NODE_FN(node)
Definition: node.h:202
vlib_node_registration_t ip6_qos_record_node
(constructor) VLIB_REGISTER_NODE (ip6_qos_record_node)
unsigned char u8
Definition: types.h:56
static u32 vnet_l2_feature_next(vlib_buffer_t *b, u32 *next_nodes, u32 feat_bit)
Return the graph node index for the feature corresponding to the next set bit after clearing the curr...
Definition: feat_bitmap.h:94
unsigned int u32
Definition: types.h:88
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vlib_node_registration_t vlan_ip6_qos_record_node
(constructor) VLIB_REGISTER_NODE (vlan_ip6_qos_record_node)
unsigned short u16
Definition: types.h:57
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
#define PREDICT_FALSE(x)
Definition: clib.h:111
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:218
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:338
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:397
vlib_main_t * vm
Definition: buffer.c:323
enum qos_source_t_ qos_source_t
QoS types.
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:456
u8 * qos_record_configs[QOS_N_SOURCES]
Per-interface, per-protocol vector of feature on/off configurations.
Definition: qos_record.c:27
vlib_node_registration_t vlan_ip4_qos_record_node
(constructor) VLIB_REGISTER_NODE (vlan_ip4_qos_record_node)
struct qos_record_trace_t_ qos_record_trace_t
per-packet trace data
ip_dscp_t tos
Definition: ip4_packet.h:141
mpls_label_t label_exp_s_ttl
Definition: packet.h:33
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
IPv6 to IPv4 translation.
#define VNET_FEATURES(...)
Definition: feature.h:442
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
vlib_node_registration_t vlan_mpls_qos_record_node
(constructor) VLIB_REGISTER_NODE (vlan_mpls_qos_record_node)
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
u32 l2_qos_input_next[QOS_N_SOURCES][32]
Definition: qos_record.c:28
#define vnet_buffer(b)
Definition: buffer.h:365
per-packet trace data
u16 flags
Copy of main node flags.
Definition: node.h:509
static u32 vnet_mpls_uc_get_exp(mpls_label_t label_exp_s_ttl)
Definition: packet.h:110
static u8 ethernet_vlan_header_get_priority_net_order(ethernet_vlan_header_t *h)
Definition: packet.h:150
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:302
vlib_node_registration_t ip4_qos_record_node
(constructor) VLIB_REGISTER_NODE (ip4_qos_record_node)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
u8 qos_bits_t
Type, er, safety for us water based entities.
Definition: qos_types.h:68
#define QOS_N_SOURCES
The maximum number of sources.
Definition: qos_types.h:45