Cint recipes
Small Cint programs that read state through the SDK API on a Trident 3
SONiC switch. All of them are read-only: they call only *_get and
*_traverse functions and change nothing on the switch. Each starts with
cint_reset(); so it can be run again, and ends by printing DONE
<name>; if that line is missing, the program did not run to the end. See
Cint: the C interpreter for how Cint runs and The Cint language
for the language.
Copy a program to /root in the syncd container and run it from the
host (see Cint: the C interpreter for why not /tmp):
Hardware-validated
$ sudo docker cp hello_info.c syncd:/root/
$ bcmcmd -t 120 "cint /root/hello_info.c"
or from an interactive bcmsh session with cint /root/hello_info.c.
Programs that walk a table hold that table’s lock while they run, so
syncd waits to update it. They print only the first entries, but they
still visit every entry; on a switch with a large L2 or route table, run
them when a short delay in programming is acceptable.
Chip identity
bcm_info_get returns the PCI vendor and device ID and the revision. The
Trident 3 below reports device 0xb870; other members of the family
report other IDs, for example 0xb873 in the capture in the cint
reference. The structure printed by print info ends with per-die arrays
that are all zero on Trident 3.
/*
* hello_info.c - print the chip identity with bcm_info_get().
* Read-only. Run: cint /root/hello_info.c
*/
cint_reset();
int hello_info()
{
int unit = 0;
int rv;
bcm_info_t info;
rv = bcm_info_get(unit, &info);
if (rv != BCM_E_NONE) {
printf("bcm_info_get failed: %d (%s)\n", rv, bcm_errmsg(rv));
return rv;
}
printf("vendor 0x%04x device 0x%04x revision 0x%02x\n",
info.vendor, info.device, info.revision);
print info;
return 0;
}
hello_info();
printf("DONE hello_info\n");
Hardware-validated
drivshell> cint /root/hello_info.c
vendor 0x14e4 device 0xb870 revision 0x01
bcm_info_t info = {
unsigned int vendor = 5348 (0x14e4)
unsigned int device = 47216 (0xb870)
unsigned int revision = 1 (0x1)
unsigned int capability = 13 (0xd)
int num_pipes = 2 (0x2)
int num_pp_pipes = 0 (0x0)
int num_buffers = 0 (0x0)
int num_instances_per_pp_pipe = 0 (0x0)
unsigned int package_rev_id = 0 (0x0)
unsigned int interposer_rev_id = 0 (0x0)
int dies_num = 0 (0x0)
unsigned int[16] die_dev_id = {
unsigned int die_dev_id[0] = 0 (0x0)
unsigned int die_dev_id[1] = 0 (0x0)
unsigned int die_dev_id[2] = 0 (0x0)
unsigned int die_dev_id[3] = 0 (0x0)
unsigned int die_dev_id[4] = 0 (0x0)
unsigned int die_dev_id[5] = 0 (0x0)
unsigned int die_dev_id[6] = 0 (0x0)
unsigned int die_dev_id[7] = 0 (0x0)
unsigned int die_dev_id[8] = 0 (0x0)
unsigned int die_dev_id[9] = 0 (0x0)
unsigned int die_dev_id[10] = 0 (0x0)
unsigned int die_dev_id[11] = 0 (0x0)
unsigned int die_dev_id[12] = 0 (0x0)
unsigned int die_dev_id[13] = 0 (0x0)
unsigned int die_dev_id[14] = 0 (0x0)
unsigned int die_dev_id[15] = 0 (0x0)
...
Port status
One line per front-panel port with the admin state, link state, speed and
untagged VLAN. Port numbers are SDK logical port numbers, as shown by
ps; see Ports and port bitmaps.
/*
* port_status.c - one line per front-panel port: enable, link, speed and
* untagged VLAN. Read-only. Run: cint /root/port_status.c
*/
cint_reset();
int ps_show(int unit, bcm_port_t port)
{
int enable = -1;
int link = -1;
int speed = -1;
bcm_vlan_t pvid = 0;
int vid;
int rv;
rv = bcm_port_enable_get(unit, port, &enable);
if (rv != BCM_E_NONE) {
printf("port %3d: bcm_port_enable_get: %s\n", port, bcm_errmsg(rv));
return rv;
}
bcm_port_link_status_get(unit, port, &link);
bcm_port_speed_get(unit, port, &speed);
bcm_port_untagged_vlan_get(unit, port, &pvid);
vid = pvid;
printf("port %3d: enable %d link %d speed %6d pvid %4d\n",
port, enable, link, speed, vid);
return 0;
}
int ps_main()
{
int unit = 0;
int rv;
int count = 0;
bcm_port_t port;
bcm_pbmp_t pbm;
bcm_port_config_t config;
bcm_port_config_t_init(&config);
rv = bcm_port_config_get(unit, &config);
if (rv != BCM_E_NONE) {
printf("bcm_port_config_get failed: %s\n", bcm_errmsg(rv));
return rv;
}
pbm = config.port;
printf("front-panel ports: ${pbm}\n");
BCM_PBMP_ITER(pbm, port) {
ps_show(unit, port);
count++;
}
printf("%d ports\n", count);
return 0;
}
ps_main();
printf("DONE port_status\n");
Hardware-validated
drivshell> cint /root/port_status.c
front-panel ports: { 1 5 9 10 11 12 13 17 21 25 29 33 37 41 45 49 53 57 61 66 67 71 75 79 83 87 91 95 99 103 107 111 115 119 123 127 }
port 1: enable 0 link 0 speed 100000 pvid 1
port 5: enable 0 link 0 speed 100000 pvid 1
port 9: enable 1 link 1 speed 10000 pvid 1
port 10: enable 1 link 1 speed 10000 pvid 1
port 11: enable 1 link 1 speed 10000 pvid 1
port 12: enable 1 link 1 speed 10000 pvid 902
port 13: enable 0 link 0 speed 100000 pvid 1
port 17: enable 0 link 0 speed 100000 pvid 1
port 21: enable 0 link 0 speed 100000 pvid 1
port 25: enable 0 link 0 speed 100000 pvid 1
port 29: enable 0 link 0 speed 100000 pvid 1
port 33: enable 0 link 0 speed 100000 pvid 1
port 37: enable 0 link 0 speed 100000 pvid 1
port 41: enable 0 link 0 speed 100000 pvid 1
port 45: enable 0 link 0 speed 100000 pvid 1
port 49: enable 0 link 0 speed 100000 pvid 1
port 53: enable 0 link 0 speed 100000 pvid 1
port 57: enable 0 link 0 speed 100000 pvid 1
port 61: enable 0 link 0 speed 100000 pvid 1
port 66: enable 0 link 0 speed 10000 pvid 1
port 67: enable 0 link 0 speed 100000 pvid 1
port 71: enable 0 link 0 speed 100000 pvid 1
port 75: enable 0 link 0 speed 100000 pvid 1
port 79: enable 0 link 0 speed 100000 pvid 1
port 83: enable 0 link 0 speed 100000 pvid 1
port 87: enable 0 link 0 speed 100000 pvid 1
port 91: enable 0 link 0 speed 100000 pvid 1
port 95: enable 0 link 0 speed 100000 pvid 1
port 99: enable 0 link 0 speed 100000 pvid 1
port 103: enable 0 link 0 speed 100000 pvid 1
port 107: enable 0 link 0 speed 100000 pvid 1
port 111: enable 0 link 0 speed 100000 pvid 1
port 115: enable 1 link 1 speed 100000 pvid 1
port 119: enable 1 link 1 speed 100000 pvid 1
port 123: enable 0 link 0 speed 100000 pvid 1
port 127: enable 0 link 0 speed 100000 pvid 1
36 ports
DONE port_status
Port counters
Reads 64-bit counters of one port with bcm_stat_get. The port number is
the first argument; without one, port 1 is read. These are the SDK’s
counters, the same ones show counters reads, so they are not reset
by sonic-clear counters.
/*
* port_counters.c - read a few SNMP-style counters of one port with
* bcm_stat_get(). Read-only.
* Run: cint /root/port_counters.c [<logical port>] (default: port 1)
*/
cint_reset();
int pc_atoi(char *s)
{
int i = 0;
int v = 0;
int c;
while (1) {
c = s[i];
if (c < '0' || c > '9') {
break;
}
v = v * 10 + (c - '0');
i++;
}
return v;
}
int pc_show(int unit, bcm_port_t port, bcm_stat_val_t stat, char *name)
{
uint64 val;
int rv;
COMPILER_64_ZERO(&val);
rv = bcm_stat_get(unit, port, stat, &val);
if (rv != BCM_E_NONE) {
printf(" %-22s error %d (%s)\n", name, rv, bcm_errmsg(rv));
return rv;
}
printf(" %-22s ${val} hi %u lo %u\n", name,
COMPILER_64_HI(&val), COMPILER_64_LO(&val));
return 0;
}
int pc_main()
{
int unit = 0;
bcm_port_t port = 1;
if (ARGC > 0) {
port = pc_atoi(ARGV[0]);
}
printf("port %d\n", port);
pc_show(unit, port, snmpIfHCInOctets, "snmpIfHCInOctets");
pc_show(unit, port, snmpIfHCInUcastPkts, "snmpIfHCInUcastPkts");
pc_show(unit, port, snmpIfInErrors, "snmpIfInErrors");
pc_show(unit, port, snmpIfInDiscards, "snmpIfInDiscards");
pc_show(unit, port, snmpIfHCOutOctets, "snmpIfHCOutOctets");
pc_show(unit, port, snmpIfHCOutUcastPkts, "snmpIfHCOutUcastPkts");
pc_show(unit, port, snmpIfOutErrors, "snmpIfOutErrors");
pc_show(unit, port, snmpIfOutDiscards, "snmpIfOutDiscards");
return 0;
}
pc_main();
printf("DONE port_counters\n");
Hardware-validated
drivshell> cint /root/port_counters.c 1
port 1
snmpIfHCInOctets {0x00000000 0x00000000} hi 0 lo 0
snmpIfHCInUcastPkts {0x00000000 0x00000000} hi 0 lo 0
snmpIfInErrors {0x00000000 0x00000000} hi 0 lo 0
snmpIfInDiscards {0x00000000 0x00000000} hi 0 lo 0
snmpIfHCOutOctets {0x00000000 0x00000000} hi 0 lo 0
snmpIfHCOutUcastPkts {0x00000000 0x00000000} hi 0 lo 0
snmpIfOutErrors {0x00000000 0x00000000} hi 0 lo 0
snmpIfOutDiscards {0x00000000 0x00000000} hi 0 lo 0
DONE port_counters
L3 table usage
How full the route, host, next-hop and interface tables are, from
bcm_l3_info. l3 info shows similar numbers.
/*
* l3_info.c - L3 table sizes and usage from bcm_l3_info().
* Read-only. Run: cint /root/l3_info.c
*/
cint_reset();
int li_main()
{
int unit = 0;
int rv;
bcm_l3_info_t info;
rv = bcm_l3_info(unit, &info);
if (rv != BCM_E_NONE) {
printf("bcm_l3_info failed: %s\n", bcm_errmsg(rv));
return rv;
}
printf("routes used %d of %d\n", info.l3info_used_route, info.l3info_max_route);
printf("hosts used %d of %d\n", info.l3info_used_host, info.l3info_max_host);
printf("egress used %d of %d\n", info.l3info_used_nexthop, info.l3info_max_nexthop);
printf("intf used %d of %d\n", info.l3info_used_intf, info.l3info_max_intf);
print info;
return 0;
}
li_main();
printf("DONE l3_info\n");
Hardware-validated
drivshell> cint /root/l3_info.c
routes used 6 of 32768
hosts used 3 of 16384
egress used 7 of 65536
intf used 6 of 16383
bcm_l3_info_t info = {
int l3info_max_vrf = 4095 (0xfff)
int l3info_used_vrf = -1 (0xffffffff)
int l3info_max_intf = 16383 (0x3fff)
int l3info_max_intf_group = 4095 (0xfff)
int l3info_max_host = 16384 (0x4000)
int l3info_max_route = 32768 (0x8000)
int l3info_max_ecmp_groups = 4096 (0x1000)
int l3info_max_ecmp = 128 (0x80)
int l3info_max_ecmp_failover_size = 0 (0x0)
int l3info_used_intf = 6 (0x6)
int l3info_used_host = 3 (0x3)
int l3info_used_route = 6 (0x6)
int l3info_max_lpm_block = 0 (0x0)
int l3info_used_lpm_block = 0 (0x0)
int l3info_max_l3 = 16384 (0x4000)
int l3info_max_defip = 16384 (0x4000)
int l3info_used_l3 = 3 (0x3)
int l3info_used_defip = 6 (0x6)
int l3info_max_nexthop = 65536 (0x10000)
int l3info_used_nexthop = 7 (0x7)
int l3info_max_tunnel_init = 4096 (0x1000)
int l3info_used_tunnel_init = 0 (0x0)
int l3info_max_tunnel_term = 2048 (0x800)
int l3info_used_tunnel_term = 0 (0x0)
int l3info_used_host_ip4 = 1 (0x1)
int l3info_used_host_ip6 = 2 (0x2)
}
DONE l3_info
Routes
Walks the IPv4 and then the IPv6 route table with bcm_l3_route_traverse
and prints the first 20 of each. The third and fourth arguments of
bcm_l3_route_traverse are the first and last position in the walk,
counted from 0, not table indices; a route with several ECMP paths may count
once per path. The intf column is the egress object or ECMP group, as in
l3 defip show. IPv6 addresses print as eight full groups
(fe80:0000:0000:…), without :: shortening.
/*
* l3_routes.c - print the first routes of the IPv4 and IPv6 route tables
* with bcm_l3_route_traverse() and a Cint callback. Read-only.
* Run: cint /root/l3_routes.c
*/
cint_reset();
int lr_seen = 0;
int lr_v4_cb(int unit, int index, bcm_l3_route_t *info, void *user_data)
{
bcm_ip_t net = info->l3a_subnet;
bcm_ip_t mask = info->l3a_ip_mask;
int vrf = info->l3a_vrf;
int intf = info->l3a_intf;
int flags = info->l3a_flags;
lr_seen++;
printf("v4 %3d vrf %d ${net} mask ${mask} intf %d flags 0x%x\n",
index, vrf, intf, flags);
return BCM_E_NONE;
}
int lr_v6_cb(int unit, int index, bcm_l3_route_t *info, void *user_data)
{
bcm_ip6_t net = info->l3a_ip6_net;
bcm_ip6_t mask = info->l3a_ip6_mask;
int vrf = info->l3a_vrf;
int intf = info->l3a_intf;
int flags = info->l3a_flags;
lr_seen++;
printf("v6 %3d vrf %d ${net} mask ${mask} intf %d flags 0x%x\n",
index, vrf, intf, flags);
return BCM_E_NONE;
}
int lr_main()
{
int unit = 0;
int rv;
int limit = 20;
lr_seen = 0;
rv = bcm_l3_route_traverse(unit, 0, 0, limit - 1, lr_v4_cb, NULL);
printf("IPv4: rv %d (%s), %d shown (limit %d)\n", rv, bcm_errmsg(rv), lr_seen, limit);
lr_seen = 0;
rv = bcm_l3_route_traverse(unit, BCM_L3_IP6, 0, limit - 1, lr_v6_cb, NULL);
printf("IPv6: rv %d (%s), %d shown (limit %d)\n", rv, bcm_errmsg(rv), lr_seen, limit);
return 0;
}
lr_main();
printf("DONE l3_routes\n");
Hardware-validated
drivshell> cint /root/l3_routes.c
v4 10240 vrf 0 198.51.100.0 mask 255.255.255.0 intf 132807 flags 0x0
v4 12288 vrf 0 0.0.0.0 mask 0.0.0.0 intf 132806 flags 0x100000
IPv4: rv 0 (Ok), 2 shown (limit 20)
v6 13312 vrf 0 fe80:0000:0000:0000:0000:0000:0000:0000 mask ffc0:0000:0000:0000:0000:0000:0000:0000 intf 132807 flags 0x20000
v6 14336 vrf 0 0000:0000:0000:0000:0000:0000:0000:0000 mask 0000:0000:0000:0000:0000:0000:0000:0000 intf 132806 flags 0x120000
IPv6: rv 0 (Ok), 2 shown (limit 20)
DONE l3_routes
Egress objects
Lists L3 egress objects (next hops) with their MAC address, VLAN and port.
The numbers match the INTF column of l3 egress show.
/*
* l3_egress.c - list L3 egress objects (next hops) with
* bcm_l3_egress_traverse(). Prints the first 50. Read-only.
* Run: cint /root/l3_egress.c
*/
cint_reset();
int le_count = 0;
int le_limit = 50;
int le_cb(int unit, bcm_if_t intf, bcm_l3_egress_t *info, void *user_data)
{
int vlan = info->vlan;
le_count++;
if (le_count > le_limit) {
return BCM_E_NONE;
}
printf("egress %d: mac %02x:%02x:%02x:%02x:%02x:%02x vlan %d port %d module %d trunk %d intf %d flags 0x%x\n",
intf,
info->mac_addr[0], info->mac_addr[1], info->mac_addr[2],
info->mac_addr[3], info->mac_addr[4], info->mac_addr[5],
vlan, info->port, info->module, info->trunk, info->intf,
info->flags);
return BCM_E_NONE;
}
int le_main()
{
int unit = 0;
int rv;
le_count = 0;
rv = bcm_l3_egress_traverse(unit, le_cb, NULL);
printf("rv %d (%s), %d egress objects\n", rv, bcm_errmsg(rv), le_count);
return 0;
}
le_main();
printf("DONE l3_egress\n");
Hardware-validated
drivshell> cint /root/l3_egress.c
egress 132768: mac 00:00:00:00:00:01 vlan 1 port 0 module 0 trunk 0 intf 8192 flags 0xa00
egress 132769: mac 00:00:00:00:00:01 vlan 1 port 0 module 0 trunk 0 intf 8192 flags 0x200
egress 132770: mac 00:00:00:00:00:00 vlan 0 port 12 module 0 trunk -1 intf -1 flags 0x0
egress 132771: mac ff:ff:ff:ff:ff:ff vlan 0 port 12 module 0 trunk 0 intf 8195 flags 0x800
egress 132806: mac e0:39:d7:88:3b:00 vlan 1 port 0 module 0 trunk -1 intf 8194 flags 0x100000
egress 132807: mac e0:39:d7:88:3b:00 vlan 0 port 0 module 0 trunk -1 intf 16383 flags 0xb001000
rv 0 (Ok), 6 egress objects
DONE l3_egress
L2 table
Counts the MAC table and prints the first 30 entries. Compare
l2 show.
/*
* l2_table.c - count the L2 (MAC) table and print the first 30 entries
* with bcm_l2_traverse(). Read-only. Run: cint /root/l2_table.c
*/
cint_reset();
int lt2_count = 0;
int lt2_static = 0;
int lt2_limit = 30;
int lt2_cb(int unit, bcm_l2_addr_t *info, void *user_data)
{
int vid = info->vid;
lt2_count++;
if (info->flags & BCM_L2_STATIC) {
lt2_static++;
}
if (lt2_count > lt2_limit) {
return BCM_E_NONE;
}
printf("%02x:%02x:%02x:%02x:%02x:%02x vlan %4d port %3d modid %d tgid %d flags 0x%x\n",
info->mac[0], info->mac[1], info->mac[2],
info->mac[3], info->mac[4], info->mac[5],
vid, info->port, info->modid, info->tgid, info->flags);
return BCM_E_NONE;
}
int lt2_main()
{
int unit = 0;
int rv;
lt2_count = 0;
lt2_static = 0;
rv = bcm_l2_traverse(unit, lt2_cb, NULL);
printf("rv %d (%s), %d entries (%d static)\n", rv, bcm_errmsg(rv), lt2_count, lt2_static);
return 0;
}
lt2_main();
printf("DONE l2_table\n");
Hardware-validated
drivshell> cint /root/l2_table.c
e0:39:d7:88:3b:00 vlan 1 port 0 modid 0 tgid 0 flags 0x20
rv 0 (Ok), 1 entries (1 static)
DONE l2_table
VLANs
Lists every VLAN with its member and untagged ports. bcm_vlan_list
allocates the list; the program frees it with bcm_vlan_list_destroy.
/*
* vlans.c - list VLANs with their member and untagged ports using
* bcm_vlan_list(). Read-only; frees the list it receives.
* Run: cint /root/vlans.c
*/
cint_reset();
int vl_main()
{
int unit = 0;
int rv;
int i;
int count = 0;
int vid;
bcm_vlan_t dflt;
bcm_vlan_data_t *list = NULL;
bcm_pbmp_t pbm;
bcm_pbmp_t ubm;
rv = bcm_vlan_default_get(unit, &dflt);
vid = dflt;
printf("default VLAN %d (rv %d)\n", vid, rv);
rv = bcm_vlan_list(unit, &list, &count);
if (rv != BCM_E_NONE) {
printf("bcm_vlan_list failed: %s\n", bcm_errmsg(rv));
return rv;
}
for (i = 0; i < count; i++) {
vid = list[i].vlan_tag;
pbm = list[i].port_bitmap;
ubm = list[i].ut_port_bitmap;
printf("vlan %4d ports ${pbm} untagged ${ubm}\n", vid);
}
printf("%d VLANs\n", count);
bcm_vlan_list_destroy(unit, list, count);
return 0;
}
vl_main();
printf("DONE vlans\n");
Hardware-validated
drivshell> cint /root/vlans.c
default VLAN 1 (rv 0)
vlan 1 ports { } untagged { }
vlan 902 ports { 12 } untagged { 12 }
vlan 3999 ports { } untagged { }
vlan 4095 ports { } untagged { }
4 VLANs
DONE vlans
KNET interfaces
Lists the KNET network interfaces, the Linux network devices through which SONiC sends and receives packets on each port, with the SDK port each is bound to. See KNET and the CPU port.
/*
* knet_netifs.c - list KNET network interfaces (the kernel netdevs that
* SONiC uses for its EthernetN ports) and the SDK port each is bound to.
* Read-only. Run: cint /root/knet_netifs.c
*/
cint_reset();
int kn_count = 0;
int kn_cb(int unit, bcm_knet_netif_t *netif, void *user_data)
{
int vlan = netif->vlan;
kn_count++;
printf("netif %3d %-16s type %d port %3d vlan %4d flags 0x%x\n",
netif->id, netif->name, netif->type, netif->port, vlan,
netif->flags);
return BCM_E_NONE;
}
int kn_main()
{
int unit = 0;
int rv;
kn_count = 0;
rv = bcm_knet_netif_traverse(unit, kn_cb, NULL);
printf("rv %d (%s), %d netifs\n", rv, bcm_errmsg(rv), kn_count);
return 0;
}
kn_main();
printf("DONE knet_netifs\n");
Hardware-validated
drivshell> cint /root/knet_netifs.c
netif 1 Ethernet0 type 2 port 1 vlan 0 flags 0x4
netif 2 Ethernet4 type 2 port 5 vlan 0 flags 0x4
netif 3 Ethernet8 type 2 port 9 vlan 0 flags 0x4
netif 4 Ethernet9 type 2 port 10 vlan 0 flags 0x4
netif 5 Ethernet10 type 2 port 11 vlan 0 flags 0x4
netif 6 Ethernet11 type 2 port 12 vlan 0 flags 0x4
netif 7 Ethernet12 type 2 port 13 vlan 0 flags 0x4
netif 8 Ethernet16 type 2 port 17 vlan 0 flags 0x4
netif 9 Ethernet20 type 2 port 21 vlan 0 flags 0x4
netif 10 Ethernet24 type 2 port 25 vlan 0 flags 0x4
netif 11 Ethernet28 type 2 port 29 vlan 0 flags 0x4
netif 12 Ethernet32 type 2 port 33 vlan 0 flags 0x4
netif 13 Ethernet36 type 2 port 37 vlan 0 flags 0x4
netif 14 Ethernet40 type 2 port 41 vlan 0 flags 0x4
netif 15 Ethernet44 type 2 port 45 vlan 0 flags 0x4
netif 16 Ethernet48 type 2 port 49 vlan 0 flags 0x4
netif 17 Ethernet52 type 2 port 53 vlan 0 flags 0x4
netif 18 Ethernet56 type 2 port 57 vlan 0 flags 0x4
netif 19 Ethernet60 type 2 port 61 vlan 0 flags 0x4
netif 20 Ethernet64 type 2 port 67 vlan 0 flags 0x4
netif 21 Ethernet68 type 2 port 71 vlan 0 flags 0x4
netif 22 Ethernet72 type 2 port 75 vlan 0 flags 0x4
netif 23 Ethernet76 type 2 port 79 vlan 0 flags 0x4
netif 24 Ethernet80 type 2 port 83 vlan 0 flags 0x4
netif 25 Ethernet84 type 2 port 87 vlan 0 flags 0x4
netif 26 Ethernet88 type 2 port 91 vlan 0 flags 0x4
netif 27 Ethernet92 type 2 port 95 vlan 0 flags 0x4
netif 28 Ethernet96 type 2 port 99 vlan 0 flags 0x4
netif 29 Ethernet100 type 2 port 103 vlan 0 flags 0x4
netif 30 Ethernet104 type 2 port 107 vlan 0 flags 0x4
netif 31 Ethernet108 type 2 port 111 vlan 0 flags 0x4
netif 32 Ethernet112 type 2 port 115 vlan 0 flags 0x4
netif 33 Ethernet116 type 2 port 119 vlan 0 flags 0x4
netif 34 Ethernet120 type 2 port 123 vlan 0 flags 0x4
netif 35 Ethernet124 type 2 port 127 vlan 0 flags 0x4
netif 36 Ethernet128 type 2 port 66 vlan 0 flags 0x4
rv 0 (Ok), 36 netifs
DONE knet_netifs
Field-processor groups
Lists the field-processor groups (SONiC ACL tables and the SAI’s own trap
rules are implemented as field-processor groups), how many entries each
has, and the priority of up to 16 entries per group. fp show
prints the full contents.
/*
* field_groups.c - list field-processor (ACL) groups, their usage and the
* priority of their first entries. Read-only.
* Run: cint /root/field_groups.c
*/
cint_reset();
int fg_groups = 0;
int fg_cb(int unit, bcm_field_group_t group, void *user_data)
{
bcm_field_group_status_t st;
bcm_field_entry_t entries[16];
int n = 0;
int i;
int prio;
int rv;
fg_groups++;
rv = bcm_field_group_status_get(unit, group, &st);
if (rv != BCM_E_NONE) {
printf("group %d: status error %s\n", group, bcm_errmsg(rv));
return BCM_E_NONE;
}
printf("group %d: %d entries, %d free of %d, prio %d..%d, %d counters\n",
group, st.entry_count, st.entries_free, st.entries_total,
st.prio_min, st.prio_max, st.counter_count);
rv = bcm_field_entry_multi_get(unit, group, 16, entries, &n);
for (i = 0; rv == BCM_E_NONE && i < n; i++) {
prio = 0;
bcm_field_entry_prio_get(unit, entries[i], &prio);
printf(" entry %d prio %d\n", entries[i], prio);
}
return BCM_E_NONE;
}
int fg_main()
{
int unit = 0;
int rv;
fg_groups = 0;
rv = bcm_field_group_traverse(unit, fg_cb, NULL);
printf("rv %d (%s), %d groups\n", rv, bcm_errmsg(rv), fg_groups);
return 0;
}
fg_main();
printf("DONE field_groups\n");
Hardware-validated
drivshell> cint /root/field_groups.c
group 3: 0 entries, 1024 free of 1024, prio -2147483647..2147483647, 0 counters
group 2: 6 entries, 506 free of 512, prio 0..2147483647, 5 counters
entry 3 prio 0
entry 4 prio 2147483647
entry 5 prio 2147483646
entry 6 prio 2147483645
entry 7 prio 2147483644
entry 8 prio 2147483643
group 1: 29 entries, 3043 free of 3072, prio 0..2147483647, 25 counters
entry 1 prio 0
entry 2 prio 0
entry 9 prio 1
entry 10 prio 1
entry 11 prio 1
entry 12 prio 2
entry 13 prio 1
entry 14 prio 4
entry 15 prio 4
entry 16 prio 4
entry 17 prio 4
entry 18 prio 4
entry 19 prio 4
entry 20 prio 4
entry 21 prio 4
entry 22 prio 4
rv 0 (Ok), 3 groups
DONE field_groups
Enum values and switch controls
Shows how to get the number behind an enum name in this build, print an enum by name, and read a switch control.
/*
* enum_values.c - resolve SDK enum names to numbers in this build and read
* one switch control. Read-only. Run: cint /root/enum_values.c
*/
cint_reset();
int ev_main()
{
int unit = 0;
int rv;
int value;
int number;
bcm_switch_control_t ctl;
bcm_stat_val_t stat;
ctl = bcmSwitchL3EgressMode;
number = ctl;
printf("bcmSwitchL3EgressMode = %d\n", number);
print ctl;
stat = snmpIfHCInOctets;
number = stat;
printf("snmpIfHCInOctets = %d (${stat})\n", number);
value = -1;
rv = bcm_switch_control_get(unit, bcmSwitchL3EgressMode, &value);
printf("bcm_switch_control_get(L3EgressMode): rv %d (%s), value %d\n",
rv, bcm_errmsg(rv), value);
return 0;
}
ev_main();
printf("DONE enum_values\n");
Hardware-validated
drivshell> cint /root/enum_values.c
bcmSwitchL3EgressMode = 230
bcm_switch_control_t ctl = bcmSwitchL3EgressMode (230)
snmpIfHCInOctets = 58 (snmpIfHCInOctets)
bcm_switch_control_get(L3EgressMode): rv 0 (Ok), value 1
DONE enum_values
Arguments
Prints the arguments given after the file name.
/*
* args.c - show the arguments passed after the file name.
* Read-only. Run: cint /root/args.c one two 3
*/
cint_reset();
int args_show()
{
int i;
printf("ARGC = %d\n", ARGC);
for (i = 0; i < ARGC; i++) {
printf("ARGV[%d] = \"%s\"\n", i, ARGV[i]);
}
return 0;
}
args_show();
printf("DONE args\n");
Hardware-validated
drivshell> cint /root/args.c one two 3
ARGC = 3
ARGV[0] = "one"
ARGV[1] = "two"
ARGV[2] = "3"
DONE args
Diag commands from Cint
Runs ps through bshell and prints the result codes, including
the code for an unknown command.
/*
* bshell_ps.c - run a diag shell command from Cint with bshell().
* Read-only. Run: cint /root/bshell_ps.c
*/
cint_reset();
int bp_main()
{
int unit = 0;
int rv;
rv = bshell(unit, "ps");
printf("bshell(ps) returned %d\n", rv);
rv = bshell(unit, "nosuchcommand");
printf("bshell(nosuchcommand) returned %d\n", rv);
return 0;
}
bp_main();
printf("DONE bshell_ps\n");
Hardware-validated
drivshell> cint /root/bshell_ps.c
ena/ speed/ link auto STP lrn inter max cut loop
port link Lns duplex scan neg? state pause discrd ops face frame thru? back encap
ce0( 1) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce1( 5) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
xe0( 9) up 1 10G FD SW No Forward Untag F XFI 9122 No IEEE
xe1( 10) up 1 10G FD SW No Forward Untag F XFI 9122 No IEEE
xe2( 11) up 1 10G FD SW No Forward Untag F XFI 9122 No IEEE
xe3( 12) up 1 10G FD SW No Forward None F XFI 9122 No IEEE
ce2( 13) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce3( 17) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce4( 21) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce5( 25) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce6( 29) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce7( 33) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce8( 37) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce9( 41) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce10( 45) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce11( 49) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce12( 53) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce13( 57) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce14( 61) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
xe4( 66) !ena 1 10G FD SW No Forward Untag F XFI 9122 No IEEE
ce15( 67) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce16( 71) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce17( 75) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce18( 79) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce19( 83) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce20( 87) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce21( 91) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
ce22( 95) !ena 4 100G FD SW No Forward Untag F CR4 9122 No IEEE
...