diff --git a/net/frr/src/opnsense/mvc/app/controllers/OPNsense/Quagga/Api/DiagnosticsController.php b/net/frr/src/opnsense/mvc/app/controllers/OPNsense/Quagga/Api/DiagnosticsController.php
index c9e7f3ff5..59d30d1a4 100644
--- a/net/frr/src/opnsense/mvc/app/controllers/OPNsense/Quagga/Api/DiagnosticsController.php
+++ b/net/frr/src/opnsense/mvc/app/controllers/OPNsense/Quagga/Api/DiagnosticsController.php
@@ -237,7 +237,7 @@ class DiagnosticsController extends ApiControllerBase
public function searchOspfneighborAction(): array
{
$records = [];
- $payload = $this->getInformation("ospf", "neighbor", "json")['response'];
+ $payload = $this->getInformation("ospf", "neighbor", "json");
if (!empty($payload['neighbors'])) {
foreach ($payload['neighbors'] as $neighborid => $neighbor) {
foreach ($neighbor as $item) {
@@ -312,4 +312,44 @@ class DiagnosticsController extends ApiControllerBase
{
return $this->getInformation("ospfv3", "interface", $format);
}
+
+ private function bfdTreeFetch($topic)
+ {
+ $records = [];
+ $payload = $this->getInformation("bfd", $topic, "json")['response'];
+ if (!empty($payload)) {
+ foreach ($payload as $peer) {
+ $peerid = $peer['peer'];
+ $records[$peerid] = $peer;
+ }
+ }
+ return ["response" => $records];
+ }
+
+ public function bfdsummaryAction(): array
+ {
+ $records = [];
+ foreach (explode("\n", $this->getInformation("bfd", "summary", "plain")['response']) as $line) {
+ $parts = preg_split('/\s+/', trim($line));
+ if (count($parts) == 4 && filter_var($parts[0], FILTER_VALIDATE_INT) !== false) {
+ $records[] = [
+ 'id' => $parts[0],
+ 'local' => $parts[1],
+ 'peer' => $parts[2],
+ 'status' => $parts[3]
+ ];
+ }
+ }
+ return $this->searchRecordsetBase($records);
+ }
+
+ public function bfdneighborsAction(): array
+ {
+ return $this->bfdTreeFetch('neighbors');
+ }
+
+ public function bfdcountersAction(): array
+ {
+ return $this->bfdTreeFetch('counters');
+ }
}
diff --git a/net/frr/src/opnsense/mvc/app/controllers/OPNsense/Quagga/DiagnosticsController.php b/net/frr/src/opnsense/mvc/app/controllers/OPNsense/Quagga/DiagnosticsController.php
index 923e0d3ed..15b1e440b 100644
--- a/net/frr/src/opnsense/mvc/app/controllers/OPNsense/Quagga/DiagnosticsController.php
+++ b/net/frr/src/opnsense/mvc/app/controllers/OPNsense/Quagga/DiagnosticsController.php
@@ -95,6 +95,31 @@ class DiagnosticsController extends \OPNsense\Base\IndexController
$this->view->default_tab = 'routing';
$this->view->pick('OPNsense/Quagga/diagnostics');
}
+ public function bfdAction()
+ {
+ $this->view->tabs = [
+ [
+ 'name' => 'summary',
+ 'endpoint' => '/api/quagga/diagnostics/bfdsummary',
+ 'tabhead' => gettext('Summary'),
+ 'type' => 'bfdsummary'
+ ],
+ [
+ 'name' => 'neighbors',
+ 'endpoint' => '/api/quagga/diagnostics/bfdneighbors',
+ 'tabhead' => gettext('Neighbors'),
+ 'type' => 'tree'
+ ],
+ [
+ 'name' => 'counters',
+ 'endpoint' => '/api/quagga/diagnostics/bfdcounters',
+ 'tabhead' => gettext('Counters'),
+ 'type' => 'tree'
+ ]
+ ];
+ $this->view->default_tab = 'summary';
+ $this->view->pick('OPNsense/Quagga/diagnostics');
+ }
public function ospfv3Action()
{
$this->view->pick('OPNsense/Quagga/diagnosticsospfv3');
diff --git a/net/frr/src/opnsense/mvc/app/models/OPNsense/Quagga/Menu/Menu.xml b/net/frr/src/opnsense/mvc/app/models/OPNsense/Quagga/Menu/Menu.xml
index 450399f57..2a0fc1634 100644
--- a/net/frr/src/opnsense/mvc/app/models/OPNsense/Quagga/Menu/Menu.xml
+++ b/net/frr/src/opnsense/mvc/app/models/OPNsense/Quagga/Menu/Menu.xml
@@ -12,6 +12,7 @@
| {{ lang._('SessionId') }} | +{{ lang._('LocalAddress') }} | +{{ lang._('PeerAddress') }} | +{{ lang._('Status') }} | +
|---|