summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-lldpd/htdocs
diff options
context:
space:
mode:
authorPaul Donald <newtwen+github@gmail.com>2024-04-22 01:31:16 +0200
committerPaul Donald <newtwen+github@gmail.com>2024-04-22 23:55:47 +0200
commitd3953006c2fe54806db97dbbadc2163847cd1dbf (patch)
tree9324fd2179127fdc57f4dee28421d21ca98c65a7 /applications/luci-app-lldpd/htdocs
parent49207b47ca048fdb9262b89c0683829f8e75972c (diff)
luci-app-lldpd: Fixes and additions
Signed-off-by: Paul Donald <newtwen+github@gmail.com>
Diffstat (limited to 'applications/luci-app-lldpd/htdocs')
-rw-r--r--applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd.js52
-rw-r--r--applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_hide.svg22
-rw-r--r--applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_show.svg23
-rw-r--r--applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/lldpd.css20
-rw-r--r--applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/config.js269
-rw-r--r--applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/status.js6
6 files changed, 266 insertions, 126 deletions
diff --git a/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd.js b/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd.js
index bc39ed5018..7b0121e548 100644
--- a/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd.js
+++ b/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd.js
@@ -1,6 +1,8 @@
/*
* Copyright (c) 2018-2020, Tano Systems LLC. All Rights Reserved.
* Anton Kikin <a.kikin@tano-systems.com>
+ * Copyright (c) 2023-2024. All Rights Reserved.
+ * Paul Donald <newtwen+github@gmail.com>
*/
'use strict';
@@ -40,6 +42,11 @@
* 18 x x x
* 19 x x x
*/
+
+const etitle = _('enable filter');
+const ptitle = _('keep only one protocol');
+const ntitle = _('keep only one neighbor');
+
var cbiFilterSelect = form.Value.extend({
__name__: 'CBI.LLDPD.FilterSelect',
@@ -98,9 +105,9 @@ var cbiFilterSelect = form.Value.extend({
// Prepend description with table legend
this.description =
- '<ul><li>' + _('E &mdash; enable filter') + '</li>' +
- '<li>' + _('P &mdash; keep only one protocol') + '</li>' +
- '<li>' + _('N &mdash; keep only one neighbor') + '</li>' +
+ '<ul><li>' + 'E &mdash; ' + etitle + '</li>' +
+ '<li>' + 'P &mdash; ' + ptitle + '</li>' +
+ '<li>' + 'N &mdash; ' + ntitle + '</li>' +
'</ul>' + this.description;
var rendered = this.super('renderFrame', arguments);
@@ -112,7 +119,8 @@ var cbiFilterSelect = form.Value.extend({
},
renderWidget: function(section_id, option_index, cfgvalue) {
- var selected = parseInt(cfgvalue) - 1;
+ //default value is "15" - rows are zero based
+ var selected = parseInt(cfgvalue) || 15;
var tbody = [];
@@ -138,12 +146,12 @@ var cbiFilterSelect = form.Value.extend({
})
]),
E('td', {}, i),
- E('td', {}, renderFilterVal(i, 0)),
- E('td', {}, renderFilterVal(i, 1)),
- E('td', {}, renderFilterVal(i, 2)),
- E('td', {}, renderFilterVal(i, 3)),
- E('td', {}, renderFilterVal(i, 4)),
- E('td', {}, renderFilterVal(i, 5))
+ E('td', {'title': etitle}, renderFilterVal(i, 0)),
+ E('td', {'title': ptitle}, renderFilterVal(i, 1)),
+ E('td', {'title': ntitle}, renderFilterVal(i, 2)),
+ E('td', {'title': etitle}, renderFilterVal(i, 3)),
+ E('td', {'title': ptitle}, renderFilterVal(i, 4)),
+ E('td', {'title': ntitle}, renderFilterVal(i, 5))
]));
};
@@ -171,6 +179,29 @@ var cbiFilterSelect = form.Value.extend({
},
});
+var CBIMultiIOSelect = form.MultiValue.extend({
+ __name__: 'CBI.MultiIOSelect',
+
+ renderWidget: function(section_id, option_index, cfgvalue) {
+ var value = (cfgvalue != null) ? cfgvalue : this.default ? this.default : '',
+ choices = this.transformChoices() ? this.transformChoices() : '';
+
+ var widget = new ui.Dropdown(L.toArray(value), choices, {
+ id: this.cbid(section_id),
+ sort: this.keylist,
+ multiple: true,
+ optional: true,
+ display_items: 5,
+ dropdown_items: -1,
+ create: true,
+ disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
+ validate: L.bind(this.validate, this, section_id),
+ });
+
+ return widget.render();
+ }
+});
+
function init() {
return new Promise(function(resolveFn, rejectFn) {
var data = session.getLocalData('luci-app-lldpd');
@@ -189,5 +220,6 @@ function init() {
return L.Class.extend({
cbiFilterSelect: cbiFilterSelect,
+ CBIMultiIOSelect: CBIMultiIOSelect,
init: init,
});
diff --git a/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_hide.svg b/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_hide.svg
index 7607870d58..0b64b95c78 100644
--- a/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_hide.svg
+++ b/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_hide.svg
@@ -1,13 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg version="1.1" viewBox="0 0 18 11.12" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-<metadata>
-<rdf:RDF>
-<cc:Work rdf:about="">
-<dc:format>image/svg+xml</dc:format>
-<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-</cc:Work>
-</rdf:RDF>
-</metadata>
-<path d="m 9,11.12 9,-9 L 15.88,0 9,6.88 2.12,0 0,2.12 Z"/>
-<path d="m-9-12h36v36h-36z" fill="none"/>
-</svg>
+<?xml version="1.0"?>
+<svg width="18" height="11.12" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" version="1.1">
+ <metadata>image/svg+xml</metadata>
+
+ <g class="layer">
+ <title>Layer 1</title>
+ <path d="m9,11.12l9,-9l-2.12,-2.12l-6.88,6.88l-6.88,-6.88l-2.12,2.12l9,9z" fill="#ff7f00" id="svg_1"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_show.svg b/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_show.svg
index 867ef4b998..e51e19ddee 100644
--- a/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_show.svg
+++ b/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/details_show.svg
@@ -1,14 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-<metadata>
-<rdf:RDF>
-<cc:Work rdf:about="">
-<dc:format>image/svg+xml</dc:format>
-<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-<dc:title/>
-</cc:Work>
-</rdf:RDF>
-</metadata>
-<path d="m4.585 2.83 9.17 9.17-9.17 9.17 2.83 2.83 12-12-12-12z"/>
-<path d="m0-24h48v48h-48z" fill="none"/>
-</svg>
+<?xml version="1.0"?>
+<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" version="1.1">
+ <metadata>image/svg+xml</metadata>
+
+ <g class="layer">
+ <title>Layer 1</title>
+ <path d="m4.58,2.83l9.17,9.17l-9.17,9.17l2.83,2.83l12,-12l-12,-12l-2.83,2.83z" fill="#ff7f00" id="svg_1"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/lldpd.css b/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/lldpd.css
index 0f3c0e1b98..5932e41536 100644
--- a/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/lldpd.css
+++ b/applications/luci-app-lldpd/htdocs/luci-static/resources/lldpd/lldpd.css
@@ -1,6 +1,8 @@
/*
* Copyright (c) 2020, Tano Systems LLC. All Rights Reserved.
* Author: Anton Kikin <a.kikin@tano-systems.com>
+ * Copyright (c) 2023-2024. All Rights Reserved.
+ * Paul Donald <newtwen+github@gmail.com>
*/
/*
@@ -9,7 +11,7 @@
table.lldpd-filter td,
table.lldpd-filter th {
border: 1px solid #ccc !important;
- padding: 2px 10px 2px 10px;
+ padding: 2px 10px;
text-align: center;
}
@@ -25,7 +27,7 @@ table.lldpd-filter tbody tr {
}
table.lldpd-filter tr.lldpd-filter-selected td {
- background-color: #eeeeee;
+ background-color: #EEE;
}
/*
@@ -33,18 +35,12 @@ table.lldpd-filter tr.lldpd-filter-selected td {
*/
.lldpd-params {
column-count: 2;
- -moz-column-count: 2;
- -webkit-column-count: 2;
column-gap: 24px;
- -moz-column-gap: 24px;
- -webkit-column-gap: 24px;
}
@media only screen and (max-width: 850px) {
.lldpd-params {
column-count: 1;
- -moz-column-count: 1;
- -webkit-column-count: 1;
}
}
@@ -53,9 +49,7 @@ table.lldpd-filter tr.lldpd-filter-selected td {
grid-template-columns: 1fr auto;
border-bottom: 1px solid #e6e6e6;
padding: 0 8px;
- -webkit-column-break-inside: avoid;
- -moz-column-break-inside: avoid;
- column-break-inside: avoid;
+/* column-break-inside: avoid;*/
}
.td .lldpd-params > div:last-of-type {
@@ -79,8 +73,6 @@ table.lldpd-filter tr.lldpd-filter-selected td {
.td .lldpd-params {
column-count: 1;
- -moz-column-count: 1;
- -webkit-column-count: 1;
}
.td .lldpd-params > div {
@@ -101,8 +93,6 @@ table.lldpd-filter tr.lldpd-filter-selected td {
display: inline-block;
width: auto !important;
width: fit-content !important;
- width: -moz-fit-content !important;
- width: -webkit-fit-content !important;
box-shadow: 0 1px 3px 0 grey;
padding: 0px 8px;
border-radius: 5px;
diff --git a/applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/config.js b/applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/config.js
index a4761f969e..a8e32b4275 100644
--- a/applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/config.js
+++ b/applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/config.js
@@ -1,12 +1,15 @@
/*
* Copyright (c) 2020 Tano Systems LLC. All Rights Reserved.
* Author: Anton Kikin <a.kikin@tano-systems.com>
+ * Copyright (c) 2023-2024. All Rights Reserved.
+ * Paul Donald <newtwen+github@gmail.com>
*/
'use strict';
'require rpc';
'require form';
'require lldpd';
+'require network';
'require uci';
'require tools.widgets as widgets';
@@ -29,6 +32,25 @@ var callInitAction = rpc.declare({
expect: { result: false }
});
+var usage = _('See syntax <a %s>here</a>.').format('href=https://lldpd.github.io/usage.html target="_blank"');
+
+const validateioentries = function(section_id, value) {
+ if (value) {
+ const emsg = _('Cannot have both interface %s and its exclusion %s');
+ const a = value.split(' ');
+ const noex = a.filter(el=> !el.startsWith('!'));
+ const ex = a.filter(el=> el.startsWith('!') && !el.startsWith('!!'));
+ for (var i of noex) {
+ for (var e of ex) {
+ if ('!'+i == e){
+ return emsg.format(i, e);
+ }
+ }
+ }
+ }
+ return true;
+};
+
return L.view.extend({
__init__: function() {
this.super('__init__', arguments);
@@ -46,7 +68,8 @@ return L.view.extend({
return Promise.all([
callInitList('lldpd'),
lldpd.init(),
- uci.load('lldpd')
+ uci.load('lldpd'),
+ network.getDevices()
]);
},
@@ -60,6 +83,7 @@ return L.view.extend({
populateBasicOptions: function(s, tab, data) {
var o;
var serviceEnabled = data[0];
+ var net_devices = data[3];
// Service enable/disable
o = s.taboption(tab, form.Flag, 'enabled', _('Enable service'));
@@ -71,17 +95,17 @@ return L.view.extend({
};
o.write = function(section_id, value) {
- uci.set('mstpd', section_id, 'enabled', value);
+ uci.set('lldpd', section_id, 'enabled', value);
if (value == '1') {
// Enable and start
- return callInitAction('lldpd', 'enable').then(function() {
+ callInitAction('lldpd', 'enable').then(function() {
return callInitAction('lldpd', 'start');
});
}
else {
// Stop and disable
- return callInitAction('lldpd', 'stop').then(function() {
+ callInitAction('lldpd', 'stop').then(function() {
return callInitAction('lldpd', 'disable');
});
}
@@ -90,71 +114,120 @@ return L.view.extend({
// System description
o = s.taboption(tab, form.Value, 'lldp_description',
_('System description'),
- _('Override system description with the provided description.'));
+ _('Override %s.').format('<code>system description</code>'));
o.placeholder = 'System description';
// System hostname
o = s.taboption(tab, form.Value, 'lldp_hostname',
_('System hostname'),
- _('Override system hostname with the provided value.'));
+ _('Override %s.').format('<code>system hostname</code>'));
o.placeholder = 'System hostname';
// Host location
o = s.taboption(tab, form.Value, 'lldp_location',
_('Host location'),
- _('Override the location of the host announced by lldp.'));
-
+ _('Override the announced location of the host.') + '<br />' +
+ usage);
+ // multiple syntaxes alert for location parameter
o.placeholder = 'address country EU';
+ o.rmempty = true;
+ o.validate = function(section_id, value) {
+ if (value) {
+ if (!value.match(/^coordinate |^address |^elin /))
+ return _("Must start: 'coordinate ...', 'address ...' or 'elin ...'");
+ }
+ return true;
+ };
+
// Platform
o = s.taboption(tab, form.Value, 'lldp_platform',
_('System platform description'),
- _('Override the platform description with the provided value. ' +
- 'The default description is the kernel name (Linux).'));
+ _('Override %s.').format('<code>system platform</code>') + '<br />' +
+ _('The default description is the kernel name (Linux).'));
o.placeholder = 'System platform description';
+ o = s.taboption(tab, form.Flag, 'lldp_capability_advertisements', _('System capability advertisements'));
+ o.default = '1'; //lldpd internal default
+
+ // Capabilities override
+ o = s.taboption(tab, form.MultiValue, 'lldp_syscapabilities',
+ _('System capabilities'),
+ _('Override %s.').format('<code>system capabilities</code>') + '<br />' +
+ _('The default is derived from kernel information.'));
+ o.depends({lldp_capability_advertisements: '1'});
+ o.value('bridge');
+ o.value('docsis');
+ o.value('other');
+ o.value('repeater');
+ o.value('router');
+ o.value('station');
+ o.value('telephone');
+ o.value('wlan');
+ o.cfgvalue = function(section_id) {
+ return String(this.super('load', [section_id]) || this.default).split(',');
+ };
+ o.write = function(section_id, value) {
+ return this.super('write', [ section_id, L.toArray(value).join(',') ]);
+ };
+
+ o = s.taboption(tab, form.Flag, 'lldp_mgmt_addr_advertisements', _('System management IO advertisements'));
+ o.default = '1'; //lldpd internal default
+
// Management addresses of this system
- o = s.taboption(tab, form.Value, 'lldp_mgmt_ip',
- _('Management addresses of this system'),
- _('Specify the management addresses of this system. ' +
- 'If not specified, the first IPv4 and the first ' +
- 'IPv6 are used. If an exact IP address is provided, it is used ' +
- 'as a management address without any check. If you want to ' +
- 'blacklist IPv6 addresses, you can use <code>!*:*</code>. ' +
- 'See more details about available patterns ' +
- '<a href=\"https://vincentbernat.github.io/lldpd/usage.html\">here</a>.'));
-
- o.placeholder = 'Management addresses';
+ // This value: lldpd.init handles as a single value, and needs a CSV for lldpd.conf: 'configure system ip management pattern'
+ o = s.taboption(tab, lldpd.CBIMultiIOSelect, 'lldp_mgmt_ip',
+ _('System management IO'),
+ _('Defaults to the first IPv4 and IPv6. ' +
+ 'If an exact IP address is provided, it is used ' +
+ 'as a management address without any check. To ' +
+ 'blacklist IPv6 addresses, use <code>!*:*</code>.') + '<br />' +
+ usage);
+ o.placeholder = 'Addresses and interfaces';
+ o.depends({lldp_mgmt_addr_advertisements: '1'});
+ o.cfgvalue = function(section_id) {
+ const opt = uci.get(this.config, section_id, this.option);
+ return opt ? opt.split(',') : '';
+ };
+ net_devices.forEach(nd => {
+ o.value(nd.getName());
+ o.value('!'+nd.getName());
+ nd.getIPAddrs().forEach(addr => o.value(addr.split('/')[0], E([], [addr.split('/')[0], ' (', E('strong', {}, nd.getName()), ')'])));
+ nd.getIP6Addrs().forEach(addr => o.value(addr.split('/')[0], E([], [addr.split('/')[0], ' (', E('strong', {}, nd.getName()), ')'])));
+ });
+ o.value('!*:*');
+ o.validate = validateioentries;
+ o.write = function(section_id, value, sep) {
+ return this.super('write', [ section_id, value.join(',') ]);
+ }
// LLDP tx interval
o = s.taboption(tab, form.Value, 'lldp_tx_interval',
_('Transmit delay'),
- _('The transmit delay is the delay between two ' +
+ _('The delay between ' +
'transmissions of LLDP PDU. The default value ' +
- 'is 30 seconds.'));
-
- o.datatype = 'uinteger';
+ 'is 30 seconds.') + '<br />' +
+ _('Suffix %s for millisecond values.').format('<code>ms</code>'));
o.default = 30;
o.placeholder = 30;
o.rmempty = false;
o.validate = function(section_id, value) {
- if (value != parseInt(value))
- return _('Must be a number');
- else if (value <= 0)
- return _('Transmit delay must be greater than 0');
+ const pattern = /^(\d+)(?:ms)?$/;
+ if (!value.match(pattern) || parseInt(value) <= 0)
+ return _('Must be a greater than zero number optionally suffixed with "ms"');
return true;
};
// LLDP tx hold
o = s.taboption(tab, form.Value, 'lldp_tx_hold',
_('Transmit hold value'),
- _('This value is used to compute the TTL of transmitted ' +
- 'packets which is the product of this value and of the ' +
- 'transmit delay. The default value is 4 and therefore ' +
+ _('Determines the transmitted ' +
+ 'packet TTL (== this value * transmit delay). ' +
+ 'The default value is 4 &therefore; ' +
'the default TTL is 120 seconds.'));
o.datatype = 'uinteger';
@@ -172,9 +245,9 @@ return L.view.extend({
// Received-only mode (-r)
o = s.taboption(tab, form.Flag, 'readonly_mode',
- _('Enable receive-only mode'),
- _('With this option, LLDPd will not send any frames. ' +
- 'It will only listen to neighbors.'));
+ _('Receive-only mode'),
+ _("LLDPd won't send any frames; " +
+ 'only listen to neighbors.'));
o.rmempty = false;
o.optional = false;
@@ -190,34 +263,43 @@ return L.view.extend({
/** @private */
populateIfacesOptions: function(s, tab, data) {
var o;
+ var net_devices = data[3];
// Interfaces to listen on
- o = s.taboption(tab, widgets.DeviceSelect, 'interface',
- _('Network interfaces'),
- _('Specify which interface to listen and send LLDPDU to. ' +
- 'If no interfaces is specified, LLDPd will use all available physical interfaces.'));
-
- o.nobridges = true;
- o.rmempty = true;
- o.multiple = true;
- o.nocreate = true;
- o.noaliases = true;
- o.networks = null;
+ // This value: lldpd.init handles as a list value, and produces a CSV for lldpd.conf: 'configure system interface pattern'
+ o = s.taboption(tab, lldpd.CBIMultiIOSelect, 'interface',
+ _('Network IO'),
+ _('Specify which interface (not) to listen upon and send LLDPDU from. ' +
+ 'Absent any value, LLDPd uses all available physical interfaces.'));
+
+ o.value('*');
+ net_devices.forEach(nd => {
+ o.value(nd.getName());
+ o.value('!'+nd.getName());
+ o.value('!!'+nd.getName());
+ });
+ o.value('!*:*');
+ o.validate = validateioentries;
// ChassisID interfaces
- o = s.taboption(tab, widgets.DeviceSelect, 'cid_interface',
- _('Network interfaces for chassis ID computing'),
- _('Specify which interfaces to use for computing chassis ID. ' +
- 'If no interfaces is specified, all interfaces are considered. ' +
- 'LLDPd will take the first MAC address from all the considered ' +
+ // This value: lldpd.init handles as a list value, and produces a CSV for the -C param
+ o = s.taboption(tab, lldpd.CBIMultiIOSelect, 'cid_interface',
+ _('Network IO for chassis ID'),
+ _('Specify which interfaces (not) to use for computing chassis ID. ' +
+ 'Absent any value, all interfaces are considered. ' +
+ 'LLDPd takes the first MAC address from all the considered ' +
'interfaces to compute the chassis ID.'));
- o.nobridges = false;
- o.rmempty = true;
- o.multiple = true;
- o.nocreate = true;
- o.noaliases = true;
- o.networks = null;
+ o.value('*');
+ o.value('!*');
+ net_devices.forEach(nd => {
+ o.value(nd.getName());
+ o.value('!'+nd.getName());
+ o.value('!!'+nd.getName());
+ });
+ o.value('!*:*');
+ o.validate = validateioentries;
+
},
// -----------------------------------------------------------------------------------------
@@ -242,7 +324,7 @@ return L.view.extend({
// o.placeholder = '/var/run/agentx.sock';
// o.default = '';
- // LLDP class
+ // LLDP-MED class
o = s.taboption(tab, form.ListValue, 'lldp_class',
_('LLDP-MED device class'));
@@ -253,12 +335,55 @@ return L.view.extend({
o.default = '4';
+ // LLDP-MED policy
+ o = s.taboption(tab, form.Value, 'lldp_policy',
+ _('LLDP-MED policy'));
+ o.depends({lldp_class: '2'});
+ o.depends({lldp_class: '3'});
+
+ o.rmempty = true;
+ o.placeholder = 'application streaming-video';
+ o.value('application voice');
+ o.value('application voice unknown');
+ o.value('application voice-signaling');
+ o.value('application voice-signaling unknown');
+ o.value('application guest-voice');
+ o.value('application guest-voice unknown');
+ o.value('application guest-voice-signaling');
+ o.value('application guest-voice-signaling unknown');
+ o.value('application softphone-voice');
+ o.value('application softphone-voice unknown');
+ o.value('application video-conferencing');
+ o.value('application video-conferencing unknown');
+ o.value('application streaming-video');
+ o.value('application streaming-video unknown');
+ o.value('application video-signaling');
+ o.value('application video-signaling unknown');
+
+ o.validate = function(section_id, value) {
+ if (value && !value.startsWith('application '))
+ return _('Must start: application ...');
+ return true;
+ };
+
+ // LLDP-MED fast-start
+ o = s.taboption(tab, form.Flag, 'lldpmed_fast_start',
+ _('LLDP-MED fast-start'));
+
+ // LLDP-MED fast-start
+ o = s.taboption(tab, form.Value, 'lldpmed_fast_start_tx_interval',
+ _('LLDP-MED fast-start tx-interval'));
+ o.depends({lldpmed_fast_start: '1'});
+ o.datatype = 'uinteger';
+ o.placeholder = '10';
+ o.rmempty = true;
+
// LLDP-MED inventory TLV transmission (-i)
o = s.taboption(tab, form.Flag, 'lldpmed_no_inventory',
_('Disable LLDP-MED inventory TLV transmission'),
_('LLDPd will still receive (and publish using SNMP if enabled) ' +
'those LLDP-MED TLV but will not send them. Use this option ' +
- 'if you don\'t want to transmit sensible information like serial numbers.'));
+ 'if you do not want to transmit sensitive information like serial numbers.'));
o.default = '0';
@@ -266,15 +391,15 @@ return L.view.extend({
o = s.taboption(tab, form.Flag, 'lldp_no_version',
_('Disable advertising of kernel release, version and machine'),
_('Kernel name (ie: Linux) will still be shared, and Inventory ' +
- 'software version will be set to \'Unknown\'.'));
+ 'software version will be set to %s.').format('<code>Unknown</code>'));
o.default = '0';
// Filter neighbors (-H)
o = s.taboption(tab, lldpd.cbiFilterSelect, 'filter',
_('Specify the behaviour when detecting multiple neighbors'),
- _('The default filter is 15. For more details see \"FILTERING NEIGHBORS\" section ' +
- '<a href=\"https://vincentbernat.github.io/lldpd/usage.html\">here</a>.'));
+ _('The default filter is 15. Refer to &quot;FILTERING NEIGHBORS&quot;.') + '<br />' +
+ usage);
o.default = 15;
@@ -291,11 +416,11 @@ return L.view.extend({
// The destination MAC address used to send LLDPDU
o = s.taboption(tab, form.ListValue, 'lldp_agenttype',
- _('The destination MAC address used to send LLDPDU'),
- _('The destination MAC address used to send LLDPDU allows an agent ' +
+ _('LLDPDU destination MAC'),
+ _('Allows an agent ' +
'to control the propagation of LLDPDUs. By default, the ' +
- '<code>01:80:c2:00:00:0e</code> MAC address is used and limit the propagation ' +
- 'of the LLDPDU to the nearest bridge.'));
+ 'MAC address %s is used and limits the propagation ' +
+ 'of the LLDPDU to the nearest bridge.').format('<code>01:80:c2:00:00:0e</code>'));
o.value('nearest-bridge', '01:80:c2:00:00:0e (nearest-bridge)');
o.value('nearest-nontpmr-bridge', '01:80:c2:00:00:03 (nearest-nontpmr-bridge)');
@@ -331,10 +456,10 @@ return L.view.extend({
o.rmempty = true;
o = ss.taboption('lldp', form.Flag, 'force_lldp',
- _('Force to send LLDP packets'),
- _('Force to send LLDP packets even when there is no LLDP peer ' +
- 'detected but there is a peer speaking another protocol detected. ' +
- 'By default, LLDP packets are sent when there is a peer speaking ' +
+ _('Force sending LLDP packets'),
+ _('Even when there is no LLDP peer ' +
+ 'detected but there is a peer speaking another protocol detected.') + '<br />' +
+ _('By default, LLDP packets are sent when there is a peer speaking ' +
'LLDP detected or when there is no peer at all.'));
o.default = '0';
@@ -469,8 +594,8 @@ return L.view.extend({
var m, s;
m = new form.Map('lldpd', _('LLDPd Settings'),
- _('LLDPd is a implementation of IEEE 802.1ab ' +
- '(<abbr title=\"Link Layer Discovery Protocol\">LLDP</abbr>).') +
+ _('LLDPd is an implementation of IEEE 802.1ab') + ' ' +
+ '(<abbr title="Link Layer Discovery Protocol">LLDP</abbr>).' + ' ' +
_('On this page you may configure LLDPd parameters.'));
s = m.section(form.TypedSection, 'lldpd');
diff --git a/applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/status.js b/applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/status.js
index 96847e11c3..b3fa30b3cb 100644
--- a/applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/status.js
+++ b/applications/luci-app-lldpd/htdocs/luci-static/resources/view/lldpd/status.js
@@ -1,6 +1,8 @@
/*
* Copyright (c) 2020 Tano Systems. All Rights Reserved.
* Author: Anton Kikin <a.kikin@tano-systems.com>
+ * Copyright (c) 2023-2024. All Rights Reserved.
+ * Paul Donald <newtwen+github@gmail.com>
*/
'use strict';
@@ -11,7 +13,7 @@
'require poll';
var callLLDPStatus = rpc.declare({
- object: 'lldpd',
+ object: 'luci.lldpd',
method: 'getStatus',
expect: {}
});
@@ -21,7 +23,7 @@ var dataMap = {
localChassis: null,
},
remote: {
- neightbors: null,
+ neighbors: null,
statistics: null,
},
};