OpenNSL API Guide and Reference Manual
example_link_monitor.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_link_monitor.c
20  *
21  * \brief OpenNSL example application for link monitoring
22  *
23  * \details Link monitoring can be used to detect uplink failures and
24  * to disable the associated downlink ports such that the
25  * traffic can failover to secondary link.
26  *
27  **********************************************************************/
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sal/driver.h>
32 #include <opennsl/error.h>
33 #include <opennsl/vlan.h>
34 #include <opennsl/link.h>
35 #include <examples/util.h>
36 
37 char example_usage[] =
38 "Syntax: example_link_monitor uplink_port downlink_ports \n\r"
39 " \n\r"
40 "Paramaters: \n\r"
41 " uplink_port - Uplink port number to be monitored. \n\r"
42 " downlink_ports - List of ports that follow the link state \n\r"
43 " of uplink port. \n\r"
44 " Maximum of 10 ports supported. \n\r"
45 " \n\r"
46 "Example: The following command is used to configure ports 2 and 3 \n\r"
47 " to follow the link state of port 1. \n\r"
48 " example_link_monitor 1 2 3 \n\r"
49 " \n\r"
50 "Usage Guidelines: This program assumes that software linkscan \n\r"
51 " is enabled on the system. \n\r";
52 
53 #define DEFAULT_VLAN 1
54 #define LINKMON_MAX_DOWN_PORTS 10
55 #define DEFAULT_UNIT 0
56 #define TRUE 1
57 #define FALSE 0
58 #define LINK_MON_ON 1
59 #define LINK_MON_OFF 2
60 #define MAX_DIGITS_IN_CHOICE 5
61 
62 int uport = -1;
63 
64 /* List of downlink ports that follow the link state of uplink ports */
67 
68 /* debug prints */
69 int verbose = 2;
70 
71 static void example_link_change_callback(int unit, opennsl_port_t port,
72  opennsl_port_info_t *info);
73 static int example_link_monitor(int unit, int mode);
74 
75 /*****************************************************************/
82 int main(int argc, char *argv[])
83 {
84  int rv = 0;
85  int i;
86  int choice;
87  int unit = DEFAULT_UNIT;
88 
89  /* Throw command usage here. This program excepts at least one
90  down port from the user. */
91  if((argc < 3) ||
92  ((argc > 1) && (strcmp(argv[1], "--help") == 0))) {
93  printf("%s\n\r", example_usage);
94  return OPENNSL_E_PARAM;
95  }
96 
97  if(argc > (2 + LINKMON_MAX_DOWN_PORTS)) {
98  printf("Invalid number of arguments passed. Please see example help.\n\r");
99  return OPENNSL_E_PARAM;
100  }
101 
102  /* Extract input parameters */
103  uport = atoi(argv[1]);
104  for(i = 2, dport_cnt = 0; i < argc; i++) {
105  dport[dport_cnt++] = atoi(argv[i]);
106  }
107 
108  if(verbose > 1) {
109  printf("Uplink Port : %d\n\r", uport);
110  printf("Downlink Ports : ");
111  for(i = 0; i < dport_cnt; i++) {
112  printf("%2d ", dport[i]);
113  }
114  printf("\n\r");
115  }
116 
117  /* Initialize the system */
119  if(rv != OPENNSL_E_NONE) {
120  printf("\r\nFailed to initialize the system. Error %s \n\r",
121  opennsl_errmsg(rv));
122  return rv;
123  }
124 
125  /* cold boot initialization commands */
126  rv = example_port_default_config(unit);
127  if (rv != OPENNSL_E_NONE) {
128  printf("\r\nFailed to apply default config on ports, rc = %d (%s).\r\n",
129  rv, opennsl_errmsg(rv));
130  }
131 
132  /* Setup link monitoring */
133  rv = example_link_monitor(DEFAULT_UNIT, LINK_MON_ON);
134  if(rv != OPENNSL_E_NONE) {
135  printf("\r\nFailed to set link monitor mode. Error: %s.\n\r",
136  opennsl_errmsg(rv));
137  }
138 
139  printf("\r\nLink monitoring is enabled successfully.\n\r");
140 
141  while(1) {
142  printf("\r\nUser menu: Select one of the following options\r\n");
143  printf("1. Enable the link monitoring mode.\r\n");
144  printf("2. Disable the link monitoring mode.\r\n");
145 #ifdef INCLUDE_DIAG_SHELL
146  printf("9. Launch diagnostic shell\n");
147 #endif
148  printf("0. Quit the application.\r\n");
149 
151  {
152  printf("Invalid option entered. Please re-enter.\n");
153  continue;
154  }
155  switch(choice)
156  {
157  case 1:
158  {
159  rv = example_link_monitor(DEFAULT_UNIT, LINK_MON_ON);
160  if(rv != OPENNSL_E_NONE) {
161  printf("\r\nFailed to enable link monitor mode. Error: %s.\n\r",
162  opennsl_errmsg(rv));
163  }
164  break;
165  }
166  case 2:
167  {
168  rv = example_link_monitor(DEFAULT_UNIT, LINK_MON_OFF);
169  if(rv != OPENNSL_E_NONE) {
170  printf("\r\nFailed to disable link monitor mode. Error: %s.\n\r",
171  opennsl_errmsg(rv));
172  }
173  break;
174  }
175 
176 #ifdef INCLUDE_DIAG_SHELL
177  case 9:
178  {
179  opennsl_driver_shell();
180  break;
181  }
182 #endif
183 
184  case 0:
185  {
186  printf("Exiting the application.\n");
187  rv = opennsl_driver_exit();
188  return rv;
189  }
190  default:
191  break;
192  } /* End of switch */
193  } /* End of while */
194 
195  return rv;
196 }
197 /* __doxy_func_body_end__ */
198 
199 /**************************************************************************/
209 int example_link_monitor(int unit, int mode) {
210 
211  if((mode != LINK_MON_ON) && (mode != LINK_MON_OFF)) {
212  return OPENNSL_E_PARAM;
213  }
214 
215  if (mode == LINK_MON_ON) {
216 
220  example_link_change_callback));
221 
222  } else {
223 
226  example_link_change_callback));
227 
228  }
229 
230  printf("Link Monitor mode is %s.\n", (mode == LINK_MON_ON) ? "enabled" : "disabled");
231  return OPENNSL_E_NONE;
232 }
233 /* __doxy_func_body_end__ */
234 
235 /**************************************************************************/
245 static void example_link_change_callback(int unit, opennsl_port_t port,
246  opennsl_port_info_t *info)
247 {
248  int mode = FALSE;
249  int i;
250 
251  if(verbose > 2) {
252  printf("Link on port %2d changed to %4s\n", port,
253  info->linkstatus ? "UP" : "DOWN");
254  }
255 
256  /* Ignore if the link change is not on the uplink port */
257  if(port != uport) {
258  return;
259  }
260 
261  if(info->linkstatus) {
262  mode = TRUE;
263  }
264 
265  printf("Uplink port %2d link state transitioned to %4s.\n\r", port,
266  (info->linkstatus) ? "UP" : "DOWN");
267 
268  /* Update the link status on the downlink ports as per the latest
269  * uplink port link state.
270  */
271  for(i = 0; i < dport_cnt; i++) {
272 
273  if(opennsl_port_enable_set(unit, dport[i], mode) != OPENNSL_E_NONE) {
274  printf("Failed to %s port %2d.\n", (mode == TRUE)? "enable" : "disable",
275  dport[i]);
276  }
277 
278  printf("%s port %2d.\n", (mode == TRUE) ? "Enabled" : "Disabled", dport[i]);
279  }
280 }
281 /* __doxy_func_body_end__ */
282