FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
qos_mark_node.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 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/ip/ip.h>
17 #include <vnet/feature/feature.h>
19 #include <vnet/qos/qos_mark.h>
20 
22 
25 {
26  ASSERT (vec_len (qos_mark_configs[output_source]) > sw_if_index);
27 
29  qos_mark_configs[output_source][sw_if_index]);
30 }
31 
32 /**
33  * per-packet trace data
34  */
35 typedef struct qos_mark_trace_t_
36 {
37  /* per-pkt trace data */
42 
43 static inline uword
47 {
48  u32 n_left_from, *from, *to_next, next_index;
49 
50  next_index = 0;
51  n_left_from = frame->n_vectors;
52  from = vlib_frame_vector_args (frame);
53 
54  while (n_left_from > 0)
55  {
56  u32 n_left_to_next;
57 
58  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
59 
60  while (n_left_from > 0 && n_left_to_next > 0)
61  {
62  qos_source_t input_source0;
64  u32 sw_if_index0, next0, bi0;
65  qos_egress_map_t *qem0;
66  ip4_header_t *ip4_0;
67  ip6_header_t *ip6_0;
68  vlib_buffer_t *b0;
69  qos_bits_t qos0;
70  u8 *mpls_bytes_0;
71  u8 eos0;
72 
73  next0 = 0;
74  bi0 = from[0];
75  to_next[0] = bi0;
76  from += 1;
77  to_next += 1;
78  n_left_from -= 1;
79  n_left_to_next -= 1;
80 
81  b0 = vlib_get_buffer (vm, bi0);
82  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
83  input_source0 = vnet_buffer2 (b0)->qos.source;
84 
85  qem0 = qos_egress_map_interface (sw_if_index0, output_source);
86  qos0 = qem0->qem_output[input_source0][vnet_buffer2 (b0)->qos.bits];
87 
88  if (PREDICT_TRUE (b0->flags & VNET_BUFFER_F_QOS_DATA_VALID))
89  {
90  /* there is a source of QoS recording for this packet */
91  if (QOS_SOURCE_IP == output_source)
92  {
93  if (is_ip6)
94  {
95  ip6_0 = (vlib_buffer_get_current (b0) +
96  vnet_buffer (b0)->ip.save_rewrite_length);
97 
99  }
100  else
101  {
102  ip4_0 = (vlib_buffer_get_current (b0) +
103  vnet_buffer (b0)->ip.save_rewrite_length);
104  if (PREDICT_FALSE (qos0 != ip4_0->tos))
105  {
106  ip4_0->tos = qos0;
107  ip4_0->checksum = ip4_header_checksum (ip4_0);
108  }
109  }
110  }
111  else if (QOS_SOURCE_MPLS == output_source)
112  {
113  mpls_bytes_0 = (vlib_buffer_get_current (b0) +
114  vnet_buffer (b0)->mpls.save_rewrite_length);
115 
116  /* apply to all the labels in the stack */
117  do
118  {
119  /* clear out the old COS bts */
120  mpls_bytes_0[2] &= 0xf1;
121  /* OR in 3 bits of the mapped value */
122  mpls_bytes_0[2] |= (qos0 & 0x7) << 1;
123  eos0 = mpls_bytes_0[2] & 0x1;
124  mpls_bytes_0 += 4;
125  }
126  while (!eos0);
127  }
128  else if (QOS_SOURCE_VLAN == output_source)
129  {
130  vlan0 = (vlib_buffer_get_current (b0) +
131  sizeof (ethernet_header_t));
132 
134  }
135  }
136  vnet_feature_next (&next0, b0);
137 
138  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
139  {
140  qos_mark_trace_t *t =
141  vlib_add_trace (vm, node, b0, sizeof (*t));
142  t->bits = qos0;
143  t->input = input_source0;
144  t->used = (b0->flags & VNET_BUFFER_F_QOS_DATA_VALID);
145  }
146 
147  /* verify speculative enqueue, maybe switch current next frame */
148  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
149  to_next, n_left_to_next,
150  bi0, next0);
151  }
152 
153  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
154  }
155 
156  return frame->n_vectors;
157 }
158 
159 /* packet trace format function */
160 static u8 *
161 format_qos_mark_trace (u8 * s, va_list * args)
162 {
163  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
164  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
165  qos_mark_trace_t *t = va_arg (*args, qos_mark_trace_t *);
166 
167  s = format (s, "source:%U qos:%d used:%s",
168  format_qos_source, t->input, t->bits, (t->used ? "yes" : "no"));
169 
170  return s;
171 }
172 
176 {
177  return (qos_mark_inline (vm, node, frame, QOS_SOURCE_IP, 0));
178 }
179 
183 {
184  return (qos_mark_inline (vm, node, frame, QOS_SOURCE_IP, 1));
185 }
186 
190 {
191  return (qos_mark_inline (vm, node, frame, QOS_SOURCE_MPLS, 0));
192 }
193 
197 {
198  return (qos_mark_inline (vm, node, frame, QOS_SOURCE_VLAN, 0));
199 }
200 
204 {
205  return (qos_mark_inline (vm, node, frame, QOS_SOURCE_VLAN, 0));
206 }
207 
211 {
212  return (qos_mark_inline (vm, node, frame, QOS_SOURCE_VLAN, 0));
213 }
214 
215 /* *INDENT-OFF* */
217  .name = "ip4-qos-mark",
218  .vector_size = sizeof (u32),
219  .format_trace = format_qos_mark_trace,
221 
222  .n_errors = 0,
223  .n_next_nodes = 1,
224 
225  .next_nodes = {
226  [0] = "ip4-drop",
227  },
228 };
229 
231  .arc_name = "ip4-output",
232  .node_name = "ip4-qos-mark",
233 };
234 
236  .name = "ip6-qos-mark",
237  .vector_size = sizeof (u32),
238  .format_trace = format_qos_mark_trace,
240 
241  .n_errors = 0,
242  .n_next_nodes = 1,
243 
244  .next_nodes = {
245  [0] = "ip6-drop",
246  },
247 };
248 
250  .arc_name = "ip6-output",
251  .node_name = "ip6-qos-mark",
252 };
253 
255  .name = "mpls-qos-mark",
256  .vector_size = sizeof (u32),
257  .format_trace = format_qos_mark_trace,
259 
260  .n_errors = 0,
261  .n_next_nodes = 1,
262 
263  .next_nodes = {
264  [0] = "mpls-drop",
265  },
266 };
267 
269  .arc_name = "mpls-output",
270  .node_name = "mpls-qos-mark",
271 };
272 
274  .name = "vlan-ip4-qos-mark",
275  .vector_size = sizeof (u32),
276  .format_trace = format_qos_mark_trace,
278 
279  .n_errors = 0,
280  .n_next_nodes = 1,
281 
282  .next_nodes = {
283  [0] = "error-drop",
284  },
285 };
286 
288  .arc_name = "ip4-output",
289  .node_name = "vlan-ip4-qos-mark",
290  .runs_after = VNET_FEATURES ("ip4-qos-mark"),
291 };
292 
294  .name = "vlan-ip6-qos-mark",
295  .vector_size = sizeof (u32),
296  .format_trace = format_qos_mark_trace,
298 
299  .n_errors = 0,
300  .n_next_nodes = 1,
301 
302  .next_nodes = {
303  [0] = "error-drop",
304  },
305 };
306 
308  .arc_name = "ip6-output",
309  .node_name = "vlan-ip6-qos-mark",
310  .runs_after = VNET_FEATURES ("ip6-qos-mark"),
311 };
312 
314  .name = "vlan-mpls-qos-mark",
315  .vector_size = sizeof (u32),
316  .format_trace = format_qos_mark_trace,
318 
319  .n_errors = 0,
320  .n_next_nodes = 1,
321 
322  .next_nodes = {
323  [0] = "error-drop",
324  },
325 };
326 
328  .arc_name = "mpls-output",
329  .node_name = "vlan-mpls-qos-mark",
330  .runs_after = VNET_FEATURES ("mpls-qos-mark"),
331 };
332 
333 /* *INDENT-ON* */
334 
335 /*
336  * fd.io coding-style-patch-verification: ON
337  *
338  * Local Variables:
339  * eval: (c-set-style "gnu")
340  * End:
341  */
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
qos_egress_map_t * qem_pool
Pool from which to allocate table.
vl_api_qos_source_t output_source
Definition: qos.api:215
#define CLIB_UNUSED(x)
Definition: clib.h:87
static_always_inline void ip6_set_traffic_class_network_order(ip6_header_t *ip6, ip_dscp_t dscp)
Definition: ip6_packet.h:341
#define vnet_buffer2(b)
Definition: buffer.h:482
#define PREDICT_TRUE(x)
Definition: clib.h:121
static u8 * format_qos_mark_trace(u8 *s, va_list *args)
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define VLIB_NODE_FN(node)
Definition: node.h:202
vlib_node_registration_t vlan_ip6_qos_mark_node
(constructor) VLIB_REGISTER_NODE (vlan_ip6_qos_mark_node)
unsigned char u8
Definition: types.h:56
VNET_FEATURE_INIT(ip4_qos_mark_node, static)
struct qos_mark_trace_t_ qos_mark_trace_t
per-packet trace data
unsigned int u32
Definition: types.h:88
bool is_ip6
Definition: ip.api:43
static uword qos_mark_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, qos_source_t output_source, int is_ip6)
Definition: qos_mark_node.c:44
u8 * format_qos_source(u8 *s, va_list *args)
format/unformat QoS source types
Definition: qos_types.c:27
vl_api_fib_path_type_t type
Definition: fib_types.api:123
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
static void ethernet_vlan_header_set_priority_net_order(ethernet_vlan_header_t *h, u8 prio)
Definition: packet.h:140
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:120
#define always_inline
Definition: ipsec.h:28
#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:224
#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:391
qos_source_t input
Definition: qos_mark_node.c:39
index_t * qos_mark_configs[QOS_N_SOURCES]
per-interface vector of which MAP is used by which interface for each output source ...
Definition: qos_mark.c:25
vlib_node_registration_t ip4_qos_mark_node
(constructor) VLIB_REGISTER_NODE (ip4_qos_mark_node)
vlib_node_registration_t ip6_qos_mark_node
(constructor) VLIB_REGISTER_NODE (ip6_qos_mark_node)
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:396
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:322
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:483
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
For a given output source a table maps each value of every input source.
#define ASSERT(truth)
per-packet trace data
Definition: qos_mark_node.c:35
ip_dscp_t tos
Definition: ip4_packet.h:96
#define VNET_FEATURES(...)
Definition: feature.h:470
static qos_egress_map_t * qos_egress_map_interface(u32 sw_if_index, qos_source_t output_source)
Definition: qos_mark_node.c:24
Definition: defs.h:47
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1583
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:297
vlib_node_registration_t vlan_ip4_qos_mark_node
(constructor) VLIB_REGISTER_NODE (vlan_ip4_qos_mark_node)
#define vnet_buffer(b)
Definition: buffer.h:417
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:577
vlib_node_registration_t vlan_mpls_qos_mark_node
(constructor) VLIB_REGISTER_NODE (vlan_mpls_qos_mark_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
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:314
qos_bits_t qem_output[QOS_N_SOURCES][256]
The array of output mapped values; output = eq_qos[input-source][input-value].
u8 qos_bits_t
Type, er, safety for us water based entities.
Definition: qos_types.h:68
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
#define QOS_N_SOURCES
The maximum number of sources.
Definition: qos_types.h:45
vlib_node_registration_t mpls_qos_mark_node
(constructor) VLIB_REGISTER_NODE (mpls_qos_mark_node)