OpenNSL API Guide and Reference Manual
example_policer.c
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * (C) Copyright Broadcom Corporation 2013-2017
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  **********************************************************************
18  *
19  * \file example_policer.c
20  *
21  * \brief OpenNSL example application for policer or service meter
22  *
23  * \details In this example, we will create a simple single rate, three color policer.
24  * This policer will be attached to a Field Processor rule that counts
25  * packets ingressing with a specific destination MAC address.
26  *
27  * If single_rate=1 - meter mode is opennslPolicerModeSrTcm (single rate 3 colors),
28  * the excess bucket has no credits of its own and it only receives excess credits
29  * from the committed bucket run ethernet packet with DA 1 and vlan tag id 1 from
30  * in_port, with:
31  *
32  * 1) priority = 1:
33  * the stream will go through the committed bucket and afterwards also through
34  * the excess bucket for single_rate: the stream will arrive at out_port with
35  * 30M rate (EIR has no credits).
36  *
37  * 2) priority = 4:
38  * the stream will go straight to the excess bucket and arrive at out_port with
39  * 20M rate
40  *
41  * Note: Stats processor is set based on the core. Use ports belonging to core=0(1 through 20)
42  * Create VLAN 100 and add input port and output port in the VLAN
43  * vlan create 100 PortBitMap=xe2,xe3
44  *
45  **********************************************************************/
46 
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <opennsl/error.h>
51 #include <opennsl/init.h>
52 #include <opennsl/port.h>
53 #include <opennsl/l2.h>
54 #include <opennsl/vlan.h>
55 #include <opennsl/field.h>
56 #include <opennsl/policer.h>
57 #include <opennsl/cosqX.h>
58 #include <examples/util.h>
59 
60 
61 char example_usage[] =
62 "Syntax: example_policer \n\r"
63 " \n\r"
64 "Paramaters: None. \n\r"
65 " \n\r"
66 "Example: The following command is used to create a policer and attach \n\r"
67 " it to a field processor rule matching traffic with \n\r"
68 " destination MAC = MAC_DA. \n\r"
69 " It also provides an option to display the number of packets \n\r"
70 " redirected to destination port. \n\r"
71 " \n\r"
72 " example_policer \n\r"
73 " \n\r"
74 "Usage Guidelines: None. \n\r";
75 
76 #define DEFAULT_UNIT 0
77 #define DEFAULT_VLAN 1
78 #define MAC_DA {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
79 /* __doxy_func_body_end__ */
80 #define MAC_MASK {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
81 /* __doxy_func_body_end__ */
82 
83 
85 int stat_id = 2;
88 
91 {
92  int rv;
93  opennsl_info_t info;
95 
96  rv = opennsl_info_get(unit, &info);
97  if (OPENNSL_FAILURE(rv))
98  {
99  printf("Error in opennsl_info_get, rv=%d\n", rv);
100  return rv;
101  }
102 
103  /* create policer 1 */
105  pol_cfg.mode = opennslPolicerModeSrTcm; /* single rate three colors mode */
106 
107  pol_cfg.ckbits_sec = 30000; /* 30Mbps */
108  pol_cfg.ckbits_burst = 1000;
109  pol_cfg.pkbits_burst = 1000;
110  pol_cfg.max_pkbits_sec = 20000; /* 20Mbps max */
111 
112  rv = opennsl_policer_create(unit, &(pol_cfg), &(policer_id));
113  if (rv != OPENNSL_E_NONE)
114  {
115  printf("Error in opennsl_policer_create no. 1, rv=%d\n",rv);
116  return rv;
117  }
118  printf("policer_id1: %d\n", policer_id);
119 
120  return rv;
121 }
122 /* __doxy_func_body_end__ */
123 
124 
127 {
128  int rv;
129  int group_priority = 6;
135  int statId;
136  opennsl_l2_addr_t l2addr;
137  opennsl_mac_t mac = MAC_DA;
138  opennsl_mac_t mask = MAC_MASK;
139 
140 
141  /* map packet to meter_id, according to in-port and dst-port */
144  rv = opennsl_field_group_create_mode_id(unit, qset, group_priority, opennslFieldGroupModeAuto, grp);
145  if (rv != OPENNSL_E_NONE)
146  {
147  printf("Error in opennsl_field_group_create_mode_id. rv=%d \n",rv);
148  return rv;
149  }
150 
155  rv = opennsl_field_group_action_set(unit, grp, aset);
156  if (rv != OPENNSL_E_NONE)
157  {
158  printf("Error in opennsl_field_group_action_set. rv=%d \n",rv);
159  return rv;
160  }
161 
162  rv = opennsl_field_entry_create(unit, grp, &ent);
163  if (rv != OPENNSL_E_NONE)
164  {
165  printf("Error in opennsl_field_entry_create. rv=%d\n",rv);
166  return rv;
167  }
168 
169  rv = opennsl_field_qualify_DstMac(unit, ent, mac, mask);
170  if (rv != OPENNSL_E_NONE)
171  {
172  printf("Error in opennsl_field_qualify_DstMac. rv=%d\n",rv);
173  return rv;
174  }
175 
178  statId = stat_id;
179  rv = opennsl_field_stat_create_id(unit, grp, 2, &(stats[0]), statId);
180  if (rv != OPENNSL_E_NONE)
181  {
182  printf("Error in opennsl_field_stat_create. rv=%d \n", rv);
183  return rv;
184  }
185 
186  rv = opennsl_field_entry_stat_attach(unit, ent, statId);
187  if (rv != OPENNSL_E_NONE)
188  {
189  printf("Error in opennsl_field_entry_stat_attach with ent %d. rv=%d\n", ent, rv);
190  return rv;
191  }
192 
193  /* Create the policer */
194  rv = example_create_meter(unit);
195  if (rv != OPENNSL_E_NONE)
196  {
197  printf("\r\nFailed to create the meter. Error: %s\r\n",
198  opennsl_errmsg(rv));
199  return rv;
200  }
201 
202  rv = opennsl_field_entry_policer_attach(unit, ent, 0, (policer_id & 0xffff));
203  if (rv != OPENNSL_E_NONE)
204  {
205  printf("Error in opennsl_field_entry_policer_attach with policer_id %d. rv=%d \n", policer_id, rv);
206  return rv;
207  }
208 
209  rv = opennsl_field_group_install(unit, grp);
210  if (rv != OPENNSL_E_NONE)
211  {
212  printf("Error in opennsl_field_group_install. rv=%d \n", rv);
213  return rv;
214  }
215 
216  /* send traffic with DA=1 and Vlan tag id 100 to out_port */
217  opennsl_l2_addr_t_init(&l2addr, mac, 100);
218  l2addr.port = out_port;
219  rv = opennsl_l2_addr_add(unit, &l2addr);
220  if (rv != OPENNSL_E_NONE)
221  {
222  printf("Error, opennsl_l2_addr_add with vid 1. rv=%d \n", rv);
223  return rv;
224  }
225 
226  /*
227  * map Vlan tag proirity=4 and cfi=0 to yellow color:
228  * this will mean that the packet will arrive with a yellow color instead of green
229  * if meter mode is not COLOR_BLIND, the packet will go straight to the excess bucket
230  * (without going through the committed bucket)
231  */
232  rv = opennsl_port_vlan_priority_map_set(unit, in_port, 4 /* priority */, 0 /* cfi */,
233  1 /* internal priority */, opennslColorYellow /* color */);
234  if (rv != OPENNSL_E_NONE)
235  {
236  printf("Error, opennsl_port_vlan_priority_map_set with prio 4. rv=%d \n", rv);
237  return rv;
238  }
239 
240  /*
241  * map Vlan tag proirity=1 and cfi=0 to green color:
242  * packet that will arrive with a green color will go through the committed bucket
243  * and the excess bucket
244  */
245  rv = opennsl_port_vlan_priority_map_set(unit, in_port, 1 /* priority */, 0 /* cfi */,
246  0 /* internal priority */, opennslColorGreen /* color */);
247  if (rv != OPENNSL_E_NONE)
248  {
249  printf("Error, opennsl_port_vlan_priority_map_set with prio 1. rv=%d \n", rv);
250  return rv;
251  }
252 
253  /* set discard DP to drop all packets with DP = 3 */
255  if (rv != OPENNSL_E_NONE)
256  {
257  printf("Error, opennsl_cosq_discard_set. rv=%d \n", rv);
258  }
259 
260  return rv;
261 }
262 /* __doxy_func_body_end__ */
263 
264 /*****************************************************************/
271 int main(int argc, char *argv[])
272 {
273  int rv = 0;
274  int unit = DEFAULT_UNIT;
275  int choice;
276  uint64 val;
277  int inport, outport;
278 
279  if((argc != 1) || ((argc > 1) && (strcmp(argv[1], "--help") == 0)))
280  {
281  printf("%s\n\r", example_usage);
282  return OPENNSL_E_PARAM;
283  }
284 
285  /* Initialize the system. */
287  if(rv != OPENNSL_E_NONE)
288  {
289  printf("\r\nFailed to initialize the system. Error: %s\r\n",
290  opennsl_errmsg(rv));
291  return rv;
292  }
293 
294  /* cold boot initialization commands */
295  rv = example_port_default_config(unit);
296  if (rv != OPENNSL_E_NONE)
297  {
298  printf("\r\nFailed to apply default config on ports, rc = %d (%s).\r\n",
299  rv, opennsl_errmsg(rv));
300  }
301 
302  /* Add ports to default vlan. */
303  printf("Adding ports to default vlan.\r\n");
305  if(rv != OPENNSL_E_NONE)
306  {
307  printf("\r\nFailed to add default ports. Error: %s\r\n",
308  opennsl_errmsg(rv));
309  }
310 
311  while(1) {
312  printf("\r\nUser menu: Select one of the following options\r\n");
313  printf("1. Apply policer to the traffic\n");
314  printf("2. Retrieve statistics of the policer\n");
315 #ifdef INCLUDE_DIAG_SHELL
316  printf("9. Launch diagnostic shell\n");
317 #endif
318  printf("0. Quit the application.\r\n");
319 
321  {
322  printf("Invalid option entered. Please re-enter.\n");
323  continue;
324  }
325  switch(choice)
326  {
327  case 1:
328  {
329  printf("Enter the input port number(belonging to core-0):\n");
331  {
332  printf("Invalid value entered. Please re-enter.\n");
333  continue;
334  }
335 
336  printf("Enter the output port number(belonging to core-0):\n");
338  {
339  printf("Invalid value entered. Please re-enter.\n");
340  continue;
341  }
342 
343  /* Create policer and test traffic rate */
344  rv = example_create_policy(unit, inport, outport);
345  if (rv != OPENNSL_E_NONE)
346  {
347  printf("\r\nFailed to create the policer. Error: %s\r\n",
348  opennsl_errmsg(rv));
349  }
350 
351  break;
352  }
353 
354  case 2:
355  {
356  rv = opennsl_field_stat_get(unit, stat_id, accept_stats, &val);
357  if (rv != OPENNSL_E_NONE) {
358  printf("Failed to get the accepted packets statistics, "
359  "Error %s\n", opennsl_errmsg(rv));
360  return rv;
361  }
362  printf("Number of packets accepted: %lld (0x%0x)\n", val, val);
363 
364  val = 0;
365  rv = opennsl_field_stat_get(unit, stat_id, drop_stats, &val);
366  if (rv != OPENNSL_E_NONE) {
367  printf("Failed to get the dropped packets statistics, "
368  "Error %s\n", opennsl_errmsg(rv));
369  return rv;
370  }
371  printf("Number of packets dropped: %lld (0x%0x)\n", val, val);
372  break;
373  }
374 
375 #ifdef INCLUDE_DIAG_SHELL
376  case 9:
377  {
378  opennsl_driver_shell();
379  break;
380  }
381 #endif
382 
383  case 0:
384  {
385  printf("Exiting the application.\n");
386  rv = opennsl_driver_exit();
387  return rv;
388  }
389  default:
390  break;
391  } /* End of switch */
392  } /* End of while */
393 
394  return rv;
395 }
396 /* __doxy_func_body_end__ */