Commit 7d04c427 authored by Adam Wujek's avatar Adam Wujek 💬

Merge branch 'adam-snmp_template' into proposed_master

Branch include SNMP related work
parents 2fa02f9f a20e15e6
......@@ -367,28 +367,53 @@ config SNMP_TEMP_THOLD_FPGA
default "0"
help
Threshold level for FPGA temperature, when exceeded warning is
notified by WR-SWITCH-MIB::tempWarning
notified by SNMP via WR-SWITCH-MIB::wrsTemperatureWarning
Require hal restart after change
config SNMP_TEMP_THOLD_PLL
int "Threshold level for PLL temperature"
default "0"
help
Threshold level for PLL temperature, when exceeded warning is
notified by WR-SWITCH-MIB::tempWarning
notified by SNMP via WR-SWITCH-MIB::wrsTemperatureWarning
Require hal restart after change
config SNMP_TEMP_THOLD_PSL
int "Threshold level for Power Supply Left (PSL) temperature"
default "0"
help
Threshold level for Power Supply Left (PSL) temperature, when
exceeded warning is notified by WR-SWITCH-MIB::tempWarning
exceeded warning is notified by SNMP via
WR-SWITCH-MIB::wrsTemperatureWarning
Require hal restart after change
config SNMP_TEMP_THOLD_PSR
int "Threshold level for Power Supply Right (PSR) temperature"
default "0"
help
Threshold level for Power Supply Right (PSR) temperature, when
exceeded warning is notified by WR-SWITCH-MIB::tempWarning
exceeded warning is notified by SNMP via
WR-SWITCH-MIB::wrsTemperatureWarning
Require hal restart after change
config SNMP_SWCORESTATUS_HP_FRAME_RATE
int "Maximum allowed rate of HP frames on a port"
default "0"
help
Error via SNMP if rate of HP frames on any port exceed given value.
config SNMP_SWCORESTATUS_RX_FRAME_RATE
int "Maximum allowed rate of RX frames on a port"
default "0"
help
Error via SNMP if rate of RX frames on any port exceed given value.
config SNMP_SWCORESTATUS_RX_PRIO_FRAME_RATE
int "Maximum allowed rate of any RX priority"
default "0"
help
Error if frame rate of any RX priority exceed given value.
endmenu
......
......@@ -1360,6 +1360,63 @@ If everything goes well, you'll get a window like the following one:
@center @image{show-pstats, 10cm,, show-pstats}
Command @t{snmptable} can also be used to get simillar results:
@smallexample
snmptable -Cw 80 -c public -v 2c 192.168.1.10 -m all \
-M $WRS_OUTPUT_DIR/build/buildroot-2011.11/output/build/netsnmp-5.6.1.1/mibs/\
:userspace/snmpd/ WR-SWITCH-MIB::wrsPstatsTable
@end smallexample
Output is in text form and looks like:
@smallexample
SNMP table: WR-SWITCH-MIB::wrsPstatsTable
wrsPstatsPortName wrsPstatsTXUnderrun wrsPstatsRXOverrun wrsPstatsRXInvalidCode
wr0 0 0 0
wr1 0 0 0
wr2 0 0 0
wr3 0 0 0
wr4 0 0 0
wr5 0 0 0
wr6 0 0 0
wr7 0 0 0
wr8 0 0 0
wr9 0 0 0
wr10 0 0 0
wr11 0 0 0
wr12 0 0 0
wr13 0 0 0
wr14 0 0 0
wr15 0 0 0
wr16 0 0 0
wr17 0 0 0
SNMP table WR-SWITCH-MIB::wrsPstatsTable, part 2
wrsPstatsRXSyncLost wrsPstatsRXPauseFrames wrsPstatsRXPfilterDropped
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
(...)
@end smallexample
Unfortunately output due to the number of counters is very wide. Number of
characters per line can be limited by switch @t{Cw}, in example was set to 80.
@c ##########################################################################
@node Bugs and Troubleshooting
......
......@@ -8,9 +8,16 @@
# First, read dot-config to get the new location, if any.
dotconfig=/wr/etc/dot-config
tmpconfig=/tmp/dot-config
tmpdir=/tmp
if [ -f $dotconfig ]; then
. $dotconfig
echo "local" > "$tmpdir"/dot-config_proto
#assume that local config is always ok
echo "config_ok" > "$tmpdir"/dot-config_status
else
echo "no_config" > "$tmpdir"/dot-config_proto
echo "config_error" > "$tmpdir"/dot-config_status
fi
# Create /etc/resolv.conf, so we can use it. /etc is ramdisk anyways
......@@ -33,6 +40,11 @@ if [ -n "$CONFIG_DOTCONF_URL" ]; then
host=$(echo $URL | cut -d/ -f 3)
filename=$(echo $URL | cut -d/ -f 4-)
# save proto, host and filename of dot-config, to be used by SNMPd
echo "$proto" > "$tmpdir"/dot-config_proto
echo "$host" > "$tmpdir"/dot-config_host
echo "$filename" > "$tmpdir"/dot-config_filename
rm -f $tmpconfig
case $proto in
http|ftp)
......@@ -45,13 +57,20 @@ if [ -n "$CONFIG_DOTCONF_URL" ]; then
echo "Invalid URL for dot-config: \"$URL\"" >& 2
;;
esac
# If it exists, it is not empty or too small, and the checker is happy..
if [ -f $tmpconfig ] &&
[ $(cat $tmpconfig | wc -c) -gt 200 ] &&
/wr/bin/wrs_checkcfg $tmpconfig /wr/etc/Kconfig; then
echo "Using newly-downloaded dot-config from $URL"
# copy it in place to use the new file (unless it is identical)
cmp -s $tmpconfig $dotconfig || cp $tmpconfig $dotconfig
if [ -f $tmpconfig ]; then
# If it exists, it is not empty or too small, and the checker is happy
if [ $(cat $tmpconfig | wc -c) -gt 200 ] &&
/wr/bin/wrs_checkcfg $tmpconfig /wr/etc/Kconfig; then
echo "Using newly-downloaded dot-config from $URL"
# copy it in place to use the new file (unless it is identical)
cmp -s $tmpconfig $dotconfig || cp $tmpconfig $dotconfig
# info for SNMP that downloading was successful and checker is happy
echo "config_ok" > "$tmpdir"/dot-config_status
else
echo "check_error" > "$tmpdir"/dot-config_status
fi
else
echo "download_error" > "$tmpdir"/dot-config_status
fi
fi
......
......@@ -6,6 +6,18 @@
# Make sure the dropbearkey progam exists
[ -f /usr/bin/dropbearkey ] || exit 0
start_counter() {
# increase boot counter
COUNTER_FILE="/tmp/start_cnt_sshd"
START_COUNTER=1
if [ -f "$COUNTER_FILE" ];
then
read -r START_COUNTER < $COUNTER_FILE
START_COUNTER=$((START_COUNTER+1))
fi
echo "$START_COUNTER" > $COUNTER_FILE
}
start() {
echo -n "Starting dropbear sshd: "
# Make sure dropbear directory exists
......@@ -28,6 +40,7 @@ start() {
fi
umask 077
start-stop-daemon -S -q -p /var/run/dropbear.pid --exec /usr/sbin/dropbear
start_counter
echo "OK"
}
stop() {
......
#!/bin/sh
COUNTER_FILE="/tmp/start_cnt_syslogd"
start_counter() {
# increase boot counter
START_COUNTER=1
if [ -f "$COUNTER_FILE" ];
then
read -r START_COUNTER < $COUNTER_FILE
START_COUNTER=$((START_COUNTER+1))
fi
echo "$START_COUNTER" > $COUNTER_FILE
}
start() {
# Check the configuration file: if there's no target, don't run the thing.
if ! grep -q '^##.*remote-host' /etc/rsyslog.conf; then
echo -n "Starting rsyslog: "
/usr/sbin/rsyslogd
start_counter
echo "OK"
else
echo "Not starting rsyslog: no target host selected"
# avoid SNMPd complaints about lack of start counter file
echo "0" > $COUNTER_FILE
fi
}
......
......@@ -3,9 +3,22 @@
SNMP_PID=/var/run/snmpd.pid
SNMP_CONF=/wr/etc/snmpd.conf
start_counter() {
# increase boot counter
COUNTER_FILE="/tmp/start_cnt_snmpd"
START_COUNTER=1
if [ -f "$COUNTER_FILE" ];
then
read -r START_COUNTER < $COUNTER_FILE
START_COUNTER=$((START_COUNTER+1))
fi
echo "$START_COUNTER" > $COUNTER_FILE
}
start() {
# Log to syslog at daemon level. And log source address (-a)
snmpd -Lsd -p $SNMP_PID -a -c $SNMP_CONF
start_counter
}
stop() {
......
......@@ -13,11 +13,22 @@ if [ -n "$WRS_VERBOSE" ]; then
set -x
fi
# will be changed later if successful
echo "hwinfo_error" > /tmp/hwinfo_read_status
# This kernel has no hwinfo partition (strange...)
if ! grep -q hwinfo /proc/mtd; then exit 0; fi
if ! grep -q hwinfo /proc/mtd; then
# probably not an error, save script result for snmp
echo "hwinfo_warning" > /tmp/hwinfo_read_status
exit 0;
fi
# Is there sdb in there? If so, nothing to do.
if /wr/bin/sdb-read /dev/mtd5ro > /dev/null; then exit 0; fi
if /wr/bin/sdb-read /dev/mtd5ro > /dev/null; then
# save script result for snmp
echo "hwinfo_ok" > /tmp/hwinfo_read_status
exit 0;
fi
echo "Creating SDB filesystem in /dev/mtd5"
......@@ -47,3 +58,6 @@ test -c /dev/mtd5 || mknod /dev/mtd5 c 90 10
flash_erase /dev/mtd5 0 0
cat /tmp/sdb-for-dataflash > /dev/mtd5
rm /dev/mtd5
# save script result for snmp
echo "hwinfo_ok" > /tmp/hwinfo_read_status
......@@ -2,9 +2,23 @@
#
# Starts lighttpd daemon.
#
start_counter() {
# increase boot counter
COUNTER_FILE="/tmp/start_cnt_httpd"
START_COUNTER=1
if [ -f "$COUNTER_FILE" ];
then
read -r START_COUNTER < $COUNTER_FILE
START_COUNTER=$((START_COUNTER+1))
fi
echo "$START_COUNTER" > $COUNTER_FILE
}
start() {
echo -n "Starting lighttpd daemon: "
/usr/sbin/lighttpd -f /var/www/lighttpd.config
start_counter
echo "OK"
}
stop() {
......
......@@ -1282,7 +1282,8 @@ function safefilerewrite($dotconfig, $tmpdotconfig){
function apply_kconfig(){
$dotconfigapp = "/usr/wr/bin/apply_dot-config";
shell_exec($dotconfigapp. " > /dev/null 2>&1 &");
/* So far all changes via web-interface are on local file. Notify apply_dot-config that changes are on local file */
shell_exec($dotconfigapp. " local_config > /dev/null 2>&1 &");
}
......
......@@ -6,6 +6,9 @@
# require restarting running processes). The script is called at
# every boot by /etc/init.d/S20dot-config
# When called with "local_config" parameter, files with information about
# dotconfig source are removed (used by SNMP)
# We create a temporary file in /tmp, to avoid wearing flash if not
# needed. Then we replace the real file if different.
......@@ -18,6 +21,16 @@ copy_conf() {
done
}
#check if config is local
if [ "$1" == "local_config" ]; then
# remove source information in case previous config was received from
# network
rm /tmp/dot-config_*
echo "local" > /tmp/dot-config_proto
#assume that local config is always ok
echo "config_ok" > /tmp/dot-config_status
fi
# Check and complain, but we need to edit some files even if unconfigured.
if [ -f /wr/etc/dot-config ]; then
. /wr/etc/dot-config
......
#!/bin/ash
export WR_HOME="/wr"
LOAD_FPGA_STATUS_FILE="/tmp/load_fpga_status"
LOAD_LM32_STATUS_FILE="/tmp/load_lm32_status"
# Get parameter from kernel commandline
for arg in $(cat /proc/cmdline); do
......@@ -26,15 +28,33 @@ LM_FILE="$WR_HOME/lib/firmware/rt_cpu.elf"
if ! [ -f "$FP_FILE" ]; then
echo "Fatal: can't find \"$FP_FILE\"" >& 2
echo "load_file_not_found" > $LOAD_FPGA_STATUS_FILE
exit 1;
fi
if ! [ -f "$LM_FILE" ]; then
echo "Fatal: can't find \"$LM_FILE\"" >& 2
echo "load_file_not_found" > $LOAD_LM32_STATUS_FILE
exit 1;
fi
$WR_HOME/bin/load-virtex $FP_FILE
if [ $? -eq 0 ];
then
echo "load_ok" > $LOAD_FPGA_STATUS_FILE
else
echo "Fatal: load FPGA failed" >& 2
echo "load_error" > $LOAD_FPGA_STATUS_FILE
fi
$WR_HOME/bin/load-lm32 $LM_FILE scb_ver=${scb_ver}
if [ $? -eq 0 ];
then
echo "load_ok" > $LOAD_LM32_STATUS_FILE
else
echo "Fatal: load LM32 failed" >& 2
echo "load_error" > $LOAD_LM32_STATUS_FILE
fi
insmod $WR_HOME/lib/modules/at91_softpwm.ko
insmod $WR_HOME/lib/modules/wr_vic.ko
insmod $WR_HOME/lib/modules/wr-nic.ko macaddr=$val
......
......@@ -24,7 +24,26 @@ CFLAGS += -I../include -I../libwr/include -I../ppsi/include -I../ppsi/arch-wrs/i
CFLAGS += -DWRS_WITH_SNMP_HACKISH_LOG=0
SHLIB = wrsSnmp.so
SOURCES = init.c wrsScalar.c wrsPstats.c wrsPpsi.c wrsVersion.c wrsDate.c shmem.c
SOURCES = \
shmem.c \
dot-config.c \
snmp_shmem.c \
snmp_mmap.c \
wrsScalar.c \
wrsGeneralStatusGroup.c \
wrsOSStatusGroup.c \
wrsNetworkingStatusGroup.c \
wrsVersionGroup.c \
wrsCurrentTimeGroup.c \
wrsBootStatusGroup.c \
wrsTemperatureGroup.c \
wrsStartCntGroup.c \
wrsSpllStatusGroup.c \
wrsPstatsTable.c \
wrsPtpDataTable.c \
wrsPortStatusTable.c \
init.c \
OBJECTS = $(SOURCES:.c=.o)
all: $(SHLIB)
......
WR-SWITCH-MIB DEFINITIONS ::= BEGIN
-- This is blatantly copied from NET-SNMP-TUTORIAL-MIB.txt and IF-MIB.txt
-- URL: http://www.net-snmp.org/tutorial/tutorial-5/
-- toolkit/mib_module/NET-SNMP-TUTORIAL-MIB.txt
-- Bugs and swearing by Alessandro Rubini
-- Original MIB, Bugs and swearing by Alessandro Rubini
-- MIB rewritten by Adam Wujek, BE-CO-HT, CERN
-- During development all unused/not implemented objects are comented out
-- to avoid later changes
-- IMPORTS: Include definitions from other mibs here
IMPORTS
OBJECT-TYPE, Integer32, Counter32, Counter64,
OBJECT-TYPE, Integer32, Unsigned32, Counter32, Counter64,
MODULE-IDENTITY, enterprises FROM SNMPv2-SMI
DisplayString FROM SNMPv2-TC;
CERN OBJECT IDENTIFIER ::= { enterprises 96 }
-- A brief description and update information about this mib.
-- (I follow the CamelCase to be sure I don't mistype. Who knows the rules...
wrSwitchMIB MODULE-IDENTITY
LAST-UPDATED "201502231000Z"
LAST-UPDATED "201503191600Z"
ORGANIZATION "CERN"
CONTACT-INFO "postal: BE-CO-HT, CERN, Geneva
email: ht-drivers@cern.ch
"
DESCRIPTION "White Rabbit Switch internal details
"
::= { CERN 100 }
::= { cern 100 }
cern OBJECT IDENTIFIER ::= { enterprises 96 }
-- Define typical mib nodes
-- we'll prefix everything in this mib with wrs (White Rabbit Switch)
wrsScalar OBJECT IDENTIFIER ::= { wrSwitchMIB 1 }
wrsPstatsTable OBJECT IDENTIFIER ::= { wrSwitchMIB 2 }
wrsPpsi OBJECT IDENTIFIER ::= { wrSwitchMIB 3 } -- going to be obsolete
wrsVersion OBJECT IDENTIFIER ::= { wrSwitchMIB 4 }
wrsDate OBJECT IDENTIFIER ::= { wrSwitchMIB 5 }
--wrsPstatsTable OBJECT IDENTIFIER ::= { wrSwitchMIB 2 } == obsolete
--wrsPpsi OBJECT IDENTIFIER ::= { wrSwitchMIB 3 } == obsolete
--wrsVersion OBJECT IDENTIFIER ::= { wrSwitchMIB 4 } == obsolete
--wrsDate OBJECT IDENTIFIER ::= { wrSwitchMIB 5 } == obsolete
wrsStatus OBJECT IDENTIFIER ::= { wrSwitchMIB 6 }
wrsExpertStatus OBJECT IDENTIFIER ::= { wrSwitchMIB 7 }
-- define one stupid object for a start
wrsScalarOne OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Integer incremented at every GET"
::= { wrsScalar 1 }
-- wrsGeneralStatusGroup (.6.1)
wrsGeneralStatusGroup OBJECT IDENTIFIER ::= { wrsStatus 1 }
wrsMainSystemStatus OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
warning(3),
warningNA(4),
bug(5)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Grouped status of WRS switch
ok - values in wrsGeneralStatusGroup are correct
error - there is an error in wrsGeneralStatusGroup
warning - there is a warning in wrsGeneralStatusGroup
warningNA - there is N/A field in wrsGeneralStatusGroup
bug - bug in checking conditions of wrsGeneralStatusGroup, please report"
::= { wrsGeneralStatusGroup 1 }
wrsOSStatus OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
warning(3),
warningNA(4),
bug(5)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Grouped status of wrsOSStatusGroup
ok - values in wrsOSStatusGroup are correct
error - there is an error in wrsOSStatusGroup
warning - there is a warning in wrsOSStatusGroup
warningNA - there is N/A field in wrsOSStatusGroup
bug - bug in checking conditions of wrsOSStatusGroup, please report"
::= { wrsGeneralStatusGroup 2 }
wrsNetworkingStatus OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
warning(3),
warningNA(4),
bug(5)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Grouped status of wrsNetworkingStatusGroup
ok - values in wrsNetworkingStatusGroup are correct
error - there is an error in wrsNetworkingStatusGroup
warning - there is a warning in wrsNetworkingStatusGroup
warningNA - there is N/A field in wrsNetworkingStatusGroup
bug - bug in checking conditions of wrsNetworkingStatusGroup, please report"
::= { wrsGeneralStatusGroup 4 }
wrsDetailedStatusesGroup OBJECT IDENTIFIER ::= { wrsStatus 2 }
-- wrsOSStatusGroup (.6.2.1)
wrsOSStatusGroup OBJECT IDENTIFIER ::= { wrsDetailedStatusesGroup 1 }
wrsBootSuccessful OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
warning(3),
warningNA(4),
bug(5)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Grouped status of wrsBootStatusGroup
ok - values in wrsBootStatusGroup are correct
error - there is an error in wrsBootStatusGroup
warning - there is a warning in wrsBootStatusGroup
warningNA - there is N/A field in wrsBootStatusGroup
bug - bug in checking conditions of wrsBootStatusGroup, please report"
::= { wrsOSStatusGroup 1 }
wrsTemperatureWarning OBJECT-TYPE
SYNTAX INTEGER {
na(0),
thresholdNotSet(1),
temperatureOK(2),
temperatureTooHigh(3)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Warning if temperature exceed threshold levels"
::= { wrsOSStatusGroup 2 }
--wrsTimingStatusGroup OBJECT IDENTIFIER ::= { wrsDetailedStatusesGroup 2 }
-- wrsNetworkingStatusGroup (.6.1.3)
wrsNetworkingStatusGroup OBJECT IDENTIFIER ::= { wrsDetailedStatusesGroup 3 }
wrsSFPsStatus OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
warning(3),
warningNA(4),
bug(5)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Grouped status of SFPs
ok - all SFPs are ok
error - there is an error in SFP
warning - there is a warning in SFP (not used)
warningNA - there is N/A field in SFP
bug - bug in checking conditions of SFPs, please report"
::= { wrsNetworkingStatusGroup 1 }
wrsEndpointStatus OBJECT-TYPE
SYNTAX INTEGER {
na(0),
firstRead(1),
ok(2),
error(3)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Check itmes described in 2.2.2 Fault in the Endpoint's transmission/reception
path in wrs_failures document.
firstRead - cannot derermine change rate from olny one read
ok - parameters below limits
error - parameters above limits"
::= { wrsNetworkingStatusGroup 2 }
wrsSwcoreStatus OBJECT-TYPE
SYNTAX INTEGER {
na(0),
firstRead(1),
ok(2),
error(3)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Check itmes described in 2.2.3 Problem with the SwCore or Endpoint HDL
module and 2.2.5 Too much HP traffic / Per-priority queue full
in wrs_failures document.
firstRead - cannot derermine change rate from olny one read
ok - parameters below limits
error - parameters above limits"
::= { wrsNetworkingStatusGroup 3 }
wrsRTUStatus OBJECT-TYPE
SYNTAX INTEGER {
na(0),
firstRead(1),
ok(2),
error(3)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Check itmes described in 2.2.4 RTU is full and cannot accept more requests
in wrs_failures document.
firstRead - cannot derermine change rate from olny one read
ok - parameters below limits
error - parameters above limits"
::= { wrsNetworkingStatusGroup 4 }
-- wrsVersionGroup (.6.3)
wrsVersionGroup OBJECT IDENTIFIER ::= { wrsStatus 3 }
wrsVersionSwVersion OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The software version, as returned from 'git describe' at build time"
::= { wrsVersionGroup 1 }
wrsVersionSwBuildBy OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The software build by, as returned from 'git config --get-all user.name' at build time"
::= { wrsVersionGroup 2 }
wrsVersionSwBuildDate OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The build date of the software, '__DATE__' at build time"
::= { wrsVersionGroup 3 }
wrsVersionBackplaneVersion OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The hardware version of minibackplane PCB"
::= { wrsVersionGroup 4 }
wrsVersionFpgaType OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The hardware version of FPGA"
::= { wrsVersionGroup 5 }
wrsVersionManufacturer OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The name of the manufacturing company of a switch"
::= { wrsVersionGroup 6 }
wrsVersionSwitchSerialNumber OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The serial number (or string) of the switch"
::= { wrsVersionGroup 7 }
wrsVersionScbVersion OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The version of the SCB (switch's motherboard)"
::= { wrsVersionGroup 8 }
wrsVersionGwVersion OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The version of gateware (FPGA bitstream)"
::= { wrsVersionGroup 9 }
wrsVersionGwBuild OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The build of gateware (FPGA bitstream)"
::= { wrsVersionGroup 10 }
wrsVersionSwitchHdlCommitId OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The gateware version: commit of wr_switch_hdl"
::= { wrsVersionGroup 11 }
wrsVersionGeneralCoresCommitId OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The gateware version: commit of general-cores"
::= { wrsVersionGroup 12 }
wrsVersionWrCoresCommitId OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The gateware version: commit of wr-cores"
::= { wrsVersionGroup 13 }
wrsOperationStatus OBJECT IDENTIFIER ::= { wrsExpertStatus 1 }
-- wrsCurrentTimeGroup (.7.1.1)
wrsCurrentTimeGroup OBJECT IDENTIFIER ::= { wrsOperationStatus 1 }
wrsDateTAI OBJECT-TYPE
SYNTAX Counter64 -- actually integer, but it is unsigned so ok
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The current time, in TAI seconds"
::= { wrsCurrentTimeGroup 1 }
wrsDateTAIString OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The current TAI time, printed as %y-%m-%d-%H:%M:%S (no time zone)"
::= { wrsCurrentTimeGroup 2 }
--wrsBootStatusGroup (.7.1.2)
wrsBootStatusGroup OBJECT IDENTIFIER ::= { wrsOperationStatus 2 }
wrsBootCnt OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of switch's boots since power-on"
::= { wrsBootStatusGroup 1 }
wrsRebootCnt OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of soft reboots. This is incremented by the
reboot system call. A healthy system should feature one
soft-reboot less than total boots."
::= { wrsBootStatusGroup 2 }
wrsRestartReason OBJECT-TYPE
SYNTAX INTEGER {
na(0),
error(1),
generalReset(2),
wakeUpReset(3),
watchdogReset(4),
softwareReset(5),
userReset(6)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Reason of last switch restart.
error(1) - unable to read restart reason or reset counters
generalReset(2) - Both VDDCORE and VDDBU rising (power-on)
wakeUpReset(3) - VDDCORE rising
watchdogReset(4) - Watchdog fault occurred
softwareReset(5) - Processor reset required by the software (system reboot)
userReset(6) - NRST pin detected low (reset button)"
::= { wrsBootStatusGroup 3 }
wrsFaultIP OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(4))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The fault address of the last panic. This is the instruction
pointer normally printed by the stack backtrace. The register
is zeroed at first boot and only modified within panic."
::= { wrsBootStatusGroup 4 }
wrsFaultLR OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(4))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The link register register at last panic.
This is usually the caller of the function that failed,
but it may be a local register if the failing function
saved lr to the stack and used it as a scratch register."
::= { wrsBootStatusGroup 5 }
wrsConfigSource OBJECT-TYPE
SYNTAX INTEGER {
na(0),
error(1),
errorMinor(2),
local(3),
tftp(4),
http(5),
ftp(6)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Source of used dotconfig, protocol if gonfig was received from network
errorMinor - cannot read status file, problem is probably somewhere else"
::= { wrsBootStatusGroup 6 }
wrsConfigSourceHost OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..64))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Server address which provided dotconfig"
::= { wrsBootStatusGroup 7 }
wrsConfigSourceFilename OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..128))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Path and filename of dotconfig file on server"
::= { wrsBootStatusGroup 8 }
wrsBootConfigStatus OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
downloadError(3),
checkError(4),
errorMinor(5)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Result of loading or downloading dot-config file
downloadError - unable to download file from given source
checkError - config file is not valid or too short (less than 200 characters).
errorMinor - cannot read status file, problem is probably somewhere else"
::= { wrsBootStatusGroup 9 }
wrsBootHwinfoReadout OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
errorMinor(3),
warning(4)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Result of hwinfo readout
error - hwinfo readout failed
errorMinor - cannot read status file, problem is probably somewhere else
warning - no hwinfo partition"
::= { wrsBootStatusGroup 10 }
wrsBootLoadFPGA OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
errorMinor(3),
fileNotFound(4)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Result of loading FPGA
error - loading failed
errorMinor - cannot read status file, problem is probably somewhere else
fileNotFound - file to be loaded not found"
::= { wrsBootStatusGroup 11 }
wrsBootLoadLM32 OBJECT-TYPE
SYNTAX INTEGER {
na(0),
ok(1),
error(2),
errorMinor(3),
fileNotFound(4)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Result of loading LM32
error - loading failed
errorMinor - cannot read status file, problem is probably somewhere else
fileNotFound - file to be loaded not found"
::= { wrsBootStatusGroup 12 }
wrsBootKernelModulesMissing OBJECT-TYPE
SYNTAX INTEGER {
allKernelModulesPresent(0)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Checking if all desired kernel modules are loaded.
allKernelModulesPresent - all modules loaded
other numbers represent number of modules not loaded
other errors (like unable to open /proc/modules) are reported as maximum number of missing modules"
::= { wrsBootStatusGroup 13 }
wrsBootUserspaceDaemonsMissing OBJECT-TYPE
SYNTAX INTEGER {
allDeamonsPresent(0)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Checking if all desired deamons are running.
allDeamonsPresent - all deamons running
other numbers represent number of deamons not running
other errors (can be: unable to run ps command or problem with multiple process instances)
are reported as maximum number of missing modules"
::= { wrsBootStatusGroup 14 }
-- wrsTemperatureGroup (.7.1.3)
wrsTemperatureGroup OBJECT IDENTIFIER ::= { wrsOperationStatus 3 }
wrsTempFPGA OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"FPGA temperature"
::= { wrsTemperatureGroup 1 }
wrsTempPLL OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"PLL temperature"
::= { wrsTemperatureGroup 2 }
wrsTempPSL OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Power Supply Left (PSL) temperature"
::= { wrsTemperatureGroup 3 }
wrsTempPSR OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Power Supply Right (PSR) temperature"
::= { wrsTemperatureGroup 4 }
wrsTempThresholdFPGA OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Threshold level for FPGA temperature"
::= { wrsTemperatureGroup 5 }
wrsTempThresholdPLL OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Threshold level for PLL temperature"
::= { wrsTemperatureGroup 6 }
wrsTempThresholdPSL OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Threshold level for Power Supply Left (PSL) temperature"
::= { wrsTemperatureGroup 7 }
wrsTempThresholdPSR OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Threshold level for Power Supply Right (PSR) temperature"
::= { wrsTemperatureGroup 8 }
wrsStartCntGroup OBJECT IDENTIFIER ::= { wrsExpertStatus 2 }
-- wrsStartCntGroup (.7.2)
wrsStartCntHAL OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of HAL deamon starts"
::= { wrsStartCntGroup 1 }
wrsStartCntPPSI OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of PPSI deamon starts"
::= { wrsStartCntGroup 2 }
wrsStartCntRTUd OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of RTU deamon starts"
::= { wrsStartCntGroup 3 }
wrsStartCntSshd OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Nmber of SSH deamon starts"
::= { wrsStartCntGroup 4 }
wrsStartCntHttpd OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Nmber of HTTP deamon starts"
::= { wrsStartCntGroup 5 }
wrsStartCntSnmpd OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Nmber of SNMP deamon starts"
::= { wrsStartCntGroup 6 }
wrsStartCntSyslogd OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Nmber of SYSLOG deamon starts"
::= { wrsStartCntGroup 7 }
wrsSpllState OBJECT IDENTIFIER ::= { wrsExpertStatus 3 }
-- wrsSpllStatusGroup (.7.3.2)
wrsSpllStatusGroup OBJECT IDENTIFIER ::= { wrsSpllState 2 }
wrsSpllMode OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Mode of Soft PLL"
::= { wrsSpllStatusGroup 1 }
wrsSpllIrqCnt OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of interrupts in Soft PLL"
::= { wrsSpllStatusGroup 2 }
wrsSpllSeqState OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Sequence state of Soft PLL"
::= { wrsSpllStatusGroup 3 }
wrsSpllAlignState OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Align state of Soft PLL"
::= { wrsSpllStatusGroup 4 }
wrsSpllHlock OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"HLock in Soft PLL"
::= { wrsSpllStatusGroup 5 }
wrsSpllMlock OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"MLock at Soft PLL"
::= { wrsSpllStatusGroup 6 }
wrsSpllHY OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"H_y at Soft PLL"
::= { wrsSpllStatusGroup 7 }
wrsSpllMY OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"M_y at Soft PLL"
::= { wrsSpllStatusGroup 8 }
wrsSpllDelCnt OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Del counter at Soft PLL"
::= { wrsSpllStatusGroup 9 }
-- wrsPstatsTable (.7.1.4)
wrsPstatsTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrsPstatsEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Information for each ptp servo"
::= { wrsExpertStatus 4 }
wrsPstatsEntry OBJECT-TYPE
SYNTAX WrsPstatsEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry containing ptp servo statuses"
INDEX { wrsPstatsIndex }
::= { wrsPstatsTable 1 }
WrsPstatsEntry ::=
SEQUENCE {
wrsPstatsIndex Unsigned32,
wrsPstatsPortName DisplayString,
wrsPstatsTXUnderrun Counter32,
wrsPstatsRXOverrun Counter32,
wrsPstatsRXInvalidCode Counter32,
wrsPstatsRXSyncLost Counter32,
wrsPstatsRXPauseFrames Counter32,
wrsPstatsRXPfilterDropped Counter32,
wrsPstatsRXPCSErrors Counter32,
wrsPstatsRXGiantFrames Counter32,
wrsPstatsRXRuntFrames Counter32,
wrsPstatsRXCRCErrors Counter32,
wrsPstatsRXPclass0 Counter32,
wrsPstatsRXPclass1 Counter32,
wrsPstatsRXPclass2 Counter32,
wrsPstatsRXPclass3 Counter32,
wrsPstatsRXPclass4 Counter32,
wrsPstatsRXPclass5 Counter32,
wrsPstatsRXPclass6 Counter32,
wrsPstatsRXPclass7 Counter32,
wrsPstatsTXFrames Counter32,
wrsPstatsRXFrames Counter32,
wrsPstatsRXDropRTUFull Counter32,
wrsPstatsRXPrio0 Counter32,
wrsPstatsRXPrio1 Counter32,
wrsPstatsRXPrio2 Counter32,
wrsPstatsRXPrio3 Counter32,
wrsPstatsRXPrio4 Counter32,
wrsPstatsRXPrio5 Counter32,
wrsPstatsRXPrio6 Counter32,
wrsPstatsRXPrio7 Counter32,
wrsPstatsRTUValid Counter32,
wrsPstatsRTUResponses Counter32,
wrsPstatsRTUDropped Counter32,
wrsPstatsFastMatchPriority Counter32,
wrsPstatsFastMatchFastForward Counter32,
wrsPstatsFastMatchNonForward Counter32,
wrsPstatsFastMatchRespValid Counter32,
wrsPstatsFullMatchRespValid Counter32,
wrsPstatsForwarded Counter32,
wrsPstatsTRURespValid Counter32
}
wrsPstatsIndex OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Index for wrsPstatsTable"
::= { wrsPstatsEntry 1 }
wrsPstatsPortName OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..12))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Port name of port"
::= { wrsPstatsEntry 2 }
wrsPstatsTXUnderrun OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of TX underrun errors"
::= { wrsPstatsEntry 3 }
wrsPstatsRXOverrun OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of RX overrun errors"
::= { wrsPstatsEntry 4 }
wrsPstatsRXInvalidCode OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received invalid 8B10B code errors"
::= { wrsPstatsEntry 5 }
wrsPstatsRXSyncLost OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of RX link synchronization lost"
::= { wrsPstatsEntry 6 }
wrsPstatsRXPauseFrames OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received pause frames"
::= { wrsPstatsEntry 7 }
wrsPstatsRXPfilterDropped OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received frames dropped at pfilter"
::= { wrsPstatsEntry 8 }
wrsPstatsRXPCSErrors OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of errors occured during frame reception in PCS"
::= { wrsPstatsEntry 9 }
wrsPstatsRXGiantFrames OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received giant frames
(bigger than Maximum Receive Unit)"
::= { wrsPstatsEntry 10 }
wrsPstatsRXRuntFrames OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received runt frames
(smaller than 64bytes)"
::= { wrsPstatsEntry 11 }
wrsPstatsRXCRCErrors OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of RX CRC errors"
::= { wrsPstatsEntry 12 }
wrsPstatsRXPclass0 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received frames assigned to
class 0 by packet filter in endpoint"
::= { wrsPstatsEntry 13 }
wrsPstatsRXPclass1 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received frames assigned to
class 1 by packet filter in endpoint"
::= { wrsPstatsEntry 14 }
wrsPstatsRXPclass2 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received frames assigned to
class 2 by packet filter in endpoint"
::= { wrsPstatsEntry 15 }
wrsPstatsRXPclass3 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received frames assigned to
class 3 by packet filter in endpoint"
::= { wrsPstatsEntry 16 }
wrsPstatsRXPclass4 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received frames assigned to
class 4 by packet filter in endpoint"
::= { wrsPstatsEntry 17 }
wrsPstatsRXPclass5 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received frames assigned to
class 5 by packet filter in endpoint"
::= { wrsPstatsEntry 18 }
-- define one stupid object for a start
wrsPstatsRXPclass6 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of received frames assigned to
class 6 by packet filter in endpoint"
::= { wrsPstatsEntry 19 }
wrsScalarOne OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
wrsPstatsRXPclass7 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Just an integer"
::= { wrsScalar 1 }
"Number of received frames assigned to
class 7 by packet filter in endpoint"
::= { wrsPstatsEntry 20 }
-- This pstats stuff is copied, in a way, from the ifTable stuff (IF-MIB.txt)
-- We have the ports as columns, so they are a fixed number. And the
-- counters as lines. This allows to change counters following gateware.
-- even if it is not standard practice. Otherwise, we'd need to rewrite
-- code every time (I *hate* this obsolete crap: code generators should not
-- be like that).
wrsPstatsTXFrames OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of transmitted frames"
::= { wrsPstatsEntry 21 }
wrsPstatsTable OBJECT-TYPE
SYNTAX SEQUENCE OF pstatsEntry
MAX-ACCESS not-accessible
STATUS current
wrsPstatsRXFrames OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"A list of pstat counters. One column per interface.
The number of entries is given by the value of pstatsNumber."
::= { wrSwitchMIB 2 }
"Number of received frames"
::= { wrsPstatsEntry 22 }
pstatsEntry OBJECT-TYPE
SYNTAX PstatsEntry
MAX-ACCESS not-accessible
STATUS current
wrsPstatsRXDropRTUFull OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"An entry containing a pstat name and values for all WR ports."
INDEX { pstatsIndex }
::= { wrsPstatsTable 1 }
"Number of RX frames dropped due to RTU full"
::= { wrsPstatsEntry 23 }
PstatsEntry ::=
SEQUENCE {
pstatsDescr DisplayString,
pstatsWR0 Counter32,
pstatsWR1 Counter32,
pstatsWR2 Counter32,
pstatsWR3 Counter32,
pstatsWR4 Counter32,
pstatsWR5 Counter32,
pstatsWR6 Counter32,
pstatsWR7 Counter32,
pstatsWR8 Counter32,
pstatsWR9 Counter32,
pstatsWR10 Counter32,
pstatsWR11 Counter32,
pstatsWR12 Counter32,
pstatsWR13 Counter32,
pstatsWR14 Counter32,
pstatsWR15 Counter32,
pstatsWR16 Counter32,
pstatsWR17 Counter32
}
wrsPstatsRXPrio0 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of RX frames at internal priority 0"
::= { wrsPstatsEntry 24 }
pstatsDescr OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
wrsPstatsRXPrio1 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"A textual string describing this counter"
::= { pstatsEntry 1 }
"Number of RX frames at internal priority 1"
::= { wrsPstatsEntry 25 }
pstatsWR0 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRXPrio2 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr0."
::= {pstatsEntry 2 }
"Number of RX frames at internal priority 2"
::= { wrsPstatsEntry 26 }
pstatsWR1 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRXPrio3 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr1."
::= {pstatsEntry 3 }
"Number of RX frames at internal priority 3"
::= { wrsPstatsEntry 27 }
pstatsWR2 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRXPrio4 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr2."
::= {pstatsEntry 4 }
"Number of RX frames at internal priority 4"
::= { wrsPstatsEntry 28 }
pstatsWR3 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRXPrio5 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr3."
::= {pstatsEntry 5 }
"Number of RX frames at internal priority 5"
::= { wrsPstatsEntry 29 }
pstatsWR4 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRXPrio6 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr4."
::= {pstatsEntry 6 }
"Number of RX frames at internal priority 6"
::= { wrsPstatsEntry 30 }
pstatsWR5 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRXPrio7 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr5."
::= {pstatsEntry 7 }
"Number of RX frames at internal priority 7"
::= { wrsPstatsEntry 31 }
pstatsWR6 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRTUValid OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr6."
::= {pstatsEntry 8 }
"Number of valid RTU requests"
::= { wrsPstatsEntry 32 }
pstatsWR7 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRTUResponses OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr7."
::= {pstatsEntry 9 }
"Number of valid RTU responses"
::= { wrsPstatsEntry 33 }
pstatsWR8 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsRTUDropped OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr8."
::= {pstatsEntry 10 }
"Number of frames dropped at RTU"
::= { wrsPstatsEntry 34 }
pstatsWR9 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsFastMatchPriority OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr9."
::= {pstatsEntry 11 }
"Number of priority frames matched by fast match"
::= { wrsPstatsEntry 35 }
pstatsWR10 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsFastMatchFastForward OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr10."
::= {pstatsEntry 12 }
"Number of forwarded frames matched by fast match"
::= { wrsPstatsEntry 36 }
pstatsWR11 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsFastMatchNonForward OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr11."
::= {pstatsEntry 13 }
"Number of not forwarded frames matched by fast match"
::= { wrsPstatsEntry 37 }
pstatsWR12 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsFastMatchRespValid OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr12."
::= {pstatsEntry 14 }
"Number of fast match decisions"
::= { wrsPstatsEntry 38 }
pstatsWR13 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsFullMatchRespValid OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr13."
::= {pstatsEntry 15 }
"Number of full match decisions"
::= { wrsPstatsEntry 39 }
pstatsWR14 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsForwarded OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr14."
::= {pstatsEntry 16 }
"Number of forwarded frames"
::= { wrsPstatsEntry 40 }
pstatsWR15 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
wrsPstatsTRURespValid OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The value of this counter for interface wr15."
::= {pstatsEntry 17 }
"Number of TRU decisions"
::= { wrsPstatsEntry 41 }
pstatsWR16 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
-- wrsPtpDataTable (.7.1.5)
wrsPtpDataTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrsPtpDataEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The value of this counter for interface wr16."
::= {pstatsEntry 18 }
"Information for each ptp servo"
::= { wrsExpertStatus 5 }
pstatsWR17 OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
wrsPtpDataEntry OBJECT-TYPE
SYNTAX WrsPtpDataEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The value of this counter for interface wr17."
::= {pstatsEntry 19 }
"An entry containing ptp servo statuses"
INDEX { wrsPtpDataIndex }
::= { wrsPtpDataTable 1 }
--following objects will be moved
wrsPpsiGlobalsX OBJECT IDENTIFIER ::= { wrsPpsi 3 }
wrsPortsTableX OBJECT IDENTIFIER ::= { wrsPpsi 4 }
wrsTemperatureX OBJECT IDENTIFIER ::= { wrsPpsi 5 }
WrsPtpDataEntry ::=
SEQUENCE {
wrsPtpDataIndex Unsigned32,
wrsPtpPortName DisplayString,
wrsPtpGrandmasterID OCTET STRING,
wrsPtpOwnID OCTET STRING,
wrsPtpMode INTEGER,
wrsPtpServoState DisplayString,
wrsPtpServoStateN INTEGER,
wrsPtpPhaseTracking INTEGER,
wrsPtpSyncSource DisplayString,
wrsPtpClockOffsetPs Counter64,
wrsPtpClockOffsetPsHR Integer32,
wrsPtpSkew Integer32,
wrsPtpRTT Counter64,
wrsPtpLinkLength Unsigned32,
wrsPtpServoUpdates Counter32,
wrsPtpDeltaTxM Integer32,
wrsPtpDeltaRxM Integer32,
wrsPtpDeltaTxS Integer32,
wrsPtpDeltaRxS Integer32
}
-- The Wr/PTP/Ppsi information is two items: an array of scalars
-- and a table. In the table, the "channel" name is the row. But
-- the index is integer, following what ppsi does internally
wrsPtpDataIndex OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Index for wrsPtpDataTable"
::= { wrsPtpDataEntry 1 }
-- globals (.3)
wrsPtpPortName OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..12))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Port name on which servo instance is running"
::= { wrsPtpDataEntry 2 }
ptpGrandmasterIDX OBJECT-TYPE
wrsPtpGrandmasterID OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(8))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The ClockID of the current grandmaster"
::= { wrsPpsiGlobalsX 1 }
::= { wrsPtpDataEntry 3 }
ptpOwnIDX OBJECT-TYPE
wrsPtpOwnID OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(8))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The ClockID of this WR device"
::= { wrsPpsiGlobalsX 2 }
::= { wrsPtpDataEntry 4 }
ptpModeX OBJECT-TYPE
wrsPtpMode OBJECT-TYPE
SYNTAX INTEGER {
unknown(0), -- same as WRC_MODE macros
grandmaster(1),
......@@ -282,167 +1238,185 @@ ptpModeX OBJECT-TYPE
STATUS current
DESCRIPTION
"The mode of this clock"
::= { wrsPpsiGlobalsX 3 }
ptpServoStateX OBJECT-TYPE
::= { wrsPtpDataEntry 5 }
wrsPtpServoState OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The servo state if slave"
::= { wrsPpsiGlobalsX 4 }
::= { wrsPtpDataEntry 6 }
ptpServoStateNX OBJECT-TYPE
wrsPtpServoStateN OBJECT-TYPE
SYNTAX INTEGER {
Uninitialized(0),
SYNC-NSEC(1), -- no idea how to keep "_" instead of "-"
SYNC-SEC(2),
SYNC-PHASE(3),
TRACK-PHASE(4),
WAIT-SYNC-IDLE(5),
WAIT-OFFSET-STABLE(6)
uninitialized(0),
syncNsec(1),
syncSec(2),
syncPhase(3),
trackPhase(4),
waitSyncIdle(5),
waitOffsetStable(6)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Numeric representation of servo state"
::= { wrsPpsiGlobalsX 5 }
::= { wrsPtpDataEntry 7 }
ptpPhaseTrackingX OBJECT-TYPE
wrsPtpPhaseTracking OBJECT-TYPE
SYNTAX INTEGER {
NA(0),
not-tracking(1),
na(0),
notTracking(1),
tracking(2)
}
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether phase tracking is enabled in the servo"
::= { wrsPpsiGlobalsX 6 }
::= { wrsPtpDataEntry 8 }
ptpSyncSourceX OBJECT-TYPE
wrsPtpSyncSource OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The port name that is currently the synchronization source"
::= { wrsPpsiGlobalsX 7 }
::= { wrsPtpDataEntry 9 }
ptpClockOffsetPsX OBJECT-TYPE
SYNTAX Counter64 -- should be integer64 (signed)
wrsPtpClockOffsetPs OBJECT-TYPE
SYNTAX Counter64 -- integer64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Current clock offset from master, in picoseconds"
::= { wrsPpsiGlobalsX 8 }
::= { wrsPtpDataEntry 10 }
ptpClockOffsetPsHRX OBJECT-TYPE
SYNTAX INTEGER
wrsPtpClockOffsetPsHR OBJECT-TYPE
SYNTAX Integer32 -- should be something like gauge32, but with int range
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Human Readable current clock offset from master, in picoseconds with saturation to integer"
::= { wrsPpsiGlobalsX 9 }
::= { wrsPtpDataEntry 11 }
ptpSkewX OBJECT-TYPE
SYNTAX INTEGER
wrsPtpSkew OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The estimated change of master-to-slave delay, in picoseconds"
::= { wrsPpsiGlobalsX 10 }
::= { wrsPtpDataEntry 12 }
ptpRTTX OBJECT-TYPE
SYNTAX Counter64 -- does unsigned64 exits?
wrsPtpRTT OBJECT-TYPE
SYNTAX Counter64 -- unsigned64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The round-trip-time, from master, in picoseconds"
::= { wrsPpsiGlobalsX 11 }
::= { wrsPtpDataEntry 13 }
ptpLinkLengthX OBJECT-TYPE
wrsPtpLinkLength OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Estimated fiber length, from master-to-slave delay, in meters"
::= { wrsPpsiGlobalsX 12 }
::= { wrsPtpDataEntry 14 }
ptpServoUpdatesX OBJECT-TYPE
SYNTAX Unsigned32
wrsPtpServoUpdates OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"How many time did the servo run"
::= { wrsPpsiGlobalsX 13 }
::= { wrsPtpDataEntry 15 }
ptpDeltaTxMX OBJECT-TYPE
SYNTAX INTEGER
wrsPtpDeltaTxM OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Fixed Tx latency on Master side"
::= { wrsPpsiGlobalsX 14 }
::= { wrsPtpDataEntry 16 }
ptpDeltaRxMX OBJECT-TYPE
SYNTAX INTEGER
wrsPtpDeltaRxM OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Fixed Rx latency on Master side"
::= { wrsPpsiGlobalsX 15 }
::= { wrsPtpDataEntry 17 }
ptpDeltaTxSX OBJECT-TYPE
SYNTAX INTEGER
wrsPtpDeltaTxS OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Fixed Tx latency on Slave side"
::= { wrsPpsiGlobalsX 16 }
::= { wrsPtpDataEntry 18 }
ptpDeltaRxSX OBJECT-TYPE
SYNTAX INTEGER
wrsPtpDeltaRxS OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Fixed Rx latency on Slave side"
::= { wrsPpsiGlobalsX 17 }
::= { wrsPtpDataEntry 19 }
-- per-port (.4)
wrsPortsTableX OBJECT-TYPE
SYNTAX SEQUENCE OF wrsPortsEntryX
-- per-port (.7.1.6)
wrsPortStatusTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrsPortStatusEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Information for each port"
::= { wrsPpsi 4 }
::= { wrsExpertStatus 6 }
wrsPortsEntryX OBJECT-TYPE
SYNTAX WrsPortsEntryX
wrsPortStatusEntry OBJECT-TYPE
SYNTAX WrsPortStatusEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry containing ports statuses"
INDEX { wrsPortIndex }
::= { wrsPortsTableX 1 }
INDEX { wrsPortStatusIndex }
::= { wrsPortStatusTable 1 }
WrsPortsEntryX ::=
WrsPortStatusEntry ::=
SEQUENCE {
portLink INTEGER,
portMode INTEGER,
portLocked INTEGER,
portPeer OCTET STRING,
portSfpVN DisplayString,
portSfpPN DisplayString,
portSfpVS DisplayString,
portSfpInDB INTEGER,
portSfpGbE INTEGER,
portSfpError INTEGER
wrsPortStatusIndex Unsigned32,
wrsPortStatusPortName DisplayString,
wrsPortStatusLink INTEGER,
wrsPortStatusMode INTEGER,
wrsPortStatusLocked INTEGER,
wrsPortStatusPeer OCTET STRING,
wrsPortStatusSfpVN DisplayString,
wrsPortStatusSfpPN DisplayString,
wrsPortStatusSfpVS DisplayString,
wrsPortStatusSfpInDB INTEGER,
wrsPortStatusSfpGbE INTEGER,
wrsPortStatusSfpError INTEGER
}
portLinkX OBJECT-TYPE
wrsPortStatusIndex OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Index for wrsPortStatusTable"
::= { wrsPortStatusEntry 1 }
wrsPortStatusPortName OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..12))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Name of port"
::= { wrsPortStatusEntry 2 }
wrsPortStatusLink OBJECT-TYPE
SYNTAX INTEGER {
NA(0),
na(0),
down(1),
up(2)
}
......@@ -450,264 +1424,96 @@ portLinkX OBJECT-TYPE
STATUS current
DESCRIPTION
"Whether the link is up or down"
::= { wrsPortsEntryX 1 }
::= { wrsPortStatusEntry 3 }
portModeX OBJECT-TYPE
wrsPortStatusMode OBJECT-TYPE
SYNTAX INTEGER {
unknown(0),
master(1),
slave(2),
non-wr(3),
nonWr(3),
auto(4)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether the port is master or slave"
::= { wrsPortsEntryX 2 }
::= { wrsPortStatusEntry 4 }
portLockedX OBJECT-TYPE
wrsPortStatusLocked OBJECT-TYPE
SYNTAX INTEGER {
NA(0),
not-locked(1),
na(0),
notLocked(1),
locked(2)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether the peers are locked or not"
::= { wrsPortsEntryX 3 }
::= { wrsPortStatusEntry 5 }
portPeerX OBJECT-TYPE
wrsPortStatusPeer OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(8))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"the ClockID of the peer, if available. Or 0"
::= { wrsPortsEntryX 4 }
::= { wrsPortStatusEntry 6 }
portSfpVNX OBJECT-TYPE
wrsPortStatusSfpVN OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Vendor Name of SFP"
::= { wrsPortsEntryX 5 }
::= { wrsPortStatusEntry 7 }
portSfpPNX OBJECT-TYPE
wrsPortStatusSfpPN OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Part Number of SFP"
::= { wrsPortsEntryX 6 }
::= { wrsPortStatusEntry 8 }
portSfpVSX OBJECT-TYPE
wrsPortStatusSfpVS OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Vendor serial number of SFP"
::= { wrsPortsEntryX 7 }
::= { wrsPortStatusEntry 9 }
portSfpInDBX OBJECT-TYPE
SYNTAX INTEGER {NA(0), not-in-Data-Base(1), in-Data-Base(2)}
wrsPortStatusSfpInDB OBJECT-TYPE
SYNTAX INTEGER {na(0), notInDataBase(1), inDataBase(2)}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether the SFP is in data base or not"
::= { wrsPortsEntryX 8 }
::= { wrsPortStatusEntry 10 }
portSfpGbEX OBJECT-TYPE
SYNTAX INTEGER {NA(0), not-GbE(1), GbE(2)}
wrsPortStatusSfpGbE OBJECT-TYPE
SYNTAX INTEGER {na(0), linkNotGbE(1), linkGbE(2)}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether the SFP is 1 GbE"
::= { wrsPortsEntryX 9 }
::= { wrsPortStatusEntry 11 }
portSfpErrorX OBJECT-TYPE
wrsPortStatusSfpError OBJECT-TYPE
SYNTAX INTEGER {
NA(0),
SFP-ok(1),
SFP-Error(2)
na(0),
sfpOk(1),
sfpError(2),
portDown(3)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Problem with SFP configuration. Port has to be always 1GbE. Port has to be in data base as long as support WR."
::= { wrsPortsEntryX 10 }
-- wrsTemperatureX (.5)
tempFPGAX OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"FPGA temperature"
::= { wrsTemperatureX 1 }
tempPLLX OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"PLL temperature"
::= { wrsTemperatureX 2 }
tempPSLX OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Power Supply Left (PSL) temperature"
::= { wrsTemperatureX 3 }
tempPSRX OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Power Supply Right (PSR) temperature"
::= { wrsTemperatureX 4 }
tempTholdFPGAX OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Threshold level for FPGA temperature"
::= { wrsTemperatureX 5 }
tempTholdPLLX OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Threshold level for PLL temperature"
::= { wrsTemperatureX 6 }
tempTholdPSLX OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Threshold level for Power Supply Left (PSL) temperature"
::= { wrsTemperatureX 7 }
tempTholdPSRX OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Threshold level for Power Supply Right (PSR) temperature"
::= { wrsTemperatureX 8 }
tempWarningX OBJECT-TYPE
SYNTAX INTEGER {
NA(0),
Threshold-not-set(1),
Temperature-OK(2),
Temperature-too-high(3),
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Warning if temperature exceed threshold levels"
::= { wrsTemperatureX 9 }
-- Versions (4) are all just strings, several of them
wrsVersionSw OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..64))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The software version, as returned from 'git describe' at build time"
::= { wrsVersion 1 }
wrsVersionGw1 OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The gateware version: commit of wr_switch_hdl"
::= { wrsVersion 2 }
wrsVersionGw2 OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The gateware version: commit of general-cores"
::= { wrsVersion 3 }
wrsVersionGw3 OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The gateware version: commit of wr-cores"
::= { wrsVersion 4 }
wrsVersionHw1 OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The hardware version: minibackplane PCB"
::= { wrsVersion 5 }
wrsVersionHw2 OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The hardware version: FPGA"
::= { wrsVersion 6 }
wrsManufacturer OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..64))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The name of the manufacturing company"
::= { wrsVersion 7 }
wrsSerialNumber OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The serial number (or string) of the switch"
::= { wrsVersion 8 }
wrsScbVersion OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The version of the SCB (motherboard)"
::= { wrsVersion 9 }
-- Date (5), to quickly check wr status
wrsDateTAI OBJECT-TYPE
SYNTAX Counter64 -- actually integer, but it is unsigned so ok
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The current time, in TAI seconds"
::= { wrsDate 1 }
wrsDateString OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The current TAI time, printed as %y-%m-%d-%H:%M:%S (no time zone)"
::= { wrsDate 2 }
::= { wrsPortStatusEntry 12 }
--wrsNetworking
--Configuration
END
../libwr/dot-config.c
\ No newline at end of file
......@@ -7,14 +7,45 @@
/* The sub-init functions */
#include "wrsSnmp.h"
#include "snmp_shmem.h"
#include "libwr/config.h"
#include "wrsGeneralStatusGroup.h"
#include "wrsOSStatusGroup.h"
#include "wrsNetworkingStatusGroup.h"
#include "wrsVersionGroup.h"
#include "wrsCurrentTimeGroup.h"
#include "wrsBootStatusGroup.h"
#include "wrsTemperatureGroup.h"
#include "wrsStartCntGroup.h"
#include "wrsSpllStatusGroup.h"
#include "wrsPstatsTable.h"
#include "wrsPtpDataTable.h"
#include "wrsPortStatusTable.h"
#define DOTCONFIG_FILE "/wr/etc/dot-config"
FILE *wrs_logf; /* for the local-hack messages */
void init_wrsSnmp(void)
{
init_shm();
if (libwr_cfg_read_file(DOTCONFIG_FILE)) {
/* unable to read dot-config,
* don't crash SNMPd, it will be reported in SNMP objects */
snmp_log(LOG_ERR, "SNMP: unable to read dot-config file %s\n",
DOTCONFIG_FILE);
}
init_wrsScalar();
init_wrsPstats();
init_wrsPpsi();
init_wrsVersion();
init_wrsDate();
init_wrsGeneralStatusGroup();
init_wrsOSStatusGroup();
init_wrsNetworkingStatusGroup();
init_wrsVersionGroup();
init_wrsCurrentTimeGroup();
init_wrsBootStatusGroup();
init_wrsTemperatureGroup();
init_wrsStartCntGroup();
init_wrsSpllStatusGroup();
init_wrsPstatsTable();
init_wrsPtpDataTable();
init_wrsPortStatusTable();
}
......@@ -2,7 +2,7 @@
# Allow user override
if [catch "set cmd \"\$env(SHOWPS_CMD)\""] {
set cmd "snmpwalk -c public -v 2c -On -Oq HOST .1.3.6.1.4.1.96.100.2.1"
set cmd "snmpwalk -c public -v 2c -On -Oq HOST .1.3.6.1.4.1.96.100.6.4.1"
}
if ![llength $argv] {
......@@ -21,13 +21,53 @@ proc updatew {wname} {
grid [label $wname.wr$i -text "WR$i" -fg blue] -row 0 -column $c
}
}
set labels {wrsPstatsPortName
wrsPstatsTXUnderrun
wrsPstatsRXOverrun
wrsPstatsRXInvalidCode
wrsPstatsRXSyncLost
wrsPstatsRXPauseFrames
wrsPstatsRXPfilterDropped
wrsPstatsRXPCSErrors
wrsPstatsRXGiantFrames
wrsPstatsRXRuntFrames
wrsPstatsRXCRCErrors
wrsPstatsRXPclass0
wrsPstatsRXPclass1
wrsPstatsRXPclass2
wrsPstatsRXPclass3
wrsPstatsRXPclass4
wrsPstatsRXPclass5
wrsPstatsRXPclass6
wrsPstatsRXPclass7
wrsPstatsTXFrames
wrsPstatsRXFrames
wrsPstatsRXDropRTUFull
wrsPstatsRXPrio0
wrsPstatsRXPrio1
wrsPstatsRXPrio2
wrsPstatsRXPrio3
wrsPstatsRXPrio4
wrsPstatsRXPrio5
wrsPstatsRXPrio6
wrsPstatsRXPrio7
wrsPstatsRTUValid
wrsPstatsRTUResponses
wrsPstatsRTUDropped
wrsPstatsFastMatchPriority
wrsPstatsFastMatchFastForward
wrsPstatsFastMatchNonForward
wrsPstatsFastMatchRespValid
wrsPstatsFullMatchRespValid
wrsPstatsForwarded
wrsPstatsTRURespValid
}
# open a file according to the command given
set F [open "| $w($wname:cmd)" r]
while {[gets $F str] > 0} {
foreach {oid value} $str {
# remove the leading part
regsub ".1.3.6.1.4.1.96.100.2.1." $oid "" oid
regsub ".1.3.6.1.4.1.96.100.6.4.1." $oid "" oid
# extract column and row
foreach {col row} [split $oid .] {
if ![string length $row] break
......@@ -38,10 +78,24 @@ proc updatew {wname} {
set width "-width 8"
if {$col == 1} {set width ""}
eval $name config -text \"$value\" $width
grid $name -row $row -column $col
set row1 [expr $row +1]
grid $name -row $col -column $row1
}
}
}
}
set n [llength $labels]
set row 0
while {$row < $n} {
set name $wname.1_${row}
if $new {
label $name
}
set counter_name [lindex $labels $row]
eval $name config -text \"$counter_name\"
set row1 [expr $row +2]
grid $name -row $row1 -column 1
incr row
}
if [catch "close $F" message] {
puts stderr "Error in snmpwalk for host $w($wname:host)"
puts stderr $message
......
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include "snmp_mmap.h"
/* FIXME: this is copied from wr_date, should be librarized */
void *create_map(unsigned long address, unsigned long size)
{
unsigned long ps = getpagesize();
unsigned long offset, fragment, len;
void *mapaddr;
int fd;
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0)
return NULL;
offset = address & ~(ps - 1);
fragment = address & (ps - 1);
len = address + size - offset;
mapaddr = mmap(0, len, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset);
close(fd);
if (mapaddr == MAP_FAILED)
return NULL;
return mapaddr + fragment;
}
void *create_map(unsigned long address, unsigned long size);
#include "wrsSnmp.h"
#include "snmp_shmem.h"
/* HAL */
struct wrs_shm_head *hal_head;
struct hal_shmem_header *hal_shmem;
struct hal_port_state *hal_ports;
int hal_nports_local;
/* PPSI */
struct wrs_shm_head *ppsi_head;
static struct pp_globals *ppg;
struct wr_servo_state_t *ppsi_servo;
/* RTUd */
struct wrs_shm_head *rtud_head;
static void init_shm_hal(void)
{
hal_head = wrs_shm_get(wrs_shm_hal, "", WRS_SHM_READ);
if (!hal_head) {
snmp_log(LOG_ERR, "unable to open shm for HAL!\n");
exit(-1);
}
/* check hal's shm version */
if (hal_head->version != HAL_SHMEM_VERSION) {
snmp_log(LOG_ERR, "unknown hal's shm version %i "
"(known is %i)\n", hal_head->version,
HAL_SHMEM_VERSION);
exit(-1);
}
hal_shmem = (void *)hal_head + hal_head->data_off;
/* Assume number of ports does not change in runtime */
hal_nports_local = hal_shmem->nports;
if (hal_nports_local > WRS_N_PORTS) {
snmp_log(LOG_ERR, "Too many ports reported by HAL. "
"%d vs %d supported\n",
hal_nports_local, WRS_N_PORTS);
exit(-1);
}
/* Even after HAL restart, HAL will place structures at the same
* addresses. No need to re-dereference pointer at each read. */
hal_ports = wrs_shm_follow(hal_head, hal_shmem->ports);
if (!hal_ports) {
snmp_log(LOG_ERR, "Unalbe to follow hal_ports pointer in HAL's"
" shmem");
exit(-1);
}
}
static void init_shm_ppsi(void)
{
ppsi_head = wrs_shm_get(wrs_shm_ptp, "", WRS_SHM_READ);
if (!ppsi_head) {
snmp_log(LOG_ERR, "unable to open shm for PPSI!\n");
exit(-1);
}
/* check ppsi's shm version */
if (ppsi_head->version != WRS_PPSI_SHMEM_VERSION) {
snmp_log(LOG_ERR, "unknown PPSI's shm version %i "
"(known is %i)\n",
ppsi_head->version, WRS_PPSI_SHMEM_VERSION);
exit(-1);
}
ppg = (void *)ppsi_head + ppsi_head->data_off;
ppsi_servo = wrs_shm_follow(ppsi_head, ppg->global_ext_data);
if (!ppsi_servo) {
snmp_log(LOG_ERR, "Cannot follow ppsi_servo in shmem.\n");
exit(-1);
}
}
static void init_shm_rtud(void)
{
/* open RTUd's shm */
rtud_head = wrs_shm_get(wrs_shm_rtu, "", WRS_SHM_READ);
if (!rtud_head) {
snmp_log(LOG_ERR, "unable to open shm for RTUd!\n");
exit(-1);
}
/* check rtud's shm version */
if (rtud_head->version != RTU_SHMEM_VERSION) {
snmp_log(LOG_ERR, "unknown RTUd's shm version %i "
"(known is %i)\n", rtud_head->version,
RTU_SHMEM_VERSION);
exit(-1);
}
}
void init_shm(void){
init_shm_hal();
init_shm_ppsi();
init_shm_rtud();
}
#ifndef WRS_SNMP_SHMEM_H
#define WRS_SNMP_SHMEM_H
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
#include <ppsi/ppsi.h>
#include <libwr/hal_shmem.h>
#include <libwr/rtu_shmem.h>
/* HAL */
extern struct wrs_shm_head *hal_head;
extern struct hal_shmem_header *hal_shmem;
extern struct hal_port_state *hal_ports;
extern int hal_nports_local;
/* PPSI */
extern struct wrs_shm_head *ppsi_head;
extern struct wr_servo_state_t *ppsi_servo;
/* RTUd */
struct wrs_shm_head *rtud_head;
void init_shm();
#endif /* WRS_SNMP_SHMEM_H */
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2010 - 2013 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
/* softpll_ng.h: public SoftPLL API header */
#ifndef __SOFTPLL_NG_H
#define __SOFTPLL_NG_H
#include <stdint.h>
/* SoftPLL operating modes, for mode parameter of spll_init(). */
/* Grand Master - lock to 10 MHz external reference */
#define SPLL_MODE_GRAND_MASTER 1
/* Free running master - 125 MHz refrence free running, DDMTD locked to it */
#define SPLL_MODE_FREE_RUNNING_MASTER 2
/* Slave mode - 125 MHz reference locked to one of the input clocks */
#define SPLL_MODE_SLAVE 3
/* Disabled mode: SoftPLL inactive */
#define SPLL_MODE_DISABLED 4
/* Shortcut for 'channels' parameter in various API functions to perform operation on all channels */
#define SPLL_ALL_CHANNELS 0xffffffff
/* Aux clock flags */
#define SPLL_AUX_ENABLED (1<<0) /* Locking the particular aux channel to the WR reference is enabled */
#define SPLL_AUX_LOCKED (1<<1) /* The particular aux clock is already locked to WR reference */
/* Phase detector types */
#define SPLL_PD_DDMTD 0
#define SPLL_PD_BANGBANG 1
/* Channels for spll_measure_frequency() */
#define SPLL_OSC_REF 0
#define SPLL_OSC_DMTD 1
#define SPLL_OSC_EXT 2
/* Note on channel naming:
- ref_channel means a PHY recovered clock input. There can be one (as in WR core) or more (WR switch).
- out_channel means an output channel, which represents PLL feedback signal from a local, tunable oscillator. Every SPLL implementation
has at least one output channel, connected to the 125 / 62.5 MHz transceiver (WR) reference. This channel has always
index 0 and is compared against all reference channels by the phase tracking mechanism.
*/
/* PUBLIC API */
/*
Initializes the SoftPLL to work in mode (mode). Extra parameters depend on choice of the mode:
- for SPLL_MODE_GRAND_MASTER: non-zero (align_pps) value enables realignment of the WR reference rising edge to the
rising edge of 10 MHz external clock that comes immediately after a PPS pulse
- for SPLL_MODE_SLAVE: (ref_channel) indicates the reference channel to which we are locking our PLL.
*/
void spll_init(int mode, int ref_channel, int align_pps);
/* Disables the SoftPLL and cleans up stuff */
void spll_shutdown();
/* Returns number of reference and output channels implemented in HW. */
void spll_get_num_channels(int *n_ref, int *n_out);
/* Starts locking output channel (out_channel) */
void spll_start_channel(int out_channel);
/* Stops locking output channel (out_channel) */
void spll_stop_channel(int out_channel);
/* Returns non-zero if output channel (out_channel) is locked to a WR reference */
int spll_check_lock(int out_channel);
/* Sets phase setpoint for given output channel. */
void spll_set_phase_shift(int out_channel, int32_t value_picoseconds);
/* Retreives the current phase shift and desired setpoint for given output channel */
void spll_get_phase_shift(int out_channel, int32_t *current, int32_t *target);
/* Returns non-zero if the given output channel is busy phase shifting to a new preset */
int spll_shifter_busy(int out_channel);
/* Returns phase detector type used by particular output channel. There are two phase detectors available:
- DDMTD: locks only 62.5 / 125 MHz. Provides independent phase shift control for each output.
- Bang-Bang: locks to any frequency that is a result of rational (M/N) multiplication of the reference frequency.
The frequency can be set by spll_set_aux_frequency(). BB detector follows phase setpoint of channel 0 (WR reference),
there is no per-output shift control.
*/
int spll_get_phase_detector_type(int out_channel);
/* Sets the aux clock freuency when a BB detector is in use.
Must be called prior to spll_start_channel(). If the frequency is out of available range,
returns negative value */
int spll_set_aux_frequency(int out_channel, int32_t frequency);
/* Enables/disables phase tracking on channel (ref_channel). Phase is always measured between
the WR local reference (out_channel 0) and ref_channel */
void spll_enable_ptracker(int ref_channel, int enable);
/* Reads tracked phase shift value for given reference channel */
int spll_read_ptracker(int ref_channel, int32_t *phase_ps, int *enabled);
/* Calls non-realtime update state machine. Must be called regularly (although
* it is not time-critical) in the main loop of the program if aux clocks or
* external reference are used in the design. */
void spll_update();
/* Returns the status of given aux clock output (SPLL_AUX_) */
int spll_get_aux_status(int out_channel);
const char *spll_get_aux_status_string(int channel);
/* Debug/testing functions */
/* Returns how many time the PLL has de-locked since last call of spll_init() */
int spll_get_delock_count();
void spll_show_stats(void);
/* Sets VCXO tuning DAC corresponding to output (out_channel) to a given value */
void spll_set_dac(int out_channel, int value);
/* Returns current DAC sample value for output (out_channel) */
int spll_get_dac(int out_channel);
void check_vco_frequencies();
/* info reported through .stat section */
struct spll_stats {
int magic; /* 0x5b1157a7 = SPLLSTAT ?;)*/
int ver; /* version of the structure */
int sequence; /* sequence number, so the host can retry */
int mode;
int irq_cnt;
int seq_state;
int align_state;
int H_lock;
int M_lock;
int H_y, M_y;
int del_cnt;
};
/* This only exists in wr-switch, but we should use it always */
extern struct spll_stats stats;
#endif // __SOFTPLL_NG_H
#include "wrsSnmp.h"
#include "snmp_mmap.h"
#include "wrsBootStatusGroup.h"
#define BOOTCOUNT_FILE "/proc/wrs-bootcount"
#define DOTCONFIGDIR "/tmp"
#define DOTCONFIG_PROTO "dot-config_proto"
#define DOTCONFIG_HOST "dot-config_host"
#define DOTCONFIG_FILENAME "dot-config_filename"
#define DOTCONFIG_DOWNLOAD "dot-config_status"
#define HWINFO_FILE "/tmp/hwinfo_read_status"
#define LOAD_FPGA_STATUS_FILE "/tmp/load_fpga_status"
#define LOAD_LM32_STATUS_FILE "/tmp/load_lm32_status"
#define MODULES_FILE "/proc/modules"
/* get process list, output only process' command */
#define PROCESS_COMMAND "/bin/ps axo command"
/* Macros for fscanf function to read line with maximum of "x" characters
* without new line. Macro expands to something like: "%10[^\n]" */
#define LINE_READ_LEN_HELPER(x) "%"#x"[^\n]"
#define LINE_READ_LEN(x) LINE_READ_LEN_HELPER(x)
#define ARM_RCSR_ADDR 0xFFFFFD04 /* address of CPU's Reset Controller Status
* Register */
#define ARM_RCSR_RESET_TYPE_MASK 0x00000700 /* reset type mast in CPU's Reset
* Controller Status Register */
static struct pickinfo wrsBootStatus_pickinfo[] = {
FIELD(wrsBootStatus_s, ASN_COUNTER, wrsBootCnt),
FIELD(wrsBootStatus_s, ASN_COUNTER, wrsRebootCnt),
FIELD(wrsBootStatus_s, ASN_INTEGER, wrsRestartReason),
FIELD(wrsBootStatus_s, ASN_OCTET_STR, wrsFaultIP),
FIELD(wrsBootStatus_s, ASN_OCTET_STR, wrsFaultLR),
FIELD(wrsBootStatus_s, ASN_INTEGER, wrsConfigSource),
FIELD(wrsBootStatus_s, ASN_OCTET_STR, wrsConfigSourceHost),
FIELD(wrsBootStatus_s, ASN_OCTET_STR, wrsConfigSourceFilename),
FIELD(wrsBootStatus_s, ASN_INTEGER, wrsBootConfigStatus),
FIELD(wrsBootStatus_s, ASN_INTEGER, wrsBootHwinfoReadout),
FIELD(wrsBootStatus_s, ASN_INTEGER, wrsBootLoadFPGA),
FIELD(wrsBootStatus_s, ASN_INTEGER, wrsBootLoadLM32),
FIELD(wrsBootStatus_s, ASN_INTEGER, wrsBootKernelModulesMissing),
FIELD(wrsBootStatus_s, ASN_INTEGER, wrsBootUserspaceDaemonsMissing),
};
struct wrsBootStatus_s wrsBootStatus_s;
struct wrs_km_item {
char *key;
};
/* list of kernel modules to check */
static struct wrs_km_item kernel_modules[] = {
[0] = {.key = "wr_clocksource"},
[1] = {"wr_pstats"},
[2] = {"wr_rtu"},
[3] = {"wr_nic"},
[4] = {"wr_vic"},
[5] = {"at91_softpwm"},
[6] = {"g_serial"},
};
/* user space deamon list item */
struct wrs_usd_item {
char *key;
};
/* user space deamon list */
static struct wrs_km_item userspace_deamons[] = {
[0] = {.key = "/usr/sbin/dropbear"},
[1] = {"/wr/bin/wrsw_hal"}, /* two wrsw_hal instances */
[2] = {"/wr/bin/wrsw_hal"}, /* two wrsw_hal instances */
[3] = {"/wr/bin/wrsw_rtud"},
[4] = {"/wr/bin/ppsi"},
[5] = {"/usr/sbin/lighttpd"},
[6] = {"/usr/bin/monit"},
[7] = {"snmpd"},
};
struct wrs_bc_item {
char *key;
uint32_t value;
};
/* items to be read from BOOTCOUNT_FILE */
static struct wrs_bc_item boot_info[] = {
[0] = {.key = "boot_count:"},
[1] = {"reboot_count:"},
[2] = {"fault_ip:"},
[3] = {"fault_lr:"},
};
static void get_boot_info(void){
static int run_once = 0;
FILE *f;
char s[80], key[40];
uint32_t value;
int i;
uint32_t *rcsr_map;
if (run_once) {
/* boot info change only at restart */
return;
}
run_once = 1;
/* get restart reason */
rcsr_map = create_map(ARM_RCSR_ADDR, sizeof(uint32_t));
if (!rcsr_map) {
snmp_log(LOG_ERR, "SNMP: wrsBootStatusGroup unable to map "
"CPU's Reset Controller Status Register\n");
/* pass error to SNMP, assign 1 */
wrsBootStatus_s.wrsRestartReason = WRS_RESTART_REASON_ERROR;
} else {
/* reset reason values are from 0 to 4, SNMP enum is from
* 2 to 6, so "+ 2", 1 is reserved for error */
wrsBootStatus_s.wrsRestartReason = 2 +
((*rcsr_map & ARM_RCSR_RESET_TYPE_MASK) >> 8);
}
f = fopen(BOOTCOUNT_FILE, "r");
if (!f) {
snmp_log(LOG_ERR, "SNMP: wrsBootStatusGroup filed to open "
BOOTCOUNT_FILE"\n");
/* notify snmp about error in restart reason */
wrsBootStatus_s.wrsRestartReason = WRS_RESTART_REASON_ERROR;
return;
}
while (fgets(s, sizeof(s), f)) {
if (sscanf(s, "%s %i", key, &value) != 2)
continue; /* error... */
for (i = 0; i < ARRAY_SIZE(boot_info); i++) {
if (strncmp(key, boot_info[i].key, 40))
continue;
boot_info[i].value = value;
}
}
fclose(f);
wrsBootStatus_s.wrsBootCnt = boot_info[0].value;
wrsBootStatus_s.wrsRebootCnt = boot_info[1].value;
snprintf(wrsBootStatus_s.wrsFaultIP,
sizeof(wrsBootStatus_s.wrsFaultIP), "0x%.8x",
boot_info[2].value);
snprintf(wrsBootStatus_s.wrsFaultLR,
sizeof(wrsBootStatus_s.wrsFaultLR), "0x%.8x",
boot_info[3].value);
}
static void get_dotconfig_source(void)
{
char buff[21]; /* 1 for null char */
FILE *f;
/* Check dotconfig source.
* dotconfig source can change in runtime, i.e. from remote to local by
* web-interface */
/* read protocol used to get dotconfig */
f = fopen(DOTCONFIGDIR "/" DOTCONFIG_PROTO, "r");
if (f) {
/* readline without newline */
fscanf(f, LINE_READ_LEN(20), buff);
fclose(f);
if (!strncmp(buff, "tftp", 10))
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_PROTO_TFTP;
else if (!strncmp(buff, "http", 10))
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_PROTO_HTTP;
else if (!strncmp(buff, "ftp", 10))
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_PROTO_FTP;
else if (!strncmp(buff, "local", 10))
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_PROTO_LOCAL;
else /* unknown proto */
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_PROTO_ERROR;
} else {
/* proto file not found, probably something else caused
* a problem */
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_SOURCE_PROTO_ERROR_MINOR;
}
/* read host used to get dotconfig */
f = fopen(DOTCONFIGDIR "/" DOTCONFIG_HOST, "r");
if (f) {
/* readline without newline */
fscanf(f, LINE_READ_LEN(WRS_CONFIG_SOURCE_HOST_LEN),
wrsBootStatus_s.wrsConfigSourceHost);
fclose(f);
} else {
/* host file not found, put "error" into wrsConfigSourceHost */
strcpy(wrsBootStatus_s.wrsConfigSourceHost, "error");
}
/* read filename used to get dotconfig */
f = fopen(DOTCONFIGDIR "/" DOTCONFIG_FILENAME, "r");
if (f) {
/* readline without newline */
fscanf(f, LINE_READ_LEN(WRS_CONFIG_SOURCE_FILENAME_LEN),
wrsBootStatus_s.wrsConfigSourceFilename);
fclose(f);
} else {
/* host file not found, put "error" into
* wrsConfigSourceFilename */
strcpy(wrsBootStatus_s.wrsConfigSourceFilename, "error");
}
f = fopen(DOTCONFIGDIR "/" DOTCONFIG_DOWNLOAD, "r");
if (f) {
/* readline without newline */
fscanf(f, LINE_READ_LEN(20), buff);
fclose(f);
if (!strncmp(buff, "config_ok", 20))
wrsBootStatus_s.wrsBootConfigStatus =
WRS_CONFIG_STATUS_OK;
else if (!strncmp(buff, "check_error", 20))
wrsBootStatus_s.wrsBootConfigStatus =
WRS_CONFIG_STATUS_CHECK_ERROR;
else if (!strncmp(buff, "download_error", 20))
wrsBootStatus_s.wrsBootConfigStatus =
WRS_CONFIG_STATUS_DL_ERROR;
else
wrsBootStatus_s.wrsBootConfigStatus =
WRS_CONFIG_STATUS_ERROR;
} else {
/* status file not found, probably something else caused
* a problem */
wrsBootStatus_s.wrsConfigSource =
WRS_CONFIG_STATUS_ERROR_MINOR;
}
}
/* get status of execution of following scripts:
* /etc/init.d/S90hwinfo
* /wr/sbin/startup-mb.sh (load FPGA and LM32)
* */
static void get_boot_scripts_status(void){
static int run_once = 0;
FILE *f;
char buff[21]; /* 1 for null char */
if (run_once) {
/* HWinfo, load of FPGA and LM32 is done only at boot */
return;
}
run_once = 1;
/* read result of S90hwinfo (HWinfo) execution */
f = fopen(HWINFO_FILE, "r");
if (f) {
/* readline without newline */
fscanf(f, LINE_READ_LEN(20), buff);
fclose(f);
if (!strncmp(buff, "hwinfo_ok", 20))
wrsBootStatus_s.wrsBootHwinfoReadout =
WRS_BOOT_HWINFO_OK;
else if (!strncmp(buff, "hwinfo_warning", 20))
wrsBootStatus_s.wrsBootHwinfoReadout =
WRS_BOOT_HWINFO_WARNING;
else /* */
wrsBootStatus_s.wrsBootHwinfoReadout =
WRS_BOOT_HWINFO_ERROR;
} else {
/* status file not found, probably something else caused
* a problem */
wrsBootStatus_s.wrsBootHwinfoReadout =
WRS_BOOT_HWINFO_ERROR_MINOR;
}
/* result of loading FPGA */
f = fopen(LOAD_FPGA_STATUS_FILE, "r");
if (f) {
/* readline without newline */
fscanf(f, LINE_READ_LEN(20), buff);
fclose(f);
if (!strncmp(buff, "load_ok", 20))
wrsBootStatus_s.wrsBootLoadFPGA =
WRS_BOOT_LOAD_FPGA_OK;
else if (!strncmp(buff, "load_file_not_found", 20))
wrsBootStatus_s.wrsBootLoadFPGA =
WRS_BOOT_LOAD_FPGA_FILE_NOT_FOUND;
else /* */
wrsBootStatus_s.wrsBootLoadFPGA =
WRS_BOOT_LOAD_FPGA_ERROR;
} else {
/* status file not found, probably something else caused
* a problem */
wrsBootStatus_s.wrsBootLoadFPGA =
WRS_BOOT_LOAD_FPGA_ERROR_MINOR;
}
/* result of loading LM32 */
f = fopen(LOAD_LM32_STATUS_FILE, "r");
if (f) {
/* readline without newline */
fscanf(f, LINE_READ_LEN(20), buff);
fclose(f);
if (!strncmp(buff, "load_ok", 20))
wrsBootStatus_s.wrsBootLoadLM32 =
WRS_BOOT_LOAD_LM32_OK;
else if (!strncmp(buff, "load_file_not_found", 20))
wrsBootStatus_s.wrsBootLoadLM32 =
WRS_BOOT_LOAD_LM32_FILE_NOT_FOUND;
else /* */
wrsBootStatus_s.wrsBootLoadLM32 =
WRS_BOOT_LOAD_LM32_ERROR;
} else {
/* status file not found, probably something else caused
* a problem */
wrsBootStatus_s.wrsBootLoadLM32 =
WRS_BOOT_LOAD_LM32_ERROR_MINOR;
}
}
/* check if all modules are loaded */
static void get_loaded_kernel_modules_status(void)
{
FILE *f;
char key[41]; /* 1 for null char */
int modules_found;
int ret;
int i;
int guess_index;
int modules_missing;
f = fopen(MODULES_FILE, "r");
if (!f) {
snmp_log(LOG_ERR, "SNMP: wrsBootStatusGroup filed to open "
MODULES_FILE"\n");
/* notify snmp about error in kernel modules */
wrsBootStatus_s.wrsBootKernelModulesMissing =
ARRAY_SIZE(kernel_modules);
return;
}
while (ret != EOF) {
/* read first word from line (module name) ignore rest of
* the line */
ret = fscanf(f, "%40s%*[^\n]", key);
if (ret != 1)
continue; /* error... or EOF */
/* try educated guess to find position in array */
if (!strncmp(key, kernel_modules[guess_index].key, 40)) {
modules_found++;
guess_index++;
continue;
}
for (i = 0; i < ARRAY_SIZE(kernel_modules); i++) {
if (strncmp(key, kernel_modules[i].key, 40))
continue;
modules_found++;
}
guess_index++;
}
modules_missing = ARRAY_SIZE(kernel_modules) - modules_found;
/* save number of missing modules */
wrsBootStatus_s.wrsBootKernelModulesMissing = modules_missing;
fclose(f);
}
/* check if deamons from userspace_deamons array are running */
static void get_deamons_status(void)
{
FILE *f;
char key[41]; /* 1 for null char */
int ret;
int i;
int processes_found;
int processes_missing;
/* use ps command to get process list, more portable, less error prone
* but probably slower than manually parsing /proc/ */
f = popen(PROCESS_COMMAND, "r");
if (!f) {
snmp_log(LOG_ERR, "SNMP: wrsBootStatusGroup failed to execute "
PROCESS_COMMAND"\n");
/* notify snmp about error in processes list */
wrsBootStatus_s.wrsBootUserspaceDaemonsMissing =
ARRAY_SIZE(userspace_deamons);
return;
}
while (ret != EOF) {
/* read first word from line (process name) ignore rest of
* the line */
ret = fscanf(f, "%40s%*[^\n]", key);
if (ret != 1)
continue; /* error... or EOF */
for (i = 0; i < ARRAY_SIZE(userspace_deamons); i++) {
if (strncmp(key, userspace_deamons[i].key, 40))
continue;
processes_found++;
break;
}
}
processes_missing = ARRAY_SIZE(userspace_deamons) - processes_found;
/* save number of processes missing */
if (processes_missing < 0) {
/* probably something wrong with multiple process' instances */
wrsBootStatus_s.wrsBootUserspaceDaemonsMissing =
ARRAY_SIZE(userspace_deamons);
} else {
wrsBootStatus_s.wrsBootUserspaceDaemonsMissing =
processes_missing;
}
pclose(f);
}
time_t wrsBootStatus_data_fill(void)
{
static time_t time_update;
time_t time_cur;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSBOOTSTATUS_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
get_boot_info();
/* get dotconfig source information */
get_dotconfig_source();
/* get result of execution of hwinfo script */
get_boot_scripts_status();
/* get loaded kernel modules */
get_loaded_kernel_modules_status();
/* get info about running deamons */
get_deamons_status();
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRSBOOTSTATUS_OID
#define GT_PICKINFO wrsBootStatus_pickinfo
#define GT_DATA_FILL_FUNC wrsBootStatus_data_fill
#define GT_DATA_STRUCT wrsBootStatus_s
#define GT_GROUP_NAME "wrsBootStatusGroup"
#define GT_INIT_FUNC init_wrsBootStatusGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_BOOT_STATUS_GROUP_H
#define WRS_BOOT_STATUS_GROUP_H
#define WRSBOOTSTATUS_CACHE_TIMEOUT 5
#define WRSBOOTSTATUS_OID WRS_OID, 7, 1, 2
#define WRS_RESTART_REASON_ERROR 1 /* error */
#define WRS_CONFIG_SOURCE_HOST_LEN 64
#define WRS_CONFIG_SOURCE_FILENAME_LEN 128
#define WRS_CONFIG_SOURCE_PROTO_ERROR 1 /* error */
#define WRS_CONFIG_SOURCE_PROTO_ERROR_MINOR 2 /* warning */
#define WRS_CONFIG_SOURCE_PROTO_LOCAL 3 /* ok */
/* below proto are ok, if host and filename not empty */
#define WRS_CONFIG_SOURCE_PROTO_TFTP 4
#define WRS_CONFIG_SOURCE_PROTO_HTTP 5
#define WRS_CONFIG_SOURCE_PROTO_FTP 6
#define WRS_CONFIG_STATUS_OK 1 /* ok */
#define WRS_CONFIG_STATUS_ERROR 2 /* error */
#define WRS_CONFIG_STATUS_DL_ERROR 3 /* error */
#define WRS_CONFIG_STATUS_CHECK_ERROR 4 /* error */
#define WRS_CONFIG_STATUS_ERROR_MINOR 5 /* warning */
#define WRS_BOOT_HWINFO_OK 1 /* ok */
#define WRS_BOOT_HWINFO_ERROR 2 /* error */
#define WRS_BOOT_HWINFO_ERROR_MINOR 3 /* warning */
#define WRS_BOOT_HWINFO_WARNING 4 /* warning */
#define WRS_BOOT_LOAD_FPGA_OK 1 /* ok */
#define WRS_BOOT_LOAD_FPGA_ERROR 2 /* error */
#define WRS_BOOT_LOAD_FPGA_ERROR_MINOR 3 /* warning */
#define WRS_BOOT_LOAD_FPGA_FILE_NOT_FOUND 4 /* error */
#define WRS_BOOT_LOAD_LM32_OK 1 /* ok */
#define WRS_BOOT_LOAD_LM32_ERROR 2 /* error */
#define WRS_BOOT_LOAD_LM32_ERROR_MINOR 3 /* warning */
#define WRS_BOOT_LOAD_LM32_FILE_NOT_FOUND 4 /* error */
struct wrsBootStatus_s {
uint32_t wrsBootCnt; /* boots since power-on must be != 0 */
uint32_t wrsRebootCnt; /* soft reboots since hard reboot
* (i.e. caused by reset button) */
int32_t wrsRestartReason; /* reason of last restart */
char wrsFaultIP[11]; /* faulty instruction pointer as string */
char wrsFaultLR[11]; /* link register at fault as string */
int32_t wrsConfigSource;
char wrsConfigSourceHost[WRS_CONFIG_SOURCE_HOST_LEN+1];
char wrsConfigSourceFilename[WRS_CONFIG_SOURCE_FILENAME_LEN+1];
int32_t wrsBootConfigStatus;
int32_t wrsBootHwinfoReadout;
int32_t wrsBootLoadFPGA;
int32_t wrsBootLoadLM32;
int32_t wrsBootKernelModulesMissing;
int32_t wrsBootUserspaceDaemonsMissing;
};
extern struct wrsBootStatus_s wrsBootStatus_s;
time_t wrsBootStatus_data_fill(void);
void init_wrsBootStatusGroup(void);
#endif /* WRS_BOOT_STATUS_GROUP_H */
#include "wrsSnmp.h"
#include "wrsCurrentTimeGroup.h"
#include "snmp_mmap.h"
/* defines for nic-hardware.h */
#define WR_SWITCH
#define WR_IS_NODE 0
#define WR_IS_SWITCH 1
#include "../../kernel/wr_nic/nic-hardware.h"
#include "../../kernel/wbgen-regs/ppsg-regs.h"
static struct PPSG_WB *pps;
static struct pickinfo wrsCurrentTime_pickinfo[] = {
FIELD(wrsCurrentTime_s, ASN_COUNTER64, wrsDateTAI),
FIELD(wrsCurrentTime_s, ASN_OCTET_STR, wrsDateTAIString),
};
struct wrsCurrentTime_s wrsCurrentTime_s;
time_t wrsCurrentTime_data_fill(void)
{
static time_t time_update;
time_t time_cur;
unsigned long utch, utcl, tmp1, tmp2;
time_t t;
struct tm tm;
uint64_t wrs_d_current_64;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSCURRENTTIME_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
memset(&wrsCurrentTime_s, 0, sizeof(wrsCurrentTime_s));
/* get TAI time from FPGA */
if (!pps) /* first time, map the fpga space */
pps = create_map(FPGA_BASE_PPSG, sizeof(*pps));
if (!pps) {
wrs_d_current_64 = 0;
strcpy(wrsCurrentTime_s.wrsDateTAIString,
"0000-00-00-00:00:00 (failed)");
return time_update;
}
do {
utch = pps->CNTR_UTCHI;
utcl = pps->CNTR_UTCLO;
tmp1 = pps->CNTR_UTCHI;
tmp2 = pps->CNTR_UTCLO;
} while ((tmp1 != utch) || (tmp2 != utcl));
wrs_d_current_64 = (uint64_t)(utch) << 32 | utcl;
/*
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
wrsCurrentTime_s.wrsDateTAI =
(wrs_d_current_64 << 32) | (wrs_d_current_64 >> 32);
t = wrs_d_current_64;
localtime_r(&t, &tm);
strftime(wrsCurrentTime_s.wrsDateTAIString,
sizeof(wrsCurrentTime_s.wrsDateTAIString),
"%Y-%m-%d-%H:%M:%S", &tm);
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRSCURRENTTIME_OID
#define GT_PICKINFO wrsCurrentTime_pickinfo
#define GT_DATA_FILL_FUNC wrsCurrentTime_data_fill
#define GT_DATA_STRUCT wrsCurrentTime_s
#define GT_GROUP_NAME "wrsCurrentTimeGroup"
#define GT_INIT_FUNC init_wrsCurrentTimeGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_CURRENT_TIME_GROUP_H
#define WRS_CURRENT_TIME_GROUP_H
#define WRSCURRENTTIME_CACHE_TIMEOUT 5
#define WRSCURRENTTIME_OID WRS_OID, 7, 1, 1
struct wrsCurrentTime_s {
uint64_t wrsDateTAI; /* current time in TAI */
char wrsDateTAIString[32]; /* current time in TAI as string */
};
extern struct wrsCurrentTime_s wrsCurrentTime_s;
time_t wrsCurrentTime_data_fill(void);
void init_wrsCurrentTimeGroup(void);
#endif /* WRS_CURRENT_TIME_GROUP_H */
/*
* White Rabbit Switch date. This is two changing values
*
* Alessandro Rubini for CERN, 2014
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/auto_nlist.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "wrsSnmp.h"
/* defines for nic-hardware.h */
#define WR_SWITCH
#define WR_IS_NODE 0
#define WR_IS_SWITCH 1
#include "../../kernel/wr_nic/nic-hardware.h"
#include "../../kernel/wbgen-regs/ppsg-regs.h"
static struct PPSG_WB *pps;
static uint64_t wrs_d_current_64;
static char wrs_d_current_string[32];
/* FIXME: this is copied from wr_date, should be librarized */
void *create_map(unsigned long address, unsigned long size)
{
unsigned long ps = getpagesize();
unsigned long offset, fragment, len;
void *mapaddr;
int fd;
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0)
return NULL;
offset = address & ~(ps - 1);
fragment = address & (ps - 1);
len = address + size - offset;
mapaddr = mmap(0, len, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset);
close(fd);
if (mapaddr == MAP_FAILED)
return NULL;
return mapaddr + fragment;
}
static void wrs_d_get(void)
{
unsigned long utch, utcl, tmp1, tmp2;
time_t t;
struct tm tm;
if (!pps) /* first time, map the fpga space */
pps = create_map(FPGA_BASE_PPSG, sizeof(*pps));
if (!pps) {
wrs_d_current_64 = 0;
strcpy(wrs_d_current_string, "0000-00-00-00:00:00 (failed)");
return;
}
do {
utch = pps->CNTR_UTCHI;
utcl = pps->CNTR_UTCLO;
tmp1 = pps->CNTR_UTCHI;
tmp2 = pps->CNTR_UTCLO;
} while ((tmp1 != utch) || (tmp2 != utcl));
wrs_d_current_64 = (uint64_t)(utch) << 32 | utcl;
t = wrs_d_current_64;
localtime_r(&t, &tm);
strftime(wrs_d_current_string,
sizeof(wrs_d_current_string), "%Y-%m-%d-%H:%M:%S", &tm);
}
static int date_group(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
oid obj; /* actually, an integer, i.e. the final index */
switch (reqinfo->mode) {
case MODE_GET:
wrs_d_get();
/*
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
wrs_d_current_64 =
(wrs_d_current_64 << 32) | (wrs_d_current_64 >> 32);
/* "- 2" because last is 0 for all scalars, I suppose */
obj = requests->requestvb->name[
requests->requestvb->name_length - 2
];
if (obj == 1) /* number */
snmp_set_var_typed_value(requests->requestvb,
ASN_COUNTER64,
&wrs_d_current_64,
sizeof(wrs_d_current_64));
else /* string */
snmp_set_var_typed_value(requests->requestvb,
ASN_OCTET_STR,
wrs_d_current_string,
strlen(wrs_d_current_string));
break;
default:
snmp_log(LOG_ERR, "unknown mode (%d) in wrs date group\n",
reqinfo->mode);
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
void
init_wrsDate(void)
{
const oid wrsDate_oid[] = { WRS_OID, 5 };
netsnmp_handler_registration *hreg;
/* do the registration */
hreg = netsnmp_create_handler_registration(
"wrsDate", date_group,
wrsDate_oid, OID_LENGTH(wrsDate_oid),
HANDLER_CAN_RONLY);
netsnmp_register_scalar_group(
hreg, 1 /* min */, 2 /* max */);
}
#include "wrsSnmp.h"
#include "wrsOSStatusGroup.h"
#include "wrsNetworkingStatusGroup.h"
#include "wrsGeneralStatusGroup.h"
static struct pickinfo wrsGeneralStatus_pickinfo[] = {
FIELD(wrsGeneralStatus_s, ASN_INTEGER, wrsMainSystemStatus),
FIELD(wrsGeneralStatus_s, ASN_INTEGER, wrsOSStatus),
FIELD(wrsGeneralStatus_s, ASN_INTEGER, wrsTimingStatus),
FIELD(wrsGeneralStatus_s, ASN_INTEGER, wrsNetworkingStatus),
};
struct wrsGeneralStatus_s wrsGeneralStatus_s;
time_t wrsGeneralStatus_data_fill(void)
{
static time_t time_update; /* time of last update */
time_t time_osstatus; /* time when wrsOSStatus data was updated */
time_t time_networking_status; /* time when wrsNetworkingStatus data
* was updated */
struct wrsOSStatus_s *o;
struct wrsNetworkingStatus_s *n;
struct wrsGeneralStatus_s *g;
time_osstatus = wrsOSStatus_data_fill();
time_networking_status = wrsNetworkingStatus_data_fill();
if (time_osstatus <= time_update
&& time_networking_status <= time_update) {
/* cache not updated, return last update time */
snmp_log(LOG_ERR,
"SNMP: wrsGeneralStatusGroup cache\n");
return time_update;
}
memset(&wrsGeneralStatus_s, 0, sizeof(wrsGeneralStatus_s));
/*********************************************************************\
|**************************** wrsOSStatus ****************************|
\*********************************************************************/
o = &wrsOSStatus_s;
if ( /* check if error */
o->wrsBootSuccessful == WRS_BOOT_SUCCESSFUL_ERROR
) {
wrsGeneralStatus_s.wrsOSStatus = WRS_OS_STATUS_ERROR;
} else if ( /* check if warning */
o->wrsBootSuccessful == WRS_BOOT_SUCCESSFUL_WARNING
|| o->wrsTemperatureWarning == WRS_TEMPERATURE_WARNING_THOLD_NOT_SET
|| o->wrsTemperatureWarning == WRS_TEMPERATURE_WARNING_TOO_HIGH
) { /* warning */
wrsGeneralStatus_s.wrsOSStatus = WRS_OS_STATUS_WARNING;
} else if ( /* check if any of fields equal to 0 or WARNING_NA */
o->wrsBootSuccessful == WRS_BOOT_SUCCESSFUL_WARNING_NA
|| o->wrsBootSuccessful == 0
|| o->wrsTemperatureWarning == 0
) { /* warning NA */
wrsGeneralStatus_s.wrsOSStatus = WRS_OS_STATUS_WARNING_NA;
} else if ( /* check if OK */
o->wrsBootSuccessful == WRS_BOOT_SUCCESSFUL_OK
&& o->wrsTemperatureWarning == WRS_TEMPERATURE_WARNING_OK
) { /* OK */
wrsGeneralStatus_s.wrsOSStatus = WRS_OS_STATUS_OK;
} else { /* probably bug in previous conditions,
* this should never happen */
wrsGeneralStatus_s.wrsOSStatus = WRS_OS_STATUS_BUG;
}
/*********************************************************************\
|************************** wrsTimingStatus **************************|
\*********************************************************************/
/* not implemented, always return OK */
wrsGeneralStatus_s.wrsTimingStatus = WRS_TIMING_STATUS_OK;
/*********************************************************************\
|************************ wrsNetworkingStatus ************************|
\*********************************************************************/
n = &wrsNetworkingStatus_s;
if ( /* check if error */
n->wrsSFPsStatus == WRS_SFPS_STATUS_ERROR
|| n->wrsEndpointStatus == WRS_ENDPOINT_STATUS_ERROR
|| n->wrsSwcoreStatus == WRS_SWCORE_STATUS_ERROR
|| n->wrsRTUStatus == WRS_RTU_STATUS_ERROR
) {
wrsGeneralStatus_s.wrsNetworkingStatus =
WRS_NETWORKING_STATUS_ERROR;
} else if ( /* check if warning */
n->wrsSFPsStatus == WRS_SFPS_STATUS_WARNING
) { /* warning */
wrsGeneralStatus_s.wrsNetworkingStatus =
WRS_NETWORKING_STATUS_WARNING;
} else if ( /* check if any of fields equal to 0 or WARNING_NA */
n->wrsSFPsStatus == WRS_SFPS_STATUS_WARNING_NA
|| n->wrsSFPsStatus == 0
|| n->wrsEndpointStatus == 0
|| n->wrsSwcoreStatus == 0
|| n->wrsRTUStatus == 0
) { /* warning NA */
wrsGeneralStatus_s.wrsNetworkingStatus =
WRS_NETWORKING_STATUS_WARNING_NA;
} else if ( /* check if OK, FR (first read) is also ok */
n->wrsSFPsStatus == WRS_SFPS_STATUS_OK
&& (n->wrsEndpointStatus == WRS_ENDPOINT_STATUS_OK
|| n->wrsEndpointStatus == WRS_ENDPOINT_STATUS_FR) /* FR*/
&& (n->wrsSwcoreStatus == WRS_SWCORE_STATUS_OK
|| n->wrsSwcoreStatus == WRS_SWCORE_STATUS_FR) /* FR */
&& (n->wrsRTUStatus == WRS_RTU_STATUS_OK
|| n->wrsRTUStatus == WRS_RTU_STATUS_FR) /* FR */
) { /* OK */
wrsGeneralStatus_s.wrsNetworkingStatus =
WRS_NETWORKING_STATUS_OK;
} else { /* probably bug in previous conditions,
* this should never happen */
wrsGeneralStatus_s.wrsNetworkingStatus =
WRS_NETWORKING_STATUS_BUG;
}
/*********************************************************************\
|************************ wrsMainSystemStatus ************************|
\*********************************************************************/
/* update at the end of this group to have latest results of other
* statuses */
g = &wrsGeneralStatus_s;
if ( /* check if error */
g->wrsOSStatus == WRS_OS_STATUS_ERROR
|| g->wrsTimingStatus == WRS_TIMING_STATUS_ERROR
|| g->wrsNetworkingStatus == WRS_NETWORKING_STATUS_ERROR
) {
wrsGeneralStatus_s.wrsMainSystemStatus =
WRS_MAIN_SYSTEM_STATUS_ERROR;
} else if ( /* check if warning */
g->wrsOSStatus == WRS_OS_STATUS_WARNING
|| g->wrsTimingStatus == WRS_TIMING_STATUS_WARNING
|| g->wrsNetworkingStatus == WRS_NETWORKING_STATUS_WARNING
) { /* warning */
wrsGeneralStatus_s.wrsMainSystemStatus =
WRS_MAIN_SYSTEM_STATUS_WARNING;
} else if ( /* check if any of fields equal to 0 or WARNING_NA */
g->wrsOSStatus == WRS_OS_STATUS_WARNING_NA
|| g->wrsOSStatus == 0
|| g->wrsTimingStatus == WRS_TIMING_STATUS_WARNING_NA
|| g->wrsTimingStatus == 0
|| g->wrsNetworkingStatus == WRS_NETWORKING_STATUS_WARNING_NA
|| g->wrsNetworkingStatus == 0
) { /* warning NA */
wrsGeneralStatus_s.wrsMainSystemStatus =
WRS_MAIN_SYSTEM_STATUS_WARNING_NA;
} else if ( /* check if OK */
g->wrsOSStatus == WRS_OS_STATUS_OK
&& g->wrsTimingStatus == WRS_TIMING_STATUS_OK
&& g->wrsNetworkingStatus == WRS_NETWORKING_STATUS_OK
) { /* OK */
wrsGeneralStatus_s.wrsMainSystemStatus =
WRS_MAIN_SYSTEM_STATUS_OK;
} else { /* probably bug in previous conditions,
* this should never happen */
wrsGeneralStatus_s.wrsMainSystemStatus =
WRS_MAIN_SYSTEM_STATUS_BUG;
}
time_update = time(NULL);
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRSGENERALSTATUS_OID
#define GT_PICKINFO wrsGeneralStatus_pickinfo
#define GT_DATA_FILL_FUNC wrsGeneralStatus_data_fill
#define GT_DATA_STRUCT wrsGeneralStatus_s
#define GT_GROUP_NAME "wrsGeneralStatusGroup"
#define GT_INIT_FUNC init_wrsGeneralStatusGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_GENERAL_STATUS_GROUP_H
#define WRS_GENERAL_STATUS_GROUP_H
#define WRSGENERALSTATUS_OID WRS_OID, 6, 1
#define WRS_MAIN_SYSTEM_STATUS_OK 1 /* ok */
#define WRS_MAIN_SYSTEM_STATUS_ERROR 2 /* error */
#define WRS_MAIN_SYSTEM_STATUS_WARNING 3 /* warning */
#define WRS_MAIN_SYSTEM_STATUS_WARNING_NA 4 /* warning, at least one field is
* equal to 0 (NA),shouldn't happen in
* normal operation */
#define WRS_MAIN_SYSTEM_STATUS_BUG 5 /* warning */
#define WRS_OS_STATUS_OK 1 /* ok */
#define WRS_OS_STATUS_ERROR 2 /* error */
#define WRS_OS_STATUS_WARNING 3 /* warning */
#define WRS_OS_STATUS_WARNING_NA 4 /* warning, at least one field is
* equal to 0 (NA),shouldn't happen in
* normal operation */
#define WRS_OS_STATUS_BUG 5 /* warning */
#define WRS_TIMING_STATUS_OK 1 /* ok */
#define WRS_TIMING_STATUS_ERROR 2 /* error */
#define WRS_TIMING_STATUS_WARNING 3 /* warning */
#define WRS_TIMING_STATUS_WARNING_NA 4 /* warning, at least one field is
* equal to 0 (NA),shouldn't happen in
* normal operation */
#define WRS_TIMING_STATUS_BUG 5 /* warning */
#define WRS_NETWORKING_STATUS_OK 1 /* ok */
#define WRS_NETWORKING_STATUS_ERROR 2 /* error */
#define WRS_NETWORKING_STATUS_WARNING 3 /* warning */
#define WRS_NETWORKING_STATUS_WARNING_NA 4 /* warning, at least one field is
* equal to 0 (NA),shouldn't happen in
* normal operation */
#define WRS_NETWORKING_STATUS_BUG 5 /* warning */
struct wrsGeneralStatus_s {
int wrsMainSystemStatus;
int wrsOSStatus;
int wrsTimingStatus;
int wrsNetworkingStatus;
};
extern struct wrsGeneralStatus_s wrsGeneralStatus_s;
time_t wrsGeneralStatus_data_fill(void);
void init_wrsGeneralStatusGroup(void);
#endif /* WRS_GENERAL_STATUS_GROUP_H */
static int group_handler(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
int obj; /* the final index */
struct pickinfo *pi;
void *ptr;
int len;
/*
* Retrieve information from ppsi itself. But this function
* is called once for every item, so only query the whole set
* once every 2 seconds.
*/
GT_DATA_FILL_FUNC();
switch (reqinfo->mode) {
case MODE_GET:
/* "- 2" because last is 0 for all scalars, I suppose */
obj = requests->requestvb->name[
requests->requestvb->name_length - 2];
obj--; /* we are 0-based */
if (obj < 0 || obj >= ARRAY_SIZE(GT_PICKINFO)) {
snmp_log(LOG_ERR,
"wrong index (%d) in "GT_GROUP_NAME"\n",
obj + 1);
return SNMP_ERR_GENERR;
}
pi = GT_PICKINFO + obj;
ptr = (void *)&GT_DATA_STRUCT + pi->offset;
len = pi->len;
if (len > 8) /* special case for strings */
len = strnlen(ptr, len);
snmp_set_var_typed_value(requests->requestvb,
pi->type, ptr, len);
break;
default:
snmp_log(LOG_ERR, "unknown mode (%d) in "GT_GROUP_NAME"\n",
reqinfo->mode);
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
/* init function */
void GT_INIT_FUNC(void)
{
const oid wrsGT_oid[] = { GT_OID };
netsnmp_handler_registration *hreg;
/* do the registration for the scalars/globals */
hreg = netsnmp_create_handler_registration(
GT_GROUP_NAME, group_handler,
wrsGT_oid, OID_LENGTH(wrsGT_oid),
HANDLER_CAN_RONLY);
netsnmp_register_scalar_group(
hreg, 1 /* min */, ARRAY_SIZE(GT_PICKINFO) /* max */);
}
#include "wrsSnmp.h"
#include "wrsPortStatusTable.h"
#include "wrsPstatsTable.h"
#include "wrsNetworkingStatusGroup.h"
#include <libwr/config.h>
static struct pickinfo wrsNetworkingStatus_pickinfo[] = {
FIELD(wrsNetworkingStatus_s, ASN_INTEGER, wrsSFPsStatus),
FIELD(wrsNetworkingStatus_s, ASN_INTEGER, wrsEndpointStatus),
FIELD(wrsNetworkingStatus_s, ASN_INTEGER, wrsSwcoreStatus),
FIELD(wrsNetworkingStatus_s, ASN_INTEGER, wrsRTUStatus),
};
struct wrsNetworkingStatus_s wrsNetworkingStatus_s;
static struct wrsNetworkingStatus_config ns_dotconfig;
static struct ns_pstats ns_pstats_copy[WRS_N_PORTS];
static void copy_pstats(struct ns_pstats *copy, struct wrsPstatsTable_s *org,
unsigned int rows)
{
int i;
for (i = 0; i < rows; i++) {
/* wrsEndpointStatus */
copy->TXUnderrun = org->TXUnderrun;
copy->RXOverrun = org->RXOverrun;
copy->RXInvalidCode = org->RXInvalidCode;
copy->RXSyncLost = org->RXSyncLost;
copy->RXPfilterDropped = org->RXPfilterDropped;
copy->RXPCSErrors = org->RXPCSErrors;
copy->RXCRCErrors = org->RXCRCErrors;
/* wrsSwcoreStatus */
copy->RXFrames = org->RXFrames;
copy->RXPrio0 = org->RXPrio0;
copy->RXPrio1 = org->RXPrio1;
copy->RXPrio2 = org->RXPrio2;
copy->RXPrio3 = org->RXPrio3;
copy->RXPrio4 = org->RXPrio4;
copy->RXPrio5 = org->RXPrio5;
copy->RXPrio6 = org->RXPrio6;
copy->RXPrio7 = org->RXPrio7;
copy->FastMatchPriority = org->FastMatchPriority;
/* wrsRTUStatus */
copy->RXDropRTUFull = org->RXDropRTUFull;
copy++;
org++;
}
}
static int get_endpoint_status(struct ns_pstats *old,
struct wrsPstatsTable_s *new, unsigned int rows,
float t_delta)
{
int i;
int ret;
ret = 0;
/* values from 2.2.2 "Fault in the Endpoint’s transmission/reception
* path" in wrs_failures document shouldn't change faster than 1
* per second */
for (i = 0; i < rows; i++) {
if (
((new[i].TXUnderrun - old[i].TXUnderrun)/t_delta > 1.0)
|| ((new[i].RXOverrun - old[i].RXOverrun)/t_delta > 1.0)
|| ((new[i].RXInvalidCode - old[i].RXInvalidCode)/t_delta > 1.0)
|| ((new[i].RXSyncLost - old[i].RXSyncLost)/t_delta > 1.0)
|| ((new[i].RXPfilterDropped - old[i].RXPfilterDropped)/t_delta > 1.0)
|| ((new[i].RXPCSErrors - old[i].RXPCSErrors)/t_delta > 1.0)
|| ((new[i].RXCRCErrors - old[i].RXCRCErrors)/t_delta > 1.0)
) {
/* if error, no need to check more, but do it just for
* logs */
ret = 1;
snmp_log(LOG_ERR, "SNMP: wrsEndpointStatus failed for "
"port %d\n", i);
}
}
return ret;
}
static int get_swcore_status(struct ns_pstats *old,
struct wrsPstatsTable_s *new, unsigned int rows,
float t_delta)
{
int i;
int ret;
ret = 0;
for (i = 0; i < rows; i++) {
/* TXFrames and Forwarded described in 2.2.3 "Problem with the
* SwCore or Endpoint HDL module" in wrs_failures document
* shouldn't differ more than FORWARD_DELTA in total */
/* counter Forwarded (38) is not implemented in HDL!!! */
#if 0
if ( /* shouldn't differ more than FORWARD_DELTA */
((new[i].TXFrames - new[i].Forwarded) > FORWARD_DELTA)
|| ((new[i].Forwarded - new[i].TXFrames) > FORWARD_DELTA)
) {
/* if error, no need to check more, but do it just for
* logs */
ret = 1;
snmp_log(LOG_ERR, "SNMP: wrsSwcoreStatus failed for "
"port %d\n", i);
}
#endif
/* values from 2.2.5 "Too much HP traffic / Per-priority queue
* full" in wrs_failures document shouldn't change faster
* than parameters defined in dotconfig per second */
if ( /* shouldn't differ more than FORWARD_DELTA */
((new[i].RXFrames - old[i].RXFrames)/t_delta >= ns_dotconfig.rx_frame_rate)
|| ((new[i].RXPrio0 - old[i].RXPrio0)/t_delta >= ns_dotconfig.rx_prio_frame_rate)
|| ((new[i].RXPrio1 - old[i].RXPrio1)/t_delta >= ns_dotconfig.rx_prio_frame_rate)
|| ((new[i].RXPrio2 - old[i].RXPrio2)/t_delta >= ns_dotconfig.rx_prio_frame_rate)
|| ((new[i].RXPrio3 - old[i].RXPrio3)/t_delta >= ns_dotconfig.rx_prio_frame_rate)
|| ((new[i].RXPrio4 - old[i].RXPrio4)/t_delta >= ns_dotconfig.rx_prio_frame_rate)
|| ((new[i].RXPrio5 - old[i].RXPrio5)/t_delta >= ns_dotconfig.rx_prio_frame_rate)
|| ((new[i].RXPrio6 - old[i].RXPrio6)/t_delta >= ns_dotconfig.rx_prio_frame_rate)
|| ((new[i].RXPrio7 - old[i].RXPrio7)/t_delta >= ns_dotconfig.rx_prio_frame_rate)
|| ((new[i].FastMatchPriority - old[i].FastMatchPriority)/t_delta >= ns_dotconfig.hp_frame_rate)
) {
/* if error, no need to check more, but do it just for
* logs */
ret = 1;
snmp_log(LOG_ERR, "SNMP: wrsSwcoreStatus failed for "
"port %d\n", i);
}
}
return ret;
}
static int get_rtu_status(struct ns_pstats *old,
struct wrsPstatsTable_s *new, unsigned int rows,
float t_delta)
{
int i;
int ret;
ret = 0;
/* values from 2.2.4 "RTU is full and cannot accept more requests" in
* wrs_failures document shouldn't increase */
for (i = 0; i < rows; i++) {
if ((new[i].TXUnderrun - old[i].TXUnderrun) > 0) {
/* if error, no need to check more, but do it just for
* logs */
ret = 1;
snmp_log(LOG_ERR, "SNMP: wrsEndpointStatus failed for "
"port %d\n", i);
}
}
/* TODO: add 2.2.7 "Network loop - two or more identical MACs on two or
* more ports" when implemented */
return ret;
}
/* read configuration from dotconfig */
static void load_dot_config(void)
{
char *tmp;
tmp = libwr_cfg_get("SNMP_SWCORESTATUS_HP_FRAME_RATE");
if (tmp)
ns_dotconfig.hp_frame_rate = atoi(tmp);
tmp = libwr_cfg_get("SNMP_SWCORESTATUS_RX_FRAME_RATE");
if (tmp)
ns_dotconfig.rx_frame_rate = atoi(tmp);
tmp = libwr_cfg_get("SNMP_SWCORESTATUS_RX_PRIO_FRAME_RATE");
if (tmp)
ns_dotconfig.rx_prio_frame_rate = atoi(tmp);
}
time_t wrsNetworkingStatus_data_fill(void)
{
static time_t time_update; /* time of last update */
time_t time_port_status; /* time when port status table was updated */
time_t time_pstats; /* time when pstats table was updated */
float time_pstats_delta; /* seconds since last update */
static time_t time_pstats_prev; /* time when previous state of pstats
* table was updated */
unsigned int port_status_nrows; /* number of rows in PortStatusTable */
unsigned int pstats_nrows; /* number of rows in PstatsTable */
unsigned int port_status_n_ok; /* number of ok ports */
unsigned int port_status_n_error; /* number of error ports */
unsigned int port_status_n_down; /* number of down ports */
unsigned int port_status_n_na; /* number of N/A ports */
int i;
int ret;
struct wrsPortStatusTable_s *p_a;
static int run_once = 1;
time_port_status = wrsPortStatusTable_data_fill(&port_status_nrows);
time_pstats = wrsPstatsTable_data_fill(&pstats_nrows);
if (time_port_status <= time_update
&& time_pstats <= time_update) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time(NULL);
if (run_once) {
run_once = 0;
/* read configuration from dotconfig */
load_dot_config();
}
time_pstats_delta = time_pstats - time_pstats_prev;
memset(&wrsNetworkingStatus_s, 0, sizeof(wrsNetworkingStatus_s));
/*********************************************************************\
|*************************** wrsSFPsStatus ***************************|
\*********************************************************************/
p_a = wrsPortStatusTable_array;
port_status_n_ok = 0;
port_status_n_error = 0;
port_status_n_down = 0;
port_status_n_na = 0;
/* count number of ports of each status */
for (i = 0; i < port_status_nrows; i++) {
if (p_a[i].sfp_error == WRS_PORT_STATUS_SFP_ERROR_SFP_OK) {
port_status_n_ok++;
}
if (p_a[i].sfp_error == WRS_PORT_STATUS_SFP_ERROR_SFP_ERROR) {
port_status_n_error++;
}
if (p_a[i].sfp_error == WRS_PORT_STATUS_SFP_ERROR_PORT_DOWN) {
port_status_n_down++;
}
if (p_a[i].sfp_error == 0) {
port_status_n_na++;
}
}
if ((port_status_n_error > 0)
|| ((port_status_n_ok + port_status_n_down + port_status_n_na)
!= port_status_nrows)
) {
/* error */
wrsNetworkingStatus_s.wrsSFPsStatus = WRS_SFPS_STATUS_ERROR;
} else if (port_status_n_na > 0) { /* warning NA */
wrsNetworkingStatus_s.wrsSFPsStatus =
WRS_SFPS_STATUS_WARNING_NA;
} else if ((port_status_n_ok + port_status_n_down) ==
port_status_nrows) {
/* OK is when port is ok or down */
wrsNetworkingStatus_s.wrsSFPsStatus = WRS_SFPS_STATUS_OK;
} else { /* probably bug in previous conditions,
* this should never happen */
wrsNetworkingStatus_s.wrsSFPsStatus = WRS_SFPS_STATUS_BUG;
}
/*********************************************************************\
|************************* wrsEndpointStatus *************************|
\*********************************************************************/
if (time_pstats_prev) { /* never generate error during first check */
ret = get_endpoint_status(ns_pstats_copy, pstats_array,
pstats_nrows, time_pstats_delta);
if (ret == 0)
wrsNetworkingStatus_s.wrsEndpointStatus =
WRS_ENDPOINT_STATUS_OK;
else
wrsNetworkingStatus_s.wrsEndpointStatus =
WRS_ENDPOINT_STATUS_ERROR;
} else {
/* first read */
wrsNetworkingStatus_s.wrsEndpointStatus =
WRS_ENDPOINT_STATUS_FR;
}
/*********************************************************************\
|************************** wrsSwcoreStatus **************************|
\*********************************************************************/
if (time_pstats_prev) { /* never generate error during first check */
ret = get_swcore_status(ns_pstats_copy, pstats_array,
pstats_nrows, time_pstats_delta);
if (ret == 0)
wrsNetworkingStatus_s.wrsSwcoreStatus =
WRS_SWCORE_STATUS_OK;
else
wrsNetworkingStatus_s.wrsSwcoreStatus =
WRS_SWCORE_STATUS_ERROR;
} else {
/* first read */
wrsNetworkingStatus_s.wrsSwcoreStatus = WRS_SWCORE_STATUS_FR;
}
/*********************************************************************\
|*************************** wrsRTUStatus ***************************|
\*********************************************************************/
if (time_pstats_prev) { /* never generate error during first check */
ret = get_rtu_status(ns_pstats_copy, pstats_array,
pstats_nrows, time_pstats_delta);
if (ret == 0)
wrsNetworkingStatus_s.wrsRTUStatus =
WRS_RTU_STATUS_OK;
else
wrsNetworkingStatus_s.wrsRTUStatus =
WRS_RTU_STATUS_ERROR;
} else {
/* first read */
wrsNetworkingStatus_s.wrsRTUStatus = WRS_RTU_STATUS_FR;
}
/* save time of pstats copy */
time_pstats_prev = time_pstats;
/* copy current set of pstats */
copy_pstats(ns_pstats_copy, pstats_array, pstats_nrows);
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRSNETWORKINGSTATUS_OID
#define GT_PICKINFO wrsNetworkingStatus_pickinfo
#define GT_DATA_FILL_FUNC wrsNetworkingStatus_data_fill
#define GT_DATA_STRUCT wrsNetworkingStatus_s
#define GT_GROUP_NAME "wrsNetworkingStatusGroup"
#define GT_INIT_FUNC init_wrsNetworkingStatusGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_NETWORKING_STATUS_GROUP_H
#define WRS_NETWORKING_STATUS_GROUP_H
#define WRSNETWORKINGSTATUS_OID WRS_OID, 6, 2, 3
#define FORWARD_DELTA 5
#define WRS_SFPS_STATUS_OK 1 /* ok */
#define WRS_SFPS_STATUS_ERROR 2 /* error */
#define WRS_SFPS_STATUS_WARNING 3 /* warning, not used */
#define WRS_SFPS_STATUS_WARNING_NA 4 /* warning, at least one field is
* equal to 0 (NA),shouldn't happen in
* normal operation */
#define WRS_SFPS_STATUS_BUG 5 /* warning */
#define WRS_ENDPOINT_STATUS_FR 1 /* ok, first read */
#define WRS_ENDPOINT_STATUS_OK 2 /* ok */
#define WRS_ENDPOINT_STATUS_ERROR 3 /* error */
#define WRS_SWCORE_STATUS_FR 1 /* ok, first read */
#define WRS_SWCORE_STATUS_OK 2 /* ok */
#define WRS_SWCORE_STATUS_ERROR 3 /* error */
#define WRS_RTU_STATUS_FR 1 /* ok, first read */
#define WRS_RTU_STATUS_OK 2 /* ok */
#define WRS_RTU_STATUS_ERROR 3 /* error */
struct wrsNetworkingStatus_s {
int wrsSFPsStatus;
int wrsEndpointStatus;
int wrsSwcoreStatus;
int wrsRTUStatus;
};
extern struct wrsNetworkingStatus_s wrsNetworkingStatus_s;
time_t wrsNetworkingStatus_data_fill(void);
void init_wrsNetworkingStatusGroup(void);
struct ns_pstats {
/* wrsEndpointStatus */
uint32_t TXUnderrun; /* 1 */
uint32_t RXOverrun; /* 2 */
uint32_t RXInvalidCode; /* 3 */
uint32_t RXSyncLost; /* 4 */
uint32_t RXPfilterDropped; /* 6 */
uint32_t RXPCSErrors; /* 7 */
uint32_t RXCRCErrors; /* 10 */
/* wrsSwcoreStatus */
/* Too much HP traffic / Per-priority queue full */
uint32_t RXFrames; /* 20 */
uint32_t RXPrio0; /* 22 */
uint32_t RXPrio1; /* 23 */
uint32_t RXPrio2; /* 24 */
uint32_t RXPrio3; /* 25 */
uint32_t RXPrio4; /* 26 */
uint32_t RXPrio5; /* 27 */
uint32_t RXPrio6; /* 28 */
uint32_t RXPrio7; /* 29 */
uint32_t FastMatchPriority; /* 33 */
/* wrsRTUStatus */
uint32_t RXDropRTUFull; /* 21 */
};
/* parameters read from dot-config */
struct wrsNetworkingStatus_config {
int hp_frame_rate;
int rx_frame_rate;
int rx_prio_frame_rate;
};
#endif /* WRS_NETWORKING_STATUS_GROUP_H */
#include "wrsSnmp.h"
#include "wrsBootStatusGroup.h"
#include "wrsTemperatureGroup.h"
#include "wrsOSStatusGroup.h"
static struct pickinfo wrsOSStatus_pickinfo[] = {
FIELD(wrsOSStatus_s, ASN_INTEGER, wrsBootSuccessful),
FIELD(wrsOSStatus_s, ASN_INTEGER, wrsTemperatureWarning),
};
struct wrsOSStatus_s wrsOSStatus_s;
time_t wrsOSStatus_data_fill(void)
{
static time_t time_update; /* time of last update */
time_t time_temp; /* time when temperature data was updated */
time_t time_boot; /* time when boot data was updated */
struct wrsBootStatus_s *b;
time_boot = wrsBootStatus_data_fill();
time_temp = wrsTemperature_data_fill();
if (time_boot <= time_update
&& time_temp <= time_update) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time(NULL);
memset(&wrsOSStatus_s, 0, sizeof(wrsOSStatus_s));
/*********************************************************************\
|************************* wrsBootSuccessful *************************|
\*********************************************************************/
b = &wrsBootStatus_s;
if ( /* check if error */
b->wrsBootCnt == 0
|| b->wrsRestartReason == WRS_RESTART_REASON_ERROR
|| b->wrsConfigSource == WRS_CONFIG_SOURCE_PROTO_ERROR
|| b->wrsBootConfigStatus == WRS_CONFIG_STATUS_ERROR
|| b->wrsBootConfigStatus == WRS_CONFIG_STATUS_DL_ERROR
|| b->wrsBootConfigStatus == WRS_CONFIG_STATUS_CHECK_ERROR
|| b->wrsBootHwinfoReadout == WRS_BOOT_HWINFO_ERROR
|| b->wrsBootLoadFPGA == WRS_BOOT_LOAD_FPGA_ERROR
|| b->wrsBootLoadFPGA == WRS_BOOT_LOAD_FPGA_FILE_NOT_FOUND
|| b->wrsBootLoadLM32 == WRS_BOOT_LOAD_LM32_ERROR
|| b->wrsBootLoadLM32 == WRS_BOOT_LOAD_LM32_FILE_NOT_FOUND
|| b->wrsBootKernelModulesMissing > 0 /* contain number of missing modules */
|| b->wrsBootUserspaceDaemonsMissing > 0 /* contain number of missing deamons */
) {
wrsOSStatus_s.wrsBootSuccessful = WRS_BOOT_SUCCESSFUL_ERROR;
} else if ( /* check if warning */
b->wrsConfigSource == WRS_CONFIG_SOURCE_PROTO_ERROR_MINOR
|| b->wrsBootConfigStatus == WRS_CONFIG_STATUS_ERROR_MINOR
|| b->wrsBootHwinfoReadout == WRS_BOOT_HWINFO_ERROR_MINOR
|| b->wrsBootHwinfoReadout == WRS_BOOT_HWINFO_WARNING
|| b->wrsBootLoadFPGA == WRS_BOOT_LOAD_FPGA_ERROR_MINOR
|| b->wrsBootLoadLM32 == WRS_BOOT_LOAD_LM32_ERROR_MINOR
) { /* warning */
wrsOSStatus_s.wrsBootSuccessful = WRS_BOOT_SUCCESSFUL_WARNING;
} else if ( /* check if any of fields equal to 0 */
b->wrsRestartReason == 0
|| b->wrsConfigSource == 0
|| b->wrsBootConfigStatus == 0
|| b->wrsBootHwinfoReadout == 0
|| b->wrsBootLoadFPGA == 0
|| b->wrsBootLoadLM32 == 0
) { /* warning NA */
wrsOSStatus_s.wrsBootSuccessful = WRS_BOOT_SUCCESSFUL_WARNING_NA;
} else if ( /* check if OK */
b->wrsBootCnt != 0
&& b->wrsRestartReason != WRS_RESTART_REASON_ERROR
&& b->wrsConfigSource != WRS_CONFIG_SOURCE_PROTO_ERROR
&& b->wrsConfigSource != WRS_CONFIG_SOURCE_PROTO_ERROR_MINOR /* warning */
&& b->wrsBootConfigStatus == WRS_CONFIG_STATUS_OK
&& b->wrsBootHwinfoReadout == WRS_BOOT_HWINFO_OK
&& b->wrsBootLoadFPGA == WRS_BOOT_LOAD_FPGA_OK
&& b->wrsBootLoadLM32 == WRS_BOOT_LOAD_LM32_OK
&& b->wrsBootKernelModulesMissing == 0
&& b->wrsBootUserspaceDaemonsMissing == 0
) { /* OK, but check source */
/* additional check of source */
if (
b->wrsConfigSource == WRS_CONFIG_SOURCE_PROTO_LOCAL
|| (
(
b->wrsConfigSource == WRS_CONFIG_SOURCE_PROTO_TFTP
|| b->wrsConfigSource == WRS_CONFIG_SOURCE_PROTO_HTTP
|| b->wrsConfigSource == WRS_CONFIG_SOURCE_PROTO_FTP
)
&& strnlen(b->wrsConfigSourceHost, WRS_CONFIG_SOURCE_HOST_LEN + 1)
&& strnlen(b->wrsConfigSourceFilename, WRS_CONFIG_SOURCE_FILENAME_LEN + 1)
)
) { /* OK */
/* when dotconfig is local or (remote and host not empty and filename not empty) */
wrsOSStatus_s.wrsBootSuccessful = WRS_BOOT_SUCCESSFUL_OK;
} else { /* error because of source */
wrsOSStatus_s.wrsBootSuccessful = WRS_BOOT_SUCCESSFUL_ERROR;
}
} else { /* probably bug in previous conditions,
* this should never happen */
wrsOSStatus_s.wrsBootSuccessful = WRS_BOOT_SUCCESSFUL_BUG;
}
/*********************************************************************\
|*********************** wrsTemperatureWarning ***********************|
\*********************************************************************/
if (!wrsTemperature_s.temp_fpga_thold
&& !wrsTemperature_s.temp_pll_thold
&& !wrsTemperature_s.temp_psl_thold
&& !wrsTemperature_s.temp_psr_thold) {
/* no threshold are set */
wrsOSStatus_s.wrsTemperatureWarning =
WRS_TEMPERATURE_WARNING_THOLD_NOT_SET;
} else {
/* rise warning when at least one threshold level
* is exceeded, add 2, since 0 is readings not available, 1 is
* no threshold set (WRS_TEMPERATURE_WARNING_THOLD_NOT_SET)
* 2 is ok (WRS_TEMPERATURE_WARNING_OK), 3 is temperature too
* high (WRS_TEMPERATURE_WARNING_TOO_HIGH) */
wrsOSStatus_s.wrsTemperatureWarning = 2 +
((wrsTemperature_s.temp_fpga > wrsTemperature_s.temp_fpga_thold)
|| (wrsTemperature_s.temp_pll > wrsTemperature_s.temp_pll_thold)
|| (wrsTemperature_s.temp_psl > wrsTemperature_s.temp_psl_thold)
|| (wrsTemperature_s.temp_psr > wrsTemperature_s.temp_psr_thold));
}
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRSOSSTATUS_OID
#define GT_PICKINFO wrsOSStatus_pickinfo
#define GT_DATA_FILL_FUNC wrsOSStatus_data_fill
#define GT_DATA_STRUCT wrsOSStatus_s
#define GT_GROUP_NAME "wrsOSStatusGroup"
#define GT_INIT_FUNC init_wrsOSStatusGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_OSSTATUS_GROUP_H
#define WRS_OSSTATUS_GROUP_H
#define WRSOSSTATUS_OID WRS_OID, 6, 2, 1
#define WRS_BOOT_SUCCESSFUL_OK 1 /* ok */
#define WRS_BOOT_SUCCESSFUL_ERROR 2 /* error */
#define WRS_BOOT_SUCCESSFUL_WARNING 3 /* warning */
#define WRS_BOOT_SUCCESSFUL_WARNING_NA 4 /* warning, at least one field is
* equal to 0 (NA),shouldn't happen in
* normal operation */
#define WRS_BOOT_SUCCESSFUL_BUG 5 /* warning */
#define WRS_TEMPERATURE_WARNING_THOLD_NOT_SET 1 /* warning */
#define WRS_TEMPERATURE_WARNING_OK 2 /* ok */
#define WRS_TEMPERATURE_WARNING_TOO_HIGH 3 /* warning */
struct wrsOSStatus_s {
int wrsBootSuccessful;
int wrsTemperatureWarning;
};
extern struct wrsOSStatus_s wrsOSStatus_s;
time_t wrsOSStatus_data_fill(void);
void init_wrsOSStatusGroup(void);
#endif /* WRS_OSSTATUS_GROUP_H */
#include "wrsSnmp.h"
#include "snmp_shmem.h"
#include "wrsPortStatusTable.h"
/* Our data: per-port information */
struct wrsPortStatusTable_s wrsPortStatusTable_array[WRS_N_PORTS];
static struct pickinfo wrsPortStatusTable_pickinfo[] = {
FIELD(wrsPortStatusTable_s, ASN_UNSIGNED, index), /* not reported */
FIELD(wrsPortStatusTable_s, ASN_OCTET_STR, port_name),
FIELD(wrsPortStatusTable_s, ASN_INTEGER, link_up),
FIELD(wrsPortStatusTable_s, ASN_INTEGER, port_mode),
FIELD(wrsPortStatusTable_s, ASN_INTEGER, port_locked),
FIELD(wrsPortStatusTable_s, ASN_OCTET_STR, peer_id),
FIELD(wrsPortStatusTable_s, ASN_OCTET_STR, sfp_vn),
FIELD(wrsPortStatusTable_s, ASN_OCTET_STR, sfp_pn),
FIELD(wrsPortStatusTable_s, ASN_OCTET_STR, sfp_vs),
FIELD(wrsPortStatusTable_s, ASN_INTEGER, sfp_in_db),
FIELD(wrsPortStatusTable_s, ASN_INTEGER, sfp_GbE),
FIELD(wrsPortStatusTable_s, ASN_INTEGER, sfp_error),
};
time_t wrsPortStatusTable_data_fill(unsigned int *n_rows)
{
unsigned ii, i;
unsigned retries = 0;
static time_t time_update;
time_t time_cur;
/* number of rows does not change for wrsPortStatusTable */
if (n_rows)
*n_rows = WRS_N_PORTS;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSPORTSTATUSTABLE_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
/* read data, with the sequential lock to have all data consistent */
struct hal_port_state *port_state;
memset(wrsPortStatusTable_array, 0, sizeof(wrsPortStatusTable_array));
while (1) {
ii = wrs_shm_seqbegin(hal_head);
for (i = 0; i < hal_nports_local; ++i) {
/* Assume that number of ports does not change between
* reads */
snprintf(wrsPortStatusTable_array[i].port_name, 10,
"wr%d", i);
port_state = hal_lookup_port(hal_ports,
hal_nports_local,
wrsPortStatusTable_array[i].port_name);
/* No need to copy all ports structures, only what
* we're interested in.
* Keep value 0 for Not available */
wrsPortStatusTable_array[i].link_up =
1 + state_up(port_state->state);
wrsPortStatusTable_array[i].port_mode =
port_state->mode;
if (port_state->state == HAL_PORT_STATE_DISABLED) {
wrsPortStatusTable_array[i].sfp_error =
WRS_PORT_STATUS_SFP_ERROR_PORT_DOWN;
/* if port is disabled don't fill
* other fields */
continue;
}
/* Keep value 0 for Not available */
wrsPortStatusTable_array[i].port_locked =
1 + port_state->locked;
/* FIXME: get real peer_id */
memset(&wrsPortStatusTable_array[i].peer_id, 0xff,
sizeof(ClockIdentity));
wrsPortStatusTable_array[i].sfp_in_db =
port_state->calib.sfp.flags & SFP_FLAG_IN_DB ? 2 : 1;
wrsPortStatusTable_array[i].sfp_GbE =
port_state->calib.sfp.flags & SFP_FLAG_1GbE ? 2 : 1;
strncpy(wrsPortStatusTable_array[i].sfp_vn,
port_state->calib.sfp.vendor_name,
sizeof(wrsPortStatusTable_array[i].sfp_vn));
strncpy(wrsPortStatusTable_array[i].sfp_pn,
port_state->calib.sfp.part_num,
sizeof(wrsPortStatusTable_array[i].sfp_pn));
strncpy(wrsPortStatusTable_array[i].sfp_vs,
port_state->calib.sfp.vendor_serial,
sizeof(wrsPortStatusTable_array[i].sfp_vs));
/* sfp error when SFP is not 1 GbE or
* (port is not wr-non mode and sfp not in data base)
* Keep value 0 for Not available
* sfp ok is 1 (WRS_PORT_STATUS_SFP_ERROR_SFP_OK)
* sfp error is 2 WRS_PORT_STATUS_SFP_ERROR_SFP_ERROR
* port down, set above, is 3
* (WRS_PORT_STATUS_SFP_ERROR_PORT_DOWN) */
wrsPortStatusTable_array[i].sfp_error = 1 +
((wrsPortStatusTable_array[i].sfp_GbE == 1) ||
((port_state->mode != HEXP_PORT_MODE_NON_WR) &&
(wrsPortStatusTable_array[i].sfp_in_db == 1)));
logmsg("reading ports name %s link %d, mode %d, "
"locked %d\n", port_state->name,
wrsPortStatusTable_array[i].link_up,
wrsPortStatusTable_array[i].port_mode,
wrsPortStatusTable_array[i].port_locked);
}
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read HAL\n",
__func__);
retries = 0;
}
if (!wrs_shm_seqretry(hal_head, ii))
break; /* consistent read */
usleep(1000);
}
/* there was an update, return current time */
return time_cur;
}
#define TT_OID WRSPORTSTATUSTABLE_OID
#define TT_PICKINFO wrsPortStatusTable_pickinfo
#define TT_DATA_FILL_FUNC wrsPortStatusTable_data_fill
#define TT_DATA_ARRAY wrsPortStatusTable_array
#define TT_GROUP_NAME "wrsPortStatusTable"
#define TT_INIT_FUNC init_wrsPortStatusTable
#define TT_CACHE_TIMEOUT WRSPORTSTATUSTABLE_CACHE_TIMEOUT
#include "wrsTableTemplate.h"
#ifndef WRS_PORT_STATUS_TABLE_H
#define WRS_PORT_STATUS_TABLE_H
#define WRSPORTSTATUSTABLE_CACHE_TIMEOUT 5
#define WRSPORTSTATUSTABLE_OID WRS_OID, 7, 6
#define WRS_PORT_STATUS_SFP_ERROR_SFP_OK 1 /* ok */
#define WRS_PORT_STATUS_SFP_ERROR_SFP_ERROR 2 /* error */
#define WRS_PORT_STATUS_SFP_ERROR_PORT_DOWN 3 /* ok */
struct wrsPortStatusTable_s {
uint32_t index; /* not reported, index fields has to be marked
* as not-accessible in MIB */
char port_name[12]; /* port name */
ClockIdentity peer_id;
/* These can't be "unsigned char" because we scanf a %i in there */
unsigned link_up;
unsigned port_mode;
unsigned port_locked;
char sfp_vn[16]; /* vendor name */
char sfp_pn[16]; /* part name */
char sfp_vs[16]; /* vendor serial */
int sfp_in_db;
int sfp_GbE;
int sfp_error;
};
extern struct wrsPortStatusTable_s wrsPortStatusTable_array[WRS_N_PORTS];
time_t wrsPortStatusTable_data_fill(unsigned int *rows);
void init_wrsPortStatusTable(void);
#endif /* WRS_PORT_STATUS_TABLE_H */
/*
* White Rabbit PTP information, from ppsi. Both globals and a table.
*
* Alessandro Rubini for CERN, 2014
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/auto_nlist.h>
/* Crap! -- everybody makes them different, and even ppsi::ieee wants them */
#undef FALSE
#undef TRUE
/* conflict between definition in net-snmp-agent-includes.h (which include
* snmp_vars.h) and ppsi.h where INST is defined as a inline function */
#undef INST
#include <ppsi/ieee1588_types.h> /* for ClockIdentity */
#include <libwr/shmem.h>
#include <ppsi/ppsi.h>
#include <libwr/hal_shmem.h>
#include <stdio.h>
#include "wrsSnmp.h"
#define PPSI_CACHE_TIMEOUT 5 /* 1 second: refresh table every so often */
/* Table-driven memcpy: declare how to pick fields (pickinfo) */
struct ppsi_pickinfo {
/* Following fields are used to format the output */
int type; int offset; int len;
};
static struct wrs_shm_head *hal_head;
static struct hal_shmem_header *hal_shmem;
static struct hal_port_state *hal_ports;
static int hal_nports_local;
static struct wrs_shm_head *ppsi_head;
static struct pp_globals *ppg;
struct wr_servo_state_t *ppsi_servo;
#define FIELD(_struct, _type, _field) { \
.type = _type, \
.offset = offsetof(struct _struct, _field), \
.len = sizeof(_struct._field), \
}
/* Our data: globals */
static struct wrs_p_globals {
ClockIdentity gm_id; /* FIXME: not implemented */
ClockIdentity my_id; /* FIXME: not implemented */
int ppsi_mode; /* FIXME: not implemented */
char servo_state_name[32]; /* State as string */
int servo_state; /* state number */
int tracking_enabled;
char sync_source[32]; /* FIXME: not implemented */
int64_t clock_offset;
int32_t clock_offsetHR; /* Human readable version of clock_offset,
* saturated to int limits */
int32_t skew;
int64_t rtt;
uint32_t llength;
uint32_t servo_updates;
int32_t delta_tx_m;
int32_t delta_rx_m;
int32_t delta_tx_s;
int32_t delta_rx_s;
} wrs_p_globals;
static struct ppsi_pickinfo g_pickinfo[] = {
/* Warning: strings are a special case for snmp format */
FIELD(wrs_p_globals, ASN_OCTET_STR, gm_id),
FIELD(wrs_p_globals, ASN_OCTET_STR, my_id),
FIELD(wrs_p_globals, ASN_INTEGER, ppsi_mode),
FIELD(wrs_p_globals, ASN_OCTET_STR, servo_state_name),
FIELD(wrs_p_globals, ASN_INTEGER, servo_state),
FIELD(wrs_p_globals, ASN_INTEGER, tracking_enabled),
FIELD(wrs_p_globals, ASN_OCTET_STR, sync_source),
FIELD(wrs_p_globals, ASN_COUNTER64, clock_offset),
FIELD(wrs_p_globals, ASN_INTEGER, clock_offsetHR),
FIELD(wrs_p_globals, ASN_INTEGER, skew),
FIELD(wrs_p_globals, ASN_COUNTER64, rtt),
FIELD(wrs_p_globals, ASN_UNSIGNED, llength),
FIELD(wrs_p_globals, ASN_UNSIGNED, servo_updates),
FIELD(wrs_p_globals, ASN_INTEGER, delta_tx_m),
FIELD(wrs_p_globals, ASN_INTEGER, delta_rx_m),
FIELD(wrs_p_globals, ASN_INTEGER, delta_tx_s),
FIELD(wrs_p_globals, ASN_INTEGER, delta_rx_s),
};
/* Our data: per-port information */
static struct wrs_p_perport {
ClockIdentity peer_id;
/* These can't be "unsigned char" because we scanf a %i in there */
unsigned link_up;
unsigned port_mode;
unsigned port_locked;
char sfp_vn[16]; /* vendor name */
char sfp_pn[16]; /* part name */
char sfp_vs[16]; /* vendor serial */
int sfp_in_db;
int sfp_GbE;
int sfp_error;
} wrs_p_perport, wrs_p_array[WRS_N_PORTS];
static struct ppsi_pickinfo p_pickinfo[] = {
FIELD(wrs_p_perport, ASN_INTEGER, link_up),
FIELD(wrs_p_perport, ASN_INTEGER, port_mode),
FIELD(wrs_p_perport, ASN_INTEGER, port_locked),
FIELD(wrs_p_perport, ASN_OCTET_STR, peer_id),
FIELD(wrs_p_perport, ASN_OCTET_STR, sfp_vn),
FIELD(wrs_p_perport, ASN_OCTET_STR, sfp_pn),
FIELD(wrs_p_perport, ASN_OCTET_STR, sfp_vs),
FIELD(wrs_p_perport, ASN_INTEGER, sfp_in_db),
FIELD(wrs_p_perport, ASN_INTEGER, sfp_GbE),
FIELD(wrs_p_perport, ASN_INTEGER, sfp_error),
};
/* Our data: globals */
static struct wrs_temperatures {
int temp_fpga; /* FPGA temperature */
int temp_pll; /* PLL temperature */
int temp_psl; /* PSL temperature */
int temp_psr; /* PSR temperature */
int temp_fpga_thold; /* Threshold value for FPGA temperature */
int temp_pll_thold; /* Threshold value for PLL temperature */
int temp_psl_thold; /* Threshold value for PSL temperature */
int temp_psr_thold; /* Threshold value for PSR temperature */
int temp_warning; /* Warning when at least one temperature
* threshold level exceeded */
} wrs_temperatures;
static struct ppsi_pickinfo temp_pickinfo[] = {
FIELD(wrs_temperatures, ASN_INTEGER, temp_fpga),
FIELD(wrs_temperatures, ASN_INTEGER, temp_pll),
FIELD(wrs_temperatures, ASN_INTEGER, temp_psl),
FIELD(wrs_temperatures, ASN_INTEGER, temp_psr),
FIELD(wrs_temperatures, ASN_INTEGER, temp_fpga_thold),
FIELD(wrs_temperatures, ASN_INTEGER, temp_pll_thold),
FIELD(wrs_temperatures, ASN_INTEGER, temp_psl_thold),
FIELD(wrs_temperatures, ASN_INTEGER, temp_psr_thold),
FIELD(wrs_temperatures, ASN_INTEGER, temp_warning),
};
static int32_t int_saturate(int64_t value)
{
if (value >= INT32_MAX)
return INT32_MAX;
else if (value <= INT32_MIN)
return INT32_MIN;
return value;
}
static void wrs_ppsi_get_globals(void)
{
unsigned ii;
unsigned retries = 0;
memset(&wrs_p_globals, 0, sizeof(wrs_p_globals));
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
strncpy(wrs_p_globals.servo_state_name,
ppsi_servo->servo_state_name,
sizeof(ppsi_servo->servo_state_name));
wrs_p_globals.servo_state = ppsi_servo->state;
/* Keep value 0 for Not available */
wrs_p_globals.tracking_enabled =
1 + ppsi_servo->tracking_enabled;
/*
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
wrs_p_globals.rtt = (ppsi_servo->picos_mu << 32)
| (ppsi_servo->picos_mu >> 32);
wrs_p_globals.clock_offset = (ppsi_servo->offset << 32)
| (ppsi_servo->offset >> 32);
wrs_p_globals.clock_offsetHR =
int_saturate(ppsi_servo->offset);
wrs_p_globals.skew = ppsi_servo->skew;
wrs_p_globals.llength = (uint32_t)(ppsi_servo->delta_ms/1e12 *
300e6 / 1.55);
wrs_p_globals.servo_updates = ppsi_servo->update_count;
wrs_p_globals.delta_tx_m = ppsi_servo->delta_tx_m;
wrs_p_globals.delta_rx_m = ppsi_servo->delta_rx_m;
wrs_p_globals.delta_tx_s = ppsi_servo->delta_tx_s;
wrs_p_globals.delta_rx_s = ppsi_servo->delta_rx_s;
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read PPSI\n",
__func__);
retries = 0;
}
if (!wrs_shm_seqretry(ppsi_head, ii))
break; /* consistent read */
usleep(1000);
}
}
static void wrs_get_temperatures(void)
{
unsigned ii;
unsigned retries = 0;
memset(&wrs_temperatures, 0, sizeof(wrs_temperatures));
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
wrs_temperatures.temp_fpga = hal_shmem->temp.fpga >> 8;
wrs_temperatures.temp_pll = hal_shmem->temp.pll >> 8;
wrs_temperatures.temp_psl = hal_shmem->temp.psl >> 8;
wrs_temperatures.temp_psr = hal_shmem->temp.psr >> 8;
wrs_temperatures.temp_fpga_thold = hal_shmem->temp.fpga_thold;
wrs_temperatures.temp_pll_thold = hal_shmem->temp.pll_thold;
wrs_temperatures.temp_psl_thold = hal_shmem->temp.psl_thold;
wrs_temperatures.temp_psr_thold = hal_shmem->temp.psr_thold;
if (!wrs_temperatures.temp_fpga_thold
&& !wrs_temperatures.temp_pll_thold
&& !wrs_temperatures.temp_psl_thold
&& !wrs_temperatures.temp_psr_thold) {
/* no threshold are set */
wrs_temperatures.temp_warning = 1;
} else {
/* rise warning when at least one threshold level
* is exceeded, add 2, since 0 is readings not
* available, 1 is no threshold set */
wrs_temperatures.temp_warning = 2 +
(wrs_temperatures.temp_fpga > wrs_temperatures.temp_fpga_thold)
|| (wrs_temperatures.temp_pll > wrs_temperatures.temp_pll_thold)
|| (wrs_temperatures.temp_psl > wrs_temperatures.temp_psl_thold)
|| (wrs_temperatures.temp_psr > wrs_temperatures.temp_psr_thold);
}
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read PPSI\n",
__func__);
retries = 0;
}
if (!wrs_shm_seqretry(ppsi_head, ii))
break; /* consistent read */
usleep(1000);
}
}
void init_shm(void)
{
hal_head = wrs_shm_get(wrs_shm_hal, "", WRS_SHM_READ);
if (!hal_head) {
snmp_log(LOG_ERR, "unable to open shm for HAL!\n");
exit(-1);
}
/* check hal's shm version */
if (hal_head->version != HAL_SHMEM_VERSION) {
snmp_log(LOG_ERR, "unknown hal's shm version %i "
"(known is %i)\n", hal_head->version,
HAL_SHMEM_VERSION);
exit(-1);
}
hal_shmem = (void *)hal_head + hal_head->data_off;
/* Assume number of ports does not change in runtime */
hal_nports_local = hal_shmem->nports;
if (hal_nports_local > WRS_N_PORTS) {
snmp_log(LOG_ERR, "Too many ports reported by HAL. "
"%d vs %d supported\n",
hal_nports_local, WRS_N_PORTS);
exit(-1);
}
/* Even after HAL restart, HAL will place structures at the same
* addresses. No need to re-dereference pointer at each read. */
hal_ports = wrs_shm_follow(hal_head, hal_shmem->ports);
if (!hal_ports) {
snmp_log(LOG_ERR, "Unalbe to follow hal_ports pointer in HAL's"
" shmem");
exit(-1);
}
ppsi_head = wrs_shm_get(wrs_shm_ptp, "", WRS_SHM_READ);
if (!ppsi_head) {
snmp_log(LOG_ERR, "unable to open shm for PPSI!\n");
exit(-1);
}
/* check hal's shm version */
if (ppsi_head->version != WRS_PPSI_SHMEM_VERSION) {
snmp_log(LOG_ERR, "wr_mon: unknown PPSI's shm version %i "
"(known is %i)\n",
ppsi_head->version, WRS_PPSI_SHMEM_VERSION);
exit(-1);
}
ppg = (void *)ppsi_head + ppsi_head->data_off;
ppsi_servo = wrs_shm_follow(ppsi_head, ppg->global_ext_data);
if (!ppsi_servo) {
snmp_log(LOG_ERR, "Cannot follow ppsi_servo in shmem.\n");
exit(-1);
}
}
static void wrs_ppsi_get_per_port(void)
{
unsigned ii, i;
unsigned retries = 0;
/* read data, with the sequential lock to have all data consistent */
struct hal_port_state *port_state;
memset(wrs_p_array, 0, sizeof(wrs_p_array));
while (1) {
ii = wrs_shm_seqbegin(hal_head);
for (i = 0; i < hal_nports_local; ++i) {
/* Assume that number of ports does not change between
* reads */
char if_name[10];
snprintf(if_name, 10, "wr%d", i);
port_state = hal_lookup_port(hal_ports,
hal_nports_local, if_name);
/* No need to copy all ports structures, only what
* we're interested in.
* Keep value 0 for Not available */
wrs_p_array[i].link_up =
1 + state_up(port_state->state);
wrs_p_array[i].port_mode = port_state->mode;
if (port_state->state == HAL_PORT_STATE_DISABLED)
/* if port is disabled don't fill
* other fields */
continue;
/* Keep value 0 for Not available */
wrs_p_array[i].port_locked = 1 + port_state->locked;
/* FIXME: get real peer_id */
memset(&wrs_p_array[i].peer_id, 0xff,
sizeof(ClockIdentity));
wrs_p_array[i].sfp_in_db =
port_state->calib.sfp.flags & SFP_FLAG_IN_DB ? 2 : 1;
wrs_p_array[i].sfp_GbE =
port_state->calib.sfp.flags & SFP_FLAG_1GbE ? 2 : 1;
strncpy(wrs_p_array[i].sfp_vn,
port_state->calib.sfp.vendor_name,
sizeof(wrs_p_array[i].sfp_vn));
strncpy(wrs_p_array[i].sfp_pn,
port_state->calib.sfp.part_num,
sizeof(wrs_p_array[i].sfp_pn));
strncpy(wrs_p_array[i].sfp_vs,
port_state->calib.sfp.vendor_serial,
sizeof(wrs_p_array[i].sfp_vs));
/* sfp error when SFP is not 1 GbE or
* (port is not wr-non mode and sfp not in data base)
* Keep value 0 for Not available */
wrs_p_array[i].sfp_error = 1 +
(wrs_p_array[i].sfp_GbE == 1) ||
((port_state->mode != HEXP_PORT_MODE_NON_WR) &&
(wrs_p_array[i].sfp_in_db == 1));
logmsg("reading ports name %s link %d, mode %d, "
"locked %d\n", port_state->name,
wrs_p_array[i].link_up, wrs_p_array[i].port_mode,
wrs_p_array[i].port_locked);
}
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read HAL\n",
__func__);
retries = 0;
}
if (!wrs_shm_seqretry(hal_head, ii))
break; /* consistent read */
usleep(1000);
}
}
/* From here on it is netsnmp-specific hook an tools */
/* This is the filler for the global scalars */
static int ppsi_g_group(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
static time_t t0, t1;
int obj; /* the final index */
struct ppsi_pickinfo *pi;
void *ptr;
int len;
/*
* Retrieve information from ppsi itself. But this function
* is called once for every item, so only query the whole set
* once every 2 seconds.
*/
t1 = time(NULL);
if (!t0 || t1 - t0 > 1) {
wrs_ppsi_get_globals();
t0 = t1;
}
switch (reqinfo->mode) {
case MODE_GET:
/* "- 2" because last is 0 for all scalars, I suppose */
obj = requests->requestvb->name[
requests->requestvb->name_length - 2
];
obj--; /* we are 0-based */
if (obj < 0 || obj >= ARRAY_SIZE(g_pickinfo)) {
snmp_log(LOG_ERR, "wrong index (%d) in wrs ppsi\n",
obj + 1);
return SNMP_ERR_GENERR;
}
pi = g_pickinfo + obj;
ptr = (void *)&wrs_p_globals + pi->offset;
len = pi->len;
if (len > 8) /* special case for strings */
len = strnlen(ptr, len);
snmp_set_var_typed_value(requests->requestvb,
pi->type, ptr, len);
break;
default:
snmp_log(LOG_ERR, "unknown mode (%d) in wrs ppsi group\n",
reqinfo->mode);
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
/* This is the filler for the temperature sensors */
static int temp_group(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
static time_t t0, t1;
int obj; /* the final index */
struct ppsi_pickinfo *pi;
void *ptr;
int len;
/*
* Retrieve information from ppsi itself. But this function
* is called once for every item, so only query the whole set
* once every 2 seconds.
*/
t1 = time(NULL);
if (!t0 || t1 - t0 > 1) {
wrs_get_temperatures();
t0 = t1;
}
switch (reqinfo->mode) {
case MODE_GET:
/* "- 2" because last is 0 for all scalars, I suppose */
obj = requests->requestvb->name[
requests->requestvb->name_length - 2];
obj--; /* we are 0-based */
if (obj < 0 || obj >= ARRAY_SIZE(temp_pickinfo)) {
snmp_log(LOG_ERR, "wrong index (%d) in wrs ppsi\n",
obj + 1);
return SNMP_ERR_GENERR;
}
pi = temp_pickinfo + obj;
ptr = (void *)&wrs_temperatures + pi->offset;
len = pi->len;
if (len > 8) /* special case for strings */
len = strnlen(ptr, len);
snmp_set_var_typed_value(requests->requestvb,
pi->type, ptr, len);
break;
default:
snmp_log(LOG_ERR, "unknown mode (%d) in wrs temp group\n",
reqinfo->mode);
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
/* For the per-port table we use an iterator like in wrsPstats.c */
static netsnmp_variable_list *
ppsi_p_next_entry(void **loop_context,
void **data_context,
netsnmp_variable_list *index,
netsnmp_iterator_info *data)
{
intptr_t i;
/* create the line ID from counter number */
i = (intptr_t)*loop_context;
//logmsg("%s: %i (i = %i)\n", __func__, __LINE__, i);
if (i >= WRS_N_PORTS)
return NULL; /* no more */
i++;
/* Create the row OID: only the counter index */
snmp_set_var_value(index, (u_char *)&i, sizeof(i));
/* Set the data context (1..4)
* Cannot be set to 0, because netsnmp_extract_iterator_context returns
* NULL in function wrsPstats_handler when table is over */
*data_context = (void *)i;
/* and set the loop context for the next iteration */
*loop_context = (void *)i;
return index;
}
static netsnmp_variable_list *
ppsi_p_first_entry(void **loop_context,
void **data_context,
netsnmp_variable_list *index,
netsnmp_iterator_info *data)
{
/* reset internal position, so "next" is "first" */
*loop_context = (void *)0; /* first counter */
return ppsi_p_next_entry(loop_context, data_context, index, data);
}
/* This function must fill the per-port information for the whole table */
static int ppsi_p_load(netsnmp_cache *cache, void *vmagic)
{
wrs_ppsi_get_per_port();
return 0;
}
static int
ppsi_p_handler(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
netsnmp_request_info *request;
netsnmp_variable_list *requestvb;
netsnmp_table_request_info *table_info;
struct wrs_p_perport *data = wrs_p_array; /* a shorter name */
struct ppsi_pickinfo *pi;
int wrport, subid;
int len;
void *ptr;
//logmsg("%s: %i\n", __func__, __LINE__);
switch (reqinfo->mode) {
case MODE_GET:
/* "break;" so read code is not indented too much */
break;
case MODE_GETNEXT:
case MODE_GETBULK:
case MODE_SET_RESERVE1:
case MODE_SET_RESERVE2:
case MODE_SET_ACTION:
case MODE_SET_COMMIT:
case MODE_SET_FREE:
case MODE_SET_UNDO:
/* unsupported mode */
return SNMP_ERR_NOERROR;
default:
/* unknown mode */
return SNMP_ERR_NOERROR;
}
for (request = requests; request; request = request->next) {
requestvb = request->requestvb;
//logmsg("%s: %i\n", __func__, __LINE__);
/* "context" is the port number */
wrport = (intptr_t)netsnmp_extract_iterator_context(request);
if (!wrport)
/* NULL returned from
* netsnmp_extract_iterator_context shuld be
* interpreted as end of table */
break;
/* change range of wrport (1..4 (snmp is 1 based) ->
* 0..3 (wrs_p_array/data array is 0 based)) */
wrport--;
table_info = netsnmp_extract_table_info(request);
subid = table_info->colnum - 1;
pi = p_pickinfo + subid;
ptr = (void *)(data + wrport) + pi->offset;
len = pi->len;
if (len > 8) /* special case for strings */
len = strnlen(ptr, len);
snmp_set_var_typed_value(requestvb, pi->type, ptr, len);
}
return SNMP_ERR_NOERROR;
}
void
init_wrsPpsi(void)
{
const oid wrsPpsiG_oid[] = { WRS_OID, 3, 3 };
netsnmp_handler_registration *hreg;
/* Above for globals, below for per-port */
const oid wrsPpsiP_oid[] = { WRS_OID, 3, 4 };
netsnmp_handler_registration *hreg_temp;
const oid wrsTemperature_oid[] = { WRS_OID, 3, 5 };
netsnmp_table_registration_info *table_info;
netsnmp_iterator_info *iinfo;
netsnmp_handler_registration *reginfo;
/* open shm */
init_shm();
/* do the registration for the scalars/globals */
hreg = netsnmp_create_handler_registration(
"wrsPpsiGlobals", ppsi_g_group,
wrsPpsiG_oid, OID_LENGTH(wrsPpsiG_oid),
HANDLER_CAN_RONLY);
netsnmp_register_scalar_group(
hreg, 1 /* min */, ARRAY_SIZE(g_pickinfo) /* max */);
/* do the registration for the table/per-port */
table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
if (!table_info)
return;
/* Add indexes: we only use one integer OID member as line identifier */
netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0);
table_info->min_column = 1;
table_info->max_column = ARRAY_SIZE(p_pickinfo);
/* Iterator info */
iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
if (!iinfo)
return; /* free table_info? */
iinfo->get_first_data_point = ppsi_p_first_entry;
iinfo->get_next_data_point = ppsi_p_next_entry;
iinfo->table_reginfo = table_info;
/* register the table */
reginfo = netsnmp_create_handler_registration("wrsPpsiPerport",
ppsi_p_handler,
wrsPpsiP_oid,
OID_LENGTH(wrsPpsiP_oid),
HANDLER_CAN_RONLY);
netsnmp_register_table_iterator(reginfo, iinfo);
/* and create a local cache */
netsnmp_inject_handler(reginfo,
netsnmp_get_cache_handler(PPSI_CACHE_TIMEOUT,
ppsi_p_load, NULL,
wrsPpsiP_oid,
OID_LENGTH(wrsPpsiP_oid)));
/* do the registration for the scalars/globals */
hreg_temp = netsnmp_create_handler_registration(
"wrsTemperature", temp_group,
wrsTemperature_oid, OID_LENGTH(wrsTemperature_oid),
HANDLER_CAN_RONLY);
netsnmp_register_scalar_group(
hreg_temp, 1 /* min */, ARRAY_SIZE(temp_pickinfo) /* max */);
}
/*
* White Rabbit Switch pstats table
* Using the netsnmp iterator, like in tcpTable
* Alessandro Rubini for CERN, 2014
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/auto_nlist.h>
#include "wrsSnmp.h"
#define PSTATS_CACHE_TIMEOUT 5 /* seconds */
/* Our structure for caching data */
#define PSTATS_MAX_N_COUNTERS 50 /* Maximum number of counters */
#define PSTATS_N_PORTS 18 /* this hardwired in the mib too */
#define PSTATS_MAX_COUNTERS_NAME_LEN 35 /* maximum length of counter's name */
#define PSTATS_SYSCTL_PATH "/proc/sys/pstats/" /* Path to sysclt entries */
#define PSTATS_SYSCTL_DESCRIPTION_FILE "description" /* file with counters' descriptions */
struct pstats_per_port {
uint32_t val[PSTATS_MAX_N_COUNTERS];
};
static struct pstats_global_data {
struct pstats_per_port port[PSTATS_N_PORTS];
char counter_name[PSTATS_MAX_N_COUNTERS][PSTATS_MAX_COUNTERS_NAME_LEN];
int n_counters;
} pstats_global_data;
/* FIXME: build error if ARRAY_SIZE(pstats_names) != PSTATS_N_COUNTERS */
static int
wrsPstats_handler(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
netsnmp_request_info *request;
netsnmp_variable_list *requestvb;
netsnmp_table_request_info *table_info;
struct pstats_global_data *data = &pstats_global_data; /* a shorter name */
int counter;
int wrport;
uint32_t *c;
logmsg("%s: %i\n", __func__, __LINE__);
switch (reqinfo->mode) {
case MODE_GET:
for (request = requests; request; request = request->next) {
requestvb = request->requestvb;
logmsg("%s: %i\n", __func__, __LINE__);
/* our "context" is the counter number; "subid" the column i.e. the port */
counter = (intptr_t)netsnmp_extract_iterator_context(request);
if (!counter)
/* NULL returned from
* netsnmp_extract_iterator_context shuld be
* interpreted as end of table */
continue;
/* change range of counter (1..39 (snmp is 1 based) ->
* 0..38 (pstats_global_data array is 0 based)) */
counter--;
table_info = netsnmp_extract_table_info(request);
/* port is 0-based and position 1 is the string */
wrport = table_info->colnum - 2;
logmsg("counter %i, port %i\n", counter, wrport);
if (wrport < 0) {
char *s = pstats_global_data.counter_name[counter];
snmp_set_var_typed_value(requestvb, ASN_OCTET_STR, s, strlen(s));
continue;
}
/* While most tables do "switch(subid)" we'd better just index */
c = &data->port[wrport].val[counter];
snmp_set_var_typed_value(requestvb, ASN_COUNTER,
(u_char *)c, sizeof(*c));
}
break;
case MODE_GETNEXT:
case MODE_GETBULK:
case MODE_SET_RESERVE1:
case MODE_SET_RESERVE2:
case MODE_SET_ACTION:
case MODE_SET_COMMIT:
case MODE_SET_FREE:
case MODE_SET_UNDO:
/* unsupported mode */
break;
default:
/* unknown mode */
break;
}
return SNMP_ERR_NOERROR;
}
static netsnmp_variable_list *
wrsPstats_next_entry(void **loop_context,
void **data_context,
netsnmp_variable_list *index,
netsnmp_iterator_info *data)
{
intptr_t i;
/* create the line ID from counter number */
i = (intptr_t)*loop_context;
//logmsg("%s: %i (i = %i)\n", __func__, __LINE__, i);
if (i >= pstats_global_data.n_counters)
return NULL; /* no more */
i++;
/* Create the row OID: only the counter index */
snmp_set_var_value(index, (u_char *)&i, sizeof(i));
/* Set the data context (1..39)
* Cannot be set to 0, because netsnmp_extract_iterator_context returns
* NULL in function wrsPstats_handler when table is over */
*data_context = (void *)i;
/* and set the loop context for the next iteration */
*loop_context = (void *)i;
return index;
}
static netsnmp_variable_list *
wrsPstats_first_entry(void **loop_context,
void **data_context,
netsnmp_variable_list *index,
netsnmp_iterator_info *data)
{
logmsg("%s: %i\n", __func__, __LINE__);
/* reset internal position, so "next" is "first" */
*loop_context = (void *)0; /* first counter */
return wrsPstats_next_entry(loop_context, data_context, index, data);
}
static int
wrsPstats_load(netsnmp_cache *cache, void *vmagic)
{
FILE *f;
char fname[32];
int wrport, counter;
struct pstats_per_port *stat;
char *p;
/* fill names of counters */
f = fopen(PSTATS_SYSCTL_PATH PSTATS_SYSCTL_DESCRIPTION_FILE, "r");
if (f) {
for (counter = 0; counter < PSTATS_MAX_N_COUNTERS; counter++) {
/* parse new line delimited file */
p = fgets(pstats_global_data.counter_name[counter],
PSTATS_MAX_COUNTERS_NAME_LEN, f);
if (p == NULL)
break;
/* fgets usualy returns strings with newline, return
string shall contain maximum one newline character */
p = strchr(pstats_global_data.counter_name[counter],
'\n');
if (p != NULL)
*p = '\0';
}
pstats_global_data.n_counters = counter;
fclose(f);
} else {
/* use PSTATS_MAX_N_COUNTERS as number of counters */
pstats_global_data.n_counters = PSTATS_MAX_N_COUNTERS;
/* fill counters' names */
for (counter = 0; counter < PSTATS_MAX_N_COUNTERS; counter++) {
snprintf(pstats_global_data.counter_name[counter],
PSTATS_MAX_COUNTERS_NAME_LEN,
"pstats counter %d", counter);
}
}
for (wrport = 0; wrport < PSTATS_N_PORTS; wrport++) {
sprintf(fname, PSTATS_SYSCTL_PATH"port%i", wrport);
stat = pstats_global_data.port + wrport;
f = fopen(fname, "r");
if (!f) {
memset(stat, 0x7f, sizeof(*stat));
continue;
}
for (counter = 0;
counter < pstats_global_data.n_counters;
counter++) {
if (fscanf(f, "%u", stat->val + counter) != 1)
stat->val[counter] = 0xffffffff;
}
fclose(f);
}
return 0;
}
void
init_wrsPstats(void)
{
const oid wrsPstats_oid[] = { WRS_OID, 2 };
netsnmp_table_registration_info *table_info;
netsnmp_iterator_info *iinfo;
netsnmp_handler_registration *reginfo;
table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
if (!table_info)
return;
/* Add indexes: we only use one integer OID member as line identifier */
netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0);
table_info->min_column = 1;
table_info->max_column = 1 + PSTATS_N_PORTS;
/* Iterator info */
iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
if (!iinfo)
return; /* free table_info? */
iinfo->get_first_data_point = wrsPstats_first_entry;
iinfo->get_next_data_point = wrsPstats_next_entry;
iinfo->table_reginfo = table_info;
/* register the table */
reginfo = netsnmp_create_handler_registration("wrsPstats",
wrsPstats_handler,
wrsPstats_oid, OID_LENGTH(wrsPstats_oid),
HANDLER_CAN_RONLY);
netsnmp_register_table_iterator(reginfo, iinfo);
/* and create a local cache */
netsnmp_inject_handler(reginfo,
netsnmp_get_cache_handler(PSTATS_CACHE_TIMEOUT,
wrsPstats_load, NULL,
wrsPstats_oid, OID_LENGTH(wrsPstats_oid)));
}
#include "wrsSnmp.h"
#include "wrsPstatsTable.h"
struct wrsPstatsTable_s pstats_array[WRS_N_PORTS];
static struct pickinfo wrsPstatsTable_pickinfo[] = {
/* Warning: strings are a special case for snmp format */
FIELD(wrsPstatsTable_s, ASN_UNSIGNED, index), /* not reported */
FIELD(wrsPstatsTable_s, ASN_OCTET_STR, port_name),
FIELD(wrsPstatsTable_s, ASN_COUNTER, TXUnderrun),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXOverrun),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXInvalidCode),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXSyncLost),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPauseFrames),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPfilterDropped),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPCSErrors),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXGiantFrames),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXRuntFrames),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXCRCErrors),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPclass0),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPclass1),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPclass2),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPclass3),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPclass4),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPclass5),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPclass6),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPclass7),
FIELD(wrsPstatsTable_s, ASN_COUNTER, TXFrames),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXFrames),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXDropRTUFull),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPrio0),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPrio1),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPrio2),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPrio3),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPrio4),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPrio5),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPrio6),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RXPrio7),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RTUValid),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RTUResponses),
FIELD(wrsPstatsTable_s, ASN_COUNTER, RTUDropped),
FIELD(wrsPstatsTable_s, ASN_COUNTER, FastMatchPriority),
FIELD(wrsPstatsTable_s, ASN_COUNTER, FastMatchFastForward),
FIELD(wrsPstatsTable_s, ASN_COUNTER, FastMatchNonForward),
FIELD(wrsPstatsTable_s, ASN_COUNTER, FastMatchRespValid),
FIELD(wrsPstatsTable_s, ASN_COUNTER, FullMatchRespValid),
FIELD(wrsPstatsTable_s, ASN_COUNTER, Forwarded),
FIELD(wrsPstatsTable_s, ASN_COUNTER, TRURespValid),
};
time_t
wrsPstatsTable_data_fill(unsigned int *n_rows)
{
FILE *f;
char fname[32];
int wrport;
uint32_t i;
uint32_t counters[PSTATS_MAX_N_COUNTERS];
static time_t time_update;
time_t time_cur;
uint32_t n_counters_in_fpga;
uint32_t counters_version;
uint32_t tmp;
if (n_rows)
*n_rows = WRS_N_PORTS;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSPSTATSTABLE_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
/* fill array with 0xff, buy this it will be easy visible in case
* some counters are invalid */
memset(&pstats_array, 0xff, sizeof(pstats_array));
/* read counters version and number of counters */
f = fopen(PSTATS_SYSCTL_PATH PSTATS_SYSCTL_INFO_FILE, "r");
if (f) {
if (fscanf(f, "%u", &counters_version) != 1) {
/* not able to read valid counters version,
* assign invalid version number */
counters_version = 0;
}
/* read number of counters per word, not used */
fscanf(f, "%u", &tmp);
if (fscanf(f, "%u", &n_counters_in_fpga) != 1) {
/* not able to read valid number of counters,
* use maximum possible */
n_counters_in_fpga = PSTATS_MAX_N_COUNTERS;
}
if (n_counters_in_fpga > PSTATS_MAX_N_COUNTERS) {
/* n_counters_in_fpga cannot be bigger than
* PSTATS_MAX_N_COUNTERS */
n_counters_in_fpga = PSTATS_MAX_N_COUNTERS;
}
fclose(f);
} else {
/* unable to open info file */
/* use PSTATS_MAX_N_COUNTERS as number of counters */
n_counters_in_fpga = PSTATS_MAX_N_COUNTERS;
counters_version = 0; /* invalid version */
}
/* read pstats for each port */
for (wrport = 0; wrport < WRS_N_PORTS; wrport++) {
snprintf(pstats_array[wrport].port_name, 10,
"wr%d", wrport);
sprintf(fname, PSTATS_SYSCTL_PATH"port%i", wrport);
f = fopen(fname, "r");
if (!f) {
snmp_log(LOG_ERR,
"SNMP: wrsPstatsTable filed to open file %s\n", fname);
continue;
}
for (i = 0; i < n_counters_in_fpga; i++) {
if (fscanf(f, "%u", &counters[i]) != 1)
counters[i] = 0xffffffff;
}
fclose(f);
/* copy counters */
switch (counters_version) {
case 1:
/* copy counters to array */
pstats_array[wrport].TXUnderrun = counters[0];
pstats_array[wrport].RXOverrun = counters[1];
pstats_array[wrport].RXInvalidCode = counters[2];
pstats_array[wrport].RXSyncLost = counters[3];
pstats_array[wrport].RXPauseFrames = counters[4];
pstats_array[wrport].RXPfilterDropped = counters[5];
pstats_array[wrport].RXPCSErrors = counters[6];
pstats_array[wrport].RXGiantFrames = counters[7];
pstats_array[wrport].RXRuntFrames = counters[8];
pstats_array[wrport].RXCRCErrors = counters[9];
pstats_array[wrport].RXPclass0 = counters[10];
pstats_array[wrport].RXPclass1 = counters[11];
pstats_array[wrport].RXPclass2 = counters[12];
pstats_array[wrport].RXPclass3 = counters[13];
pstats_array[wrport].RXPclass4 = counters[14];
pstats_array[wrport].RXPclass5 = counters[15];
pstats_array[wrport].RXPclass6 = counters[16];
pstats_array[wrport].RXPclass7 = counters[17];
pstats_array[wrport].TXFrames = counters[18];
pstats_array[wrport].RXFrames = counters[19];
pstats_array[wrport].RXDropRTUFull = counters[20];
pstats_array[wrport].RXPrio0 = counters[21];
pstats_array[wrport].RXPrio1 = counters[22];
pstats_array[wrport].RXPrio2 = counters[23];
pstats_array[wrport].RXPrio3 = counters[24];
pstats_array[wrport].RXPrio4 = counters[25];
pstats_array[wrport].RXPrio5 = counters[26];
pstats_array[wrport].RXPrio6 = counters[27];
pstats_array[wrport].RXPrio7 = counters[28];
pstats_array[wrport].RTUValid = counters[29];
pstats_array[wrport].RTUResponses = counters[30];
pstats_array[wrport].RTUDropped = counters[31];
pstats_array[wrport].FastMatchPriority = counters[32];
pstats_array[wrport].FastMatchFastForward = counters[33];
pstats_array[wrport].FastMatchNonForward = counters[34];
pstats_array[wrport].FastMatchRespValid = counters[35];
pstats_array[wrport].FullMatchRespValid = counters[36];
pstats_array[wrport].Forwarded = counters[37];
pstats_array[wrport].TRURespValid = counters[38];
break;
case 2:
default:
break;
}
}
/* there was an update, return current time */
return time_update;
}
#define TT_OID WRSPSTATSTABLE_OID
#define TT_PICKINFO wrsPstatsTable_pickinfo
#define TT_DATA_FILL_FUNC wrsPstatsTable_data_fill
#define TT_DATA_ARRAY pstats_array
#define TT_GROUP_NAME "wrsPstatsTable"
#define TT_INIT_FUNC init_wrsPstatsTable
#define TT_CACHE_TIMEOUT WRSPSTATSTABLE_CACHE_TIMEOUT
#include "wrsTableTemplate.h"
#ifndef WRS_PSTATS_TABLE_H
#define WRS_PSTATS_TABLE_H
#define WRSPSTATSTABLE_CACHE_TIMEOUT 5
#define WRSPSTATSTABLE_OID WRS_OID, 7, 4
#define PSTATS_MAX_N_COUNTERS 39 /* maximum number of counters */
#define PSTATS_SYSCTL_PATH "/proc/sys/pstats/" /* Path to sysclt entries */
#define PSTATS_SYSCTL_INFO_FILE "info" /* file with version of pstats counters
* and number of counters */
struct wrsPstatsTable_s {
uint32_t index; /* not reported, index fields has to be marked
* as not-accessible in MIB */
char port_name[12]; /* port name of counters */
uint32_t TXUnderrun;
uint32_t RXOverrun;
uint32_t RXInvalidCode;
uint32_t RXSyncLost;
uint32_t RXPauseFrames;
uint32_t RXPfilterDropped;
uint32_t RXPCSErrors;
uint32_t RXGiantFrames;
uint32_t RXRuntFrames;
uint32_t RXCRCErrors;
uint32_t RXPclass0;
uint32_t RXPclass1;
uint32_t RXPclass2;
uint32_t RXPclass3;
uint32_t RXPclass4;
uint32_t RXPclass5;
uint32_t RXPclass6;
uint32_t RXPclass7;
uint32_t TXFrames;
uint32_t RXFrames;
uint32_t RXDropRTUFull;
uint32_t RXPrio0;
uint32_t RXPrio1;
uint32_t RXPrio2;
uint32_t RXPrio3;
uint32_t RXPrio4;
uint32_t RXPrio5;
uint32_t RXPrio6;
uint32_t RXPrio7;
uint32_t RTUValid;
uint32_t RTUResponses;
uint32_t RTUDropped;
uint32_t FastMatchPriority;
uint32_t FastMatchFastForward;
uint32_t FastMatchNonForward;
uint32_t FastMatchRespValid;
uint32_t FullMatchRespValid;
uint32_t Forwarded;
uint32_t TRURespValid;
};
extern struct wrsPstatsTable_s pstats_array[WRS_N_PORTS];
time_t wrsPstatsTable_data_fill(unsigned int *rows);
void init_wrsPstatsTable(void);
#endif /* WRS_PSTATS_TABLE_H */
#include "wrsSnmp.h"
#include "snmp_shmem.h"
#include "wrsPtpDataTable.h"
struct wrsPtpDataTable_s wrsPtpDataTable_array[WRS_MAX_N_SERVO_INSTANCES];
static struct pickinfo wrsPtpDataTable_pickinfo[] = {
/* Warning: strings are a special case for snmp format */
FIELD(wrsPtpDataTable_s, ASN_UNSIGNED, index), /* not reported */
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, port_name),
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, gm_id),
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, my_id),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, ppsi_mode),
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, servo_state_name),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, servo_state),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, tracking_enabled),
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, sync_source),
FIELD(wrsPtpDataTable_s, ASN_COUNTER64, clock_offset),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, clock_offsetHR),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, skew),
FIELD(wrsPtpDataTable_s, ASN_COUNTER64, rtt),
FIELD(wrsPtpDataTable_s, ASN_UNSIGNED, llength),
FIELD(wrsPtpDataTable_s, ASN_COUNTER, servo_updates),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, delta_tx_m),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, delta_rx_m),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, delta_tx_s),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, delta_rx_s),
};
static int32_t int_saturate(int64_t value)
{
if (value >= INT32_MAX)
return INT32_MAX;
else if (value <= INT32_MIN)
return INT32_MIN;
return value;
}
time_t wrsPtpDataTable_data_fill(unsigned int *n_rows)
{
unsigned ii;
unsigned retries = 0;
static time_t time_update;
time_t time_cur;
/* number of rows does not change for wrsPortStatusTable */
if (n_rows)
*n_rows = WRS_MAX_N_SERVO_INSTANCES;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSPTPDATATABLE_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
memset(&wrsPtpDataTable_array, 0, sizeof(wrsPtpDataTable_array));
/* assume that there is only one servo, will change when switchover is
* implemented */
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
strncpy(wrsPtpDataTable_array[0].servo_state_name,
ppsi_servo->servo_state_name,
sizeof(ppsi_servo->servo_state_name));
wrsPtpDataTable_array[0].servo_state = ppsi_servo->state;
/* Keep value 0 for Not available */
wrsPtpDataTable_array[0].tracking_enabled =
1 + ppsi_servo->tracking_enabled;
/*
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
wrsPtpDataTable_array[0].rtt = (ppsi_servo->picos_mu << 32)
| (ppsi_servo->picos_mu >> 32);
wrsPtpDataTable_array[0].clock_offset =
(ppsi_servo->offset << 32)
| (ppsi_servo->offset >> 32);
wrsPtpDataTable_array[0].clock_offsetHR =
int_saturate(ppsi_servo->offset);
wrsPtpDataTable_array[0].skew = ppsi_servo->skew;
wrsPtpDataTable_array[0].llength =
(uint32_t)(ppsi_servo->delta_ms/1e12 * 300e6 / 1.55);
wrsPtpDataTable_array[0].servo_updates =
ppsi_servo->update_count;
wrsPtpDataTable_array[0].delta_tx_m = ppsi_servo->delta_tx_m;
wrsPtpDataTable_array[0].delta_rx_m = ppsi_servo->delta_rx_m;
wrsPtpDataTable_array[0].delta_tx_s = ppsi_servo->delta_tx_s;
wrsPtpDataTable_array[0].delta_rx_s = ppsi_servo->delta_rx_s;
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read PPSI\n",
__func__);
retries = 0;
}
if (!wrs_shm_seqretry(ppsi_head, ii))
break; /* consistent read */
usleep(1000);
}
/* there was an update, return current time */
return time_update;
}
#define TT_OID WRSPTPDATATABLE_OID
#define TT_PICKINFO wrsPtpDataTable_pickinfo
#define TT_DATA_FILL_FUNC wrsPtpDataTable_data_fill
#define TT_DATA_ARRAY wrsPtpDataTable_array
#define TT_GROUP_NAME "wrsPtpDataTable"
#define TT_INIT_FUNC init_wrsPtpDataTable
#define TT_CACHE_TIMEOUT WRSPTPDATATABLE_CACHE_TIMEOUT
#include "wrsTableTemplate.h"
#ifndef WRS_PTP_DATA_TABLE_H
#define WRS_PTP_DATA_TABLE_H
#define WRSPTPDATATABLE_CACHE_TIMEOUT 5
#define WRSPTPDATATABLE_OID WRS_OID, 7, 5
/* Right now we allow only one servo instance, it will change in the future
* when switchover is implemented */
#define WRS_MAX_N_SERVO_INSTANCES 1
struct wrsPtpDataTable_s {
uint32_t index; /* not reported, index fields has to be marked
* as not-accessible in MIB */
char port_name[12]; /* port name on which ptp servo instance in
* running FIXME: not implemented */
ClockIdentity gm_id; /* FIXME: not implemented */
ClockIdentity my_id; /* FIXME: not implemented */
int ppsi_mode; /* FIXME: not implemented */
char servo_state_name[32]; /* State as string */
int servo_state; /* state number */
int tracking_enabled;
char sync_source[32]; /* FIXME: not implemented */
int64_t clock_offset;
int32_t clock_offsetHR; /* Human readable version of clock_offset,
* saturated to int limits */
int32_t skew;
int64_t rtt;
uint32_t llength;
uint32_t servo_updates;
int32_t delta_tx_m;
int32_t delta_rx_m;
int32_t delta_tx_s;
int32_t delta_rx_s;
};
time_t wrsPtpDataTable_data_fill(unsigned int *rows);
void init_wrsPtpDataTable(void);
#endif /* WRS_PTP_DATA_TABLE_H */
#ifndef WRS_SNMP_H
#define WRS_SNMP_H
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
/* Crap! -- everybody makes them different, and even ppsi::ieee wants them */
#undef FALSE
#undef TRUE
/* conflict between definition in net-snmp-agent-includes.h (which include
* snmp_vars.h) and ppsi.h where INST is defined as a inline function */
#undef INST
#include <ppsi/ieee1588_types.h> /* for ClockIdentity */
/*
* local hack: besides the file pointer, that is there anyways,
......@@ -77,12 +89,17 @@ static inline int dumpstruct(FILE *dest, char *name, void *ptr, int size)
/* Scalar is just a stupid thing, but let's keep it */
extern void init_wrsScalar(void);
/* Real stuff follows */
extern void init_wrsPstats(void);
extern void init_wrsPpsi(void);
extern void init_wrsVersion(void);
extern void init_wrsDate(void);
#define WRS_OID 1, 3, 6, 1, 4, 1, 96, 100
struct pickinfo {
/* Following fields are used to format the output */
int type; int offset; int len;
};
#define FIELD(_struct, _type, _field) { \
.type = _type, \
.offset = offsetof(struct _struct, _field), \
.len = sizeof(((struct _struct *)0)->_field), \
}
#endif /* WRS_SNMP_H */
#include "wrsSnmp.h"
#include "wrsSpllStatusGroup.h"
#include "softpll_ng.h"
#include "snmp_mmap.h"
#define FPGA_SPLL_STAT 0x10006800
#define SPLL_MAGIC 0x5b1157a7
static struct spll_stats *spll_stats_p;
static struct pickinfo wrsSpllStatus_pickinfo[] = {
FIELD(wrsSpllStatus_s, ASN_INTEGER, wrsSpllMode),
FIELD(wrsSpllStatus_s, ASN_COUNTER, wrsSpllIrqCnt),
FIELD(wrsSpllStatus_s, ASN_INTEGER, wrsSpllSeqState),
FIELD(wrsSpllStatus_s, ASN_INTEGER, wrsSpllAlignState),
FIELD(wrsSpllStatus_s, ASN_COUNTER, wrsSpllHlock),
FIELD(wrsSpllStatus_s, ASN_COUNTER, wrsSpllMlock),
FIELD(wrsSpllStatus_s, ASN_INTEGER, wrsSpllHY),
FIELD(wrsSpllStatus_s, ASN_INTEGER, wrsSpllMY),
FIELD(wrsSpllStatus_s, ASN_COUNTER, wrsSpllDelCnt),
};
struct wrsSpllStatus_s wrsSpllStatus_s;
time_t wrsSpllStatus_data_fill(void)
{
static time_t time_update;
time_t time_cur;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSSPLLSTATUS_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
memset(&wrsSpllStatus_s, 0, sizeof(wrsSpllStatus_s));
if (!spll_stats_p) /* first time, map the fpga space */
spll_stats_p = create_map(FPGA_SPLL_STAT,
sizeof(*spll_stats_p));
if (!spll_stats_p) {
/* unable to mmap */
return time_update;
}
/* check magic number in SPLL stat memory */
if (spll_stats_p->magic != SPLL_MAGIC) {
/* wrong magic */
snmp_log(LOG_ERR,
"wrsSpllStatusGroup Wrong SPLL magic number\n");
return time_update;
}
/* check version of SPLL's stat structure */
if (spll_stats_p->ver == 1) {
wrsSpllStatus_s.wrsSpllMode = spll_stats_p->mode;
wrsSpllStatus_s.wrsSpllIrqCnt = spll_stats_p->irq_cnt;
wrsSpllStatus_s.wrsSpllSeqState = spll_stats_p->seq_state;
wrsSpllStatus_s.wrsSpllAlignState = spll_stats_p->align_state;
wrsSpllStatus_s.wrsSpllHlock = spll_stats_p->H_lock;
wrsSpllStatus_s.wrsSpllMlock = spll_stats_p->M_lock;
wrsSpllStatus_s.wrsSpllHY = spll_stats_p->H_y;
wrsSpllStatus_s.wrsSpllMY = spll_stats_p->M_y;
wrsSpllStatus_s.wrsSpllDelCnt = spll_stats_p->del_cnt;
}
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRSSPLLSTATUS_OID
#define GT_PICKINFO wrsSpllStatus_pickinfo
#define GT_DATA_FILL_FUNC wrsSpllStatus_data_fill
#define GT_DATA_STRUCT wrsSpllStatus_s
#define GT_GROUP_NAME "wrsSpllStatusGroup"
#define GT_INIT_FUNC init_wrsSpllStatusGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_SPLL_STATUS_GROUP_H
#define WRS_SPLL_STATUS_GROUP_H
#define WRSSPLLSTATUS_CACHE_TIMEOUT 5
#define WRSSPLLSTATUS_OID WRS_OID, 7, 3, 2
struct wrsSpllStatus_s {
int32_t wrsSpllMode;
int32_t wrsSpllIrqCnt;
int32_t wrsSpllSeqState;
int32_t wrsSpllAlignState;
int32_t wrsSpllHlock;
int32_t wrsSpllMlock;
int32_t wrsSpllHY;
int32_t wrsSpllMY;
int32_t wrsSpllDelCnt;
};
extern struct wrsSpllStatus_s wrsSpllStatus_s;
time_t wrsSpllStatus_data_fill(void);
void init_wrsSpllStatusGroup(void);
#endif /* WRS_SPLL_STATUS_GROUP_H */
#include "wrsSnmp.h"
#include "snmp_shmem.h"
#include "wrsStartCntGroup.h"
#define START_CNT_SSHD "/tmp/start_cnt_sshd"
#define START_CNT_HTTPD "/tmp/start_cnt_httpd"
#define START_CNT_SNMPD "/tmp/start_cnt_snmpd"
#define START_CNT_SYSLOGD "/tmp/start_cnt_syslogd"
static struct pickinfo wrsStartCnt_pickinfo[] = {
FIELD(wrsStartCnt_s, ASN_COUNTER, wrsStartCntHAL),
FIELD(wrsStartCnt_s, ASN_COUNTER, wrsStartCntPPSI),
FIELD(wrsStartCnt_s, ASN_COUNTER, wrsStartCntRTUd),
FIELD(wrsStartCnt_s, ASN_COUNTER, wrsStartCntSshd),
FIELD(wrsStartCnt_s, ASN_COUNTER, wrsStartCntHttpd),
FIELD(wrsStartCnt_s, ASN_COUNTER, wrsStartCntSnmpd),
FIELD(wrsStartCnt_s, ASN_COUNTER, wrsStartCntSyslogd),
};
struct wrsStartCnt_s wrsStartCnt_s;
/* read start counter from files in /tmp */
static void read_start_count(char *file, uint32_t *counter)
{
FILE *f;
f = fopen(file, "r");
if (!f) {
snmp_log(LOG_ERR, "SNMP: wrsStartCntGroup filed to open file "
"%s\n", file);
} else {
/* ignore fscanf errors */
fscanf(f, "%d", counter);
fclose(f);
}
}
time_t wrsStartCnt_data_fill(void){
static time_t time_update;
time_t time_cur;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSSTARTCNT_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
memset(&wrsStartCnt_s, 0, sizeof(wrsStartCnt_s));
/* get start counters from shmem's */
wrsStartCnt_s.wrsStartCntHAL = hal_head->pidsequence;
wrsStartCnt_s.wrsStartCntPPSI = ppsi_head->pidsequence;
wrsStartCnt_s.wrsStartCntRTUd = rtud_head->pidsequence;
read_start_count(START_CNT_SSHD, &wrsStartCnt_s.wrsStartCntSshd);
read_start_count(START_CNT_HTTPD, &wrsStartCnt_s.wrsStartCntHttpd);
read_start_count(START_CNT_SNMPD, &wrsStartCnt_s.wrsStartCntSnmpd);
read_start_count(START_CNT_SYSLOGD, &wrsStartCnt_s.wrsStartCntSyslogd);
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRSSTARTCNT_OID
#define GT_PICKINFO wrsStartCnt_pickinfo
#define GT_DATA_FILL_FUNC wrsStartCnt_data_fill
#define GT_DATA_STRUCT wrsStartCnt_s
#define GT_GROUP_NAME "wrsStartCntGroup"
#define GT_INIT_FUNC init_wrsStartCntGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_START_CNT_GROUP_H
#define WRS_START_CNT_GROUP_H
#define WRSSTARTCNT_CACHE_TIMEOUT 5
#define WRSSTARTCNT_OID WRS_OID, 7, 2
struct wrsStartCnt_s {
uint32_t wrsStartCntHAL;
uint32_t wrsStartCntPPSI;
uint32_t wrsStartCntRTUd;
uint32_t wrsStartCntSshd;
uint32_t wrsStartCntHttpd;
uint32_t wrsStartCntSnmpd;
uint32_t wrsStartCntSyslogd;
};
extern struct wrsStartCnt_s wrsStartCnt_s;
time_t wrsStartCnt_data_fill(void);
void init_wrsStartCntGroup(void);
#endif /* WRS_START_CNT_GROUP_H */
/* global variable to keep number of rows, filled by cache function */
unsigned int n_rows;
static netsnmp_variable_list *
table_next_entry(void **loop_context,
void **data_context,
netsnmp_variable_list *index,
netsnmp_iterator_info *data)
{
intptr_t i;
/* create the line ID from counter number */
i = (intptr_t)*loop_context;
if (i >= n_rows)
return NULL; /* no more */
i++;
/* Create the row OID: only the counter index */
snmp_set_var_value(index, (u_char *)&i, sizeof(i));
/* Set the data context (1..4)
* Cannot be set to 0, because netsnmp_extract_iterator_context returns
* NULL in function wrsPstats_handler when table is over */
*data_context = (void *)i;
/* and set the loop context for the next iteration */
*loop_context = (void *)i;
return index;
}
static netsnmp_variable_list *
table_first_entry(void **loop_context,
void **data_context,
netsnmp_variable_list *index,
netsnmp_iterator_info *data)
{
/* reset internal position, so "next" is "first" */
*loop_context = (void *)0; /* first counter */
return table_next_entry(loop_context, data_context, index, data);
}
static int
table_handler(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
netsnmp_request_info *request;
netsnmp_variable_list *requestvb;
netsnmp_table_request_info *table_info;
struct pickinfo *pi;
int row, subid;
int len;
void *ptr;
switch (reqinfo->mode) {
case MODE_GET:
/* "break;" so read code is not indented too much */
break;
case MODE_GETNEXT:
case MODE_GETBULK:
case MODE_SET_RESERVE1:
case MODE_SET_RESERVE2:
case MODE_SET_ACTION:
case MODE_SET_COMMIT:
case MODE_SET_FREE:
case MODE_SET_UNDO:
/* unsupported mode */
return SNMP_ERR_NOERROR;
default:
/* unknown mode */
return SNMP_ERR_NOERROR;
}
for (request = requests; request; request = request->next) {
requestvb = request->requestvb;
/* "context" is the row number */
row = (intptr_t)netsnmp_extract_iterator_context(request);
if (!row)
/* NULL returned from
* netsnmp_extract_iterator_context shuld be
* interpreted as end of table */
break;
/* change range of row (1..X (snmp is 1 based) ->
* 0..X (wrs_t_table_array/data array is 0 based)) */
row--;
table_info = netsnmp_extract_table_info(request);
subid = table_info->colnum - 1;
pi = TT_PICKINFO + subid;
ptr = (void *)(TT_DATA_ARRAY + row) + pi->offset;
len = pi->len;
if (len > 8) /* special case for strings */
len = strnlen(ptr, len);
snmp_set_var_typed_value(requestvb, pi->type, ptr, len);
}
return SNMP_ERR_NOERROR;
}
static int table_cache_load(netsnmp_cache *cache, void *vmagic)
{
TT_DATA_FILL_FUNC(&n_rows);
return 0;
}
void TT_INIT_FUNC(void)
{
const oid wrsTT_oid[] = { TT_OID };
netsnmp_table_registration_info *table_info;
netsnmp_iterator_info *iinfo;
netsnmp_handler_registration *reginfo;
/* do the registration for the table/per-port */
table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
if (!table_info)
return;
/* Add indexes: we only use one integer OID member as line identifier */
netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0);
/* first column is index, but don't return it, it is only for MIB */
table_info->min_column = 2;
table_info->max_column = ARRAY_SIZE(TT_PICKINFO);
/* Iterator info */
iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
if (!iinfo)
return; /* free table_info? */
iinfo->get_first_data_point = table_first_entry;
iinfo->get_next_data_point = table_next_entry;
iinfo->table_reginfo = table_info;
/* register the table */
reginfo = netsnmp_create_handler_registration(TT_GROUP_NAME,
table_handler,
wrsTT_oid,
OID_LENGTH(wrsTT_oid),
HANDLER_CAN_RONLY);
netsnmp_register_table_iterator(reginfo, iinfo);
netsnmp_inject_handler(reginfo,
netsnmp_get_cache_handler(TT_CACHE_TIMEOUT,
table_cache_load, NULL,
wrsTT_oid,
OID_LENGTH(wrsTT_oid)));
}
#include "wrsSnmp.h"
#include "snmp_shmem.h"
#include "wrsTemperatureGroup.h"
static struct pickinfo wrsTemperature_pickinfo[] = {
FIELD(wrsTemperature_s, ASN_INTEGER, temp_fpga),
FIELD(wrsTemperature_s, ASN_INTEGER, temp_pll),
FIELD(wrsTemperature_s, ASN_INTEGER, temp_psl),
FIELD(wrsTemperature_s, ASN_INTEGER, temp_psr),
FIELD(wrsTemperature_s, ASN_INTEGER, temp_fpga_thold),
FIELD(wrsTemperature_s, ASN_INTEGER, temp_pll_thold),
FIELD(wrsTemperature_s, ASN_INTEGER, temp_psl_thold),
FIELD(wrsTemperature_s, ASN_INTEGER, temp_psr_thold),
};
struct wrsTemperature_s wrsTemperature_s;
time_t wrsTemperature_data_fill(void)
{
unsigned ii;
unsigned retries = 0;
static time_t time_update;
time_t time_cur;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSTEMPERATURE_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
memset(&wrsTemperature_s, 0, sizeof(wrsTemperature_s));
while (1) {
ii = wrs_shm_seqbegin(hal_head);
wrsTemperature_s.temp_fpga = hal_shmem->temp.fpga >> 8;
wrsTemperature_s.temp_pll = hal_shmem->temp.pll >> 8;
wrsTemperature_s.temp_psl = hal_shmem->temp.psl >> 8;
wrsTemperature_s.temp_psr = hal_shmem->temp.psr >> 8;
wrsTemperature_s.temp_fpga_thold = hal_shmem->temp.fpga_thold;
wrsTemperature_s.temp_pll_thold = hal_shmem->temp.pll_thold;
wrsTemperature_s.temp_psl_thold = hal_shmem->temp.psl_thold;
wrsTemperature_s.temp_psr_thold = hal_shmem->temp.psr_thold;
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read HAL\n",
__func__);
retries = 0;
}
if (!wrs_shm_seqretry(hal_head, ii))
break; /* consistent read */
usleep(1000);
}
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRSTEMPERATURE_OID
#define GT_PICKINFO wrsTemperature_pickinfo
#define GT_DATA_FILL_FUNC wrsTemperature_data_fill
#define GT_DATA_STRUCT wrsTemperature_s
#define GT_GROUP_NAME "wrsTemperatureGroup"
#define GT_INIT_FUNC init_wrsTemperatureGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_TEMPERATURE_GROUP_H
#define WRS_TEMPERATURE_GROUP_H
#define WRSTEMPERATURE_CACHE_TIMEOUT 5
#define WRSTEMPERATURE_OID WRS_OID, 7, 1, 3
struct wrsTemperature_s {
int temp_fpga; /* FPGA temperature */
int temp_pll; /* PLL temperature */
int temp_psl; /* PSL temperature */
int temp_psr; /* PSR temperature */
int temp_fpga_thold; /* Threshold value for FPGA temperature */
int temp_pll_thold; /* Threshold value for PLL temperature */
int temp_psl_thold; /* Threshold value for PSL temperature */
int temp_psr_thold; /* Threshold value for PSR temperature */
};
extern struct wrsTemperature_s wrsTemperature_s;
time_t wrsTemperature_data_fill(void);
void init_wrsTemperatureGroup(void);
#endif /* WRS_TEMPERATURE_GROUP_H */
/*
* White Rabbit Switch versions. This is a series of scalars,
* so I used the approach of disman/expr/expScalars.c
*
* Alessandro Rubini for CERN, 2014
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/auto_nlist.h>
#include "wrsSnmp.h"
/* Our structure for caching data */
#define VERSION_N_STRINGS 9 /* sw, 3 gw, 2 hw, 3 added later */
struct wrs_v_item {
char *key;
char *value;
};
static struct wrs_v_item wrs_version[] = {
/* Warning: the order here msut match the MIB file */
[0] = {.key = "software-version:"},
[1] = {"wr_switch_hdl-commit:"},
[2] = {"general-cores-commit:"},
[3] = {"wr-cores-commit:"},
[4] = {"backplane-version:"},
[5] = {"fpga-type:"},
[6] = {"manufacturer:"},
[7] = {"serial-number:"},
[8] = {"scb-version:"},
};
static int version_group(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
oid obj; /* actually, an integer, i.e. the final index */
char *s;
switch (reqinfo->mode) {
case MODE_GET:
/* "- 2" because last is 0 for all scalars, I suppose */
obj = requests->requestvb->name[
requests->requestvb->name_length - 2
];
s = wrs_version[obj - 1].value ? : "unknown";
snmp_set_var_typed_value(requests->requestvb,
ASN_OCTET_STR, s, strlen(s));
break;
default:
snmp_log(LOG_ERR, "unknown mode (%d) in wrs version group\n",
reqinfo->mode);
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
/*
* We parse versions at initialization time, as they won't change.
* FIXME: we should factorize parsing, this duplicates ./wrsPpsi.c
* (while being different, as here we need simpler stuff)
*/
static void wrs_v_init(void)
{
char s[80], key[40], value[40];
FILE *f = popen("/wr/bin/wrs_version -t", "r");
int i;
if (!f) {
/* The "unknown" above will apply, bad but acceptable */
return;
}
while (fgets(s, sizeof(s), f)) {
if (sscanf(s, "%s %[^\n]", key, value) != 2)
continue; /* error... */
for (i = 0; i < ARRAY_SIZE(wrs_version); i++) {
if (strcmp(key, wrs_version[i].key))
continue;
wrs_version[i].value = strdup(value);
}
}
pclose(f);
}
void
init_wrsVersion(void)
{
const oid wrsVersion_oid[] = { WRS_OID, 4 };
netsnmp_handler_registration *hreg;
wrs_v_init();
/* do the registration */
hreg = netsnmp_create_handler_registration(
"wrsVersion", version_group,
wrsVersion_oid, OID_LENGTH(wrsVersion_oid),
HANDLER_CAN_RONLY);
netsnmp_register_scalar_group(
hreg, 1 /* min */, VERSION_N_STRINGS /* max */);
}
/*
* White Rabbit Switch versions.
*
* Based on work by Alessandro Rubini for CERN, 2014
* Adam Wujek
*/
#include "wrsSnmp.h"
#include "wrsVersionGroup.h"
#define VERSION_COMMAND "/wr/bin/wrs_version -t"
struct wrs_v_item {
char *key;
};
static struct pickinfo wrsVersion_pickinfo[] = {
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[0]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[1]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[2]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[3]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[4]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[5]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[6]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[7]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[8]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[9]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[10]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[11]),
FIELD(wrsVersion_s, ASN_OCTET_STR, wrsVersions[12]),
};
struct wrsVersion_s wrsVersion_s;
static struct wrs_v_item wrs_version[] = {
/* Warning: the order here must match the MIB file
* wrs_version has to have the same size as wrsVersion_s.wrsVersions */
[0] = {.key = "software-version:"},
[1] = {"bult-by:"},
[2] = {"build-date:"},
[3] = {"backplane-version:"},
[4] = {"fpga-type:"},
[5] = {"manufacturer:"},
[6] = {"serial-number:"},
[7] = {"scb-version:"},
[8] = {"gateware-version:"},
[9] = {"gateware-build:"},
[10] = {"wr_switch_hdl-commit:"},
[11] = {"general-cores-commit:"},
[12] = {"wr-cores-commit:"},
};
time_t wrsVersion_data_fill(void)
{
char s[80], key[40], value[40];
FILE *f;
int i;
int guess_index;
static int run_once = 0;
time_t time_cur;
time_cur = time(NULL);
/* assume that version does not change in runtime */
if (run_once) {
/* return time like there was an update */
return time_cur;
}
run_once = 1;
f = popen(VERSION_COMMAND, "r");
if (!f) {
snmp_log(LOG_ERR, "SNMP: wrsVersion filed to execute "
VERSION_COMMAND"\n");
return time_cur;
}
guess_index = 0;
while (fgets(s, sizeof(s), f)) {
if (sscanf(s, "%s %[^\n]", key, value) != 2)
continue; /* error... */
/* try educated guess to find position in array */
if (!strcmp(key, wrs_version[guess_index].key)) {
strncpy(wrsVersion_s.wrsVersions[guess_index],
value, 32);
guess_index++;
continue;
}
/* check all */
for (i = 0; i < ARRAY_SIZE(wrs_version); i++) {
if (strcmp(key, wrs_version[i].key))
continue;
strncpy(wrsVersion_s.wrsVersions[i], value, 32);
}
guess_index++;
}
pclose(f);
return time_cur;
}
#define GT_OID WRSVERSION_OID
#define GT_PICKINFO wrsVersion_pickinfo
#define GT_DATA_FILL_FUNC wrsVersion_data_fill
#define GT_DATA_STRUCT wrsVersion_s
#define GT_GROUP_NAME "wrsVersionGroup"
#define GT_INIT_FUNC init_wrsVersionGroup
#include "wrsGroupTemplate.h"
#ifndef WRS_VERSION_GROUP_H
#define WRS_VERSION_GROUP_H
#define WRSVERSION_OID WRS_OID, 6, 3
struct wrsVersion_s {
char wrsVersions[13][32]; /* array of version strings */
};
extern struct wrsVersion_s wrsVersion_s;
time_t wrsVersion_data_fill(void);
void init_wrsVersionGroup(void);
#endif /* WRS_VERSION_GROUP_H */
......@@ -318,9 +318,23 @@ int load_fpga_main(char *fname)
exit(0);
default: /* parent */
waitpid(pid, &status, 0);
if (!WEXITSTATUS(status))
return 0;
return -1;
/* check if exited normally and returned 0 */
if (WIFEXITED(status)) {
if (!WEXITSTATUS(status)) {
return 0; /* success */
} else {
/* process returned not 0 */
fprintf(stderr, "load-virtex: Error, child "
"process returned %d\n",
WEXITSTATUS(status));
return -1; /* fail */
}
} else {
/* Child process terminated abnormally */
fprintf(stderr, "load-virtex: Child process terminated"
" abnormally\n");
return -1; /* fail */
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment