if.c (17732B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * Network interface configuration routines and support utilities. 8 */ 9 10 #ifndef NO_SAL_APPL 11 12 13 #if defined(VXWORKS) 14 #include <vxWorks.h> 15 #include <hostLib.h> 16 #include <netShow.h> 17 #include <assert.h> 18 19 #ifndef VXWORKS_NETWORK_STACK_6_5 20 #include <ifLib.h> 21 #include <routeLib.h> 22 #endif /* VXWORKS_NETWORK_STACK_6_5 */ 23 24 #if VX_VERSION == 66 || VX_VERSION == 68 25 #include <net/utils/ifconfig.h> 26 #include <net/utils/routeCmd.h> 27 #endif /* VX_VERSION == 66 || VX_VERSION == 68 */ 28 29 #include <soc/debug.h> 30 #include <shared/bsl.h> 31 #include <appl/diag/shell.h> 32 #include <appl/diag/system.h> 33 #include <appl/diag/parse.h> 34 #include <appl/diag/pp.h> 35 #include <appl/diag/diag.h> 36 37 #include <bcm/error.h> 38 #include <bcm/link.h> 39 #include <bcm/stack.h> 40 #include <bcm/port.h> 41 #include <bcm/debug.h> 42 43 #include <pingLib.h> 44 45 #ifndef SOC_END_NAME 46 #define SOC_END_NAME "sc" 47 #endif 48 49 typedef struct if_soc_s { 50 void *ifs_sal; /* SAL Cookie */ 51 char *ifs_net_name; /* Network Name */ 52 int ifs_net_interface; /* Network interface # */ 53 sal_mac_addr_t ifs_net_mac; /* MAC Address */ 54 int ifs_net_vlan; /* VLAN ID */ 55 ip_addr_t ifs_net_ip; /* IP Address */ 56 ip_addr_t ifs_net_mask; /* Subnet Mask */ 57 ip_addr_t ifs_gateway; /* Default Gateway */ 58 char *ifs_net_host; /* Host name */ 59 } if_soc_t; 60 61 #define MAX_INTERFACE 32 62 63 static if_soc_t *if_table[SOC_MAX_NUM_DEVICES]; 64 #include <sys/types.h> 65 66 #include <soc/types.h> 67 68 #include <vxWorks.h> 69 #if defined(INCLUDE_DRIVERS) 70 #include <end.h> 71 #include <endLib.h> 72 #include <netLib.h> 73 #include <hostLib.h> 74 #include <etherMultiLib.h> 75 #endif 76 77 #include <sal/appl/sal.h> 78 #include <sal/appl/io.h> 79 80 #include <soc/debug.h> 81 82 IMPORT int ipAttach (); /* Import VxWorks routine */ 83 84 /* 85 * Macro: SAL_MAP_NETUNIT 86 * Purpose: Takes "normalized" unit number and turns it into 87 * something VxWorks can deal with 88 * Parameters: _x - unit number passed down. 89 */ 90 #define SAL_MAP_NETUNIT(_x) (_x) += 2 91 92 #if !defined(INCLUDE_DRIVERS) 93 typedef void *END_OBJ; 94 #endif 95 96 #if defined(INCLUDE_DRIVERS) 97 static int 98 sal_if_do_deconfig(char *pfx, END_OBJ *eo, char *if_name, int if_unit) 99 /* 100 * Function: 101 * Purpose: 102 * Parameters: 103 * Returns: 104 */ 105 { 106 #if VX_VERSION == 66 || VX_VERSION == 68 107 char ifconfigstr[32]; 108 #endif /* VX_VERSION == 66 || VX_VERSION == 68 */ 109 110 LOG_INFO(BSL_LS_APPL_END, 111 (BSL_META("%s: Stopping %s %d %08x \n"), 112 pfx, if_name, if_unit, (uint32)eo)); 113 if (OK != muxDevStop(eo)) { 114 cli_out("%s: Error: muxDevStop failed: %s%d\n", 115 pfx, if_name, if_unit); 116 return(-1); 117 } 118 119 #if VX_VERSION == 66 || VX_VERSION == 68 120 sprintf(ifconfigstr, "%s%d down", if_name, if_unit); 121 if (ERROR == ifconfig(ifconfigstr)) { 122 cli_out("%s: ifconfig down failed: %s%d <-- %s\n", pfx, if_name, if_unit, ifconfigstr); 123 return(-1); 124 } 125 126 sprintf(ifconfigstr, "%s%d detach", if_name, if_unit); 127 if (ERROR == ifconfig(ifconfigstr)) { 128 cli_out("%s: ifconfig down failed: %s%d <-- %s\n", pfx, if_name, if_unit, ifconfigstr); 129 return(-1); 130 } 131 #else /* VX_VERSION == 66 || VX_VERSION == 68 */ 132 133 LOG_INFO(BSL_LS_APPL_END, 134 (BSL_META("%s: Clearing Routes\n"), pfx)); 135 136 #ifdef VXWORKS_NETWORK_STACK_6_5 137 #else 138 ifRouteDelete(if_name, if_unit); 139 #endif /* VXWORKS_NETWORK_STACK_6_5 */ 140 141 LOG_INFO(BSL_LS_APPL_END, 142 (BSL_META("%s: Unloading\n"), pfx)); 143 if (OK != muxDevUnload(if_name, if_unit)) { 144 cli_out("%s: Error: muxDevUnload failed: %s%d\n", 145 pfx, if_name, if_unit); 146 return(-1); 147 } 148 LOG_INFO(BSL_LS_APPL_END, 149 (BSL_META("%s: Stopped and Unloaded: %s%d\n"), 150 pfx, if_name, if_unit)); 151 #endif /* VX_VERSION == 66 || VX_VERSION == 68 */ 152 return(0); 153 } 154 #endif /* defined(INCLUDE_DRIVERS) */ 155 156 static int 157 sal_if_deconfig(char *pfx, END_OBJ *eo, char *if_name, int if_unit) 158 /* 159 * Function: 160 * Purpose: 161 * Parameters: pfx - prefix to print on errors/warnings 162 * if_name - name of interface ("sn" for "sn0") 163 * if_unit - unit # (0 for "sn0") 164 * Returns: 0 - success 165 * -1 - failed 166 */ 167 { 168 #if defined(INCLUDE_DRIVERS) 169 int rv; 170 171 SAL_MAP_NETUNIT(if_unit); 172 173 if (NULL == endFindByName(if_name, if_unit)) { 174 cli_out("%s: Error: can not locate device: %s%d\n", 175 pfx, if_name, if_unit); 176 return(-1); 177 } 178 179 rv = sal_if_do_deconfig(pfx, eo, if_name, if_unit); 180 LOG_INFO(BSL_LS_APPL_END, 181 (BSL_META("%s: sal_if_deconfig complete: %s%d (%d)\n"), 182 pfx, if_name, if_unit, rv)); 183 return(rv); 184 #else /* !defined(INCLUDE_DRIVERS) */ 185 return(-1); 186 #endif /* !defined(INCLUDE_DRIVERS) */ 187 } 188 189 static void * 190 sal_if_config(char *pfx, int u, char *if_name, int if_unit, 191 char *if_host, sal_mac_addr_t if_mac, int if_vlan, 192 sal_ip_addr_t if_ip, sal_ip_addr_t if_netmask) 193 /* 194 * Function: sal_if_config 195 * Purpose: Configure a network device (load driver and start) 196 * Parameters: pfx - string printed for error messages. 197 * name - device name ("sn" for "sn0") 198 * unit - unint number (0 for "sn0") 199 * Returns: NULL - failed 200 * !NULL - opaque pointer. 201 */ 202 { 203 #ifdef INCLUDE_DRIVERS 204 extern END_OBJ *socend_load(char *is, void *); 205 char if_name_str[END_NAME_MAX]; 206 char if_init_str[64]; 207 char if_ip_str[SAL_IPADDR_STR_LEN]; 208 char if_mac_str[SAL_MACADDR_STR_LEN]; 209 END_OBJ *eo; /* END object */ 210 #if VX_VERSION == 64 || VX_VERSION == 65 || VX_VERSION == 66 || VX_VERSION == 68 211 #else 212 M2_INTERFACETBL m2; 213 #endif 214 #if VX_VERSION == 66 || VX_VERSION == 68 215 char if_cfg_str[256]; 216 char if_mask_str[SAL_IPADDR_STR_LEN]; 217 #endif 218 219 SAL_MAP_NETUNIT(if_unit); 220 LOG_INFO(BSL_LS_APPL_END, 221 (BSL_META_U(u, 222 "%s: sal_if_config *** if_name=%s if_unit=%d\n"), 223 pfx, if_name, if_unit)); 224 /* Build vxWorks device name */ 225 sprintf(if_name_str, "%s%d", if_name, if_unit); 226 227 /* Check to see if end device already loaded */ 228 229 if (NULL == (eo = endFindByName(if_name, if_unit))) { 230 LOG_INFO(BSL_LS_APPL_END, 231 (BSL_META_U(u, 232 "%s: End device not loaded: if %s if_unit %d\n"), 233 pfx, if_name, if_unit)); 234 format_macaddr(if_mac_str, if_mac); 235 sprintf(if_init_str, "%d:%s:%d", u, if_mac_str, if_vlan); 236 if (NULL == (eo = muxDevLoad(if_unit, socend_load, 237 if_init_str, 0, NULL))) { 238 cli_out("%s: muxDevLoad failed: Unit %d\n", pfx, u); 239 return(NULL); 240 } 241 242 LOG_INFO(BSL_LS_APPL_END, 243 (BSL_META_U(u, 244 "%s: muxDevLoad successful: 0x%x\n"), pfx, (int)eo)); 245 if (ERROR == muxDevStart(eo)) { 246 cli_out("%s: muxDevStart failed: Unit %d\n", pfx, u); 247 (void)muxDevUnload(if_name, if_unit); 248 return(NULL); 249 } 250 LOG_INFO(BSL_LS_APPL_END, 251 (BSL_META_U(u, 252 "%s: muxDevStart successful: 0x%x\n"), pfx, (int)eo)); 253 } 254 #if VX_VERSION == 64 || VX_VERSION == 65 || VX_VERSION == 66 || VX_VERSION == 68 255 #else 256 /* 257 * Configure device.... 258 */ 259 if (OK != muxIoctl(eo, EIOCGMIB2, (caddr_t)&m2)) { 260 cli_out("%s: muxIoctl failed: Unit %d\n", pfx, u); 261 (void)sal_if_do_deconfig(pfx, eo, if_name, if_unit); 262 return(NULL); 263 } 264 LOG_INFO(BSL_LS_APPL_END, 265 (BSL_META_U(u, 266 "%s: muxIOCTL successful: Unit %d\n"), pfx, u)); 267 #endif /* VX_VERSION */ 268 269 /* 270 * Setup interface in following order: 271 * [1] Attach TCP/IP to END device 272 * [2] Set Netmask (if non-0) 273 * [3] Set IP address 274 * [4] Set host name associated with interface (if given). 275 */ 276 if (OK != ipAttach(if_unit, if_name)) { /* [1] */ 277 cli_out("%s: ipAttach failed: Unit %d (interface %s)\n", 278 pfx, u, if_name_str); 279 (void)sal_if_do_deconfig(pfx, eo, if_name, if_unit); 280 return(NULL); 281 } 282 LOG_INFO(BSL_LS_APPL_END, 283 (BSL_META_U(u, 284 "%s: ipAttach successful: if_name %s if_unit %d\n"), 285 pfx, if_name, if_unit)); 286 287 #if VX_VERSION == 66 || VX_VERSION == 68 288 289 format_ipaddr(if_ip_str, if_ip); /* [3] */ 290 291 if (0 != if_netmask) { /* [2] */ 292 format_ipaddr(if_mask_str, if_netmask); /* [3] */ 293 } 294 295 sprintf(if_cfg_str, "%s up inet add %s netmask %s", if_name_str, if_ip_str, if_mask_str); 296 297 if (ERROR == ifconfig(if_cfg_str)) { 298 cli_out("%s: ifconfig failed: %s%d: %s\n", 299 pfx, if_name, if_unit, if_cfg_str); 300 (void)sal_if_do_deconfig(pfx, eo, if_name, if_unit); 301 return(NULL); 302 } 303 LOG_INFO(BSL_LS_APPL_END, 304 (BSL_META_U(u, 305 "%s: ifconfig: if %s, cfg str %s\n"), 306 pfx, if_name_str, if_cfg_str)); 307 #else 308 if (0 != if_netmask) { /* [2] */ 309 #ifdef VXWORKS_NETWORK_STACK_6_5 310 #else 311 if (ERROR == ifMaskSet(if_name_str, if_netmask)) { 312 cli_out("%s: ifMaskSet failed: %s 0x%x\n", 313 pfx, if_name_str, if_netmask); 314 (void)sal_if_do_deconfig(pfx, eo, if_name, if_unit); 315 return(NULL); 316 } 317 #endif /* VXWORKS_NETWORK_STACK_6_5 */ 318 } 319 320 format_ipaddr(if_ip_str, if_ip); /* [3] */ 321 #ifdef VXWORKS_NETWORK_STACK_6_5 322 #else 323 if (OK != ifAddrSet(if_name_str, (char *)if_ip_str)) { 324 cli_out("%s: ifAddrSet failed: %s <-- %s\n", pfx, if_name, if_ip_str); 325 (void)sal_if_do_deconfig(pfx, eo, if_name, if_unit); 326 return(NULL); 327 } 328 #endif /* VXWORKS_NETWORK_STACK_6_5 */ 329 330 LOG_INFO(BSL_LS_APPL_END, 331 (BSL_META_U(u, 332 "%s: ifAddrSet successful: if %s\n"), pfx, if_name_str)); 333 #endif 334 335 if (if_host && *if_host) { /* [4] */ 336 LOG_INFO(BSL_LS_APPL_END, 337 (BSL_META_U(u, 338 "%s: Setting hostname: %s\n"), pfx, if_host)); 339 if (OK != hostAdd (if_host, if_ip_str)) { 340 cli_out("%s: Warning: Failed to set hostname %s for device %s\n", 341 pfx, if_host, if_name_str); 342 } 343 } 344 345 return((void *)eo); /* This is our opaque value */ 346 #else /* !defined(INCLUDE_DRIVERS) */ 347 cli_out("sal_if_config: Interface configuration not compiled in\n"); 348 return(NULL); 349 #endif /* !defined(INCLUDE_DRIVERS) */ 350 } 351 352 353 /* 354 * Function: if_dump_table 355 * Purpose: Dump the interface table. 356 * Parameters: Unit - Strataswitch Unit #. 357 * interface - interface # 358 * Returns: Nothing 359 */ 360 static void 361 if_dump_table(int u, int interface, int all) 362 { 363 int us, ue; 364 int is, ie; 365 char ip_str[SAL_IPADDR_STR_LEN+3]; 366 char mac_str[SAL_MACADDR_STR_LEN]; 367 if_soc_t *ifs; 368 369 if (SOC_UNIT_VALID(u)) { 370 us = ue = u; 371 } else { 372 us = 0; 373 ue = soc_ndev; 374 } 375 if (interface < 0) { 376 is = 0; 377 ie = MAX_INTERFACE-1; 378 } else { 379 is = interface; 380 ie = interface; 381 } 382 for (u = us; u <= ue; u++) { 383 if (if_table[u] == NULL) { 384 continue; 385 } 386 for (interface = is; interface <= ie; interface++) { 387 ifs = &if_table[u][interface]; 388 if (!all && !ifs->ifs_sal) { 389 continue;; 390 } 391 if (ifs->ifs_sal) { 392 format_ipaddr_mask(ip_str, ifs->ifs_net_ip, ifs->ifs_net_mask); 393 format_macaddr(mac_str, ifs->ifs_net_mac); 394 cli_out("unit %d interface %s%d: mac %s ip %s\n", u, 395 ifs->ifs_net_name, ifs->ifs_net_interface, 396 mac_str, ip_str); 397 } else { 398 cli_out("unit %d interface %d: down\n", u, interface); 399 } 400 } 401 } 402 } 403 404 static cmd_result_t 405 if_config_parse(int unit, if_soc_t *ifs, args_t *a) 406 /* 407 * Function: if_config_parse 408 * Purpose: Parse the input parameters for the specified unit/port. 409 * Parameters: u - SOC unit number 410 * p - SOC port number 411 * a - remaining arguments 412 * Returns: CMD_OK/CMD_FAIL/CMD_USAGE 413 */ 414 { 415 parse_table_t pt; 416 417 parse_table_init(unit, &pt); 418 parse_table_add(&pt, "MACaddress", PQ_DFL|PQ_MAC, 0, &ifs->ifs_net_mac, 0); 419 parse_table_add(&pt, "VLan", PQ_DFL|PQ_INT, 0, &ifs->ifs_net_vlan, 0); 420 parse_table_add(&pt, "IPaddress", PQ_DFL|PQ_IP, 0, &ifs->ifs_net_ip, 0); 421 parse_table_add(&pt, "GateWay", PQ_DFL|PQ_IP, 0, &ifs->ifs_gateway, 0); 422 parse_table_add(&pt, "SubNetMask", PQ_DFL|PQ_IP, 0, &ifs->ifs_net_mask,0); 423 parse_table_add(&pt, "HostName", PQ_DFL|PQ_STRING,0,&ifs->ifs_net_host,0); 424 425 if (0 > parse_arg_eq(a, &pt)) { 426 parse_arg_eq_done(&pt); 427 return(CMD_USAGE); 428 } 429 return(CMD_OK); 430 } 431 432 char cmd_if_config_usage[] = 433 "Parameters: [<ifnum> [up|down [<option>=<value> ...]]]\n\t" 434 "With no parameters, all current interfaces are listed. If only\n\t" 435 "an interface name is specified, information on that interface is\n\t" 436 "listed. If \"up\" or \"down\" is specified, the interface is\n\t" 437 "activated or de-activated.\n" 438 #ifndef COMPILER_STRING_CONST_LIMIT 439 "\tValue options are:\n\t" 440 " MACaddress=<address> - MAC address for interface\n\t" 441 " VLan=<vlanid> - VLAN id for interface\n\t" 442 " IPaddress=<address> - IP address associated with interface\n\t" 443 " SubNetMask=<value> - Subnet mask associated with interface\n\t" 444 " HostName=<name> - Host name associated with interface\n\t" 445 " GateWay=<adress> - Default gateway\n"; 446 #endif 447 ; 448 449 cmd_result_t 450 cmd_if_config(int u, args_t *a) 451 /* 452 * Function: if_config 453 * Purpose: Perform a variety of configuration functions on an interface. 454 * Parameters: u - unit number to act on. 455 * a - Parameters. 456 * Returns: CMD_USAGE/CMD_FAIL/CMD_OK. 457 */ 458 { 459 if_soc_t *ifs; 460 int interface; 461 cmd_result_t rv; 462 if_soc_t newif; 463 #if VX_VERSION == 66 || VX_VERSION == 68 464 char gw_cfg_str[32]; 465 #endif 466 467 /* 468 * Just dump all of our information. 469 */ 470 if (0 == ARG_CNT(a)) { 471 if_dump_table(u, -1, FALSE); 472 return(CMD_OK); 473 } 474 475 /* Pick up interface number */ 476 477 if (!isint(ARG_CUR(a))) { 478 cli_out("%s: Invalid interface number: %s\n", 479 ARG_CMD(a), ARG_CUR(a)); 480 return(CMD_FAIL); 481 } 482 483 interface = parse_integer(ARG_GET(a)); 484 if (interface >= MAX_INTERFACE) { 485 cli_out("%s: ERROR: Interface # too high, only permitted %d\n", 486 ARG_CMD(a), MAX_INTERFACE); 487 return(CMD_FAIL); 488 } 489 490 /* If no parameters left now, display information on the port */ 491 492 if (0 == ARG_CNT(a)) { 493 if_dump_table(u, interface, TRUE); 494 return(CMD_OK); 495 } 496 497 if (if_table[u] == NULL) { 498 sal_memset(&newif, 0, sizeof(newif)); 499 ifs = &newif; 500 } else { 501 ifs = &if_table[u][interface]; 502 } 503 ifs->ifs_net_name = SOC_END_NAME; 504 ifs->ifs_net_interface = interface; 505 506 /* Check for UP/DOWN */ 507 508 if (sal_strcasecmp("up", _ARG_CUR(a)) == 0) { 509 ARG_NEXT(a); /* Passed UP */ 510 511 if (ifs->ifs_sal) { 512 cli_out("%s: ERROR: Interface %d already running\n", 513 ARG_CMD(a), interface); 514 return(CMD_FAIL); 515 } 516 517 /* Parse the Parameters and try to configure the device */ 518 519 if (CMD_OK != (rv = if_config_parse(u, ifs, a))) { 520 return(rv); 521 } 522 if (ARG_CNT(a)) { 523 return(CMD_USAGE); 524 } 525 526 ifs->ifs_sal = sal_if_config(ARG_CMD(a), u, 527 ifs->ifs_net_name, 528 ifs->ifs_net_interface, 529 ifs->ifs_net_host, 530 ifs->ifs_net_mac, 531 ifs->ifs_net_vlan, 532 ifs->ifs_net_ip, 533 ifs->ifs_net_mask); 534 535 if (ifs->ifs_sal == NULL) { 536 return CMD_FAIL; 537 } 538 if (if_table[u] == NULL) { 539 if_table[u] = sal_alloc(sizeof(*ifs) * MAX_INTERFACE, "if_table"); 540 if (if_table[u] == NULL) { 541 cli_out("%s: ERROR: cannot allocate interface table\n", 542 ARG_CMD(a)); 543 return CMD_FAIL; 544 } 545 sal_memset(if_table[u], 0, sizeof(*ifs) * MAX_INTERFACE); 546 if_table[u][interface] = *ifs; 547 } 548 549 /* Add default gateway */ 550 if (ifs->ifs_gateway != 0) { 551 char gateway_str[SAL_IPADDR_STR_LEN]; 552 553 format_ipaddr(gateway_str, ifs->ifs_gateway); 554 #if VX_VERSION == 66 || VX_VERSION == 68 555 sprintf(gw_cfg_str, "add default %s", gateway_str); 556 LOG_INFO(BSL_LS_APPL_END, 557 (BSL_META_U(u, 558 "Default gateway: %s\n"), gw_cfg_str)); 559 if (ERROR == routec(gw_cfg_str)) { 560 cli_out("Warning: Failed to add default route gatway = %s\n", 561 gateway_str); 562 } 563 #else 564 #ifdef VXWORKS_NETWORK_STACK_6_5 565 #else 566 if (OK != routeAdd("0.0.0.0", gateway_str)) { 567 cli_out("Warning: Failed to add default route gatway = %s\n", 568 gateway_str); 569 } 570 #endif /* VXWORKS_NETWORK_STACK_6_5 */ 571 #endif 572 } 573 return CMD_OK; 574 } else if (sal_strcasecmp("down", _ARG_CUR(a)) == 0) { 575 ARG_NEXT(a); 576 577 #if VX_VERSION == 66 || VX_VERSION == 68 578 if (ifs->ifs_gateway != 0) { 579 char gateway_str[SAL_IPADDR_STR_LEN]; 580 581 format_ipaddr(gateway_str, ifs->ifs_gateway); 582 sprintf(gw_cfg_str, "delete default %s", gateway_str); 583 if (OK != routec(gw_cfg_str)) { 584 cli_out("Warning: Failed to delete default route gatway = %s\n", 585 gateway_str); 586 } 587 } 588 #endif /* VX_VERSION == 66 || VX_VERSION == 68 */ 589 590 if (!ifs->ifs_sal) { 591 cli_out("%s: Interface %d not running\n", 592 ARG_CMD(a), interface); 593 return(CMD_FAIL); 594 } 595 if (sal_if_deconfig(ARG_CMD(a), ifs->ifs_sal, ifs->ifs_net_name, 596 ifs->ifs_net_interface)) { 597 ifs->ifs_sal = NULL; 598 return CMD_FAIL; 599 } 600 ifs->ifs_sal = NULL; 601 return CMD_OK; 602 } 603 cli_out("%s: ERROR: Invalid option %s: [up|down] expected\n", 604 ARG_CMD(a), ARG_CUR(a)); 605 return(CMD_USAGE); 606 } 607 608 #else 609 int _appl_diag_if_c_not_empty; 610 #endif 611 612 613 #endif /* NO_SAL_APPL */