diff --git a/html/includes/graphs/device/sla.inc.php b/html/includes/graphs/device/sla.inc.php
new file mode 100644
index 000000000..b52401638
--- /dev/null
+++ b/html/includes/graphs/device/sla.inc.php
@@ -0,0 +1,37 @@
+= "450") { $descr_len = "48"; } else { $descr_len = "21"; }
+$descr_len = intval($_GET['width'] / 8) * 0.8;
+
+$unit_long = 'milliseconds';
+$unit = 'ms';
+
+$rrd_options .= " -l 0 -E ";
+$rrd_options .= " COMMENT:'".str_pad($unit_long,$descr_len)." Cur Min Max\\n'";
+
+$name = "";
+if ($sla['tag'])
+ $name .= $sla['tag'];
+if ($sla['owner'])
+ $name .= " (Owner: ". $sla['owner'] .")";
+
+$descr_fixed = substr(str_pad($name, $descr_len-3),0,$descr_len-3);
+$avg_fixed = substr(str_pad('Average', $descr_len-3),0,$descr_len-3);
+
+$rrd_file = $config['rrd_dir'] . "/" . $device['hostname'] . "/" . safename("sla-" . $sla['sla_nr'] . ".rrd");
+
+$rrd_options .= " DEF:rtt=$rrd_file:rtt:AVERAGE ";
+$rrd_options .= " VDEF:avg=rtt,AVERAGE ";
+$rrd_options .= " LINE1:avg#CCCCFF:'".$avg_fixed."':dashes";
+$rrd_options .= " GPRINT:rtt:AVERAGE:%4.1lf".$unit."\\\l ";
+$rrd_options .= " LINE1:rtt#CC0000:'" . str_replace(':','\:',str_replace('\*','*',$descr_fixed)) . "'";
+$rrd_options .= " GPRINT:rtt:LAST:%4.1lf".$unit." ";
+$rrd_options .= " GPRINT:rtt:MIN:%4.1lf".$unit." ";
+$rrd_options .= " GPRINT:rtt:MAX:%4.1lf".$unit."\\\l ";
+
+?>
diff --git a/html/pages/device.inc.php b/html/pages/device.inc.php
index 3803a6102..630b003f5 100644
--- a/html/pages/device.inc.php
+++ b/html/pages/device.inc.php
@@ -100,6 +100,15 @@ if (device_permitted($vars['device']) || $check_device == $vars['device'])
');
}
+ if (@dbFetchCell("SELECT COUNT(sla_id) FROM slas WHERE device_id = '" . $device['device_id'] . "'") > '0')
+ {
+ echo('
+
+
SLAs
+
+ ');
+ }
+
if (isset($config['smokeping']['dir']))
{
$smokeping_files = array();
diff --git a/html/pages/device/slas.inc.php b/html/pages/device/slas.inc.php
new file mode 100644
index 000000000..f194f1b96
--- /dev/null
+++ b/html/pages/device/slas.inc.php
@@ -0,0 +1,77 @@
+SLA » ");
+
+$slas = dbFetchRows("SELECT * FROM `slas` WHERE `device_id` = ? AND `deleted` = 0 ORDER BY `sla_nr`", array($device['device_id']));
+
+// Collect types
+$sla_types = array('all' => 'All');
+foreach ($slas as $sla)
+{
+ $sla_type = $sla['rtt_type'];
+
+ if (!in_array($sla_type, $sla_types))
+ if (isset($config['sla_type_labels'][$sla_type]))
+ {
+ $text = $config['sla_type_labels'][$sla_type];
+ }
+ else
+ {
+ $text = ucfirst($sla_type);
+ }
+
+ $sla_types[$sla_type] = $text;
+}
+asort($sla_types);
+
+$sep = "";
+foreach ($sla_types as $sla_type => $text)
+{
+ if (!$vars['view']) { $vars['view'] = $sla_type; }
+
+ echo($sep);
+ if ($vars['view'] == $sla_type)
+ {
+ echo("");
+ }
+ $sep = " | ";
+}
+unset($sep);
+
+print_optionbar_end();
+
+echo('');
+
+foreach ($slas as $sla)
+{
+ if ($vars['view'] != 'all' && $vars['view'] != $sla['rtt_type'])
+ continue;
+
+ $name = "SLA #". $sla['sla_nr'];
+ if ($sla['tag'])
+ $name .= ": ".$sla['tag'];
+ if ($sla['owner'])
+ $name .= " (Owner: ". $sla['owner'] .")";
+
+ $graph_array['type'] = "device_sla";
+ $graph_array['id'] = $sla['sla_id'];
+ echo('');
+ echo(''.htmlentities($name).'');
+
+ include("includes/print-quadgraphs.inc.php");
+
+ echo(' |
');
+}
+
+echo('
');
+
+$pagetitle[] = "SLAs";
+
+?>
diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php
index a977de659..d46130b59 100644
--- a/includes/defaults.inc.php
+++ b/includes/defaults.inc.php
@@ -368,6 +368,29 @@ $config['auth_ldap_groups']['support']['level'] = 1;
$config['astext'][65332] = "Cymru FullBogon Feed";
$config['astext'][65333] = "Cymru Bogon Feed";
+### Nicer labels for the SLA types
+$config['sla_type_labels']['echo'] = 'ICMP ping';
+$config['sla_type_labels']['pathEcho'] = 'Path ICMP ping';
+$config['sla_type_labels']['fileIO'] = 'File I/O';
+$config['sla_type_labels']['script'] = 'Script';
+$config['sla_type_labels']['udpEcho'] = 'UDP ping';
+$config['sla_type_labels']['tcpConnect'] = 'TCP connect';
+$config['sla_type_labels']['http'] = 'HTTP';
+$config['sla_type_labels']['dns'] = 'DNS';
+$config['sla_type_labels']['jitter'] = 'Jitter';
+$config['sla_type_labels']['dlsw'] = 'DLSW';
+$config['sla_type_labels']['dhcp'] = 'DHCP';
+$config['sla_type_labels']['ftp'] = 'FTP';
+$config['sla_type_labels']['voip'] = 'VoIP';
+$config['sla_type_labels']['rtp'] = 'RTP';
+$config['sla_type_labels']['lspGroup'] = 'LSP group';
+$config['sla_type_labels']['icmpjitter'] = 'ICMP jitter';
+$config['sla_type_labels']['lspPing'] = 'LSP ping';
+$config['sla_type_labels']['lspTrace'] = 'LSP trace';
+$config['sla_type_labels']['ethernetPing'] = 'Ethernet ping';
+$config['sla_type_labels']['ethernetJitter'] = 'Ethernet jitter';
+$config['sla_type_labels']['lspPingPseudowire'] = 'LSP Pseudowire ping';
+
### Warnings on front page
$config['warn']['ifdown'] = TRUE; ## Show down interfaces
@@ -396,6 +419,7 @@ $config['poller_modules']['ospf'] = 1;
$config['poller_modules']['cisco-ipsec-flow-monitor'] = 1;
$config['poller_modules']['cisco-remote-access-monitor'] = 1;
$config['poller_modules']['cisco-cef'] = 1;
+$config['poller_modules']['cisco-sla'] = 1;
$config['poller_modules']['cisco-mac-accounting'] = 1;
$config['poller_modules']['cipsec-tunnels'] = 1;
$config['poller_modules']['cisco-ace-loadbalancer'] = 1;
@@ -426,6 +450,7 @@ $config['discovery_modules']['cisco-mac-accounting'] = 1;
$config['discovery_modules']['cisco-pw'] = 1;
$config['discovery_modules']['cisco-vrf'] = 1;
#$config['discovery_modules']['cisco-cef'] = 1;
+$config['discovery_modules']['cisco-sla'] = 1;
$config['discovery_modules']['vmware-vminfo'] = 1;
$config['discovery_modules']['libvirt-vminfo'] = 1;
$config['discovery_modules']['toner'] = 1;
diff --git a/includes/discovery/cisco-sla.inc.php b/includes/discovery/cisco-sla.inc.php
new file mode 100644
index 000000000..e4a09ca7c
--- /dev/null
+++ b/includes/discovery/cisco-sla.inc.php
@@ -0,0 +1,106 @@
+ $device['device_id']));
+
+ foreach ($sla_table as $sla_nr => $sla_config)
+ {
+ $query_data = array(
+ 'device_id' => $device['device_id'],
+ 'sla_nr' => $sla_nr,
+ );
+ $sla_id = dbFetchCell("SELECT `sla_id` FROM `slas` WHERE `device_id` = :device_id AND `sla_nr` = :sla_nr", $query_data);
+
+ $data = array(
+ 'device_id' => $device['device_id'],
+ 'sla_nr' => $sla_nr,
+ 'owner' => $sla_config['rttMonCtrlAdminOwner'],
+ 'tag' => $sla_config['rttMonCtrlAdminTag'],
+ 'rtt_type' => $sla_config['rttMonCtrlAdminRttType'],
+ 'status' => ($sla_config['rttMonCtrlAdminStatus'] == 'active') ? 1 : 0,
+ 'deleted' => 0,
+ );
+
+ // Some fallbacks for when the tag is empty
+ if (!$data['tag'])
+ {
+ switch ($data['rtt_type'])
+ {
+ case 'http':
+ $data['tag'] = $sla_config['rttMonEchoAdminURL'];
+ break;
+
+ case 'dns':
+ $data['tag'] = $sla_config['rttMonEchoAdminTargetAddressString'];
+ break;
+
+ case 'echo':
+ $parts = explode(" ", $sla_config['rttMonEchoAdminTargetAddress']);
+ if (count($parts) == 4)
+ {
+ // IPv4
+ $data['tag'] = implode(".", array_map('hexdec', $parts));
+ }
+ elseif (count($parts) == 16)
+ {
+ // IPv6
+ $data['tag'] = $parts[0].$parts[1].':'.$parts[2].$parts[3].':'.$parts[4].$parts[5].':'.$parts[6].$parts[7].':'.$parts[8].$parts[9].':'.$parts[10].$parts[11].':'.$parts[12].$parts[13].':'.$parts[14].$parts[15];
+ $data['tag'] = preg_replace('/:0*([0-9])/', ':$1', $data['tag']);
+ }
+ break;
+ }
+ }
+
+ if( !$sla_id )
+ {
+ $sla_id = dbInsert($data, 'slas');
+ echo "+";
+ }
+ else
+ {
+ // Remove from the list
+ $existing_slas = array_diff($existing_slas, array($sla_id));
+
+ dbUpdate($data, 'slas', "`sla_id` = :sla_id", array('sla_id' => $sla_id));
+ echo ".";
+ }
+ }
+
+ // Mark all remaining SLAs as deleted
+ foreach ($existing_slas as $existing_sla)
+ {
+ dbUpdate(array('deleted' => 1), 'slas', "`sla_id` = :sla_id", array('sla_id' => $existing_sla));
+ echo "-";
+ }
+
+ echo("\n");
+} # enable_sla && cisco
+
+?>
diff --git a/includes/polling/cisco-sla.inc.php b/includes/polling/cisco-sla.inc.php
new file mode 100644
index 000000000..3564a8f26
--- /dev/null
+++ b/includes/polling/cisco-sla.inc.php
@@ -0,0 +1,71 @@
+
diff --git a/sql-schema/012.sql b/sql-schema/012.sql
new file mode 100644
index 000000000..ec9872489
--- /dev/null
+++ b/sql-schema/012.sql
@@ -0,0 +1 @@
+CREATE TABLE IF NOT EXISTS `slas` ( `sla_id` int(11) NOT NULL auto_increment, `device_id` int(11) NOT NULL, `sla_nr` int(11) NOT NULL, `owner` varchar(255) NOT NULL, `tag` varchar(255) NOT NULL, `rtt_type` varchar(16) NOT NULL, `status` tinyint(1) NOT NULL, `deleted` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`sla_id`), UNIQUE KEY `unique_key` (`device_id`,`sla_nr`), KEY `device_id` (`device_id`)) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_bin;