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

visibility.c (17153B)


      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 #include <shared/bsl.h>
      8 #include <soc/defs.h>
      9 
     10 #ifdef BCM_INSTRUMENTATION_SUPPORT
     11 
     12 #include <bcm/pkt.h>
     13 #include <bcm/trunk.h>
     14 #include <bcm/stg.h>
     15 
     16 #include <appl/diag/system.h>
     17 #include <appl/diag/visibility.h>
     18 
     19 /* hex dump without offset header
     20  * blocks of 8 bytes, 16 bytes per line
     21  *
     22  * 0000000000000000 0000000000000000
     23  */
     24 static void hexdump_8x2(uint8 *raw_data, int len)
     25 {
     26     int  ri;
     27     uint8 data[8] = {0};
     28 
     29     for (ri = 0; ri + 16 <= len; ) {        
     30         sal_memcpy(&data, &raw_data[ri], 8);
     31         cli_out("%02x%02x%02x%02x%02x%02x%02x%02x ", 
     32                 data[0], data[1], data[2], data[3], 
     33                 data[4], data[5], data[6], data[7]);
     34         ri += 8;
     35         sal_memcpy(&data, &raw_data[ri], 8);
     36         cli_out("%02x%02x%02x%02x%02x%02x%02x%02x\n", 
     37                 data[0], data[1], data[2], data[3], 
     38                 data[4], data[5], data[6], data[7]);
     39         ri += 8; 
     40     }
     41 }
     42 
     43 /* hex dump with 2 bytes offset header
     44  * blocks of 4 bytes, 32 bytes per line
     45  *
     46  * 0000  00000000 11222222 33333333 44444444  55555555 66666666 77777777
     47  */
     48 static void hexdump_offset_4x8(uint8 *raw_data, int len)
     49 {
     50     int  ri;
     51 
     52     for (ri = 0; ri < len; ri++) {
     53         if (!(ri & 0x1f)) {
     54             cli_out("\n%04x  ", ri);
     55         }
     56         cli_out("%s%s%02x",
     57                 (!(ri & 0x03)) ? " " : "",
     58                 (!(ri & 0x0f)) ? " " : "",
     59                 raw_data[ri]);
     60     }
     61     cli_out("\n");
     62 }
     63 
     64 typedef struct {
     65     bcm_switch_pkt_trace_resolution_t resolution;
     66     char *name;
     67 } abs_resolution_t;
     68 
     69 static void abs_resolution_print(int unit, bcm_switch_pkt_trace_resolution_t resolution)
     70 {
     71     abs_resolution_t abs_resolution_table[] = {
     72         { bcmSwitchPktTraceResolutionUnkown, "UnknownPkt" },
     73         { bcmSwitchPktTraceResolutionControlPkt, "ControlPkt" },
     74         { bcmSwitchPktTraceResolutionOamPkt, "OamPkt" },
     75         { bcmSwitchPktTraceResolutionBfdPkt, "BfdPkt" },
     76         { bcmSwitchPktTraceResolutionBpduPkt, "BpduPkt" },
     77         { bcmSwitchPktTraceResolution1588Pkt, "1588Pkt" },
     78         { bcmSwitchPktTraceResolutionKnownL2UcPkt, "KnownL2UcPkt" },
     79         { bcmSwitchPktTraceResolutionUnknownL2UcPkt, "UnknownL2UcPkt" },
     80         { bcmSwitchPktTraceResolutionKnownL2McPkt, "KnownL2McPkt" },
     81         { bcmSwitchPktTraceResolutionUnknownL2McPkt, "UnknownL2McPkt" },
     82         { bcmSwitchPktTraceResolutionL2BcPkt, "L2BcPkt" },
     83         { bcmSwitchPktTraceResolutionKnownL3UcPkt, "KnownL3UcPkt" },
     84         { bcmSwitchPktTraceResolutionUnknownL3UcPkt, "UnknownL3UcPkt" },
     85         { bcmSwitchPktTraceResolutionKnownIpmcPkt, "KnownIpmcPkt" },
     86         { bcmSwitchPktTraceResolutionUnknownIpmcPkt, "UnknownIpmcPkt" },
     87         { bcmSwitchPktTraceResolutionKnownMplsL2Pkt, "KnownMplsL2Pkt" },
     88         { bcmSwitchPktTraceResolutionUnknownMplsPkt, "UnknownMplsPkt" },
     89         { bcmSwitchPktTraceResolutionKnownMplsL3Pkt, "KnownMplsL3Pkt" },
     90         { bcmSwitchPktTraceResolutionKnownMplsPkt, "KnownMplsPkt" },
     91         { bcmSwitchPktTraceResolutionKnownMimPkt, "KnownMimPkt" },
     92         { bcmSwitchPktTraceResolutionUnknownMimPkt, "UnknownMimPkt" },
     93         { bcmSwitchPktTraceResolutionKnownTrillPkt, "KnownTrillPkt" },
     94         { bcmSwitchPktTraceResolutionUnknownTrillPkt, "UnknownTrillPkt" },
     95         { bcmSwitchPktTraceResolutionKnownNivPkt, "KnownNivPkt" },
     96         { bcmSwitchPktTraceResolutionUnknownNivPkt, "UnknownNivPkt" },
     97         { bcmSwitchPktTraceResolutionKnownL2GrePkt, "KnownL2GrePkt" },
     98         { bcmSwitchPktTraceResolutionKnownVxlanPkt, "KnownVxlanPkt" },
     99         { bcmSwitchPktTraceResolutionKnownFCOEPkt, "KnownFCOEPkt" },
    100         { bcmSwitchPktTraceResolutionUnknownFCOEPkt, "UnknownFCOEPkt" },
    101         { 0, NULL }
    102     };
    103 
    104     abs_resolution_t *artp = &(abs_resolution_table[0]);
    105     cli_out("Packet Resolution Result:\n");
    106     while (1) {
    107         if (! artp->name) {
    108             break;
    109         }
    110         
    111         if (resolution == artp->resolution) {
    112             cli_out("   %s\n", artp->name);
    113         }
    114         artp++;
    115     }
    116 }
    117 
    118 typedef struct {
    119     bcm_switch_pkt_trace_drop_reason_t bit;
    120     char *name;
    121 } abs_drop_reasons_t;
    122 
    123 static void abs_drop_reasons_print(int unit, bcm_switch_pkt_trace_drop_reason_t *dr)
    124 {
    125     uint32 i = 0;
    126     abs_drop_reasons_t abs_drop_reasons_table[] = {
    127         { bcmSwitchPktTraceNoDrop,
    128           "NoDrop" },
    129         { bcmSwitchPktTraceDropReasonInternal,
    130           "Internal" },
    131         {bcmSwitchPktTraceDropReasonMplsLabelLookupMiss,
    132           "MplsLabelLookupMiss"},
    133         {bcmSwitchPktTraceDropReasonMplsInvalidAction,
    134           "MplsInvalidAction"},
    135         {bcmSwitchPktTraceDropReasonMplsInvalidPayload,
    136           "MplsInvalidPayload"},
    137         {bcmSwitchPktTraceDropReasonMplsTtlCheckFail,
    138           "MplsTtlCheckFail"},
    139         {bcmSwitchPktTraceDropReasonMplsInvalidControlWord,
    140           "MplsInvalidControlWord"},
    141         {bcmSwitchPktTraceDropReasonL2greSipLookupMiss,
    142           "L2greSipLookupMiss"},
    143         {bcmSwitchPktTraceDropReasonL2greVpnLookupMiss,
    144           "L2greVpnLookupMiss"},
    145         {bcmSwitchPktTraceDropReasonL2greTunnelError,
    146           "L2greTunnelError"},
    147         {bcmSwitchPktTraceDropReasonVxlanSipLookupMiss,
    148           "VxlanSipLookupMiss"},
    149         {bcmSwitchPktTraceDropReasonVxlanVnidLookupMiss,
    150           "VxlanVnidLookupMiss"},
    151         {bcmSwitchPktTraceDropReasonVxlanTunnelError,
    152           "VxlanTunnelError"},
    153         {bcmSwitchPktTraceDropReasonVlanNotValid,
    154           "VlanNotValid"},
    155         {bcmSwitchPktTraceDropReasonIngressPortNotInVlanMember,
    156           "IngressPortNotInVlanMember"},
    157         {bcmSwitchPktTraceDropReasonTpidMismatch,
    158           "TpidMismatch"},
    159         {bcmSwitchPktTraceDropReasonIpv4ProtocolError,
    160           "Ipv4ProtocolError"},
    161         {bcmSwitchPktTraceDropReasonHigigLoopback,
    162           "HigigLoopback"},
    163         {bcmSwitchPktTraceDropReasonHigigMirrorOnly,
    164           "HigigMirrorOnly"},
    165         {bcmSwitchPktTraceDropReasonHigigUnknownHeader,
    166           "HigigUnknownHeader"},
    167         {bcmSwitchPktTraceDropReasonHigigUnknownOpcode,
    168           "HigigUnknownOpcode"},
    169         {bcmSwitchPktTraceDropReasonLagFailLoopback,
    170           "LagFailLoopback"},
    171         {bcmSwitchPktTraceDropReasonL2SrcEqualL2Dst,
    172           "L2SrcEqualL2Dst"},
    173         {bcmSwitchPktTraceDropReasonIpv6ProtocolError,
    174           "Ipv6ProtocolError"},
    175         {bcmSwitchPktTraceDropReasonNivVntagPresent,
    176           "NivVntagPresent"},
    177         {bcmSwitchPktTraceDropReasonNivVntagNotPresent,
    178           "NivVntagNotPresent"},
    179         {bcmSwitchPktTraceDropReasonNivVntagFormat,
    180           "NivVntagFormat"},
    181         {bcmSwitchPktTraceDropReasonTrillErrorFrame,
    182           "TrillErrorFrame"},
    183         {bcmSwitchPktTraceDropReasonBpdu,
    184           "Bpdu"},
    185         {bcmSwitchPktTraceDropReasonBadUdpChecksum,
    186           "BadUdpChecksum"},
    187         {bcmSwitchPktTraceDropReasonTunnlDecapEcnError,
    188           "TunnlDecapEcnError"},
    189         {bcmSwitchPktTraceDropReasonIpv4HeaderError,
    190           "Ipv4HeaderError"},
    191         {bcmSwitchPktTraceDropReasonIpv6HeaderError,
    192           "Ipv6HeaderError"},
    193         {bcmSwitchPktTraceDropReasonParityError,
    194           "ParityError"},
    195         {bcmSwitchPktTraceDropReasonRpfCheckFail,
    196           "RpfCheckFail"},
    197         {bcmSwitchPktTraceDropReasonStageLookup,
    198           "StageLookup"},
    199         {bcmSwitchPktTraceDropReasonStageIngress,
    200           "StageIngress"},
    201         {bcmSwitchPktTraceDropReasonTunnelObjectValidationFail,
    202           "TunnelObjectValidationFail"},
    203         {bcmSwitchPktTraceDropReasonTunnelShimHeaderError,
    204           "TunnelShimHeaderError"},
    205         {bcmSwitchPktTraceDropReasonTunnelTTLError,
    206           "TunnelTTLError"},
    207         {bcmSwitchPktTraceDropReasonTunnelInterfaceCheckFail,
    208           "TunnelInterfaceCheckFail"},
    209         {bcmSwitchPktTraceDropReasonTunnelError,
    210           "TunnelError"},
    211         {bcmSwitchPktTraceDropReasonTunnelAdapt1LookupMiss,
    212           "TunnelAdapt1LookupMiss"},
    213         {bcmSwitchPktTraceDropReasonTunnelAdapt2LookupMiss,
    214           "TunnelAdapt2LookupMiss"},
    215         {bcmSwitchPktTraceDropReasonTunnelAdapt3LookupMiss,
    216           "TunnelAdapt3LookupMiss"},
    217         {bcmSwitchPktTraceDropReasonTunnelAdapt4LookupMiss,
    218           "TunnelAdapt4LookupMiss"},
    219         {bcmSwitchPktTraceDropReasonCount,
    220           NULL }
    221 
    222     };
    223     abs_drop_reasons_t *adrtp = &(abs_drop_reasons_table[0]);
    224 
    225     cli_out("Drop Reasons:\n");
    226     while (1) {
    227         if (!adrtp->name) {
    228             break;
    229         }
    230         i = (adrtp->bit / BYTES2BITS(sizeof(uint32)));
    231         if (dr[i] & (1 << (adrtp->bit - (32 * i)))) {
    232             cli_out("   %s\n", adrtp->name);
    233         }
    234         adrtp++;
    235     }
    236 }
    237 
    238 typedef struct {
    239     bcm_switch_pkt_trace_lookup_t bit;
    240     char *name;
    241 } abs_lookup_results_t;
    242 
    243 static void abs_lookup_results_print(int unit, bcm_switch_pkt_trace_lookup_result_t *lr)
    244 {
    245     abs_lookup_results_t abs_lookup_results_table[] = {
    246         { bcmSwitchPktTraceLookupFirstVlanTranslationHit,
    247           "FirstVlanTranslationHit" },
    248         { bcmSwitchPktTraceLookupSecondVlanTranslationHit,
    249           "SecondVlanTranslationHit" },
    250         { bcmSwitchPktTraceLookupForwardingVlanValid,
    251           "ForwardingVlanValid" },
    252         { bcmSwitchPktTraceLookupL2SrcHit,
    253           "L2SrcHit" },
    254         { bcmSwitchPktTraceLookupL2SrcStatic,
    255           "L2SrcStatic" },
    256         { bcmSwitchPktTraceLookupL2DstHit,
    257           "L2DstHit" },
    258         { bcmSwitchPktTraceLookupL2CacheHit,
    259           "L2CacheHit" },
    260         { bcmSwitchPktTraceLookupL3SrcHostHit,
    261           "L3SrcHostHit" },
    262         { bcmSwitchPktTraceLookupL3DestHostHit,
    263           "L3DestHostHit" },
    264         { bcmSwitchPktTraceLookupL3DestRouteHit,
    265           "L3DestRouteHit" },
    266         { bcmSwitchPktTraceLookupL2SrcMiss,
    267           "L2SrcMiss" },
    268         { bcmSwitchPktTraceLookupDosAttack,
    269           "DosAttack" },
    270         { bcmSwitchPktTraceLookupIpTunnelHit,
    271           "IpTunnelHit" },
    272         { bcmSwitchPktTraceLookupMplsLabel1Hit,
    273           "MplsLabel1Hit" },
    274         { bcmSwitchPktTraceLookupMplsLabel2Hit,
    275           "MplsLabel2Hit" },
    276         { bcmSwitchPktTraceLookupMplsTerminated,
    277           "MplsTerminated" },
    278         { bcmSwitchPktTraceLookupMystationHit,
    279           "MystationHit" },
    280         { bcmSwitchPktTraceLookupInvalid,
    281           NULL }
    282     };
    283     abs_lookup_results_t *alrtp = &(abs_lookup_results_table[0]);
    284 
    285     cli_out("Lookup Status Results:\n");
    286     while (1) {
    287         if (! alrtp->name) {
    288             break;
    289         }
    290         
    291         if (lr->pkt_trace_status_bitmap[0] & (1 << alrtp->bit )) {
    292             cli_out("   %s\n", alrtp->name);
    293         }
    294         alrtp++;
    295     }
    296 }
    297  
    298 
    299 static void gport_print(bcm_port_t gp)
    300 {
    301     if (BCM_GPORT_IS_SET(gp)) {
    302         if (BCM_GPORT_IS_LOCAL(gp)) 
    303             cli_out("local(%d)\n", BCM_GPORT_LOCAL_GET(gp));
    304         else if (BCM_GPORT_IS_MODPORT(gp))
    305             cli_out("modport(%d, %d)\n", 
    306                    BCM_GPORT_MODPORT_MODID_GET(gp), 
    307                    BCM_GPORT_MODPORT_PORT_GET(gp));
    308         else if (BCM_GPORT_IS_TRUNK(gp))
    309             cli_out("trunk(%d)\n", BCM_GPORT_TRUNK_GET(gp));
    310         else if (BCM_GPORT_IS_BLACK_HOLE(gp))
    311             cli_out("blackhole\n");
    312         else if (BCM_GPORT_IS_LOCAL_CPU(gp))
    313             cli_out("cpu\n");
    314     } else if (gp == BCM_GPORT_INVALID) {
    315         cli_out("Invalid GPORT\n");
    316     } else {
    317         cli_out("%d\n", gp);
    318     }
    319 }
    320 
    321 static void fp_trunk_print(int unit, bcm_trunk_t tid)
    322 {
    323     int rv;
    324     int i;
    325     bcm_trunk_info_t tinfo;
    326     bcm_trunk_member_t member_array[BCM_TRUNK_MAX_PORTCNT];
    327     int member_count;
    328 
    329     rv = bcm_trunk_get(unit,
    330                        tid,
    331                        &tinfo,
    332                        BCM_TRUNK_MAX_PORTCNT,
    333                        member_array, 
    334                        &member_count);
    335 
    336     if (BCM_FAILURE(rv)) {
    337         cli_out("bcm_trunk_get(unit=%d,tid=%d): rv=%d, %s\n",
    338                 unit,
    339                 tid,
    340                 rv,
    341                 bcm_errmsg(rv));
    342         return;
    343     }
    344     cli_out("   Trunk id: %d\n", tid);
    345     cli_out("     Rtag: %d\n", tinfo.psc);
    346     cli_out("     Members: %d ports\n", member_count);
    347     for (i = 0; i < member_count; i++) {
    348         cli_out("       "); gport_print(member_array[i].gport);
    349     }
    350 }
    351 
    352 static void abs_hashing_info_print(int unit, bcm_switch_pkt_trace_hashing_info_t *hi)
    353 {
    354     /* Hashing resolution? */
    355     if (hi->flags == 0) {
    356         return;
    357     }
    358     if (hi->flags & BCM_SWITCH_PKT_TRACE_ECMP_1) {
    359         cli_out("Hash resolution: ECMP1 (MULTIPATH)\n");
    360         cli_out("  ecmp_1_group %d\n", hi->ecmp_1_group);
    361         cli_out("  > l3 multipath show %d\n", hi->ecmp_1_group);
    362 
    363         cli_out("Egress multipath interface:\n");
    364         cli_out("  ecmp_1_egress %d\n", hi->ecmp_1_egress);
    365         cli_out("  > l3 egress show %d\n", hi->ecmp_1_egress);
    366     }
    367     if (hi->flags & BCM_SWITCH_PKT_TRACE_ECMP_2) {
    368         cli_out("Hash resolution: ECMP2 (MULTIPATH)\n");
    369         cli_out("   ecmp_2_group %d\n", hi->ecmp_2_group);
    370         cli_out("   > l3 multipath show %d\n", hi->ecmp_2_group);
    371         cli_out("   ecmp2_egress %d\n", hi->ecmp_2_egress);
    372     }
    373     if (hi->flags & BCM_SWITCH_PKT_TRACE_TRUNK) {
    374         cli_out("Hash resolution: Trunk\n");
    375         fp_trunk_print(unit, hi->trunk);
    376         cli_out("     Trunk egress member: "); gport_print(hi->trunk_member);
    377     }
    378     if (hi->flags & BCM_SWITCH_PKT_TRACE_FABRIC_TRUNK) {
    379         cli_out("Hash resolution: Fabric trunk\n");
    380         cli_out("   Fabric trunk: "); gport_print(hi->fabric_trunk);
    381         cli_out("   Fabric trunk egress member: "); gport_print(hi->fabric_trunk_member);
    382     }
    383 }
    384 
    385 static void abs_fwd_dst_info_print(int unit,  bcm_switch_pkt_trace_fwd_dst_info_t *fd)
    386 {
    387     /* Forward destination information*/
    388     if (fd->flags == 0) {
    389         return;
    390     }
    391     if (fd->flags & BCM_SWITCH_PKT_TRACE_FWD_DST_DGPP) {
    392         cli_out(" Destination port %x\n", fd->port);
    393     }
    394     if (fd->flags & BCM_SWITCH_PKT_TRACE_FWD_DST_DVP) {
    395         cli_out(" DVP %x\n", fd->dvp);
    396     }
    397     if (fd->flags & BCM_SWITCH_PKT_TRACE_FWD_DST_DVP) {
    398         cli_out(" DVP %d\n", fd->dvp);
    399     }
    400     if (fd->flags & BCM_SWITCH_PKT_TRACE_FWD_DST_VLAN) {
    401         cli_out(" Forwarding VlAN  %d\n", fd->fwd_vlan);
    402     }
    403     if (fd->flags & BCM_SWITCH_PKT_TRACE_FWD_DST_L2MC) {
    404         cli_out(" l2 multicast group %d\n", fd->mc_group);
    405     }
    406     if (fd->flags & BCM_SWITCH_PKT_TRACE_FWD_DST_IPMC) {
    407         cli_out(" l3 multicast group %d\n", fd->mc_group);
    408     }
    409     if (fd->flags & BCM_SWITCH_PKT_TRACE_FWD_DST_NH) {
    410         cli_out("  > l3 egress show %d\n", fd->egress_intf);
    411     } 
    412 }
    413 
    414 static void abs_stp_state_print(int unit, bcm_stg_stp_t stp_state)
    415 {
    416     char *stp_state_names[] =  {
    417         /* In Tomahawk, there is no learning */
    418         "Disable", "Block", "Listen", "Forward", "Forward"
    419     };
    420 
    421     cli_out("Source port STP state: ");
    422     if (stp_state > BCM_STG_STP_FORWARD) {
    423         cli_out(" Invalid STP state\n");
    424     } else {
    425         cli_out(" %s\n", stp_state_names[stp_state]);
    426     }
    427 }
    428 
    429 void appl_pkt_trace_info_print(int unit, bcm_switch_pkt_trace_info_t *pkt_trace_info)
    430 {
    431     abs_lookup_results_print(unit, &pkt_trace_info->pkt_trace_lookup_status);
    432     abs_resolution_print(unit, pkt_trace_info->pkt_trace_resolution);
    433     abs_stp_state_print(unit, pkt_trace_info->pkt_trace_stp_state);
    434     abs_hashing_info_print(unit, &pkt_trace_info->pkt_trace_hash_info);
    435     abs_fwd_dst_info_print(unit, &pkt_trace_info->pkt_trace_fwd_dst_info);
    436     abs_drop_reasons_print(unit, pkt_trace_info->pkt_trace_drop_reason);
    437 }
    438 
    439 
    440 int appl_visibility_trace(int unit, int vis_options, int vis_sport, bcm_pkt_t *pkt_info)
    441 {
    442     int rv;
    443     uint16 i = 0;
    444     uint16 print_raw_data = 0;
    445     bcm_switch_pkt_trace_info_t pkt_trace_info;
    446 
    447     rv = bcm_switch_pkt_trace_info_get(unit,
    448                                        vis_options,
    449                                        vis_sport,
    450                                        pkt_info->pkt_data->len,
    451                                        pkt_info->pkt_data->data,
    452                                        &pkt_trace_info);
    453     cli_out("\n=====PACKET TRACE source_port=%s, %s\n",
    454             BCM_PORT_NAME(unit, vis_sport),
    455             bcm_errmsg(rv));
    456     if (rv == BCM_E_NONE) {
    457         cli_out("\n=====RAW PACKET");
    458         hexdump_offset_4x8(pkt_info->pkt_data->data,
    459                            pkt_info->pkt_data->len);
    460         cli_out("\n=====RESULTS\n");
    461         cli_out("Ingress pipeline = %d\n", 
    462                 pkt_trace_info.dest_pipe_num);
    463         appl_pkt_trace_info_print(unit, &pkt_trace_info);
    464 
    465         for (i = 0; i < BCM_SWITCH_PKT_TRACE_RAW_DATA_MAX; i++) {
    466            if (pkt_trace_info.raw_data[i]) {
    467                print_raw_data = 1;
    468                break;
    469            }
    470         }
    471         if (print_raw_data) {
    472             cli_out("\n=====RAW DATA\n");
    473             hexdump_8x2(pkt_trace_info.raw_data,
    474                     sizeof(pkt_trace_info.raw_data));
    475         }
    476     }
    477 
    478     return rv;
    479 }
    480 #endif /* BCM_INSTRUMENTATION_SUPPORT */