#!/pkg/bin/ksh
# ---------------------------------------------------------------------
# platform_show_tech_mcast_spirit -- Runs eXR based ASR9K specific 
#     commands for 'show tech-support multicast' command.
#
# November 2015 - gcp-ipmc team
#
# Copyright (c) 2015-2017, 2020 by Cisco Systems, Inc.
# All rights reserved.
#----------------------------------------------------------------------

#
# This script runs all the HFR specific mutlicast commands for show
# tech-support multicast. The script is invoked by show_tech_mcast.
# 
# Options:
#   -n nodeid         Run commands on specified node id.
#   -m nodename       Specify the printable node name of the node id.
#   -g group          Run route commands for specified group addr. (optional)
#   -s source         Run route commands for specified source addr. (optional)
#   

# *****************************************************************
#  Functions for formatting
#
#  All inherited from infra/showtech. They are supposed to convert 
#  some command libraries into script module, so the formatting 
#  will be in sync with other show tech output.#
# *****************************************************************

#
# This function prints a row of a specified character.  
# 
# Argument $1: Number of times to print the character
# Argument $2: Character to print
#
print_char() {
    j=1; while [ "$j" -le "$1" ]; do 
        echo -e "$2\c"
        j=$(($j + 1))
    done;
}

#
# This function prints a string centered with a row of a character each side 
# of it with one space between each end of the string and the characters. 
# 
# Argument $1: String to print
# Argument $2: Character to print round string
# 
# Note: This function assumes that each line is 79 characters long. 
#
print_heading() {
    title="$1"
    title_length=${#title}
    
    # There is a space each side of the sting, so the remaining 
    # number of spaces to be filled with the string and characters is 77. 
    twice_char_length=$((77 - $title_length))
    char_length=$(($twice_char_length / 2))

    echo -e "\n"
    print_char $char_length "$2"
    echo -e  " $title \c"
    print_char $char_length "$2"
    echo -e "\n"
}

# Set address-family specific multicast addresses
# Also set address-family specific show commands.
ip2hex()
{
   set -A n2h 0 1 2 3 4 5 6 7 8 9 a b c d e f
   nib2hex() { echo -e -n ${n2h[$1]}; }

   for octet in $(IFS=.; echo -e $1); do
     nib2hex $((octet / 16))
     nib2hex $((octet % 16))
   done
   echo
}

ipv62hex()
{
   str=$1
   hex=""
        # blkptr and blkptr_end is used to point to the begining and end of
        # a 4 hex digit block
        typeset -i blkptr=1
        typeset -i blkptr_end

        # For each set of 4 digits
        while [ blkptr -lt 39 ] ; do
            blkptr_end=$blkptr+3
            v6_addr_part=$(echo -e ${str} | cut -c ${blkptr}-${blkptr_end})
            v6_hex="$hex$v6_addr_part"
            blkptr=$blkptr+5
        done

    # Strip all trailing :
    hex=${hex%%:*}
    echo -e $hex
}

#
# Attempts to determine what type of linecard we are executing
# on.
#
set_lc_type() {

   if [ -x $BIN_DIR/$PRM_EXEC_NAME_TR ] ||
      [ -x $BIN_DIR/$PRM_EXEC_NAME_TY ] ||
      [ -x $BIN_DIR/$PRM_EXEC_NAME_LS ] ||
      [ -x $BIN_DIR/$PRM_EXEC_NAME_TO ]; then
        lc_type="LC_NP"
   elif [ -x $BIN_DIR/$DPC_RM_SVR_NAME ]; then
        lc_type="LC_SS"
   else
        lc_type="UNKNOWN"
   fi
}

#
# Attempts to determine what kind of platform we are executing on
# Assume Viking by default
#
set_rp_type() {

    is_ss_rp=`/pkg/bin/show_platform_sysdb | grep IOSXRV9000 | wc -l`

    if [[ $is_ss_rp -gt 0 ]]; then
        rp_type="RP_SUNSTONE"
    else
        rp_type="RP_VIKING"
    fi
    echo -e "RP Type: $rp_type ($is_ss_rp)\n"
}

# ***************************
#  Function to run commands 
# ***************************

#
# execute_lc_command() prints the command description and issues the command.
# Commands with group option will get executed only if group is specified.
# 

exec_lc_command() {
    cmd=$1
    node_id=$2
    group_hex=$3
    source_hex=$4
    cmd_vrf_option=$5
    addr_family=$6  

    vkg_cmd=""
    if [[ $group != "" && $group != "unspecified" ]]; then
       vkg_cmd="$vkg_cmd -g $group_hex"
    fi
    if [[ $source != "" && $source != "unspecified" ]]; then
       vkg_cmd="$vkg_cmd -s $source_hex"
    fi
    if [[ -n "$cmd_vrf_option" ]]; then
       vkg_vrf="$vkg_vrf $cmd_vrf_option"
       vkg_cmd="$vkg_cmd $cmd_vrf_option"
    fi

    eval "$cmd $node_id $vkg_cmd"
    echo -e "\n##### end clock: \c"; iosclock -d 0
}


# disp_lc_cmd_title() prints the command description.
# Commands with group/source option will get executed with group/source specified.
# 
# Argument $1: command_desc
# Argumnet $2: printable node name in the form of x/x/x
# Argument $3: group
# Argument $4: source
# Argument $5: vrf option
disp_lc_cmd_title() {
    cmd_desc=$1
    node_name=$2
    group=$3
    source=$4
    cmd_vrf_option=$5

    vkg_cmd=""
    if [[ $group != "" && $group != "unspecified" ]]; then
       vkg_cmd="$vkg_cmd -g $group"
    fi
    if [[ $source != "" && $source != "unspecified" ]]; then
       vkg_cmd="$vkg_cmd -s $source"
    fi
    if [[ -n "$cmd_vrf_option" ]]; then
       vkg_cmd="$vkg_cmd $cmd_vrf_option"
    fi

    print_heading "$cmd_desc $node_name $vkg_cmd" "-"
    echo -e "----------------------------------------------------------------\n"
    echo -e "$cmd_desc $node_name $vkg_cmd\n"
    echo -e "----------------------------------------------------------------\n"
    echo -e "##### start clock: \c"; iosclock -d 0
}

# ******************
#  Main starts here 
# ******************

. /pkg/bin/show_tech_main_fragment

#
# Set the default values for the argument variables.
#
card_type=`node_type`
addr_type="unspecified"
node_id="unspecified"
node_name="unspecified"
group="unspecified"
source="unspecified"
vrf_name="unspecified"
group_hex="unspecified"
source_hex="unspecified"

BIN_DIR=/pkg/bin
PRM_EXEC_NAME_TR="prm_server_tr"
PRM_EXEC_NAME_TY="prm_server_ty"
PRM_EXEC_NAME_TO="prm_server_to"
PRM_EXEC_NAME_LS="ls_prm_svr"
DPC_RM_SVR_NAME="dpc_rm_svr"

#
# Read in the arguments to the script. Node id must be in integer, node
# name must be in x/x/x format, group addr in dotted decimal format.
#
while [ $# -gt 0 ]; do
  case "$1" in 
     -c) card_type="$2"; shift 2;;
     -i) addr_type="$2"; shift 2;;
     -n) node_id="$2"; shift 2;;
     -m) node_name="$2"; shift 2;;
     -g) group="$2"; shift 2;;
     -s) source="$2"; shift 2;;
     -v) vrf_name="$2"; shift 2;; 
     -x) source_hex="$2"; shift 2;;
     -y) group_hex="$2"; shift 2;;
     *)  echo -e "Invalid arguments to platform_show_tech_mcast_spirit _$2_"; exit;;
  esac
done


if [[ $addr_type == "unspecified" ]]; then
    echo -e "platform_show_tech_mcast_spirit: address family is not specified, use ipv4"
    addr_type="ipv4"
fi

if [[ $node_id == "unspecified" || $node_name == "unspecified" ]]; then
    echo -e "platform_show_tech_mcast_spirit: node name and node id are required args"
    exit
fi

if [[ $group != "unspecified" ]]; then
    if [[ $addr_type = "ipv6" ]]; then 
        if [[ $group != *:*:*:*:*:*:*:* ]]; then
        echo -e "platform_show_tech_mcast_spirit: invalid ipv6 group format $group"
        exit
        fi
    else
        if [[ $group != *.*.*.* ]]; then
        echo -e "platform_show_tech_mcast_spirit: invalid ipv4 group format $group"
        exit
        fi
    fi
fi

if [[ $source != "unspecified" ]]; then
    if [[ $addr_type = "ipv6" ]]; then 
        if [[ $source != *:*:*:*:*:*:*:* ]]; then
        echo -e "platform_show_tech_mcast_spirit: invalid ipv6 group format $source"
        exit
        fi
    else
        if [[ $source != *.*.*.* ]]; then
        echo -e "platform_show_tech_mcast_spirit: invalid ipv4 group format $source"
        exit
        fi
    fi
fi

if [[ $addr_type = "ipv4" ]] ;then 
    show_mrib_vkg_ltrace_ksh="mrib_show_ltrace_platf -A -Z"
    show_mrib_vkg_connections_ksh="mrib4_show_client -c -d"
    show_mrib_vkg_intf_all_ksh="mrib4_show_client -a -i -d"
    show_mrib_vkg_regdb_all_ksh="mrib4_show_client -r -a -d"
    show_mfwd_vkg_ltrace_ksh="ipv4_mfwd_show_ltrace"
    show_mfwd_hw_vkg_ksh="gcp_ipmc_ipv4_cmn_show_client"
    show_mfwd_hw_vkg_ltrace_ksh="gcp_ipmc_ipv4_cmn_show_ltrace"
    mfwd_proc_name="ipv4_mfwd_partner"
    show_mrib_vkg_resources_nv_edge_ksh="mrib4_show_client -e -d"
else
    show_mrib_vkg_ltrace_ksh="mrib6_show_ltrace_platf -A -Z"
    show_mrib_vkg_connections_ksh="mrib6_show_client -c -d"
    show_mrib_vkg_intf_all_ksh="mrib6_show_client -a -i -d"
    show_mrib_vkg_regdb_all_ksh="mrib6_show_client -r -a -d"
    show_mfwd_vkg_ltrace_ksh="ipv6_mfwd_show_ltrace"
    show_mfwd_hw_vkg_ksh="gcp_ipmc_ipv6_cmn_show_client"
    show_mfwd_hw_vkg_ltrace_ksh="gcp_ipmc_ipv6_cmn_show_ltrace"
    mfwd_proc_name="ipv6_mfwd_partner"
    show_mrib_vkg_resources_nv_edge_ksh="mrib6_show_client -e -d"
fi

mfwd_proc_pid=`sysmgr_show -o -p $mfwd_proc_name | grep -e PID | cut -c 27-`


# ***********************************************************
#  Show commands to be run by the show tech-support commands
# ***********************************************************

#
# For each command in the list, two mandatory variables are defined as:
# 1. <component>_command_desc[i] is the command that would be entered at the 
#    CLI. This is used as the headline for the command in the script output. 
# 2. <component>_command[i] is the executable obtained from "describe 
#    <show command>" at the CLI. Note that the location filter option must
#    be the last option in the string.
#
# The group filter is optional:
#
# 3. <component>_command_group[i] is the group filter option of the command.
#    Command with the group option will get executed only if a group addr
#    is specified, otherwise the show command is skipped.
#
# New commands may be added at any point in the list but the list must 
# remain numbered consecutively from 1 and must end with an empty command.
#
# To add a new command, first pick the right group it should go in --
# RP commands, LC commands that need a VRF option, LC commands that
# don't need VRF option, etc.  There are also sections for specific
# LC types.
#
# As described above, commands are specified in pairs of parallel
# arrays.  The *_command_desc[i] array has the command that the user
# would type at the CLI and the *command[i] is the actual program
# and options that would get executed as a result of the user typing
# in that command at the CLI.
#
# So, find the right group to add to, copy/paste one of the existing
# pairs for that group, then update it for you new command.  Put it
# wherever you want the command output to appear within that group
# of commands.  Then, make sure that all of the pairs in that group
# are numbered consecutively and that the last entry in the
# *_command[last] entry is empty (it needs no companion description
# array entry.  It is simply the terminator of the list.
#
# Look for some commands similar to the one that you are adding
# and just mimic what is already there.
#

# Commands for RP only
hw_rp_command_desc[1]="show platform"
hw_rp_command[1]="show_sdr_sysdb -m"

hw_rp_command_desc[2]="show version"
hw_rp_command[2]="ng_show_version"

hw_rp_command_desc[3]="Show build info"
hw_rp_command[3]="cat /etc/build-info.txt"

hw_rp_command_desc[4]="show install active"
hw_rp_command[4]="sdr_instcmd show install active"

hw_rp_command_desc[5]="show running-config"
hw_rp_command[5]="nvgen -c -l 1 -t 1 -o 1"

hw_rp_command_desc[6]="admin show inventory"
hw_rp_command[6]="show_inventory -e"

hw_rp_command_desc[7]="admin show running-config"
hw_rp_command[7]="admin-cli-proxy-xr_run_cmd show running"

hw_rp_command_desc[8]="show logging"
hw_rp_command[8]="show_logging"

hw_rp_command_desc[9]="show mrib platform trace all all"
hw_rp_command[9]="$show_mrib_vkg_ltrace_ksh"

hw_rp_command_desc[10]="show mrib platform connections detail"
hw_rp_command[10]="$show_mrib_vkg_connections_ksh"

hw_rp_command_desc[11]="show mrib platform interface all detail"
hw_rp_command[11]="$show_mrib_vkg_intf_all_ksh"

hw_rp_command_desc[12]="show mrib platform regdb all detail"
hw_rp_command[12]="$show_mrib_vkg_regdb_all_ksh"

hw_rp_command[13]=''

#Viking only RP commands
hw_vkg_rp_command_desc[1]="show mgid trace"
hw_vkg_rp_command[1]="show_ltrace_mgid"

hw_vkg_rp_command[2]=''

#Sunstone only RP commands
hw_ss_rp_command_desc[1]="show uidb index"
hw_ss_rp_command[1]="sunstone_uidb_show index -a"

hw_ss_rp_command[2]=''

# Commands to display state of the mfwd_partner process (All linecards)
hw_lc_all_mfwd_proc_command_desc[1]="show processes blocked location"
hw_lc_all_mfwd_proc_command[1]="sh_proc_ng_blocked"

hw_lc_all_mfwd_proc_command_desc[2]="show process $mfwd_proc_name location"
hw_lc_all_mfwd_proc_command[2]="sysmgr_show -o -p $mfwd_proc_name -n"

hw_lc_all_mfwd_proc_command_desc[3]="follow process $mfwd_proc_pid iteration 1 location"
hw_lc_all_mfwd_proc_command[3]="attach_process -p $mfwd_proc_pid -i 1 -n"

hw_lc_all_mfwd_proc_command[4]=''


# MFIB PD per-VRF commands at LC (All linecards)
hw_lc_all_mfwd_vrf_command_desc[1]="show mfib platform aggregator location"
hw_lc_all_mfwd_vrf_command[1]="$show_mfwd_hw_vkg_ksh -Z -l"

hw_lc_all_mfwd_vrf_command[2]=''


# MFIB PD commands at LC (All linecards)
hw_lc_all_mfwd_command_desc[1]="show mfib platform connections location"
hw_lc_all_mfwd_command[1]="$show_mfwd_hw_vkg_ksh -N -l"

hw_lc_all_mfwd_command_desc[2]="show mfib platform resource-counter detail location"
hw_lc_all_mfwd_command[2]="$show_mfwd_hw_vkg_ksh -R -d -l"

hw_lc_all_mfwd_command[3]=''

# MFIB PD trace commands at LC (All linecards)
hw_lc_all_mfwd_trace_command_desc[1]="show mfib platform ltrace location"
hw_lc_all_mfwd_trace_command[1]="$show_mfwd_hw_vkg_ltrace_ksh -i"

hw_lc_all_mfwd_trace_command_desc[2]="show mlib trace location"
hw_lc_all_mfwd_trace_command[2]="$show_mfwd_vkg_ltrace_ksh -B -i"

hw_lc_all_mfwd_trace_command[3]=''

# Misc commands for LC (All linecards)
hw_lc_all_command_desc[1]="show lpts pifib hardware entry statistics location"
hw_lc_all_command[1]="platform_show_pifib -z 0x3 -i"

hw_lc_all_command_desc[2]="show im database brief location"
hw_lc_all_command[2]="im_show database -l 0x1 -h"

hw_lc_all_command[3]=''

# NP (Trident/Typhoon) LC specific commands
hw_lc_np_command_desc[1]="show controller np ports all location"
hw_lc_np_command[1]="prm_np_show ports -s"

hw_lc_np_command_desc[2]="show controller np counters all location"
hw_lc_np_command[2]="prm_np_show counters -s"

hw_lc_np_command_desc[3]="show prm stats summary location"
hw_lc_np_command[3]="prm_stats_show summary -s"

hw_lc_np_command_desc[4]="show prm stats client all location"
hw_lc_np_command[4]="prm_stats_show client -c 0x0 -s"

hw_lc_np_command_desc[5]="show prm server trace error location"
hw_lc_np_command[5]="show_prm_server_ltrace -E -i"

hw_lc_np_command_desc[6]="show uidb index all location"
hw_lc_np_command[6]="uidb_show index -s"

hw_lc_np_command_desc[7]="ship_show -c asr9k-ipmcast"
hw_lc_np_command[7]="ship_show -c asr9k-ipmcast"

hw_lc_np_command[8]=''

# Sunstone LC specific commands (Non-DPA specific)
hw_lc_ss_command_desc[1]="show controllers dpc rm trace all location"
hw_lc_ss_command[1]="show_dpc_rm_svr_ltrace -i"

hw_lc_ss_command_desc[2]="show controllers dpc rm resource table location"
hw_lc_ss_command[2]="dpc_rm_svr_show table -l"

hw_lc_ss_command_desc[3]="ship_show -c asr9k-ipmcast"
hw_lc_ss_command[3]="ship_show -c asr9k-ipmcast"

hw_lc_ss_command[4]=''

# Sunstone LC specific commands (DPA specific)
hw_lc_ss_dpa_command_desc[1]="show controllers dpa uptime"
hw_lc_ss_dpa_command[1]="dpa_exec -l default show dpa uptime"

hw_lc_ss_dpa_command_desc[2]="show controllers dpa version"
hw_lc_ss_dpa_command[2]="dpa_exec -l default show version"

hw_lc_ss_dpa_command_desc[3]="show controllers dpa statistics global"
hw_lc_ss_dpa_command[3]="dpa_exec -l default show dpa stat global"

hw_lc_ss_dpa_command_desc[4]="show controllers dpa statistics connection"
hw_lc_ss_dpa_command[4]="dpa_exec -l default show dpa connection"

hw_lc_ss_dpa_command_desc[5]="show controllers dpa logging"
hw_lc_ss_dpa_command[5]="dpa_exec -l default show dpa logging"

hw_lc_ss_dpa_command[6]=''


#
# Execute commands for the RP only.
#
do_rp_commands() {
    i=1; while [ -n "${hw_rp_command[i]}" ]; do
        echo -e "----------------------------------------------------------------\n"
        echo -e "${hw_rp_command_desc[i]} $node_name\n"
        echo -e "----------------------------------------------------------------\n"
        print_heading "${hw_rp_command_desc[i]} $node_name " "-"
        echo -e "##### start clock: \c"; iosclock -d 0
        eval "${hw_rp_command[i]}"
        echo -e "\n##### end clock: \c"; iosclock -d 0
        i=$(($i + 1))
    done
}

#
# Execute commands for the Sunstone RPs only
#
do_ss_rp_commands() {
    i=1; while [ -n "${hw_ss_rp_command[i]}" ]; do
        echo -e "----------------------------------------------------------------\n"
        echo -e "${hw_ss_rp_command_desc[i]} $node_name\n"
        echo -e "----------------------------------------------------------------\n"
        print_heading "${hw_ss_rp_command_desc[i]} $node_name " "-"
        echo -e "##### start clock: \c"; iosclock -d 0
        eval "${hw_ss_rp_command[i]}"
        echo -e "\n##### end clock: \c"; iosclock -d 0
        i=$(($i + 1))
    done
}

#
# Execute commands for the Viking RPs only
#
do_vkg_rp_commands() {
    i=1; while [ -n "${hw_vkg_rp_command[i]}" ]; do
        echo -e "----------------------------------------------------------------\n"
        echo -e "${hw_vkg_rp_command_desc[i]} $node_name\n"
        echo -e "----------------------------------------------------------------\n"
        print_heading "${hw_vkg_rp_command_desc[i]} $node_name " "-"
        echo -e "##### start clock: \c"; iosclock -d 0
        eval "${hw_vkg_rp_command[i]}"
        echo -e "\n##### end clock: \c"; iosclock -d 0
        i=$(($i + 1))
    done
}

#
# Execute commands common to all linecards.
#
do_all_lc_commands() {
    #
    # First, do commands related to the mfwd process
    #
    i=1; while [ -n "${hw_lc_all_mfwd_proc_command[i]}" ]; do
       disp_lc_cmd_title "${hw_lc_all_mfwd_proc_command_desc[i]}" "$node_name" \
         "" "" ""
        exec_lc_command \
        "${hw_lc_all_mfwd_proc_command[i]}" "$node_id" \
        "" "" "" ""
        i=$(($i + 1))
    done

    #
    # Next, do the global mfib platform commands
    #
    i=1; while [ -n "${hw_lc_all_mfwd_command[i]}" ]; do
       disp_lc_cmd_title "${hw_lc_all_mfwd_command_desc[i]}" "$node_name" \
        "" "" ""
       exec_lc_command \
	"${hw_lc_all_mfwd_command[i]}" "$node_id" \
	"" "" \
        "" "$addr_type"
       i=$(($i + 1))
    done

    #
    # Next, do the per-VRF mfib platform commands
    #
    i=1; while [ -n "${hw_lc_all_mfwd_vrf_command[i]}" ]; do
       disp_lc_cmd_title "${hw_lc_all_mfwd_vrf_command_desc[i]}" "$node_name" \
        "" "" "$vrf_opt"
       exec_lc_command \
	"${hw_lc_all_mfwd_vrf_command[i]}" "$node_id" \
	"" "" \
        "$vrf_opt" "$addr_type"
       i=$(($i + 1))
    done

    #
    # Next, do the traces
    #
    i=1; while [ -n "${hw_lc_all_mfwd_trace_command[i]}" ]; do
       disp_lc_cmd_title "${hw_lc_all_mfwd_trace_command_desc[i]}" "$node_name" \
        "" "" ""
       exec_lc_command \
	"${hw_lc_all_mfwd_trace_command[i]}" "$node_id" \
	"" "" \
        "" "$addr_type"
       i=$(($i + 1))
    done

    #
    # Next, do the resource manager specific CLIs
    #
    i=1; while [ -n "${hw_lc_all_command[i]}" ]; do
       disp_lc_cmd_title "${hw_lc_all_command_desc[i]}" "$node_name" \
        "" "" ""
       exec_lc_command \
	"${hw_lc_all_command[i]}" "$node_id" \
	"" "" "" ""
       i=$(($i + 1))
    done
}

#
# Execute commands specific to NP-based cards (Typhoon/Trident)
#
do_lc_np_commands() {
   i=1; while [ -n "${hw_lc_np_command[i]}" ]; do
       disp_lc_cmd_title "${hw_lc_np_command_desc[i]}" "$node_name" \
        "" "" ""
        exec_lc_command \
        "${hw_lc_np_command[i]}" "$node_id" \
	    "" "" "" ""
        i=$(($i + 1))
       done
}

#
# Execute commands specific to Sunstone
#
do_lc_ss_commands() {
   #Do general SS commands first
   i=1; while [ -n "${hw_lc_ss_command[i]}" ]; do
       disp_lc_cmd_title "${hw_lc_ss_command_desc[i]}" "$node_name" \
        "" "" ""
        exec_lc_command \
        "${hw_lc_ss_command[i]}" "$node_id" \
        "" "" "" ""
        i=$(($i + 1))
       done
   #Do DPA specific commands next (location option is skipped)
   i=1; while [ -n "${hw_lc_ss_dpa_command[i]}" ]; do
       disp_lc_cmd_title "${hw_lc_ss_dpa_command_desc[i]}" "$node_name" \
        "" "" ""
        exec_lc_command \
        "${hw_lc_ss_dpa_command[i]}" "" \
        "" "" "" ""
        i=$(($i + 1))
       done
}

if [[ $card_type == "RP" ]]; then
    #
    # Do commands applicable to all RPs
    #
      do_rp_commands

    # Set the rp_type variable
    set_rp_type

    #
    # Now any RP specific commands
    #
    case $rp_type in
        "RP_SUNSTONE")
            do_ss_rp_commands
            ;;
        "RP_VIKING")
            do_vkg_rp_commands
            ;;
        *)
            ;;
    esac
fi #  [[ $card_type == "RP" ]]

if [[ $card_type == "LC" ]]; then 

    vrf_opt=""

    if [[ $vrf_name != "" && $vrf_name != "unspecified" ]]; then
       vrf_opt="-v $vrf_name"
    fi

    #
    # Do commands applicable to all linecards
    #
    do_all_lc_commands

    # Sets the 'lc_type' variable
    set_lc_type

    #
    # Now any card specific commands
    #
    case $lc_type in
        "LC_NP")
            do_lc_np_commands
            ;;
        "LC_SS")
            do_lc_ss_commands
            ;;
        *)
            ;;
    esac

fi # [[ $card_type == "LC" ]]
