FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
qos_mark.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/ip/ip.h>
17 #include <vnet/feature/feature.h>
19 #include <vnet/qos/qos_mark.h>
20 
21 /**
22  * per-interface vector of which MAP is used by which interface
23  * for each output source
24  */
26 
27 void
29 {
30  vnet_feature_enable_disable ("ip6-output", "ip6-qos-mark",
31  sw_if_index, enable, NULL, 0);
32  vnet_feature_enable_disable ("ip4-output", "ip4-qos-mark",
33  sw_if_index, enable, NULL, 0);
34 }
35 
36 void
38 {
39  /*
40  * one cannot run a feature on a sub-interface, so we need
41  * to enable a feature on all the L3 output paths
42  */
43  vnet_feature_enable_disable ("ip6-output", "vlan-ip6-qos-mark",
44  sw_if_index, enable, NULL, 0);
45  vnet_feature_enable_disable ("ip4-output", "vlan-ip4-qos-mark",
46  sw_if_index, enable, NULL, 0);
47  vnet_feature_enable_disable ("mpls-output", "vlan-mpls-qos-mark",
48  sw_if_index, enable, NULL, 0);
49 }
50 
51 void
53 {
54  vnet_feature_enable_disable ("mpls-output", "mpls-qos-mark",
55  sw_if_index, enable, NULL, 0);
56 }
57 
58 static void
60 {
61  switch (qs)
62  {
63  case QOS_SOURCE_EXT:
64  ASSERT (0);
65  break;
66  case QOS_SOURCE_VLAN:
67  qos_mark_vlan_enable_disable (sw_if_index, enable);
68  break;
69  case QOS_SOURCE_MPLS:
70  qos_mark_mpls_enable_disable (sw_if_index, enable);
71  break;
72  case QOS_SOURCE_IP:
73  qos_mark_ip_enable_disable (sw_if_index, enable);
74  break;
75  }
76 }
77 
78 int
81 {
82  index_t qemi;
83 
85  sw_if_index, INDEX_INVALID);
86 
87  qemi = qos_egress_map_find (mid);
88 
89  if (INDEX_INVALID == qemi)
90  return VNET_API_ERROR_NO_SUCH_TABLE;
91 
92  if (INDEX_INVALID == qos_mark_configs[output_source][sw_if_index])
93  {
94  qos_egress_map_feature_config (sw_if_index, output_source, 1);
95  }
96 
98 
99  return (0);
100 }
101 
102 int
104 {
105  if (vec_len (qos_mark_configs[output_source]) <= sw_if_index)
106  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
107  if (INDEX_INVALID == qos_mark_configs[output_source][sw_if_index])
108  return VNET_API_ERROR_VALUE_EXIST;
109 
110  if (INDEX_INVALID != qos_mark_configs[output_source][sw_if_index])
111  {
112  qos_egress_map_feature_config (sw_if_index, output_source, 0);
113  }
114 
116 
117  return (0);
118 }
119 
120 void
122 {
123  qos_source_t qs;
124 
126  {
128 
129  vec_foreach_index (sw_if_index, qos_mark_configs[qs])
130  {
131  if (INDEX_INVALID != qos_mark_configs[qs][sw_if_index])
132  fn (sw_if_index,
133  qos_egress_map_get_id (qos_mark_configs[qs][sw_if_index]), qs, c);
134  }
135  }
136 }
137 
138 static clib_error_t *
140  unformat_input_t * input, vlib_cli_command_t * cmd)
141 {
143  u32 sw_if_index, qs;
144  vnet_main_t *vnm;
145  int rv, enable;
146 
147  vnm = vnet_get_main ();
148  map_id = ~0;
149  qs = 0xff;
150  enable = 1;
151 
153  {
154  if (unformat (input, "id %d", &map_id))
155  ;
156  else if (unformat (input, "disable"))
157  enable = 0;
158  else if (unformat (input, "%U", unformat_qos_source, &qs))
159  ;
160  else if (unformat (input, "%U",
161  unformat_vnet_sw_interface, vnm, &sw_if_index))
162  ;
163  else
164  break;
165  }
166 
167  if (~0 == sw_if_index)
168  return clib_error_return (0, "interface must be specified");
169  if (0xff == qs)
170  return clib_error_return (0, "output location must be specified");
171 
172  if (enable)
173  rv = qos_mark_enable (sw_if_index, qs, map_id);
174  else
175  rv = qos_mark_disable (sw_if_index, qs);
176 
177  if (0 == rv)
178  return (NULL);
179 
180  return clib_error_return (0, "Failed to map interface");
181 }
182 
183 /*?
184  * Apply a QoS egress mapping table to an interface for QoS marking packets
185  * at the given output protocol.
186  *
187  * @cliexpar
188  * @cliexcmd{qos egress interface GigEthernet0/9/0 id 0 output ip}
189  ?*/
190 /* *INDENT-OFF* */
191 VLIB_CLI_COMMAND (qos_egress_map_interface_command, static) = {
192  .path = "qos mark",
193  .short_help = "qos mark <SOURCE> <INTERFACE> id <MAP>",
194  .function = qos_mark_cli,
195  .is_mp_safe = 1,
196 };
197 /* *INDENT-ON* */
198 
199 static void
201 {
202  index_t qemis[QOS_N_SOURCES];
203  qos_source_t qs;
204  bool set;
205 
206  set = false;
208 
210  {
211  if (vec_len (qos_mark_configs[qs]) <= sw_if_index)
212  continue;
213  if (INDEX_INVALID != (qemis[qs] = qos_mark_configs[qs][sw_if_index]))
214  set = true;
215  }
216 
217  if (set)
218  {
220  vnet_get_main (), sw_if_index);
221 
223  {
224  if (qemis[qs] != INDEX_INVALID)
225  vlib_cli_output (vm, " %U: map:%d", format_qos_source, qs,
226  qemis[qs]);
227  }
228  }
229 }
230 
231 static clib_error_t *
233  unformat_input_t * input, vlib_cli_command_t * cmd)
234 {
235  vnet_main_t *vnm = vnet_get_main ();
236  qos_source_t qs;
238 
239  sw_if_index = ~0;
240 
242  {
243  if (unformat (input, "%U", unformat_vnet_sw_interface,
244  vnm, &sw_if_index))
245  ;
246  }
247 
248  if (~0 == sw_if_index)
249  {
250  u32 ii, n_ints = 0;
251 
253  {
254  n_ints = clib_max (n_ints, vec_len (qos_mark_configs[qs]));
255  }
256 
257  for (ii = 0; ii < n_ints; ii++)
258  {
260  }
261  }
262  else
263  qos_mark_show_one_interface (vm, sw_if_index);
264 
265  return (NULL);
266 }
267 
268 /*?
269  * Show Egress Qos Maps
270  *
271  * @cliexpar
272  * @cliexcmd{show qos egress map}
273  ?*/
274 /* *INDENT-OFF* */
275 VLIB_CLI_COMMAND (qos_mark_show_command, static) = {
276  .path = "show qos mark",
277  .short_help = "show qos mark [interface]",
278  .function = qos_mark_show,
279  .is_mp_safe = 1,
280 };
281 /* *INDENT-ON* */
282 
283 /*
284  * fd.io coding-style-patch-verification: ON
285  *
286 * Local Variables:
287 * eval: (c-set-style "gnu")
288 * End:
289 *
290 */
#define vec_foreach_index(var, v)
Iterate over vector indices.
vl_api_qos_source_t output_source
Definition: qos.api:215
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
index_t qos_egress_map_find(qos_egress_map_id_t mid)
Get the VPP QoS map index from the user&#39;s map-ID.
qos_egress_map_id_t qos_egress_map_get_id(index_t qemi)
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
void qos_mark_vlan_enable_disable(u32 sw_if_index, u8 enable)
Definition: qos_mark.c:37
vlib_main_t * vm
Definition: in2out_ed.c:1582
void qos_mark_ip_enable_disable(u32 sw_if_index, u8 enable)
Definition: qos_mark.c:28
static void qos_mark_show_one_interface(vlib_main_t *vm, u32 sw_if_index)
Definition: qos_mark.c:200
u32 map_id
Definition: qos.api:214
unformat_function_t unformat_vnet_sw_interface
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
int qos_mark_disable(u32 sw_if_index, qos_source_t output_source)
Definition: qos_mark.c:103
Some external source, e.g.
Definition: qos_types.h:35
#define clib_error_return(e, args...)
Definition: error.h:99
int qos_mark_enable(u32 sw_if_index, qos_source_t output_source, qos_egress_map_id_t mid)
enable QoS marking by associating a MAP with an interface.
Definition: qos_mark.c:79
#define FOR_EACH_QOS_SOURCE(_src)
Definition: qos_types.h:54
unsigned int u32
Definition: types.h:88
u8 * format_qos_source(u8 *s, va_list *args)
format/unformat QoS source types
Definition: qos_types.c:27
struct _unformat_input_t unformat_input_t
walk_rc_t(* qos_mark_walk_cb_t)(u32 sw_if_index, u32 map_id, qos_source_t input_source, void *ctx)
Definition: qos_mark.h:31
static clib_error_t * qos_mark_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: qos_mark.c:232
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
svmdb_client_t * c
enum qos_source_t_ qos_source_t
QoS types.
static void qos_egress_map_feature_config(u32 sw_if_index, qos_source_t qs, u8 enable)
Definition: qos_mark.c:59
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
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
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
#define clib_max(x, y)
Definition: clib.h:320
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
void qos_mark_walk(qos_mark_walk_cb_t fn, void *c)
Definition: qos_mark.c:121
static clib_error_t * qos_mark_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: qos_mark.c:139
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:556
void qos_mark_mpls_enable_disable(u32 sw_if_index, u8 enable)
Definition: qos_mark.c:52
uword unformat_qos_source(unformat_input_t *input, va_list *args)
Definition: qos_types.c:35
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
u32 qos_egress_map_id_t
A QOS egress map translates from the COS bits stored in the packet&#39;s meta-data into a per-protocol CO...
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:303
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
#define QOS_N_SOURCES
The maximum number of sources.
Definition: qos_types.h:45
static_always_inline void clib_memset_u32(void *p, u32 val, uword count)
Definition: string.h:332