OpenNSL API Guide and Reference Manual
example_sflow.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_sflow.c
20  *
21  * \brief OPENNSL example program to demonstrate sFlow
22  *
23  * \details sFlow is a statistical sampling technology for monitoring
24  * traffic in data networks. On average, one packet in N is sampled for
25  * analysis. This example demonstrates configuration of sFlow on the
26  * ingress ports and displays the part of the sampled packets
27  * on the console.
28  *
29  * This application also supports Warmboot feature. Warmboot is
30  * the process of restarting the device driver software while
31  * the hardware is running without interrupting the dataplane.
32  *
33  * Setup the following envinonment variable before running the application.
34  * For Cold boot mode, use "export OPENNSL_BOOT_FLAGS = 0x000000".
35  * For Warm boot mode, use "export OPENNSL_BOOT_FLAGS = 0x200000".
36  *
37  **********************************************************************/
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sal/driver.h>
42 #include <opennsl/error.h>
43 #include <opennsl/switch.h>
44 #include <opennsl/rx.h>
45 #include <examples/util.h>
46 
47 char example_usage[] =
48 "Syntax: example_sflow \n\r"
49 " \n\r"
50 "Paramaters: None \n\r"
51 " \n\r"
52 "Example: The following command is used to demonstrate sFlow \n\r"
53 " example_sflow \n\r"
54 " \n\r"
55 "Usage Guidelines: This program allows the user to configure sFlow \n\r"
56 "parameters. It also has a provision to display the sFlow sampled \n\r"
57 "packet on the console. \n\r"
58 " \n\r"
59 "Note: Configure sFlow in such a way that less number of packets are \n\r"
60 "sampled, as it prints the packet on the console which is time consuming\n\r";
61 
62 
63 int verbose = 4;
64 
65 /**************************************************************************/
76  void *cookie)
77 {
78  static int pkt_total_count = 0;
79  static int pkt_sflow_count = 0;
80  int i;
81 
82  /* Increment the receive packet count */
83  pkt_total_count++;
84 
85  if(verbose > 3)
86  {
87  /* Print first 32 bytes of the received packet */
88  printf("==========================================\n\r");
89  printf("Packet %d of length %d is received:\n\r",
90  pkt_total_count, pkt->pkt_len);
91 
92  for (i = 0; i < 32; i++)
93  {
94  printf("%02x ", pkt->pkt_data->data[i]);
95  if(((i + 1) % 16) == 0)
96  {
97  printf("\n\r");
98  }
99  }
100  printf("\n\r");
101 
102  }
103 
104  printf("Received pkt on rx_port %d, src_port %d "
105  "flags 0x%x, vlan %d cos %d\n",
106  pkt->rx_port, pkt->src_port, pkt->flags,
107  pkt->vlan, pkt->cos);
108 
110  {
111  /* we are here as the packets received is sFlow sampled packet */
112  pkt_sflow_count++;
113  printf("The received packet is sFlow sampled packet. "
114  "Sample packet count: %d\n\r", pkt_sflow_count);
115  }
116 
117  if(verbose > 3)
118  {
119  printf("==========================================\n\r");
120  }
121  printf("\n\r");
122 
123  return OPENNSL_RX_HANDLED;
124 }
125 /* __doxy_func_body_end__ */
126 
127 /*****************************************************************/
134 int main(int argc, char *argv[])
135 {
136  int rv = 0;
137  int unit = 0;
138  int choice;
139  unsigned int warm_boot;
140  int index = 0;
141  int port;
142  int irate, erate;
143 
144  if(strcmp(argv[0], "gdb") == 0)
145  {
146  index = 1;
147  }
148  if((argc != (index + 1)) || ((argc > (index + 1))
149  && (strcmp(argv[index + 1], "--help") == 0))) {
150  printf("%s\n\r", example_usage);
151  return OPENNSL_E_PARAM;
152  }
153 
154  /* Initialize the system */
156 
157  if(rv != 0) {
158  printf("\r\nFailed to initialize the system.\r\n");
159  return rv;
160  }
161 
163 
164  if(!warm_boot)
165  {
166  /* Add ports to default vlan. */
167  printf("Adding ports to default vlan.\r\n");
169  if(rv != OPENNSL_E_NONE)
170  {
171  printf("\r\nFailed to add default ports. rv: %s\r\n", opennsl_errmsg(rv));
172  return rv;
173  }
174 
175  rv = example_port_default_config(unit);
176  if (rv != OPENNSL_E_NONE)
177  {
178  printf("\r\nFailed to apply default config on ports, rc = %d (%s).\r\n",
179  rv, opennsl_errmsg(rv));
180  }
181  }
182 
183  /* rx start */
184  if (!opennsl_rx_active(unit))
185  {
186  rv = opennsl_rx_start(unit, NULL);
187  if (OPENNSL_FAILURE(rv))
188  printf("RX start failed unit %d.\n", unit);
189  }
190 
191  rv = opennsl_rx_register(
192  unit,
193  "sflow_rx_callback_function",
194  example_sflow_handle_rx_event, /*(opennsl_rx_cb_f) */
195  100,
196  NULL,
197  OPENNSL_RCO_F_ALL_COS /*| OPENNSL_RCO_F_INTR*/);
198 
199  if(rv != OPENNSL_E_NONE) {
200  printf("Failed to register sFlow Rx callback function. Error %s\n",
201  opennsl_errmsg(rv));
202  return rv;
203  }
204  printf("Registered callback function to received sFlow sampled packets\n");
205 
206  while(1) {
207  printf("\r\nUser menu: Select one of the following options\r\n");
208  printf("1. Enable sFlow and configure sFlow sampling rate\n");
209  printf("2. Disable sFlow\n");
210  printf("3. Display sFlow configuration\n");
211  printf("4. Save the configuration to scache\n");
212 #ifdef INCLUDE_DIAG_SHELL
213  printf("9. Launch diagnostic shell\n");
214 #endif
215  printf("0. Quit the application.\r\n");
216 
218  {
219  printf("Invalid option entered. Please re-enter.\n");
220  continue;
221  }
222  switch(choice)
223  {
224  case 1:
225  {
226  printf("Enter port number\n");
228  {
229  printf("Invalid option entered. Please re-enter.\n");
230  continue;
231  }
232 
233  printf("Enter ingress sampling rate\n");
235  {
236  printf("Invalid option entered. Please re-enter.\n");
237  continue;
238  }
239 
240  rv = opennsl_port_sample_rate_set(unit, port, irate, 0);
241  if(rv != OPENNSL_E_NONE) {
242  printf("Failed to configure sFlow sample rate. Error %s\n",
243  opennsl_errmsg(rv));
244  return rv;
245  }
246 
247  /* To copy packets to CPU */
248  rv = opennsl_port_control_set(unit, port,
251 
252  /* Some of the older chips do not have support for this port *
253  * control and returns UNAVAIL return code. Ignore it safely. */
254  if(rv != OPENNSL_E_NONE && rv != OPENNSL_E_UNAVAIL) {
255  printf("Failed to configure sFlow port control. Error %s\n",
256  opennsl_errmsg(rv));
257  return rv;
258  }
259 
260  printf("Enabled sFlow on port %d with sample rate of %d\n",
261  port, irate);
262 
263  break;
264  }
265 
266  case 2:
267  {
268  printf("Enter port number\n");
270  {
271  printf("Invalid option entered. Please re-enter.\n");
272  continue;
273  }
274 
275  rv = opennsl_port_sample_rate_set(unit, port, 0, 0);
276  if(rv != OPENNSL_E_NONE) {
277  printf("Failed to clear sFlow sample rate. Error %s\n",
278  opennsl_errmsg(rv));
279  return rv;
280  }
281 
282  rv = opennsl_port_control_set(unit, port,
284  0);
285 
286  /* Some of the older chips do not have support for this port *
287  * control and returns UNAVAIL return code. Ignore it safely. */
288  if(rv != OPENNSL_E_NONE && rv != OPENNSL_E_UNAVAIL) {
289  printf("Failed to configure sFlow port control. Error %s\n",
290  opennsl_errmsg(rv));
291  return rv;
292  }
293  printf("Disabled sFlow on port %d successfully\n", port);
294 
295  break;
296  }
297 
298  case 3:
299  {
300  printf("Enter port number\n");
302  {
303  printf("Invalid option entered. Please re-enter.\n");
304  continue;
305  }
306 
307  rv = opennsl_port_sample_rate_get(unit, port, &irate, &erate);
308  if(rv != OPENNSL_E_NONE) {
309  printf("Failed to get sFlow configuration. Error %s\n",
310  opennsl_errmsg(rv));
311  return rv;
312  }
313  printf("sFlow configuration parameters on port: %d\n", port);
314  printf(" Ingress sampling rate: %d Egress sampling rate: %d\n",
315  irate, erate);
316 
317  break;
318  }
319 
320  case 4:
321  {
322  /* Sync the current configuration */
324  if(rv != OPENNSL_E_NONE) {
325  printf("Failed to synchronize the configuration to scache. "
326  "Error %s\n", opennsl_errmsg(rv));
327  return rv;
328  }
329  printf("Warmboot configuration is saved successfully.\n");
330  break;
331  } /* End of case 1 */
332 
333 #ifdef INCLUDE_DIAG_SHELL
334  case 9:
335  {
336  opennsl_driver_shell();
337  break;
338  }
339 #endif
340 
341  case 0:
342  {
343  printf("Exiting the application.\n");
344  rv = opennsl_driver_exit();
345  return rv;
346  }
347  default:
348  break;
349  } /* End of switch */
350  } /* End of while */
351 
352  return rv;
353 }
354 /* __doxy_func_body_end__ */