mirror of
				https://github.com/librenms/librenms.git
				synced 2024-10-07 16:52:45 +00:00 
			
		
		
		
	Merge pull request #2764 from vitalisator/stp
Add STP port polling and device information
This commit is contained in:
		
							
								
								
									
										39
									
								
								html/includes/common/stp-ports.inc.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								html/includes/common/stp-ports.inc.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | $common_output[] = ' | ||||||
|  | <div class="table-responsive"> | ||||||
|  |     <table id="stp-ports" class="table table-condensed table-hover"> | ||||||
|  |         <thead> | ||||||
|  |             <tr> | ||||||
|  |                 <th data-column-id="port_id">Port</th> | ||||||
|  |                 <th data-column-id="priority">Priority</th> | ||||||
|  |                 <th data-column-id="state">State</th> | ||||||
|  |                 <th data-column-id="enable">Enable</th> | ||||||
|  |                 <th data-column-id="pathCost">Path cost</th> | ||||||
|  |                 <th data-column-id="designatedRoot">Designated root</th> | ||||||
|  |                 <th data-column-id="designatedCost">Designated cost</th> | ||||||
|  |                 <th data-column-id="designatedBridge">Designated bridge</th> | ||||||
|  |                 <th data-column-id="designatedPort">Designated port</th> | ||||||
|  |                 <th data-column-id="forwardTransitions">Forward transitions</th> | ||||||
|  |             </tr> | ||||||
|  |         </thead> | ||||||
|  |     </table> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |  | ||||||
|  | var grid = $("#stp-ports").bootgrid( {  | ||||||
|  |     ajax: true, | ||||||
|  |     templates: {search: ""}, | ||||||
|  |     post: function ()  | ||||||
|  |     { | ||||||
|  |         return { | ||||||
|  |             id: "stp-ports", | ||||||
|  |             device_id: ' . $device['device_id'] . ', | ||||||
|  |         }; | ||||||
|  |     }, | ||||||
|  |     url: "ajax_table.php" | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | </script> | ||||||
|  | '; | ||||||
| @@ -1,5 +1,6 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
|  | echo '<table class="table table-condensed table-striped table-hover">'; | ||||||
| $stp_raw = dbFetchRow('SELECT * FROM `stp` WHERE `device_id` = ?', array($device['device_id'])); | $stp_raw = dbFetchRow('SELECT * FROM `stp` WHERE `device_id` = ?', array($device['device_id'])); | ||||||
| $stp = array ( | $stp = array ( | ||||||
|     'Root bridge'                 => ($stp_raw['rootBridge'] == 1) ? 'Yes' : 'No', |     'Root bridge'                 => ($stp_raw['rootBridge'] == 1) ? 'Yes' : 'No', | ||||||
| @@ -22,8 +23,9 @@ $stp = array ( | |||||||
| foreach (array_keys($stp) as $key) { | foreach (array_keys($stp) as $key) { | ||||||
|     echo " |     echo " | ||||||
|       <tr> |       <tr> | ||||||
|         <td width=280 class=list-large>$key</td> |         <td>$key</td> | ||||||
|         <td class=box-desc>$stp[$key]</td> |         <td>$stp[$key]</td> | ||||||
|       </tr> |       </tr> | ||||||
|     "; |     "; | ||||||
| } | } | ||||||
|  | echo '</table>'; | ||||||
|   | |||||||
							
								
								
									
										57
									
								
								html/includes/table/stp-ports.inc.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								html/includes/table/stp-ports.inc.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | $device_id = mres($_POST['device_id']); | ||||||
|  |  | ||||||
|  | $param[] = $device_id; | ||||||
|  |  | ||||||
|  | $sql = " FROM `ports_stp` `ps` JOIN `ports` `p` ON `ps`.`port_id`=`p`.`port_id` WHERE `ps`.`device_id` = ?"; | ||||||
|  |  | ||||||
|  | $count_sql = "SELECT COUNT(*) $sql"; | ||||||
|  | $total     = dbFetchCell($count_sql, $param); | ||||||
|  | if (empty($total)) { | ||||||
|  |         $total = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if (!isset($sort) || empty($sort)) { | ||||||
|  |         $sort = 'port_id DESC'; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $sql .= " ORDER BY ps.$sort"; | ||||||
|  |  | ||||||
|  | if (isset($current)) { | ||||||
|  |         $limit_low  = (($current * $rowCount) - ($rowCount)); | ||||||
|  |             $limit_high = $rowCount; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if ($rowCount != -1) { | ||||||
|  |         $sql .= " LIMIT $limit_low,$limit_high"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $sql = "SELECT `ps`.*, `p`.* $sql"; | ||||||
|  |  | ||||||
|  | foreach (dbFetchRows($sql, array($device_id)) as $stp_ports_db) { | ||||||
|  |  | ||||||
|  |     $bridge_device = dbFetchRow("SELECT `devices`.*, `stp`.`device_id`, `stp`.`bridgeAddress` FROM `devices` JOIN `stp` ON `devices`.`device_id`=`stp`.`device_id` WHERE `stp`.`bridgeAddress` = ?", array($stp_ports_db['designatedBridge'])); | ||||||
|  |     $root_device = dbFetchRow("SELECT `devices`.*, `stp`.`device_id`, `stp`.`bridgeAddress` FROM `devices` JOIN `stp` ON `devices`.`device_id`=`stp`.`device_id` WHERE `stp`.`bridgeAddress` = ?", array($stp_ports_db['designatedRoot'])); | ||||||
|  |  | ||||||
|  |     $response[] = array ( | ||||||
|  |         'port_id'            => generate_port_link($stp_ports_db, $stp_ports_db['ifName'])."<br>".$stp_ports_db['ifAlias'], | ||||||
|  |         'priority'           => $stp_ports_db['priority'], | ||||||
|  |         'state'              => $stp_ports_db['state'], | ||||||
|  |         'enable'             => $stp_ports_db['enable'], | ||||||
|  |         'pathCost'           => $stp_ports_db['pathCost'], | ||||||
|  |         'designatedRoot'     => generate_device_link($root_device, $root_device['hostname'])."<br>".$stp_ports_db['designatedRoot'], | ||||||
|  |         'designatedCost'     => $stp_ports_db['designatedCost'], | ||||||
|  |         'designatedBridge'   => generate_device_link($bridge_device, $bridge_device['hostname'])."<br>".$stp_ports_db['designatedBridge'], | ||||||
|  |         'designatedPort'     => $stp_ports_db['designatedPort'], | ||||||
|  |         'forwardTransitions' => $stp_ports_db['forwardTransitions'] | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $output = array( | ||||||
|  |     'current'  => $current, | ||||||
|  |     'rowCount' => $rowCount, | ||||||
|  |     'rows'     => $response, | ||||||
|  |     'total'    => $total, | ||||||
|  | ); | ||||||
|  | echo _json_encode($output); | ||||||
| @@ -15,7 +15,7 @@ if (!$vars['view']) { | |||||||
| } | } | ||||||
|  |  | ||||||
| $menu_options['basic'] = 'Basic'; | $menu_options['basic'] = 'Basic'; | ||||||
| // $menu_options['details'] = 'Details'; | $menu_options['ports'] = 'Ports'; | ||||||
| $sep = ''; | $sep = ''; | ||||||
| foreach ($menu_options as $option => $text) { | foreach ($menu_options as $option => $text) { | ||||||
|     echo $sep; |     echo $sep; | ||||||
| @@ -35,16 +35,13 @@ unset($sep); | |||||||
|  |  | ||||||
| print_optionbar_end(); | print_optionbar_end(); | ||||||
|  |  | ||||||
| echo '<table border="0" cellspacing="0" cellpadding="5" width="100%">'; | if ($vars['view'] == 'basic') { | ||||||
|  |  | ||||||
| $i = '1'; |  | ||||||
|  |  | ||||||
| foreach (dbFetchRows("SELECT * FROM `stp` WHERE `device_id` = ? ORDER BY 'stp_id'", array($device['device_id'])) as $stp) { |  | ||||||
|     include 'includes/print-stp.inc.php'; |     include 'includes/print-stp.inc.php'; | ||||||
|  |  | ||||||
|     $i++; |  | ||||||
| }     | }     | ||||||
|  |  | ||||||
| echo '</table>'; | if ($vars['view'] == 'ports') { | ||||||
|  |     include 'includes/common/stp-ports.inc.php'; | ||||||
|  |     echo implode('',$common_output); | ||||||
|  | } | ||||||
|  |  | ||||||
| $pagetitle[] = 'STP'; | $pagetitle[] = 'STP'; | ||||||
|   | |||||||
| @@ -112,7 +112,72 @@ if ($stpprotocol == 'ieee8021d' || $stpprotocol == 'unknown') { | |||||||
|         log_event('STP removed', $device, 'stp'); |         log_event('STP removed', $device, 'stp'); | ||||||
|         echo '-'; |         echo '-'; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // STP port related stuff | ||||||
|  |     foreach ($stp_raw as $port => $value){ | ||||||
|  |         if ($port) { // $stp_raw[0] ist not port related so we skip this one | ||||||
|  |             $stp_port = array( | ||||||
|  |                 'priority'              => $stp_raw[$port]['dot1dStpPortPriority'], | ||||||
|  |                 'state'                 => $stp_raw[$port]['dot1dStpPortState'], | ||||||
|  |                 'enable'                => $stp_raw[$port]['dot1dStpPortEnable'], | ||||||
|  |                 'pathCost'              => $stp_raw[$port]['dot1dStpPortPathCost'], | ||||||
|  |                 'designatedCost'        => $stp_raw[$port]['dot1dStpPortDesignatedCost'], | ||||||
|  |                 'designatedPort'        => $stp_raw[$port]['dot1dStpPortDesignatedPort'], | ||||||
|  |                 'forwardTransitions'    => $stp_raw[$port]['dot1dStpPortForwardTransitions'] | ||||||
|  |             ); | ||||||
|  |              | ||||||
|  |             // set device binding | ||||||
|  |             $stp_port['device_id'] = $device['device_id']; | ||||||
|  |              | ||||||
|  |             // set port binding | ||||||
|  |             $stp_port['port_id'] = dbFetchCell('SELECT port_id FROM `ports` WHERE `device_id` = ? AND `ifIndex` = ?', array($device['device_id'], $stp_raw[$port]['dot1dStpPort'])); | ||||||
|  |              | ||||||
|  |             $dr = str_replace(array(' ', ':', '-'), '', strtolower($stp_raw[$port]['dot1dStpPortDesignatedRoot'])); | ||||||
|  |             $dr = substr($dr, -12); //remove first two octets | ||||||
|  |             $stp_port['designatedRoot'] = $dr; | ||||||
|  |              | ||||||
|  |             $db = str_replace(array(' ', ':', '-'), '', strtolower($stp_raw[$port]['dot1dStpPortDesignatedBridge'])); | ||||||
|  |             $db = substr($db, -12); //remove first two octets | ||||||
|  |             $stp_port['designatedBridge'] = $db; | ||||||
|  |  | ||||||
|  |             if ($device['os'] == 'pbn') { | ||||||
|  |                 // It seems that PBN guys don't care about ieee 802.1d :-( | ||||||
|  |                 // So try to find the right port with some crazy conversations | ||||||
|  |                 $dp_value = dechex($stp_port['priority']); | ||||||
|  |                 $dp_value = $dp_value.'00'; | ||||||
|  |                 $dp_value = hexdec($dp_value); | ||||||
|  |                 if ($stp_raw[$port]['dot1dStpPortDesignatedPort']) { | ||||||
|  |                     $dp = $stp_raw[$port]['dot1dStpPortDesignatedPort'] - $dp_value; | ||||||
|  |                     $stp_port['designatedPort'] = $dp; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 // Port saved in format priority+port (ieee 802.1d-1998: clause 8.5.5.1) | ||||||
|  |                 $dp = substr($stp_raw[$port]['dot1dStpPortDesignatedPort'], -2); //discard the first octet (priority part) | ||||||
|  |                 $stp_port['designatedPort'] = hexdec($dp); | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             d_echo($stp_port); | ||||||
|  |  | ||||||
|  |             // Write to db | ||||||
|  |             if (!dbFetchCell('SELECT 1 FROM `ports_stp` WHERE `device_id` = ? AND `port_id` = ?', array($device['device_id'], $stp_port['port_id']))) { | ||||||
|  |                 dbInsert($stp_port,'ports_stp'); | ||||||
|  |                 echo '+'; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Delete STP ports from db if absent in SNMP query      | ||||||
|  |     $stp_port_db = dbFetchRows('SELECT * FROM `ports_stp` WHERE `device_id` = ?', array($device['device_id'])); | ||||||
|  |     //d_echo($stp_port_db); | ||||||
|  |     foreach($stp_port_db as $port => $value){ | ||||||
|  |         $if_index = dbFetchCell('SELECT `ifIndex` FROM `ports` WHERE `device_id` = ? AND `port_id` = ?', array($device['device_id'], $value['port_id'])); | ||||||
|  |         if ($if_index != $stp_raw[$if_index]['dot1dStpPort']){ | ||||||
|  |             dbDelete('ports_stp', '`device_id` = ? AND `port_id` = ?', array($device['device_id'], $value['port_id'])); | ||||||
|  |             echo '-'; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| unset($stp_raw, $stp, $stp_db); | unset($stp_raw, $stp, $stp_db, $stp_port, $stp_port_db); | ||||||
| echo "\n"; | echo "\n"; | ||||||
|   | |||||||
| @@ -39,6 +39,7 @@ if ($stpprotocol == 'ieee8021d' || $stpprotocol == 'unknown') { | |||||||
|      |      | ||||||
|     // read the 802.1D subtree |     // read the 802.1D subtree | ||||||
|     $stp_raw = snmpwalk_cache_oid($device, 'dot1dStp', array(), 'RSTP-MIB'); |     $stp_raw = snmpwalk_cache_oid($device, 'dot1dStp', array(), 'RSTP-MIB'); | ||||||
|  |     d_echo($stp_raw); | ||||||
|     $stp = array( |     $stp = array( | ||||||
|         'protocolSpecification'   => $stp_raw[0]['dot1dStpProtocolSpecification'], |         'protocolSpecification'   => $stp_raw[0]['dot1dStpProtocolSpecification'], | ||||||
|         'priority'                => $stp_raw[0]['dot1dStpPriority'], |         'priority'                => $stp_raw[0]['dot1dStpPriority'], | ||||||
| @@ -121,7 +122,59 @@ if ($stpprotocol == 'ieee8021d' || $stpprotocol == 'unknown') { | |||||||
|         dbUpdate($stp,'stp','device_id = ?', array($device['device_id'])); |         dbUpdate($stp,'stp','device_id = ?', array($device['device_id'])); | ||||||
|         echo '.'; |         echo '.'; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // STP port related stuff | ||||||
|  |     foreach ($stp_raw as $port => $value){ | ||||||
|  |         if ($port) { // $stp_raw[0] ist not port related so we skip this one | ||||||
|  |             $stp_port = array( | ||||||
|  |                 'priority'              => $stp_raw[$port]['dot1dStpPortPriority'], | ||||||
|  |                 'state'                 => $stp_raw[$port]['dot1dStpPortState'], | ||||||
|  |                 'enable'                => $stp_raw[$port]['dot1dStpPortEnable'], | ||||||
|  |                 'pathCost'              => $stp_raw[$port]['dot1dStpPortPathCost'], | ||||||
|  |                 'designatedCost'        => $stp_raw[$port]['dot1dStpPortDesignatedCost'], | ||||||
|  |                 'designatedPort'        => $stp_raw[$port]['dot1dStpPortDesignatedPort'], | ||||||
|  |                 'forwardTransitions'    => $stp_raw[$port]['dot1dStpPortForwardTransitions'] | ||||||
|  |             ); | ||||||
|  |              | ||||||
|  |             // set device binding | ||||||
|  |             $stp_port['device_id'] = $device['device_id']; | ||||||
|  |              | ||||||
|  |             // set port binding | ||||||
|  |             $stp_port['port_id'] = dbFetchCell('SELECT port_id FROM `ports` WHERE `device_id` = ? AND `ifIndex` = ?', array($device['device_id'], $stp_raw[$port]['dot1dStpPort'])); | ||||||
|  |              | ||||||
|  |             $dr = str_replace(array(' ', ':', '-'), '', strtolower($stp_raw[$port]['dot1dStpPortDesignatedRoot'])); | ||||||
|  |             $dr = substr($dr, -12); //remove first two octets | ||||||
|  |             $stp_port['designatedRoot'] = $dr; | ||||||
|  |              | ||||||
|  |             $db = str_replace(array(' ', ':', '-'), '', strtolower($stp_raw[$port]['dot1dStpPortDesignatedBridge'])); | ||||||
|  |             $db = substr($db, -12); //remove first two octets | ||||||
|  |             $stp_port['designatedBridge'] = $db; | ||||||
|  |  | ||||||
|  |             if ($device['os'] == 'pbn') { | ||||||
|  |                 // It seems that PBN guys don't care about ieee 802.1d :-( | ||||||
|  |                 // So try to find the right port with some crazy conversations | ||||||
|  |                 $dp_value = dechex($stp_port['priority']); | ||||||
|  |                 $dp_value = $dp_value.'00'; | ||||||
|  |                 $dp_value = hexdec($dp_value); | ||||||
|  |                 if ($stp_raw[$port]['dot1dStpPortDesignatedPort']) { | ||||||
|  |                     $dp = $stp_raw[$port]['dot1dStpPortDesignatedPort'] - $dp_value; | ||||||
|  |                     $stp_port['designatedPort'] = $dp; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 // Port saved in format priority+port (ieee 802.1d-1998: clause 8.5.5.1) | ||||||
|  |                 $dp = substr($stp_raw[$port]['dot1dStpPortDesignatedPort'], -2); //discard the first octet (priority part) | ||||||
|  |                 $stp_port['designatedPort'] = hexdec($dp); | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             //d_echo($stp_port); | ||||||
|  |  | ||||||
|  |             // Update db | ||||||
|  |             dbUpdate($stp_port,'ports_stp','`device_id` = ? AND `port_id` = ?', array($device['device_id'], $stp_port['port_id'])); | ||||||
|  |             echo '.'; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| unset($stp_raw, $stp, $stp_db); | unset($stp_raw, $stp, $stp_db, $stp_port); | ||||||
| echo "\n"; | echo "\n"; | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								sql-schema/095.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								sql-schema/095.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | CREATE TABLE IF NOT EXISTS `ports_stp` (`port_stp_id` int(11) NOT NULL,`device_id` int(11) NOT NULL,`port_id` int(11) NOT NULL,`priority` tinyint(3) unsigned NOT NULL,`state` varchar(11) NOT NULL,`enable` varchar(8) NOT NULL,`pathCost` int(10) unsigned NOT NULL,`designatedRoot` varchar(32) NOT NULL,`designatedCost` smallint(5) unsigned NOT NULL,`designatedBridge` varchar(32) NOT NULL,`designatedPort` mediumint(9) NOT NULL,`forwardTransitions` int(10) unsigned NOT NULL) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; | ||||||
|  | ALTER TABLE `ports_stp` ADD PRIMARY KEY (`port_stp_id`), ADD UNIQUE KEY `device_id` (`device_id`,`port_id`); | ||||||
|  | ALTER TABLE `ports_stp` MODIFY `port_stp_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1; | ||||||
		Reference in New Issue
	
	Block a user