FD.io VPP  v21.10.1-2-g0a485f517
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 {
27 
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;
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 */
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 */
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  */
qos_egress_map_t_
For a given output source a table maps each value of every input source.
Definition: qos_egress_map.h:37
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
vlan_mpls_qos_mark_node
vlib_node_registration_t vlan_mpls_qos_mark_node
(constructor) VLIB_REGISTER_NODE (vlan_mpls_qos_mark_node)
Definition: qos_mark_node.c:313
qos_mark_trace_t_::bits
qos_bits_t bits
Definition: qos_mark_node.c:38
qos_egress_map_interface
static qos_egress_map_t * qos_egress_map_interface(u32 sw_if_index, qos_source_t output_source)
Definition: qos_mark_node.c:24
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
ethernet_vlan_header_t
Definition: packet.h:128
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
QOS_SOURCE_MPLS
@ QOS_SOURCE_MPLS
Definition: qos_types.h:37
VLIB_NODE_TYPE_INTERNAL
@ VLIB_NODE_TYPE_INTERNAL
Definition: node.h:72
VNET_FEATURE_INIT
VNET_FEATURE_INIT(ip4_qos_mark_node, static)
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
qos_mark_configs
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
ip6_qos_mark_node
vlib_node_registration_t ip6_qos_mark_node
(constructor) VLIB_REGISTER_NODE (ip6_qos_mark_node)
Definition: qos_mark_node.c:235
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
qos_egress_map_t_::qem_output
qos_bits_t qem_output[QOS_N_SOURCES][256]
The array of output mapped values; output = eq_qos[input-source][input-value].
Definition: qos_egress_map.h:48
qos_mark_inline
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
vnet_buffer2
#define vnet_buffer2(b)
Definition: buffer.h:505
format_qos_mark_trace
static u8 * format_qos_mark_trace(u8 *s, va_list *args)
Definition: qos_mark_node.c:161
output_source
vl_api_qos_source_t output_source
Definition: qos.api:215
vlib_frame_t
Definition: node.h:372
ip4_header_t
Definition: ip4_packet.h:87
ip4_header_t::tos
ip_dscp_t tos
Definition: ip4_packet.h:96
qos_mark_trace_t_::used
u32 used
Definition: qos_mark_node.c:40
qos_mark_trace_t_
per-packet trace data
Definition: qos_mark_node.c:35
qos_bits_t
u8 qos_bits_t
Type, er, safety for us water based entities.
Definition: qos_types.h:68
vlan_ip6_qos_mark_node
vlib_node_registration_t vlan_ip6_qos_mark_node
(constructor) VLIB_REGISTER_NODE (vlan_ip6_qos_mark_node)
Definition: qos_mark_node.c:293
QOS_SOURCE_VLAN
@ QOS_SOURCE_VLAN
Definition: qos_types.h:36
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
format_qos_source
u8 * format_qos_source(u8 *s, va_list *args)
format/unformat QoS source types
Definition: qos_types.c:27
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
feature.h
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
ethernet_vlan_header_set_priority_net_order
static void ethernet_vlan_header_set_priority_net_order(ethernet_vlan_header_t *h, u8 prio)
Definition: packet.h:140
qos_egress_map.h
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
vnet_feature_next
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:322
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
index_t
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:43
uword
u64 uword
Definition: types.h:112
ethernet_header_t
Definition: packet.h:52
ip4_header_t::checksum
u16 checksum
Definition: ip4_packet.h:118
qos_mark_trace_t
struct qos_mark_trace_t_ qos_mark_trace_t
per-packet trace data
qem_pool
qos_egress_map_t * qem_pool
Pool from which to allocate table.
Definition: qos_egress_map.c:24
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
qos_source_t
enum qos_source_t_ qos_source_t
QoS types.
is_ip6
bool is_ip6
Definition: ip.api:43
vlib_validate_buffer_enqueue_x1
#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
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
ip4_qos_mark_node
vlib_node_registration_t ip4_qos_mark_node
(constructor) VLIB_REGISTER_NODE (ip4_qos_mark_node)
Definition: qos_mark_node.c:216
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
ip6_set_traffic_class_network_order
static_always_inline void ip6_set_traffic_class_network_order(ip6_header_t *ip6, ip_dscp_t dscp)
Definition: ip6_packet.h:347
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
ip.h
u32
unsigned int u32
Definition: types.h:88
qos_mark.h
ip6_header_t
Definition: ip6_packet.h:294
qos_mark_trace_t_::input
qos_source_t input
Definition: qos_mark_node.c:39
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
VNET_FEATURES
#define VNET_FEATURES(...)
Definition: feature.h:470
u8
unsigned char u8
Definition: types.h:56
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
ip4_header_checksum
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:314
QOS_N_SOURCES
#define QOS_N_SOURCES
The maximum number of sources.
Definition: qos_types.h:45
mpls_qos_mark_node
vlib_node_registration_t mpls_qos_mark_node
(constructor) VLIB_REGISTER_NODE (mpls_qos_mark_node)
Definition: qos_mark_node.c:254
QOS_SOURCE_IP
@ QOS_SOURCE_IP
Definition: qos_types.h:38
vlib_node_runtime_t
Definition: node.h:454
from
from
Definition: nat44_ei_hairpinning.c:415
PREDICT_TRUE
#define PREDICT_TRUE(x)
Definition: clib.h:125
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
vlib_get_next_frame
#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:395
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
vlan_ip4_qos_mark_node
vlib_node_registration_t vlan_ip4_qos_mark_node
(constructor) VLIB_REGISTER_NODE (vlan_ip4_qos_mark_node)
Definition: qos_mark_node.c:273