openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

l3.c (14866B)


      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  * File:     l3.c
      8  * Purpose:  BCMX L3 commands
      9  */
     10 
     11 #include <sal/appl/io.h>
     12 #include <shared/bsl.h>
     13 #include <bcm/error.h>
     14 
     15 #include <bcmx/bcmx.h>
     16 #include <bcmx/l3.h>
     17 
     18 #include <appl/diag/shell.h>
     19 #include <appl/diag/system.h>
     20 #include <appl/diag/parse.h>
     21 
     22 #ifdef	INCLUDE_BCMX
     23 
     24 #include "bcmx.h"
     25 #include <appl/diag/diag.h>
     26 
     27 #ifdef	INCLUDE_L3
     28 
     29 STATIC int
     30 _bcmx_l3_intf_show(bcmx_l3_intf_t *intf)
     31 {
     32     char if_mac_str[SAL_MACADDR_STR_LEN];
     33 
     34     cli_out("%-5s %-5s %-5s %-4s %-18s %-4s %-4s %-5s %-5s\n",
     35             "INTF", "VRF", "Group", "VLAN", "Source Mac", "MTU", "TTL",
     36             "Tunnel", "InnerVlan");
     37 
     38     format_macaddr(if_mac_str, intf->l3a_mac_addr);
     39     cli_out("%-5d %-5d %-5d %-4d %-18s %-4d %-4d %-5d  %-5d\n",
     40             intf->l3a_intf_id, intf->l3a_vrf, intf->l3a_group, 
     41             intf->l3a_vid, if_mac_str, intf->l3a_mtu, intf->l3a_ttl, 
     42             intf->l3a_tunnel_idx, intf->l3a_inner_vlan);
     43 
     44     return BCM_E_NONE;
     45 }
     46 
     47 
     48 STATIC int
     49 _bcmx_l3_ip_show(bcmx_l3_host_t *info)
     50 {
     51     char ip_str[IP6ADDR_STR_LEN];
     52     char if_mac_str[SAL_MACADDR_STR_LEN];
     53     char *hit;
     54     char *trunk = " ";
     55     bcmx_lport_t port;
     56 
     57     if (info->l3a_flags & BCM_L3_IP6) {
     58         cli_out("%-4s %-42s %-18s %-4s  %-11s %6s  %3s\n",
     59                 "VRF", "IP address", "Mac Address", "INTF",
     60                 "LPORT", "CLASS", "HIT");
     61     } else {
     62         cli_out("%-4s %-16s %-18s %-4s  %-11s %6s  %3s\n",
     63                 "VRF", "IP address", "Mac Address", "INTF",
     64                 "LPORT", "CLASS", "HIT");
     65     }
     66 
     67     hit = (info->l3a_flags & BCM_L3_HIT) ? "y" : "n";
     68     
     69     format_macaddr(if_mac_str, info->l3a_nexthop_mac);
     70     if (BCM_GPORT_IS_SET(info->l3a_lport)) {
     71         if (BCM_GPORT_IS_TRUNK(info->l3a_lport)) {
     72             trunk = "t";
     73         }
     74         port = info->l3a_lport;
     75 
     76     } else {
     77         if (info->l3a_flags & BCM_L3_TGID) {
     78             trunk = "t" ; 
     79             port = info->l3a_trunk;
     80         } else {
     81             port = info->l3a_lport;
     82         }
     83     }
     84     
     85     if (info->l3a_flags & BCM_L3_IP6) {
     86         format_ip6addr(ip_str, info->l3a_ip6_addr);
     87         cli_out("%-4d %-42s %-18s %-4d  0x%8.8x%1s  %-6d  %-3s\n",
     88                 info->l3a_vrf, ip_str, if_mac_str, info->l3a_intf,
     89                 port, trunk, info->l3a_lookup_class, hit);
     90     } else {
     91         format_ipaddr(ip_str, info->l3a_ip_addr);
     92         cli_out("%-4d %-16s %-18s %-4d  0x%8.8x%1s  %-6d  %-3s\n",
     93                 info->l3a_vrf, ip_str, if_mac_str, info->l3a_intf,
     94                 port, trunk, info->l3a_lookup_class, hit);
     95     }
     96 
     97     return BCM_E_NONE;
     98 }
     99 
    100 
    101 
    102 char bcmx_cmd_l3_usage[] =
    103     "Usages:\n"
    104 #ifdef COMPILER_STRING_CONST_LIMIT
    105     "    l3 intf create | delete | show ...\n"
    106     "    l3 ip add | del | show\n"
    107     "    l3 defip add | del | show\n"
    108 #else
    109     "    l3 intf create Mac=<mac> Vlan=<vid> [INtf=<n>]\n"
    110     "                                     - Create an L3 interface\n"
    111     "                 Interface index may be optionally specified\n"
    112     "    l3 intf delete <intf>            - Destroy an L3 interface\n"
    113     "    l3 intf show INtf=<n>            - Show L3 interface\n"
    114 
    115     "    l3 ip add IP=<ipaddr> Mac=<nexthop_mac> Port=<uport> INt=<intf>\n"
    116     "                                     - Add L3 cache entry\n"
    117     "    l3 ip del IP=<ipaddr>            - Remove L3 cache entry\n"
    118     "    l3 ip show IP=<ipaddr>           - Display L3 cache entry\n"
    119 
    120     "    l3 defip add IP=<ipaddr> MaSk=<mask>\n"
    121     "                 Mac=<nexthop_mac> Port=<uport> INt=<intf>\n"
    122     "                                     - Add L3 route\n"
    123     "    l3 defip del IP=<ipaddr> MaSk=<mask>\n"
    124     "                                     - Delete L3 route\n"
    125     "    l3 defip show                    - Show L3 routes\n"
    126 #endif
    127     ;
    128 
    129 cmd_result_t
    130 bcmx_cmd_l3(int unit, args_t *args)
    131 {
    132     parse_table_t pt;
    133     char *table, *subcmd, *ch;
    134     sal_mac_addr_t mac;
    135     int vid;	/* not a bcm_vlan_t due to parsing uint16 vs uint32 */
    136     int intf;
    137     int rv = BCM_E_NONE;
    138     cmd_result_t cmd_rv;
    139 
    140     if ((table = ARG_GET(args)) == NULL) {
    141         sal_printf("Table required\n");
    142         return CMD_USAGE;
    143     }
    144 
    145     if ((subcmd = ARG_GET(args)) == NULL) {
    146         sal_printf("Subcommand required\n");
    147         return CMD_USAGE;
    148     }
    149 
    150     /*
    151      * L3 interface table
    152      */
    153     if (sal_strcasecmp(table, "intf") == 0 ||
    154 	sal_strcasecmp(table, "if") == 0 ||
    155 	sal_strcasecmp(table, "interface") == 0) {
    156 
    157         /* l3 intf create Mac=<mac> Vlan=<vid> */
    158         if (sal_strcasecmp(subcmd, "create") == 0 ||
    159 	    sal_strcasecmp(subcmd, "add") == 0) {
    160             bcmx_l3_intf_t  intrf;
    161             int intf_idx = -1;
    162 
    163             parse_table_init(0, &pt);
    164             parse_table_add(&pt, "Mac", PQ_DFL | PQ_MAC, 0, &mac, 0);
    165             parse_table_add(&pt, "Vlan", PQ_DFL | PQ_INT, 0, &vid, 0);
    166             parse_table_add(&pt, "INtf", PQ_DFL | PQ_INT, 0, &intf_idx, 0);
    167             if (!parseEndOk(args, &pt, &cmd_rv)) {
    168                 return cmd_rv;
    169             }
    170 
    171             bcmx_l3_intf_t_init(&intrf);
    172             sal_memcpy(intrf.l3a_mac_addr, mac, sizeof(bcm_mac_t));
    173             intrf.l3a_vid = vid;
    174             intrf.l3a_intf_id = intf_idx;
    175             intrf.l3a_flags |= BCM_L3_ADD_TO_ARL;
    176             intrf.l3a_flags   |= BCM_L3_WITH_ID;
    177             if (intf_idx < 0) { /* Not specified */
    178                 rv = bcmx_l3_intf_create(&intrf);
    179                 if (rv == BCM_E_NONE) {
    180                     intf_idx = rv;
    181                 }
    182             } else {
    183                 rv = bcmx_l3_intf_create(&intrf);
    184             }
    185 
    186             if (rv < 0) {
    187                 sal_printf("ERROR: l3 interface create %sfailed: %s\n",
    188 			   intf_idx < 0 ? "" : "with id ", bcm_errmsg(rv));
    189                 return CMD_FAIL;
    190             }
    191 	    sal_printf("l3 interface %d created\n", intf_idx);
    192 	    return CMD_OK;
    193         }
    194 
    195         /* l3 intf delete <intf> */
    196         if (sal_strcasecmp(subcmd, "delete") == 0 ||
    197 	    sal_strcasecmp(subcmd, "del") == 0 ||
    198 	    sal_strcasecmp(subcmd, "destroy") == 0) {
    199             bcmx_l3_intf_t  intrf;
    200             if ((ch = ARG_GET(args)) == NULL) {
    201                 return CMD_USAGE;
    202             }
    203             intf = parse_integer(ch);
    204 
    205             bcmx_l3_intf_t_init(&intrf);
    206             intrf.l3a_intf_id = intf;
    207 
    208             rv = bcmx_l3_intf_delete(&intrf);
    209             if (rv < 0) {
    210                 sal_printf("ERROR: l3 interface destroy failed: %s\n",
    211 			   bcm_errmsg(rv));
    212                 return CMD_FAIL;
    213             }
    214 	    return CMD_OK;
    215         }
    216 
    217         /* l3 intf show INtf=<intf> */
    218         if (sal_strcasecmp(subcmd, "show") == 0) {
    219             bcmx_l3_intf_t  intf;
    220             int             intf_id;
    221 
    222             parse_table_init(0, &pt);
    223             parse_table_add(&pt, "INtf", PQ_DFL | PQ_INT, 0, (void*)&intf_id, 0);
    224 
    225             if (!parse_arg_eq(args, &pt)) {
    226                 sal_printf("%s: Unknown options: %s\n",
    227                            ARG_CMD(args), ARG_CUR(args));
    228                 parse_arg_eq_done(&pt);
    229                 return(CMD_FAIL);
    230             }
    231 
    232             parse_arg_eq_done(&pt);   /* No longer needed */
    233 
    234             bcmx_l3_intf_t_init(&intf);
    235             intf.l3a_intf_id = intf_id;
    236 
    237             rv = bcmx_l3_intf_get(&intf);
    238             if (rv < 0) {
    239                 sal_printf("BCMX L3 intf get failed: %s\n", bcm_errmsg(rv));
    240                 return CMD_FAIL;
    241             }
    242 
    243             _bcmx_l3_intf_show(&intf);
    244             return CMD_OK;
    245         }
    246 
    247 	sal_printf("%s: unknown %s subcommand %s\n",
    248 		   ARG_CMD(args), table, subcmd);
    249 	return CMD_USAGE;
    250     }
    251 
    252     /*
    253      * L3 IP cache table
    254      */
    255     if (sal_strcasecmp(table, "ip") == 0) {
    256         ip_addr_t ipaddr;
    257         char *lpstr;
    258         bcmx_uport_t uport;
    259         bcmx_lport_t lport;
    260 
    261         /* l3 ip add IP=<ipaddr> Mac=<nexthop_mac> Port=<uport> INt=<intf> */
    262         if (sal_strcasecmp(subcmd, "add") == 0 ||
    263             sal_strcasecmp(subcmd, "create") == 0) {
    264             bcmx_l3_host_t l3ip;
    265             int tid;
    266 
    267             parse_table_init(0, &pt);
    268             parse_table_add(&pt, "IP", PQ_DFL | PQ_IP, 0, (void *)&ipaddr, NULL);
    269             parse_table_add(&pt, "Mac", PQ_DFL | PQ_MAC, 0, &mac, NULL);
    270             parse_table_add(&pt, "Port", PQ_STRING, 0, &lpstr, NULL);
    271             parse_table_add(&pt, "INtf", PQ_DFL | PQ_INT, 0, (void *)&intf, NULL);
    272             tid = -1;
    273             parse_table_add(&pt, "Trunk", PQ_DFL | PQ_INT, 0, (void *)&tid, NULL);
    274             if (!parse_arg_eq(args, &pt)) {
    275                 sal_printf("%s: Unknown options: %s\n",
    276                            ARG_CMD(args), ARG_CUR(args));
    277 		parse_arg_eq_done(&pt);
    278                 return(CMD_FAIL);
    279             }
    280 
    281 	    uport = bcmx_uport_parse(lpstr, NULL);
    282 	    lport = BCMX_UPORT_TO_LPORT(uport);
    283             if (lport == BCMX_NO_SUCH_LPORT) {
    284                 sal_printf("%s: bad uport given: %s\n", ARG_CMD(args), lpstr);
    285 		parse_arg_eq_done(&pt);
    286                 return CMD_FAIL;
    287             }
    288 
    289             
    290 	    bcmx_l3_host_t_init(&l3ip);
    291             l3ip.l3a_ip_addr = ipaddr;
    292             l3ip.l3a_intf = intf;
    293             sal_memcpy(l3ip.l3a_nexthop_mac, mac, sizeof(mac));
    294             l3ip.l3a_lport = lport;
    295             l3ip.l3a_flags = 0;
    296             if (tid != -1) {
    297                 l3ip.l3a_trunk = tid;
    298                 l3ip.l3a_flags |= BCM_L3_TGID;
    299             }
    300 
    301             rv = bcmx_l3_host_add(&l3ip);
    302             if (rv < 0) {
    303                 sal_printf("BCMX L3 add failed: %s\n", bcm_errmsg(rv));
    304 		parse_arg_eq_done(&pt);
    305                 return CMD_FAIL;
    306             }
    307 	    parse_arg_eq_done(&pt);
    308 	    return CMD_OK;
    309         }
    310 
    311         /* l3 ip del IP=<ipaddr> */
    312         if (sal_strcasecmp(subcmd, "delete") == 0 ||
    313 	    sal_strcasecmp(subcmd, "del") == 0 ||
    314 	    sal_strcasecmp(subcmd, "destroy") == 0) {
    315             bcmx_l3_host_t l3ip;
    316             parse_table_init(0, &pt);
    317             parse_table_add(&pt, "IP", PQ_DFL | PQ_IP, 0, (void *)&ipaddr, 0);
    318             if (!parseEndOk(args, &pt, &cmd_rv)) {
    319                 return cmd_rv;
    320             }
    321             bcmx_l3_host_t_init(&l3ip);
    322             l3ip.l3a_ip_addr = ipaddr;
    323             l3ip.l3a_flags = 0;
    324 
    325             rv = bcmx_l3_host_delete(&l3ip);
    326             if (rv < 0) {
    327                 sal_printf("BCMX L3 delete failed: %s\n", bcm_errmsg(rv));
    328                 return CMD_FAIL;
    329             }
    330 	    return CMD_OK;
    331         }
    332 
    333         /* l3 ip show IP=<ipaddr> */
    334         if (sal_strcasecmp(subcmd, "show") == 0) {
    335             bcmx_l3_host_t l3ip;
    336 
    337             parse_table_init(0, &pt);
    338             parse_table_add(&pt, "IP", PQ_DFL | PQ_IP, 0, (void *)&ipaddr, NULL);
    339 
    340             if (!parse_arg_eq(args, &pt)) {
    341                 sal_printf("%s: Unknown options: %s\n",
    342                            ARG_CMD(args), ARG_CUR(args));
    343                 parse_arg_eq_done(&pt);
    344                 return(CMD_FAIL);
    345             }
    346 
    347             parse_arg_eq_done(&pt);   /* No longer needed */
    348 
    349             bcmx_l3_host_t_init(&l3ip);
    350             l3ip.l3a_ip_addr = ipaddr;
    351             l3ip.l3a_flags = 0;
    352 
    353             rv = bcmx_l3_host_find(&l3ip);
    354             if (rv < 0) {
    355                 sal_printf("BCMX L3 find failed: %s\n", bcm_errmsg(rv));
    356                 return CMD_FAIL;
    357             }
    358 
    359             _bcmx_l3_ip_show(&l3ip);
    360             return CMD_OK;
    361         }
    362 
    363 	sal_printf("%s: unknown %s subcommand %s\n",
    364 		   ARG_CMD(args), table, subcmd);
    365 	return CMD_USAGE;
    366     }
    367 
    368     /*
    369      * L3 DEFIP route table
    370      */
    371     if (sal_strcasecmp(table, "defip") == 0) {
    372         bcmx_l3_route_t l3route;
    373         ip_addr_t ipaddr, mask;
    374         char *lpstr;
    375         bcmx_lport_t lport;
    376         bcmx_uport_t uport;
    377 
    378         /*
    379          * l3 defip add IP=<ipaddr> MaSk=<mask>
    380          *                          Mac=<nexthop_mac> Port=<uport> INt=<intf>
    381          */
    382         if (sal_strcasecmp(subcmd, "add") == 0 ||
    383 	    sal_strcasecmp(subcmd, "create") == 0) {
    384             parse_table_init(0, &pt);
    385             parse_table_add(&pt, "IP", PQ_DFL | PQ_IP, 0, &ipaddr, NULL);
    386             parse_table_add(&pt, "MaSk", PQ_DFL | PQ_IP, 0, &mask, NULL);
    387             parse_table_add(&pt, "Mac", PQ_DFL | PQ_MAC, 0, &mac, NULL);
    388             parse_table_add(&pt, "Port", PQ_STRING, 0, &lpstr, NULL);
    389             parse_table_add(&pt, "INtf", PQ_DFL | PQ_INT, 0, &intf, NULL);
    390             if (!parse_arg_eq(args, &pt)) {
    391                 sal_printf("%s: Unknown options: %s\n",
    392                            ARG_CMD(args), ARG_CUR(args));
    393 		parse_arg_eq_done(&pt);
    394                 return(CMD_FAIL);
    395             }
    396 
    397 	    uport = bcmx_uport_parse(lpstr, NULL);
    398 	    lport = BCMX_UPORT_TO_LPORT(uport);
    399             if (lport == BCMX_NO_SUCH_LPORT) {
    400                 sal_printf("%s: bad uport given: %s\n", ARG_CMD(args), lpstr);
    401 		parse_arg_eq_done(&pt);
    402                 return CMD_FAIL;
    403             }
    404 
    405 	    sal_memset(&l3route, 0, sizeof(l3route));
    406             l3route.l3a_subnet = ipaddr;
    407             l3route.l3a_ip_mask = mask;
    408             l3route.l3a_intf = intf;
    409             sal_memcpy(l3route.l3a_nexthop_mac, mac, sizeof(mac));
    410             l3route.l3a_lport = lport;
    411             l3route.l3a_flags = 0;
    412 
    413             rv = bcmx_l3_route_add(&l3route);
    414             if (rv < 0) {
    415                 sal_printf("BCMX L3 defip add failed: %s\n", bcm_errmsg(rv));
    416 		parse_arg_eq_done(&pt);
    417                 return CMD_FAIL;
    418             }
    419 	    parse_arg_eq_done(&pt);
    420 	    return CMD_OK;
    421         }
    422 
    423         /* l3 defip del IP=<ipaddr> MaSk=<mask> */
    424         if (sal_strcasecmp(subcmd, "delete") == 0 ||
    425 	    sal_strcasecmp(subcmd, "del") == 0 ||
    426 	    sal_strcasecmp(subcmd, "destroy") == 0) {
    427             parse_table_init(0, &pt);
    428             parse_table_add(&pt, "IP", PQ_DFL | PQ_IP, 0, &ipaddr, NULL);
    429             parse_table_add(&pt, "MaSk", PQ_DFL | PQ_IP, 0, &mask, NULL);
    430             if (!parseEndOk(args, &pt, &cmd_rv)) {
    431                 return cmd_rv;
    432             }
    433 
    434 	    sal_memset(&l3route, 0, sizeof(l3route));
    435             l3route.l3a_subnet = ipaddr;
    436             l3route.l3a_ip_mask = mask;
    437 
    438             rv = bcmx_l3_route_delete(&l3route);
    439             if (rv < 0) {
    440                 sal_printf("BCMX L3 defip delete failed: %s\n",
    441 			   bcm_errmsg(rv));
    442                 return CMD_FAIL;
    443             }
    444 	    return CMD_OK;
    445         }
    446 
    447         /* l3 defip show */
    448         if (sal_strcasecmp(subcmd, "show") == 0) {
    449             sal_printf("To be implemented\n");
    450             return CMD_FAIL;
    451         }
    452 
    453 	sal_printf("%s: unknown %s subcommand %s\n",
    454 		   ARG_CMD(args), table, subcmd);
    455 	return CMD_USAGE;
    456     }
    457 
    458 
    459     sal_printf("%s: unknown table %s\n", ARG_CMD(args), table);
    460     return CMD_USAGE;
    461 }
    462 
    463 #endif	/* INCLUDE_L3 */
    464 #endif	/* INCLUDE_BCMX */