FD.io VPP  v21.01.1
Vector Packet Processing
qos_egress_map.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2018 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
19 #include <vnet/qos/qos_mark.h>
20 
21 /**
22  * Pool from which to allocate table
23  */
25 
26 /**
27  * DB to map user table-IDs to internal table indicies.
28  */
30 
31 index_t
33 {
34  uword *p = NULL;
35 
36  p = hash_get (qem_db, mid);
37 
38  if (NULL != p)
39  return p[0];
40 
41  return (INDEX_INVALID);
42 }
43 
46 {
48  index_t qmi;
49 
50  /* *INDENT-OFF* */
51  hash_foreach(qid, qmi, qem_db,
52  ({
53  if (qmi == qemi)
54  return (qid);
55  }));
56  /* *INDENT-OFF* */
57 
58  return (~0);
59 }
60 
63 {
64  index_t qemi;
65 
66  qemi = qos_egress_map_find (mid);
67 
68  if (INDEX_INVALID != qemi)
69  {
70  return (pool_elt_at_index (qem_pool, qemi));
71  }
72 
73  return (NULL);
74 }
75 
76 static qos_egress_map_t *
78 {
79  qos_egress_map_t *qem;
80 
81  /*
82  * Find the existing or create a new table
83  */
84  qem = qos_egress_map_find_i (mid);
85 
86  if (NULL == qem)
87  {
88  index_t qemi;
89 
90  pool_get_aligned (qem_pool, qem, CLIB_CACHE_LINE_BYTES);
91  qemi = qem - qem_pool;
92 
93  clib_memset (qem, 0, sizeof (*qem));
94  hash_set (qem_db, mid, qemi);
95  }
96 
97  return (qem);
98 }
99 
100 void
103 {
104  qos_egress_map_t *qem;
105 
106  qem = qos_egress_map_find_or_create (mid);
107 
108  clib_memcpy (qem->qem_output[input_source],
109  values, sizeof (qem->qem_output[input_source]));
110 }
111 
112 void
114 {
115  qos_egress_map_t *qem;
116 
117  qem = qos_egress_map_find_i (mid);
118  hash_unset (qem_db, mid);
119 
120  if (NULL != qem)
121  {
122  pool_put (qem_pool, qem);
123  }
124 }
125 
126 void
128 {
130  index_t qmi;
131 
132  /* *INDENT-OFF* */
133  hash_foreach(qid, qmi, qem_db,
134  ({
135  fn(qid, pool_elt_at_index(qem_pool, qmi), c);
136  }));
137  /* *INDENT-OFF* */
138 }
139 
140 static clib_error_t *
142  unformat_input_t * input, vlib_cli_command_t * cmd)
143 {
145  qos_egress_map_t *qem;
146  u8 add;
147 
148  add = 1;
149  map_id = ~0;
150  qem = NULL;
151 
153  {
154  if (unformat (input, "delete") || unformat (input, "del"))
155  add = 0;
156  else if (unformat (input, "id %d", &map_id))
157  qem = qos_egress_map_find_or_create (map_id);
158  else
159  {
160  int qs, qi, qo;
161 
162  if (NULL == qem)
163  return clib_error_return (0, "map-id must be specified");
164 
165  while (unformat
166  (input, "[%U][%d]=%d", unformat_qos_source, &qs, &qi, &qo))
167  qem->qem_output[qs][qi] = qo;
168  break;
169  }
170  }
171 
172  if (!add)
173  qos_egress_map_delete (map_id);
174 
175  return (NULL);
176 }
177 
178 /*?
179  * Update a Egress Qos Map table
180  *
181  * @cliexpar
182  * @cliexcmd{qos egress map id 0 [ip][4]=4}
183  ?*/
184 /* *INDENT-OFF* */
185 VLIB_CLI_COMMAND (qos_egress_map_update_command, static) = {
186  .path = "qos egress map",
187  .short_help = "qos egress map id %d [delete] {[SOURCE][INPUT]=OUTPUT}",
188  .function = qos_egress_map_update_cli,
189  .is_mp_safe = 1,
190 };
191 /* *INDENT-ON* */
192 
193  u8 *format_qos_egress_map (u8 * s, va_list * args)
194  {
195  qos_egress_map_t *qem = va_arg (*args, qos_egress_map_t *);
196  u32 indent = va_arg (*args, u32);
197  int qs;
198  u32 ii;
199 
201  {
202  s = format (s, "%U%U:[",
204 
205  for (ii = 0; ii < ARRAY_LEN (qem->qem_output[qs]) - 1; ii++)
206  {
207  s = format (s, "%d,", qem->qem_output[qs][ii]);
208  }
209  s = format (s, "%d]\n", qem->qem_output[qs][ii]);
210  }
211 
212  return (s);
213  }
214 
216  unformat_input_t * input,
217  vlib_cli_command_t * cmd)
218  {
220  qos_egress_map_t *qem;
222 
223  map_id = ~0;
224  qem = NULL;
225  error = NULL;
226 
228  {
229  if (unformat (input, "id %d", &map_id))
230  ;
231  else
232  {
233  error = unformat_parse_error (input);
234  goto done;
235  }
236  }
237 
238  if (~0 == map_id)
239  {
240  index_t qemi;
241 
242  /* *INDENT-OFF* */
243  hash_foreach(map_id, qemi, qem_db,
244  ({
245  vlib_cli_output (vm, " Map-ID:%d\n%U",
246  map_id,
248  pool_elt_at_index(qem_pool, qemi), 2);
249  }));
250  /* *INDENT-ON* */
251  }
252  else
253  {
254  qem = qos_egress_map_find_i (map_id);
255 
256  if (NULL == qem)
257  {
258  error = clib_error_return (0, "No Map for ID %d", map_id);
259  }
260  else
261  {
262  vlib_cli_output (vm, " Map-ID:%d\n%U",
263  map_id, format_qos_egress_map, qem, 2);
264  }
265  }
266 
267  done:
268  return (error);
269  }
270 
271 /*?
272  * Show Egress Qos Maps
273  *
274  * @cliexpar
275  * @cliexcmd{show qos egress map}
276  ?*/
277 /* *INDENT-OFF* */
278 VLIB_CLI_COMMAND (qos_egress_map_show_command, static) = {
279  .path = "show qos egress map",
280  .short_help = "show qos egress map id %d",
281  .function = qos_egress_map_show,
282  .is_mp_safe = 1,
283 };
284 /* *INDENT-ON* */
285 
286 /*
287  * fd.io coding-style-patch-verification: ON
288  *
289  * Local Variables:
290  * eval: (c-set-style "gnu")
291  * End:
292  */
qos_egress_map_t * qem_pool
Pool from which to allocate table.
#define hash_set(h, key, value)
Definition: hash.h:255
#define hash_unset(h, key)
Definition: hash.h:261
static qos_egress_map_t * qos_egress_map_find_or_create(qos_egress_map_id_t mid)
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)
void qos_egress_map_walk(qos_egress_map_walk_cb_t fn, void *c)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
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:1580
u32 map_id
Definition: qos.api:214
u8 * format_qos_egress_map(u8 *s, va_list *args)
unsigned char u8
Definition: types.h:56
uword * qem_db
DB to map user table-IDs to internal table indicies.
void qos_egress_map_delete(qos_egress_map_id_t mid)
#define clib_memcpy(d, s, n)
Definition: string.h:180
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
static clib_error_t * qos_egress_map_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
description fragment has unexpected format
Definition: map.api:433
static clib_error_t * qos_egress_map_update_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
#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
void qos_egress_map_update(qos_egress_map_id_t mid, qos_source_t input_source, qos_bits_t *values)
Add a qos-egress map to an interface.
u8 * format_qos_source(u8 *s, va_list *args)
format/unformat QoS source types
Definition: qos_types.c:27
Definition: cJSON.c:84
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
struct _unformat_input_t unformat_input_t
qos_egress_map_t * qos_egress_map_find_i(qos_egress_map_id_t mid)
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:245
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
svmdb_client_t * c
enum qos_source_t_ qos_source_t
QoS types.
#define ARRAY_LEN(x)
Definition: clib.h:67
walk_rc_t(* qos_egress_map_walk_cb_t)(qos_egress_map_id_t id, const qos_egress_map_t *m, void *c)
Walk each of the configured maps.
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
For a given output source a table maps each value of every input source.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
#define unformat_parse_error(input)
Definition: format.h:268
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
u64 uword
Definition: types.h:112
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
uword unformat_qos_source(unformat_input_t *input, va_list *args)
Definition: qos_types.c:35
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
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
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170