FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
qos_record.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 
24 /**
25  * Per-interface, per-protocol vector of feature on/off configurations
26  */
29 
30 static void
33 {
34  switch (input_source)
35  {
36  case QOS_SOURCE_IP:
37  vnet_feature_enable_disable ("ip6-unicast", "ip6-qos-record",
38  sw_if_index, enable, NULL, 0);
39  vnet_feature_enable_disable ("ip6-multicast", "ip6-qos-record",
40  sw_if_index, enable, NULL, 0);
41  vnet_feature_enable_disable ("ip4-unicast", "ip4-qos-record",
42  sw_if_index, enable, NULL, 0);
43  vnet_feature_enable_disable ("ip4-multicast", "ip4-qos-record",
44  sw_if_index, enable, NULL, 0);
45  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_L2_IP_QOS_RECORD,
46  enable);
47  break;
48  case QOS_SOURCE_MPLS:
49  vnet_feature_enable_disable ("mpls-input", "mpls-qos-record",
50  sw_if_index, enable, NULL, 0);
51  break;
52  case QOS_SOURCE_VLAN:
53  vnet_feature_enable_disable ("ip6-unicast", "vlan-ip6-qos-record",
54  sw_if_index, enable, NULL, 0);
55  vnet_feature_enable_disable ("ip6-multicast", "vlan-ip6-qos-record",
56  sw_if_index, enable, NULL, 0);
57  vnet_feature_enable_disable ("ip4-unicast", "vlan-ip4-qos-record",
58  sw_if_index, enable, NULL, 0);
59  vnet_feature_enable_disable ("ip4-multicast", "vlan-ip4-qos-record",
60  sw_if_index, enable, NULL, 0);
61  vnet_feature_enable_disable ("mpls-input", "vlan-mpls-qos-record",
62  sw_if_index, enable, NULL, 0);
63  break;
64  case QOS_SOURCE_EXT:
65  /* not a valid option for recording */
66  break;
67  }
68 }
69 
70 int
72 {
73  vec_validate (qos_record_configs[input_source], sw_if_index);
74 
75  if (0 == qos_record_configs[input_source][sw_if_index])
76  {
77  qos_record_feature_config (sw_if_index, input_source, 1);
78  }
79 
81  return (0);
82 }
83 
84 int
86 {
87  if (vec_len (qos_record_configs[input_source]) <= sw_if_index)
88  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
89 
90  if (0 == qos_record_configs[input_source][sw_if_index])
91  return VNET_API_ERROR_VALUE_EXIST;
92 
94 
95  if (0 == qos_record_configs[input_source][sw_if_index])
96  {
97  qos_record_feature_config (sw_if_index, input_source, 0);
98  }
99 
100  return (0);
101 }
102 
103 void
105 {
106  qos_source_t qs;
107 
109  {
111 
112  vec_foreach_index (sw_if_index, qos_record_configs[qs])
113  {
114  if (0 != qos_record_configs[qs][sw_if_index])
115  fn (sw_if_index, qs, c);
116  }
117  }
118 }
119 
120 /*
121  * Disable recording feature for all protocols when the interface
122  * is deleted
123  */
124 static clib_error_t *
126  u32 sw_if_index, u32 is_add)
127 {
128  if (!is_add)
129  {
130  qos_source_t qs;
131 
133  {
134  while (qos_record_disable (sw_if_index, qs) == 0);
135  }
136  }
137 
138  return (NULL);
139 }
140 
142 
143 clib_error_t *
145 {
146  qos_source_t qs;
147  vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "l2-ip-qos-record");
148 
149  /* Initialize the feature next-node indexes */
152  node->index,
155  l2_qos_input_next[qs]);
156  return 0;
157 }
158 
160 
161 static clib_error_t *
163  unformat_input_t * input, vlib_cli_command_t * cmd)
164 {
165  vnet_main_t *vnm = vnet_get_main ();
166  u32 sw_if_index, qs;
167  u8 enable;
168 
169  qs = 0xff;
170  enable = 1;
171  sw_if_index = ~0;
172 
174  {
175  if (unformat (input, "%U", unformat_vnet_sw_interface,
176  vnm, &sw_if_index))
177  ;
178  else if (unformat (input, "%U", unformat_qos_source, &qs))
179  ;
180  else if (unformat (input, "enable"))
181  enable = 1;
182  else if (unformat (input, "disable"))
183  enable = 0;
184  else
185  break;
186  }
187 
188  if (~0 == sw_if_index)
189  return clib_error_return (0, "interface must be specified");
190  if (0xff == qs)
191  return clib_error_return (0, "input location must be specified");
192 
193  if (enable)
194  qos_record_enable (sw_if_index, qs);
195  else
196  qos_record_disable (sw_if_index, qs);
197 
198  return (NULL);
199 }
200 
201 /*?
202  * Enable QoS bit recording on an interface using the packet's input DSCP bits
203  * Which input QoS bits to use are either; IP, MPLS or VLAN. If more than
204  * one protocol is chosen (which is foolish) the higher layers override the
205  * lower.
206  *
207  * @cliexpar
208  * @cliexcmd{qos record ip GigEthernet0/1/0}
209  ?*/
210 /* *INDENT-OFF* */
211 VLIB_CLI_COMMAND (qos_record_command, static) = {
212  .path = "qos record",
213  .short_help = "qos record <record-source> <INTERFACE> [disable]",
214  .function = qos_record_cli,
215  .is_mp_safe = 1,
216 };
217 /* *INDENT-ON* */
218 
219 static void
221 {
222  u8 n_cfgs[QOS_N_SOURCES] = { };
223  qos_source_t qs;
224  bool set;
225 
226  set = false;
227 
229  {
230  if (vec_len (qos_record_configs[qs]) <= sw_if_index)
231  continue;
232  if (0 != (n_cfgs[qs] = qos_record_configs[qs][sw_if_index]))
233  set = true;
234  }
235 
236  if (set)
237  {
239  vnet_get_main (), sw_if_index);
240 
242  {
243  if (n_cfgs[qs] != 0)
244  vlib_cli_output (vm, " %U", format_qos_source, qs);
245  }
246  }
247 }
248 
249 static clib_error_t *
251  unformat_input_t * input, vlib_cli_command_t * cmd)
252 {
253  vnet_main_t *vnm = vnet_get_main ();
254  qos_source_t qs;
256 
257  sw_if_index = ~0;
258 
260  {
261  if (unformat (input, "%U", unformat_vnet_sw_interface,
262  vnm, &sw_if_index))
263  ;
264  }
265 
266  if (~0 == sw_if_index)
267  {
268  u32 ii, n_ints = 0;
269 
271  {
272  n_ints = clib_max (n_ints, vec_len (qos_record_configs[qs]));
273  }
274 
275  for (ii = 0; ii < n_ints; ii++)
276  {
278  }
279  }
280  else
281  qos_record_show_one_interface (vm, sw_if_index);
282 
283  return (NULL);
284 }
285 
286 /*?
287  * Show Egress Qos Maps
288  *
289  * @cliexpar
290  * @cliexcmd{show qos egress map}
291  ?*/
292 /* *INDENT-OFF* */
293 VLIB_CLI_COMMAND (qos_record_show_command, static) = {
294  .path = "show qos record",
295  .short_help = "show qos record [interface]",
296  .function = qos_record_show,
297  .is_mp_safe = 1,
298 };
299 /* *INDENT-ON* */
300 
301 /*
302  * fd.io coding-style-patch-verification: ON
303  *
304  * Local Variables:
305  * eval: (c-set-style "gnu")
306  * End:
307  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
#define vec_foreach_index(var, v)
Iterate over vector indices.
void qos_record_walk(qos_record_walk_cb_t fn, void *c)
Definition: qos_record.c:104
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
u32 index
Definition: node.h:279
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(qos_record_ip_interface_add_del)
u8 * qos_record_configs[QOS_N_SOURCES]
Per-interface, per-protocol vector of feature on/off configurations.
Definition: qos_record.c:27
static void qos_record_show_one_interface(vlib_main_t *vm, u32 sw_if_index)
Definition: qos_record.c:220
vlib_main_t * vm
Definition: in2out_ed.c:1582
unformat_function_t unformat_vnet_sw_interface
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
Some external source, e.g.
Definition: qos_types.h:35
static clib_error_t * qos_record_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: qos_record.c:162
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
#define clib_error_return(e, args...)
Definition: error.h:99
#define FOR_EACH_QOS_SOURCE(_src)
Definition: qos_types.h:54
unsigned int u32
Definition: types.h:88
vl_api_qos_source_t input_source
Definition: qos.api:53
u8 * format_qos_source(u8 *s, va_list *args)
format/unformat QoS source types
Definition: qos_types.c:27
static clib_error_t * qos_record_ip_interface_add_del(vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
Definition: qos_record.c:125
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
u32 l2_qos_input_next[QOS_N_SOURCES][32]
Definition: qos_record.c:28
clib_error_t * qos_record_init(vlib_main_t *vm)
Definition: qos_record.c:144
struct _unformat_input_t unformat_input_t
static void qos_record_feature_config(u32 sw_if_index, qos_source_t input_source, u8 enable)
Definition: qos_record.c:31
walk_rc_t(* qos_record_walk_cb_t)(u32 sw_if_index, qos_source_t input_source, void *ctx)
Definition: qos_record.h:24
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
svmdb_client_t * c
enum qos_source_t_ qos_source_t
QoS types.
static void feat_bitmap_init_next_nodes(vlib_main_t *vm, u32 node_index, u32 num_features, char **feat_names, u32 *next_nodes)
Initialize the feature next-node indexes of a graph node.
Definition: feat_bitmap.h:43
char ** l2input_get_feat_names(void)
Return an array of strings containing graph node names of each feature.
Definition: l2_input.c:62
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
int qos_record_disable(u32 sw_if_index, qos_source_t input_source)
Definition: qos_record.c:85
u32 l2input_intf_bitmap_enable(u32 sw_if_index, l2input_feat_masks_t feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_input.c:527
IPv6 to IPv4 translation.
#define clib_max(x, y)
Definition: clib.h:320
static clib_error_t * qos_record_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: qos_record.c:250
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
int qos_record_enable(u32 sw_if_index, qos_source_t input_source)
Definition: qos_record.c:71
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
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