diff options
author | Vladislav Grigoryev <vg.aetera@gmail.com> | 2021-08-05 03:50:37 +0300 |
---|---|---|
committer | Vladislav Grigoryev <vg.aetera@gmail.com> | 2021-08-07 10:51:38 +0300 |
commit | 5cd9209636921d73ef140857b62ba57b03195e26 (patch) | |
tree | 2bb9f0496251764bb0eb5ccd8bc98a0415664fc3 /modules/luci-mod-status | |
parent | 39cc16d2eb8678b10deba7fca995f295674c43b1 (diff) |
luci-mod-status: status/routing support for pbr
Provide comprehensive status information for routing.
Rename the "Status > Routes" page to "Status > Routing".
Unify sorting for the "Status" and "Network" menus.
Add tabs for IPv4 and IPv6 and reorganize the contents.
Display routing rules and their priorities for each protocol.
Policy-based routing is an increasingly popular problem.
Netifd natively supports policy-based routing:
* The interface-specific options "ip4table" and "ip6table".
* The routing rules using the "rule" and "rule6" sections.
LuCI is missing the information about routing rules.
Signed-off-by: Vladislav Grigoryev <vg.aetera@gmail.com>
Diffstat (limited to 'modules/luci-mod-status')
3 files changed, 91 insertions, 29 deletions
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js index 6051b74c3b..91adae2434 100644 --- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js +++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js @@ -3,6 +3,7 @@ 'require fs'; 'require rpc'; 'require validation'; +'require ui'; var callNetworkInterfaceDump = rpc.declare({ object: 'network.interface', @@ -32,8 +33,10 @@ return view.extend({ callNetworkInterfaceDump(), L.resolveDefault(fs.exec('/sbin/ip', [ '-4', 'neigh', 'show' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-4', 'route', 'show', 'table', 'all' ]), {}), + L.resolveDefault(fs.exec('/sbin/ip', [ '-4', 'rule', 'show' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'neigh', 'show' ]), {}), - L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'route', 'show', 'table', 'all' ]), {}) + L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'route', 'show', 'table', 'all' ]), {}), + L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'rule', 'show' ]), {}) ]); }, @@ -143,12 +146,32 @@ return view.extend({ return res; }, + parseRule: function(s) { + var lines = s.trim().split(/\n/), + res = []; + + for (var i = 0; i < lines.length; i++) { + var m = lines[i].match(/^(\d+):\s+(.+)$/), + prio = m ? m[1] : null, + rule = m ? m[2] : null; + + res.push([ + prio, + rule + ]); + } + + return res; + }, + render: function(data) { var networks = data[0], ip4neigh = data[1].stdout || '', ip4route = data[2].stdout || '', - ip6neigh = data[3].stdout || '', - ip6route = data[4].stdout || ''; + ip4rule = data[3].stdout || '', + ip6neigh = data[4].stdout || '', + ip6route = data[5].stdout || '', + ip6rule = data[6].stdout || ''; var neigh4tbl = E('table', { 'class': 'table' }, [ E('tr', { 'class': 'tr table-titles' }, [ @@ -165,7 +188,14 @@ return view.extend({ E('th', { 'class': 'th' }, [ _('IPv4 gateway') ]), E('th', { 'class': 'th' }, [ _('Metric') ]), E('th', { 'class': 'th' }, [ _('Table') ]), - E('th', { 'class': 'th' }, [ _('Protocol') ]), + E('th', { 'class': 'th' }, [ _('Protocol') ]) + ]) + ]); + + var rule4tbl = E('table', { 'class': 'table' }, [ + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th' }, [ _('Priority') ]), + E('th', { 'class': 'th' }, [ _('Rule') ]) ]) ]); @@ -184,31 +214,62 @@ return view.extend({ E('th', { 'class': 'th' }, [ _('Source') ]), E('th', { 'class': 'th' }, [ _('Metric') ]), E('th', { 'class': 'th' }, [ _('Table') ]), - E('th', { 'class': 'th' }, [ _('Protocol') ]), + E('th', { 'class': 'th' }, [ _('Protocol') ]) + ]) + ]); + + var rule6tbl = E('table', { 'class': 'table' }, [ + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th' }, [ _('Priority') ]), + E('th', { 'class': 'th' }, [ _('Rule') ]) ]) ]); cbi_update_table(neigh4tbl, this.parseNeigh(ip4neigh, networks, false)); cbi_update_table(route4tbl, this.parseRoute(ip4route, networks, false)); + cbi_update_table(rule4tbl, this.parseRule(ip4rule, networks, false)); cbi_update_table(neigh6tbl, this.parseNeigh(ip6neigh, networks, true)); cbi_update_table(route6tbl, this.parseRoute(ip6route, networks, true)); - - return E([], [ - E('h2', {}, [ _('Routes') ]), + cbi_update_table(rule6tbl, this.parseRule(ip6rule, networks, false)); + + var view = E([], [ + E('style', { 'type': 'text/css' }, [ + '.cbi-tooltip-container, span.jump { border-bottom:1px dotted #00f;cursor:pointer }', + 'ul { list-style:none }', + '.references { position:relative }', + '.references .cbi-tooltip { left:0!important;top:1.5em!important }', + 'h4>span { font-size:90% }' + ]), + + E('h2', {}, [ _('Routing') ]), E('p', {}, [ _('The following rules are currently active on this system.') ]), + E('div', {}, [ + E('div', { 'data-tab': 'ipv4routing', 'data-tab-title': _('IPv4 Routing') }, [ + E('h3', {}, [ _('ARP') ]), + neigh4tbl, + + E('h3', {}, _('Active <abbr title="Internet Protocol Version 4">IPv4</abbr>-Routes')), + route4tbl, + + E('h3', {}, _('Active <abbr title="Internet Protocol Version 4">IPv4</abbr>-Rules')), + rule4tbl + ]), + E('div', { 'data-tab': 'ipv6routing', 'data-tab-title': _('IPv6 Routing') }, [ + E('h3', {}, [ _('IPv6 Neighbours') ]), + neigh6tbl, + + E('h3', {}, _('Active <abbr title="Internet Protocol Version 6">IPv6</abbr>-Routes')), + route6tbl, + + E('h3', {}, _('Active <abbr title="Internet Protocol Version 6">IPv6</abbr>-Rules')), + rule6tbl + ]) + ]) + ]); - E('h3', {}, [ _('ARP') ]), - neigh4tbl, - - E('h3', {}, _('Active <abbr title="Internet Protocol Version 4">IPv4</abbr>-Routes')), - route4tbl, - - E('h3', {}, [ _('IPv6 Neighbours') ]), - neigh6tbl, + ui.tabs.initTabGroup(view.lastElementChild.childNodes); - E('h3', {}, _('Active <abbr title="Internet Protocol Version 6">IPv6</abbr>-Routes')), - route6tbl - ]); + return view; }, handleSaveApply: null, diff --git a/modules/luci-mod-status/root/usr/share/luci/menu.d/luci-mod-status.json b/modules/luci-mod-status/root/usr/share/luci/menu.d/luci-mod-status.json index 0f066e67ad..1e6556bab2 100644 --- a/modules/luci-mod-status/root/usr/share/luci/menu.d/luci-mod-status.json +++ b/modules/luci-mod-status/root/usr/share/luci/menu.d/luci-mod-status.json @@ -11,27 +11,27 @@ } }, - "admin/status/iptables": { - "title": "Firewall", + "admin/status/routes": { + "title": "Routing", "order": 2, "action": { "type": "view", - "path": "status/iptables" + "path": "status/routes" }, "depends": { - "acl": [ "luci-mod-status-firewall" ] + "acl": [ "luci-mod-status-routes" ] } }, - "admin/status/routes": { - "title": "Routes", + "admin/status/iptables": { + "title": "Firewall", "order": 3, "action": { "type": "view", - "path": "status/routes" + "path": "status/iptables" }, "depends": { - "acl": [ "luci-mod-status-routes" ] + "acl": [ "luci-mod-status-firewall" ] } }, diff --git a/modules/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status.json b/modules/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status.json index 3e7d823014..63ff83132d 100644 --- a/modules/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status.json +++ b/modules/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status.json @@ -44,11 +44,12 @@ }, "luci-mod-status-routes": { - "description": "Grant access to the system route status", + "description": "Grant access to routing status", "read": { "file": { "/sbin/ip -[46] neigh show": [ "exec" ], - "/sbin/ip -[46] route show table all": [ "exec" ] + "/sbin/ip -[46] route show table all": [ "exec" ], + "/sbin/ip -[46] rule show": [ "exec" ] }, "ubus": { "file": [ "exec" ] |