Repository: librenms/librenms (language: php)

Issue:
Libre nms LLDP map
### The problem

before 1 nov update port-channel multiple links are showing on network maps. bot now its now showing and some devices where lldp is not on after update those devices are showing on map. suggest how to fix or rollback previous map
<img width="728" alt="map" src="https://github.com/user-attachments/assets/8c661f68-8d82-45ac-b073-1a6ef5e39707">


### Output of ./validate.php

```txt
librenms@web-server:~$ ./validate.php
===========================================
Component | Version
--------- | -------
LibreNMS  | 24.9.1-113-gaaa100251 (2024-11-02T09:03:13+05:30)
DB Schema | 2023_12_21_085427_create_view_port_mac_link (304)
PHP       | 8.2.24
Python    | 3.11.2
Database  | MariaDB 10.3.39-MariaDB-0ubuntu0.20.04.2
RRDTool   | 1.7.2
SNMP      | 5.9.3
===========================================

[OK]    Composer Version: 2.8.2
[OK]    Dependencies up-to-date.
[OK]    Database connection successful
[OK]    Database connection successful
[OK]    Database Schema is current
[OK]    SQL Server meets minimum requirements
[OK]    lower_case_table_names is enabled
[OK]    MySQL engine is optimal
[OK]    Database and column collations are correct
[OK]    Database schema correct
[OK]    MySQL and PHP time match
[OK]    Distributed Polling setting is enabled globally
[OK]    Connection to memcached is ok
[OK]    Connected to rrdcached
[OK]    Active pollers found
[OK]    Dispatcher Service not detected
[OK]    Locks are functional
[OK]    Python poller wrapper is polling
[OK]    Redis is unavailable
[OK]    rrdtool version ok
[OK]    Connected to rrdcached
```


### What was the last working version of LibreNMS?

24.9.1-113-gaaa100251 - Sat Nov 02 2024 09:03:13 GMT+0530

### Anything in the logs that might be useful for us?

_No response_


Discussion / hints:
Can you please clarify what you expect to see by answering the following:
1 - Do you expect devices to only show on the map if they have LLDP neighbours?  For example, would you expect pradip_chattraj in the image above to disappear from the map?
2 - Can you please tell me 2 devices that are on the image above that have port-channels between them?  I want to know if the issue is that you are seeing gigabit-ethernet ports where you expect to see port-channel, or if the issue is that port-channel LLDP neighbours are just not showing on the map at all.
Only single link is there

On Sat, 2 Nov 2024, 19:10 eskyuu, ***@***.***> wrote:

> Can you please clarify what you expect to see by answering the following:
> 1 - Do you expect devices to only show on the map if they have LLDP
> neighbours? For example, would you expect pradip_chattraj in the image
> above to disappear from the map?
> 2 - Can you please tell me 2 devices that are on the image above that have
> port-channels between them? I want to know if the issue is that you are
> seeing gigabit-ethernet ports where you expect to see port-channel, or if
> the issue is that port-channel LLDP neighbours are just not showing on the
> map at all.
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/librenms/librenms/issues/16635#issuecomment-2452993795>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/BC26HXNBMXHV3ZEZOGJJRNTZ6TI5DAVCNFSM6AAAAABRBQCXZGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJSHE4TGNZZGU>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>

In the devices neighbour section both links are showing...but the problem
is on the map

On Sat, 2 Nov 2024, 19:14 Abhishek Sadhukhan, <
***@***.***> wrote:

> Only single link is there
>
> On Sat, 2 Nov 2024, 19:10 eskyuu, ***@***.***> wrote:
>
>> Can you please clarify what you expect to see by answering the following:
>> 1 - Do you expect devices to only show on the map if they have LLDP
>> neighbours? For example, would you expect pradip_chattraj in the image
>> above to disappear from the map?
>> 2 - Can you please tell me 2 devices that are on the image above that
>> have port-channels between them? I want to know if the issue is that you
>> are seeing gigabit-ethernet ports where you expect to see port-channel, or
>> if the issue is that port-channel LLDP neighbours are just not showing on
>> the map at all.
>>
>> —
>> Reply to this email directly, view it on GitHub
>> <https://github.com/librenms/librenms/issues/16635#issuecomment-2452993795>,
>> or unsubscribe
>> <https://github.com/notifications/unsubscribe-auth/BC26HXNBMXHV3ZEZOGJJRNTZ6TI5DAVCNFSM6AAAAABRBQCXZGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJSHE4TGNZZGU>
>> .
>> You are receiving this because you authored the thread.Message ID:
>> ***@***.***>
>>
>

includes/html/print-map.inc.php ---this file is missing on new update

Fix patch:
diff --git a/app/Http/Controllers/Maps/MapDataController.php b/app/Http/Controllers/Maps/MapDataController.php
index 552953b71118..a1600a0e9c1d 100644
--- a/app/Http/Controllers/Maps/MapDataController.php
+++ b/app/Http/Controllers/Maps/MapDataController.php
@@ -360,20 +360,17 @@ protected static function deviceList(Request $request)
         }
     }
 
-    protected function linkSpeedWidth(int|null $speed): float
+    protected function linkSpeedWidth(int|null $speed): int
     {
-        $speed /= 1000000000;
-        if ($speed > 500000) {
-            return 20;
-        }
+        $speed /= 10000000;
         if (is_nan($speed)) {
             return 1;
         }
-        if ($speed < 10) {
+        if ($speed < 1) {
             return 1;
         }
 
-        return round(0.77 * pow($speed, 0.25));
+        return strlen(strval(round($speed))) * 2;
     }
 
     protected function linkUseColour(float $link_pct): string
@@ -633,7 +630,7 @@ public function getDeviceLinks(Request $request): JsonResponse
     {
         // List all links
         $link_list = [];
-        $device_assoc_seen = [];
+        $port_assoc_seen = [];
         $link_types = $request->link_types;
 
         foreach ($link_types as $link_type) {
@@ -658,16 +655,17 @@ public function getDeviceLinks(Request $request): JsonResponse
                         continue;
                     }
 
-                    $device_ids_1 = $port->device_id . '.' . $remote_port->device_id;
-                    $device_ids_2 = $remote_port->device_id . '.' . $port->device_id;
+                    if ($port->port_id < $remote_port->port_id) {
+                        $port_ids = $port->port_id . '.' . $remote_port->port_id;
+                    } else {
+                        $port_ids = $remote_port->port_id . '.' . $port->port_id;
+                    }
 
                     // Ignore any associations that have already been processed
-                    if (array_key_exists($device_ids_1, $device_assoc_seen)
-                        || array_key_exists($device_ids_2, $device_assoc_seen)) {
+                    if (array_key_exists($port_ids, $port_assoc_seen)) {
                         continue;
                     }
-                    $device_assoc_seen[$device_ids_1] = true;
-                    $device_assoc_seen[$device_ids_2] = true;
+                    $port_assoc_seen[$port_ids] = true;
 
                     $width = $this->linkSpeedWidth($port->ifSpeed);
 
diff --git a/resources/views/map/netmap.blade.php b/resources/views/map/netmap.blade.php
index dd3483604015..7cf3ef3a726e 100644
--- a/resources/views/map/netmap.blade.php
+++ b/resources/views/map/netmap.blade.php
@@ -58,8 +58,13 @@ function refreshMap() {
         var group = null;
 @endif
 
-        $.post( '{{ route('maps.getdevices') }}', {disabled: 0, disabled_alerts: null, url_type: "links", group: group, highlight_node: highlight})
-            .done(function( data ) {
+        var hide_devices = new Map();
+        $.ajax({
+            type: 'POST',
+            url: '{{ route('maps.getdevices') }}',
+            data: {disabled: 0, disabled_alerts: null, url_type: "links", group: group, highlight_node: highlight},
+            dataType: 'json',
+            success: function (data) {
                 function deviceSort(a,b) {
                     return (data[a]["sname"] > data[b]["sname"]) ? 1 : -1;
                 }
@@ -78,6 +83,8 @@ function deviceSort(a,b) {
                         network_nodes.add([this_dev]);
                         $("#highlight_node").append("<option value='" + device_id + "' id='highlight-device-" + device_id + "'>" + device["sname"] + "</option>")
                     }
+                    // Hide the device until we find a link
+                    hide_devices.set(device_id.toString(), null);
                 })
 
                 // Remove any nodes that have been removed
@@ -100,10 +107,16 @@ function deviceSort(a,b) {
                     $("#alert").html("");
                     $("#alert-row").hide();
                 }
-            });
-
-        $.post( '{{ route('maps.getdevicelinks') }}', {disabled: 0, disabled_alerts: null, group: group, link_types: @json($link_types)})
-            .done(function( data ) {
+            },
+            async: false
+        });
+
+        $.ajax({
+            type: 'POST',
+            url: '{{ route('maps.getdevicelinks') }}',
+            data: {disabled: 0, disabled_alerts: null, group: group, link_types: @json($link_types)},
+            dataType: 'json',
+            success: function (data) {
                 $.each( data, function( link_id, link ) {
                     var this_edge = link['style'];
                     this_edge['from'] = link['ldev'];
@@ -114,6 +127,9 @@ function deviceSort(a,b) {
                     if (!network_edges.get(link_id)) {
                         network_edges.add([this_edge]);
                     }
+                    // Unhide any devices we find
+                    hide_devices.delete(link['ldev'].toString());
+                    hide_devices.delete(link['rdev'].toString());
                 })
 
                 // Remove any links that have disappeared
@@ -122,15 +138,25 @@ function deviceSort(a,b) {
                         network_edges.remove(link_id);
                     }
                 });
-            });
-
+            },
+            async: false
+        });
+
+        // Flush the nodes and edges (needed for the forEach() loop below)
+        network_nodes.flush();
+        network_edges.flush();
+
+        // Hide and unhide nodes
+        network_nodes.forEach(function (item) {
+            oldval = item.hidden;
+            item.hidden = hide_devices.has(item.id.toString());
+            if (oldval != item.hidden) {
+                network_nodes.update(item);
+            }
+        });
 
         // Initialise map if we haven't already.  If we do it earlier, the radom seeding doesn not work
         if (! network) {
-            // Flush the nodes and edges so they are rendered immediately
-            network_nodes.flush();
-            network_edges.flush();
-
             var container = document.getElementById('visualization');
             var options = {!! $options !!};
             network = new vis.Network(container, {nodes: network_nodes, edges: network_edges, stabilize: true}, options);
@@ -180,4 +206,3 @@ function deviceSort(a,b) {
     });
 </script>
 @endsection
-


Test patch: