1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-02-15 03:51:51 +00:00

Update luci-mod-admin-full to latest version

This commit is contained in:
Ycarus 2018-05-25 14:36:55 +02:00
parent b108aa9789
commit 027d882f4d
20 changed files with 1589 additions and 169 deletions

View file

@ -82,7 +82,7 @@ function index()
end
page = entry({"admin", "network", "iface_add"}, cbi("admin_network/iface_add"), nil)
page = entry({"admin", "network", "iface_add"}, form("admin_network/iface_add"), nil)
page.leaf = true
page = entry({"admin", "network", "iface_delete"}, post("iface_delete"), nil)
@ -301,7 +301,8 @@ function iface_reconnect(iface)
local netmd = require "luci.model.network".init()
local net = netmd:get_network(iface)
if net then
luci.sys.call("env -i /sbin/ifup %q >/dev/null 2>/dev/null" % iface)
luci.sys.call("env -i /sbin/ifup %s >/dev/null 2>/dev/null"
% luci.util.shellquote(iface))
luci.http.status(200, "Reconnected")
return
end
@ -313,7 +314,8 @@ function iface_shutdown(iface)
local netmd = require "luci.model.network".init()
local net = netmd:get_network(iface)
if net then
luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
% luci.util.shellquote(iface))
luci.http.status(200, "Shutdown")
return
end
@ -325,7 +327,8 @@ function iface_delete(iface)
local netmd = require "luci.model.network".init()
local net = netmd:del_network(iface)
if net then
luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
% luci.util.shellquote(iface))
luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
netmd:commit("network")
netmd:commit("wireless")
@ -339,9 +342,11 @@ function wifi_status(devs)
local s = require "luci.tools.status"
local rv = { }
local dev
for dev in devs:gmatch("[%w%.%-]+") do
rv[#rv+1] = s.wifi_network(dev)
if type(devs) == "string" then
local dev
for dev in devs:gmatch("[%w%.%-]+") do
rv[#rv+1] = s.wifi_network(dev)
end
end
if #rv > 0 then
@ -401,7 +406,7 @@ function diag_command(cmd, addr)
if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
luci.http.prepare_content("text/plain")
local util = io.popen(cmd % addr)
local util = io.popen(cmd % luci.util.shellquote(addr))
if util then
while true do
local ln = util:read("*l")
@ -420,23 +425,23 @@ function diag_command(cmd, addr)
end
function diag_ping(addr)
diag_command("ping -c 5 -W 1 %q 2>&1", addr)
diag_command("ping -c 5 -W 1 %s 2>&1", addr)
end
function diag_traceroute(addr)
diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr)
diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
end
function diag_nslookup(addr)
diag_command("nslookup %q 2>&1", addr)
diag_command("nslookup %s 2>&1", addr)
end
function diag_ping6(addr)
diag_command("ping6 -c 5 %q 2>&1", addr)
diag_command("ping6 -c 5 %s 2>&1", addr)
end
function diag_traceroute6(addr)
diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr)
diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)
end
function diag_iperf3(addr)

View file

@ -0,0 +1,433 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2011-2015 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
module("luci.controller.admin.network", package.seeall)
function index()
local uci = require("luci.model.uci").cursor()
local page
page = node("admin", "network")
page.target = firstchild()
page.title = _("Network")
page.order = 50
page.index = true
-- if page.inreq then
local has_switch = false
uci:foreach("network", "switch",
function(s)
has_switch = true
return false
end)
if has_switch then
page = node("admin", "network", "vlan")
page.target = cbi("admin_network/vlan")
page.title = _("Switch")
page.order = 20
page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil)
page.leaf = true
end
local has_wifi = false
uci:foreach("wireless", "wifi-device",
function(s)
has_wifi = true
return false
end)
if has_wifi then
page = entry({"admin", "network", "wireless_join"}, post("wifi_join"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_add"}, post("wifi_add"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_delete"}, post("wifi_delete"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_status"}, call("wifi_status"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_reconnect"}, post("wifi_reconnect"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless_shutdown"}, post("wifi_shutdown"), nil)
page.leaf = true
page = entry({"admin", "network", "wireless"}, arcombine(template("admin_network/wifi_overview"), cbi("admin_network/wifi")), _("Wireless"), 15)
page.leaf = true
page.subindex = true
if page.inreq then
local wdev
local net = require "luci.model.network".init(uci)
for _, wdev in ipairs(net:get_wifidevs()) do
local wnet
for _, wnet in ipairs(wdev:get_wifinets()) do
entry(
{"admin", "network", "wireless", wnet:id()},
alias("admin", "network", "wireless"),
wdev:name() .. ": " .. wnet:shortname()
)
end
end
end
end
page = entry({"admin", "network", "iface_add"}, form("admin_network/iface_add"), nil)
page.leaf = true
page = entry({"admin", "network", "iface_delete"}, post("iface_delete"), nil)
page.leaf = true
page = entry({"admin", "network", "iface_status"}, call("iface_status"), nil)
page.leaf = true
page = entry({"admin", "network", "iface_reconnect"}, post("iface_reconnect"), nil)
page.leaf = true
page = entry({"admin", "network", "iface_shutdown"}, post("iface_shutdown"), nil)
page.leaf = true
page = entry({"admin", "network", "network"}, arcombine(cbi("admin_network/network"), cbi("admin_network/ifaces")), _("Interfaces"), 10)
page.leaf = true
page.subindex = true
if page.inreq then
uci:foreach("network", "interface",
function (section)
local ifc = section[".name"]
if ifc ~= "loopback" then
entry({"admin", "network", "network", ifc},
true, ifc:upper())
end
end)
end
if nixio.fs.access("/etc/config/dhcp") then
page = node("admin", "network", "dhcp")
page.target = cbi("admin_network/dhcp")
page.title = _("DHCP and DNS")
page.order = 30
page = entry({"admin", "network", "dhcplease_status"}, call("lease_status"), nil)
page.leaf = true
page = node("admin", "network", "hosts")
page.target = cbi("admin_network/hosts")
page.title = _("Hostnames")
page.order = 40
end
page = node("admin", "network", "routes")
page.target = cbi("admin_network/routes")
page.title = _("Static Routes")
page.order = 50
page = node("admin", "network", "diagnostics")
page.target = template("admin_network/diagnostics")
page.title = _("Diagnostics")
page.order = 60
page = entry({"admin", "network", "diag_ping"}, post("diag_ping"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_nslookup"}, post("diag_nslookup"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_traceroute"}, post("diag_traceroute"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_ping6"}, post("diag_ping6"), nil)
page.leaf = true
page = entry({"admin", "network", "diag_traceroute6"}, post("diag_traceroute6"), nil)
page.leaf = true
-- end
end
function wifi_join()
local tpl = require "luci.template"
local http = require "luci.http"
local dev = http.formvalue("device")
local ssid = http.formvalue("join")
if dev and ssid then
local cancel = (http.formvalue("cancel") or http.formvalue("cbi.cancel"))
if not cancel then
local cbi = require "luci.cbi"
local map = luci.cbi.load("admin_network/wifi_add")[1]
if map:parse() ~= cbi.FORM_DONE then
tpl.render("header")
map:render()
tpl.render("footer")
end
return
end
end
tpl.render("admin_network/wifi_join")
end
function wifi_add()
local dev = luci.http.formvalue("device")
local ntm = require "luci.model.network".init()
dev = dev and ntm:get_wifidev(dev)
if dev then
local net = dev:add_wifinet({
mode = "ap",
ssid = "OpenWrt",
encryption = "none"
})
ntm:save("wireless")
luci.http.redirect(net:adminlink())
end
end
function wifi_delete(network)
local ntm = require "luci.model.network".init()
local wnet = ntm:get_wifinet(network)
if wnet then
local dev = wnet:get_device()
local nets = wnet:get_networks()
if dev then
ntm:del_wifinet(network)
ntm:commit("wireless")
local _, net
for _, net in ipairs(nets) do
if net:is_empty() then
ntm:del_network(net:name())
ntm:commit("network")
end
end
luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null")
end
end
luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
end
function iface_status(ifaces)
local netm = require "luci.model.network".init()
local rv = { }
local iface
for iface in ifaces:gmatch("[%w%.%-_]+") do
local net = netm:get_network(iface)
local device = net and net:get_interface()
if device then
local data = {
id = iface,
proto = net:proto(),
uptime = net:uptime(),
gwaddr = net:gwaddr(),
ipaddrs = net:ipaddrs(),
ip6addrs = net:ip6addrs(),
dnsaddrs = net:dnsaddrs(),
ip6prefix = net:ip6prefix(),
name = device:shortname(),
type = device:type(),
ifname = device:name(),
macaddr = device:mac(),
is_up = device:is_up(),
rx_bytes = device:rx_bytes(),
tx_bytes = device:tx_bytes(),
rx_packets = device:rx_packets(),
tx_packets = device:tx_packets(),
subdevices = { }
}
for _, device in ipairs(net:get_interfaces() or {}) do
data.subdevices[#data.subdevices+1] = {
name = device:shortname(),
type = device:type(),
ifname = device:name(),
macaddr = device:mac(),
is_up = device:is_up(),
rx_bytes = device:rx_bytes(),
tx_bytes = device:tx_bytes(),
rx_packets = device:rx_packets(),
tx_packets = device:tx_packets(),
}
end
rv[#rv+1] = data
else
rv[#rv+1] = {
id = iface,
name = iface,
type = "ethernet"
}
end
end
if #rv > 0 then
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
end
luci.http.status(404, "No such device")
end
function iface_reconnect(iface)
local netmd = require "luci.model.network".init()
local net = netmd:get_network(iface)
if net then
luci.sys.call("env -i /sbin/ifup %s >/dev/null 2>/dev/null"
% luci.util.shellquote(iface))
luci.http.status(200, "Reconnected")
return
end
luci.http.status(404, "No such interface")
end
function iface_shutdown(iface)
local netmd = require "luci.model.network".init()
local net = netmd:get_network(iface)
if net then
luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
% luci.util.shellquote(iface))
luci.http.status(200, "Shutdown")
return
end
luci.http.status(404, "No such interface")
end
function iface_delete(iface)
local netmd = require "luci.model.network".init()
local net = netmd:del_network(iface)
if net then
luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
% luci.util.shellquote(iface))
luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
netmd:commit("network")
netmd:commit("wireless")
return
end
luci.http.status(404, "No such interface")
end
function wifi_status(devs)
local s = require "luci.tools.status"
local rv = { }
if type(devs) == "string" then
local dev
for dev in devs:gmatch("[%w%.%-]+") do
rv[#rv+1] = s.wifi_network(dev)
end
end
if #rv > 0 then
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
return
end
luci.http.status(404, "No such device")
end
local function wifi_reconnect_shutdown(shutdown, wnet)
local netmd = require "luci.model.network".init()
local net = netmd:get_wifinet(wnet)
local dev = net:get_device()
if dev and net then
dev:set("disabled", nil)
net:set("disabled", shutdown and 1 or nil)
netmd:commit("wireless")
luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null")
luci.http.status(200, shutdown and "Shutdown" or "Reconnected")
return
end
luci.http.status(404, "No such radio")
end
function wifi_reconnect(wnet)
wifi_reconnect_shutdown(false, wnet)
end
function wifi_shutdown(wnet)
wifi_reconnect_shutdown(true, wnet)
end
function lease_status()
local s = require "luci.tools.status"
luci.http.prepare_content("application/json")
luci.http.write('[')
luci.http.write_json(s.dhcp_leases())
luci.http.write(',')
luci.http.write_json(s.dhcp6_leases())
luci.http.write(']')
end
function switch_status(switches)
local s = require "luci.tools.status"
luci.http.prepare_content("application/json")
luci.http.write_json(s.switch_status(switches))
end
function diag_command(cmd, addr)
if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
luci.http.prepare_content("text/plain")
local util = io.popen(cmd % luci.util.shellquote(addr))
if util then
while true do
local ln = util:read("*l")
if not ln then break end
luci.http.write(ln)
luci.http.write("\n")
end
util:close()
end
return
end
luci.http.status(500, "Bad address")
end
function diag_ping(addr)
diag_command("ping -c 5 -W 1 %s 2>&1", addr)
end
function diag_traceroute(addr)
diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
end
function diag_nslookup(addr)
diag_command("nslookup %s 2>&1", addr)
end
function diag_ping6(addr)
diag_command("ping6 -c 5 %s 2>&1", addr)
end
function diag_traceroute6(addr)
diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)
end

View file

@ -14,7 +14,7 @@ function index()
entry({"admin", "status", "routes"}, template("admin_status/routes"), _("Routes"), 3)
entry({"admin", "status", "syslog"}, call("action_syslog"), _("System Log"), 4)
entry({"admin", "status", "dmesg"}, call("action_dmesg"), _("Kernel Log"), 5)
entry({"admin", "status", "processes"}, cbi("admin_status/processes"), _("Processes"), 6)
entry({"admin", "status", "processes"}, form("admin_status/processes"), _("Processes"), 6)
entry({"admin", "status", "realtime"}, alias("admin", "status", "realtime", "load"), _("Realtime Graphs"), 7)
@ -62,7 +62,9 @@ end
function action_bandwidth(iface)
luci.http.prepare_content("application/json")
local bwc = io.popen("luci-bwc -i %q 2>/dev/null" % iface)
local bwc = io.popen("luci-bwc -i %s 2>/dev/null"
% luci.util.shellquote(iface))
if bwc then
luci.http.write("[")
@ -80,7 +82,9 @@ end
function action_wireless(iface)
luci.http.prepare_content("application/json")
local bwc = io.popen("luci-bwc -r %q 2>/dev/null" % iface)
local bwc = io.popen("luci-bwc -r %s 2>/dev/null"
% luci.util.shellquote(iface))
if bwc then
luci.http.write("[")

View file

@ -27,7 +27,8 @@ function index()
entry({"admin", "system", "fstab", "swap"}, cbi("admin_system/fstab/swap"), nil).leaf = true
end
if fs.access("/sys/class/leds") then
local nodes, number = fs.glob("/sys/class/leds/*")
if number > 0 then
entry({"admin", "system", "leds"}, cbi("admin_system/leds"), _("<abbr title=\"Light Emitting Diode\">LED</abbr> Configuration"), 60)
end
@ -195,7 +196,7 @@ local function supports_sysupgrade()
end
local function supports_reset()
return (os.execute([[grep -sqE '"rootfs_data"|"ubi"' /proc/mtd]]) == 0)
return (os.execute([[grep -sq "^overlayfs:/overlay / overlay " /proc/mounts]]) == 0)
end
local function storage_size()

View file

@ -5,60 +5,97 @@
module("luci.controller.admin.uci", package.seeall)
function index()
local redir = luci.http.formvalue("redir", true) or
luci.dispatcher.build_url(unpack(luci.dispatcher.context.request))
local redir = luci.http.formvalue("redir", true)
or table.concat(luci.dispatcher.context.request, "/")
entry({"admin", "uci"}, nil, _("Configuration"))
entry({"admin", "uci", "changes"}, call("action_changes"), _("Changes"), 40).query = {redir=redir}
entry({"admin", "uci", "revert"}, post("action_revert"), _("Revert"), 30).query = {redir=redir}
entry({"admin", "uci", "apply"}, post("action_apply"), _("Apply"), 20).query = {redir=redir}
entry({"admin", "uci", "saveapply"}, post("action_apply"), _("Save &#38; Apply"), 10).query = {redir=redir}
local node
local authen = function(checkpass, allowed_users)
return "root", luci.http.formvalue("sid")
end
node = entry({"admin", "uci", "apply_rollback"}, post("action_apply_rollback"), nil)
node.cors = true
node.sysauth_authenticator = authen
node = entry({"admin", "uci", "apply_unchecked"}, post("action_apply_unchecked"), nil)
node.cors = true
node.sysauth_authenticator = authen
node = entry({"admin", "uci", "confirm"}, post("action_confirm"), nil)
node.cors = true
node.sysauth_authenticator = authen
end
function action_changes()
local uci = luci.model.uci.cursor()
local uci = require "luci.model.uci"
local changes = uci:changes()
luci.template.render("admin_uci/changes", {
changes = next(changes) and changes
changes = next(changes) and changes,
timeout = timeout
})
end
function action_apply()
local path = luci.dispatcher.context.path
local uci = luci.model.uci.cursor()
local changes = uci:changes()
local reload = {}
-- Collect files to be applied and commit changes
for r, tbl in pairs(changes) do
table.insert(reload, r)
if path[#path] ~= "apply" then
uci:load(r)
uci:commit(r)
uci:unload(r)
end
end
luci.template.render("admin_uci/apply", {
changes = next(changes) and changes,
configs = reload
})
end
function action_revert()
local uci = luci.model.uci.cursor()
local uci = require "luci.model.uci"
local changes = uci:changes()
-- Collect files to be reverted
local r, tbl
for r, tbl in pairs(changes) do
uci:load(r)
uci:revert(r)
uci:unload(r)
end
luci.template.render("admin_uci/revert", {
changes = next(changes) and changes
})
end
local function ubus_state_to_http(errstr)
local map = {
["Invalid command"] = 400,
["Invalid argument"] = 400,
["Method not found"] = 404,
["Entry not found"] = 404,
["No data"] = 204,
["Permission denied"] = 403,
["Timeout"] = 504,
["Not supported"] = 500,
["Unknown error"] = 500,
["Connection failed"] = 503
}
local code = map[errstr] or 200
local msg = errstr or "OK"
luci.http.status(code, msg)
if code ~= 204 then
luci.http.prepare_content("text/plain")
luci.http.write(msg)
end
end
function action_apply_rollback()
local uci = require "luci.model.uci"
local _, errstr = uci:apply(true)
ubus_state_to_http(errstr)
end
function action_apply_unchecked()
local uci = require "luci.model.uci"
local _, errstr = uci:apply(false)
ubus_state_to_http(errstr)
end
function action_confirm()
local uci = require "luci.model.uci"
local _, errstr = uci:confirm()
ubus_state_to_http(errstr)
end

View file

@ -115,7 +115,7 @@ s:taboption("advanced", Flag, "nonegcache",
s:taboption("advanced", Value, "serversfile",
translate("Additional servers file"),
translate("This file may contain lines like 'server=/domain/1.2.3.4' or 'server=1.2.3.4' for"..
"domain-specific or full upstream <abbr title=\"Domain Name System\">DNS</abbr> servers."))
"domain-specific or full upstream <abbr title=\"Domain Name System\">DNS</abbr> servers."))
s:taboption("advanced", Flag, "strictorder",
translate("Strict order"),
@ -212,6 +212,12 @@ cq.optional = true
cq.datatype = "uinteger"
cq.placeholder = 150
cs = s:taboption("advanced", Value, "cachesize",
translate("Size of DNS query cache"),
translate("Number of cached DNS entries (max is 10000, 0 is no caching)"))
cs.optional = true
cs.datatype = "range(0,10000)"
cs.placeholder = 150
s:taboption("tftp", Flag, "enable_tftp",
translate("Enable TFTP server")).optional = true
@ -264,7 +270,7 @@ s = m:section(TypedSection, "host", translate("Static Leases"),
"DHCP clients. They are also required for non-dynamic interface configurations where " ..
"only hosts with a corresponding lease are served.") .. "<br />" ..
translate("Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> " ..
"indentifies the host, the <em>IPv4-Address</em> specifies the fixed address to " ..
"identifies the host, the <em>IPv4-Address</em> specifies the fixed address to " ..
"use, and the <em>Hostname</em> is assigned as a symbolic name to the requesting host. " ..
"The optional <em>Lease time</em> can be used to set non-standard host-specific " ..
"lease time, e.g. 12h, 3d or infinite."))
@ -274,7 +280,7 @@ s.anonymous = true
s.template = "cbi/tblsection"
name = s:option(Value, "name", translate("Hostname"))
name.datatype = "hostname"
name.datatype = "hostname('strict')"
name.rmempty = true
function name.write(self, section, value)
@ -291,6 +297,11 @@ mac = s:option(Value, "mac", translate("<abbr title=\"Media Access Control\">MAC
mac.datatype = "list(macaddr)"
mac.rmempty = true
function mac.cfgvalue(self, section)
local val = Value.cfgvalue(self, section)
return ipc.checkmac(val) or val
end
ip = s:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
ip.datatype = "or(ip4addr,'ignore')"
@ -298,7 +309,7 @@ gw = s:option(Value, "gw", translate("Gateway"))
gw.datatype = "or(ip4addr,'ignore')"
time = s:option(Value, "leasetime", translate("Lease time"))
time.rmempty = true
time.rmempty = true
duid = s:option(Value, "duid", translate("<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"))
duid.datatype = "and(rangelength(20,36),hexstring)"

View file

@ -0,0 +1,343 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
local ipc = require "luci.ip"
local sys = require "luci.sys"
local o
require "luci.util"
m = Map("dhcp", translate("DHCP and DNS"),
translate("Dnsmasq is a combined <abbr title=\"Dynamic Host Configuration Protocol" ..
"\">DHCP</abbr>-Server and <abbr title=\"Domain Name System\">DNS</abbr>-" ..
"Forwarder for <abbr title=\"Network Address Translation\">NAT</abbr> " ..
"firewalls"))
s = m:section(TypedSection, "dnsmasq", translate("Server Settings"))
s.anonymous = true
s.addremove = false
s:tab("general", translate("General Settings"))
s:tab("files", translate("Resolv and Hosts Files"))
s:tab("tftp", translate("TFTP Settings"))
s:tab("advanced", translate("Advanced Settings"))
s:taboption("general", Flag, "domainneeded",
translate("Domain required"),
translate("Don't forward <abbr title=\"Domain Name System\">DNS</abbr>-Requests without " ..
"<abbr title=\"Domain Name System\">DNS</abbr>-Name"))
s:taboption("general", Flag, "authoritative",
translate("Authoritative"),
translate("This is the only <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</" ..
"abbr> in the local network"))
s:taboption("files", Flag, "readethers",
translate("Use <code>/etc/ethers</code>"),
translate("Read <code>/etc/ethers</code> to configure the <abbr title=\"Dynamic Host " ..
"Configuration Protocol\">DHCP</abbr>-Server"))
s:taboption("files", Value, "leasefile",
translate("Leasefile"),
translate("file where given <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</" ..
"abbr>-leases will be stored"))
s:taboption("files", Flag, "noresolv",
translate("Ignore resolve file")).optional = true
rf = s:taboption("files", Value, "resolvfile",
translate("Resolve file"),
translate("local <abbr title=\"Domain Name System\">DNS</abbr> file"))
rf:depends("noresolv", "")
rf.optional = true
s:taboption("files", Flag, "nohosts",
translate("Ignore <code>/etc/hosts</code>")).optional = true
s:taboption("files", DynamicList, "addnhosts",
translate("Additional Hosts files")).optional = true
qu = s:taboption("advanced", Flag, "quietdhcp",
translate("Suppress logging"),
translate("Suppress logging of the routine operation of these protocols"))
qu.optional = true
se = s:taboption("advanced", Flag, "sequential_ip",
translate("Allocate IP sequentially"),
translate("Allocate IP addresses sequentially, starting from the lowest available address"))
se.optional = true
bp = s:taboption("advanced", Flag, "boguspriv",
translate("Filter private"),
translate("Do not forward reverse lookups for local networks"))
bp.default = bp.enabled
s:taboption("advanced", Flag, "filterwin2k",
translate("Filter useless"),
translate("Do not forward requests that cannot be answered by public name servers"))
s:taboption("advanced", Flag, "localise_queries",
translate("Localise queries"),
translate("Localise hostname depending on the requesting subnet if multiple IPs are available"))
local have_dnssec_support = luci.util.checklib("/usr/sbin/dnsmasq", "libhogweed.so")
if have_dnssec_support then
o = s:taboption("advanced", Flag, "dnssec",
translate("DNSSEC"))
o.optional = true
o = s:taboption("advanced", Flag, "dnsseccheckunsigned",
translate("DNSSEC check unsigned"),
translate("Requires upstream supports DNSSEC; verify unsigned domain responses really come from unsigned domains"))
o.optional = true
end
s:taboption("general", Value, "local",
translate("Local server"),
translate("Local domain specification. Names matching this domain are never forwarded and are resolved from DHCP or hosts files only"))
s:taboption("general", Value, "domain",
translate("Local domain"),
translate("Local domain suffix appended to DHCP names and hosts file entries"))
s:taboption("advanced", Flag, "expandhosts",
translate("Expand hosts"),
translate("Add local domain suffix to names served from hosts files"))
s:taboption("advanced", Flag, "nonegcache",
translate("No negative cache"),
translate("Do not cache negative replies, e.g. for not existing domains"))
s:taboption("advanced", Value, "serversfile",
translate("Additional servers file"),
translate("This file may contain lines like 'server=/domain/1.2.3.4' or 'server=1.2.3.4' for"..
"domain-specific or full upstream <abbr title=\"Domain Name System\">DNS</abbr> servers."))
s:taboption("advanced", Flag, "strictorder",
translate("Strict order"),
translate("<abbr title=\"Domain Name System\">DNS</abbr> servers will be queried in the " ..
"order of the resolvfile")).optional = true
bn = s:taboption("advanced", DynamicList, "bogusnxdomain", translate("Bogus NX Domain Override"),
translate("List of hosts that supply bogus NX domain results"))
bn.optional = true
bn.placeholder = "67.215.65.132"
s:taboption("general", Flag, "logqueries",
translate("Log queries"),
translate("Write received DNS requests to syslog")).optional = true
df = s:taboption("general", DynamicList, "server", translate("DNS forwardings"),
translate("List of <abbr title=\"Domain Name System\">DNS</abbr> " ..
"servers to forward requests to"))
df.optional = true
df.placeholder = "/example.org/10.1.2.3"
rp = s:taboption("general", Flag, "rebind_protection",
translate("Rebind protection"),
translate("Discard upstream RFC1918 responses"))
rp.rmempty = false
rl = s:taboption("general", Flag, "rebind_localhost",
translate("Allow localhost"),
translate("Allow upstream responses in the 127.0.0.0/8 range, e.g. for RBL services"))
rl:depends("rebind_protection", "1")
rd = s:taboption("general", DynamicList, "rebind_domain",
translate("Domain whitelist"),
translate("List of domains to allow RFC1918 responses for"))
rd.optional = true
rd:depends("rebind_protection", "1")
rd.datatype = "host(1)"
rd.placeholder = "ihost.netflix.com"
pt = s:taboption("advanced", Value, "port",
translate("<abbr title=\"Domain Name System\">DNS</abbr> server port"),
translate("Listening port for inbound DNS queries"))
pt.optional = true
pt.datatype = "port"
pt.placeholder = 53
qp = s:taboption("advanced", Value, "queryport",
translate("<abbr title=\"Domain Name System\">DNS</abbr> query port"),
translate("Fixed source port for outbound DNS queries"))
qp.optional = true
qp.datatype = "port"
qp.placeholder = translate("any")
lm = s:taboption("advanced", Value, "dhcpleasemax",
translate("<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration " ..
"Protocol\">DHCP</abbr> leases"),
translate("Maximum allowed number of active DHCP leases"))
lm.optional = true
lm.datatype = "uinteger"
lm.placeholder = translate("unlimited")
em = s:taboption("advanced", Value, "ednspacket_max",
translate("<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Extension Mechanisms for " ..
"Domain Name System\">EDNS0</abbr> packet size"),
translate("Maximum allowed size of EDNS.0 UDP packets"))
em.optional = true
em.datatype = "uinteger"
em.placeholder = 1280
cq = s:taboption("advanced", Value, "dnsforwardmax",
translate("<abbr title=\"maximal\">Max.</abbr> concurrent queries"),
translate("Maximum allowed number of concurrent DNS queries"))
cq.optional = true
cq.datatype = "uinteger"
cq.placeholder = 150
cs = s:taboption("advanced", Value, "cachesize",
translate("Size of DNS query cache"),
translate("Number of cached DNS entries (max is 10000, 0 is no caching)"))
cs.optional = true
cs.datatype = "range(0,10000)"
cs.placeholder = 150
s:taboption("tftp", Flag, "enable_tftp",
translate("Enable TFTP server")).optional = true
tr = s:taboption("tftp", Value, "tftp_root",
translate("TFTP server root"),
translate("Root directory for files served via TFTP"))
tr.optional = true
tr:depends("enable_tftp", "1")
tr.placeholder = "/"
db = s:taboption("tftp", Value, "dhcp_boot",
translate("Network boot image"),
translate("Filename of the boot image advertised to clients"))
db.optional = true
db:depends("enable_tftp", "1")
db.placeholder = "pxelinux.0"
o = s:taboption("general", Flag, "localservice",
translate("Local Service Only"),
translate("Limit DNS service to subnets interfaces on which we are serving DNS."))
o.optional = false
o.rmempty = false
o = s:taboption("general", Flag, "nonwildcard",
translate("Non-wildcard"),
translate("Bind only to specific interfaces rather than wildcard address."))
o.optional = false
o.rmempty = false
o = s:taboption("general", DynamicList, "interface",
translate("Listen Interfaces"),
translate("Limit listening to these interfaces, and loopback."))
o.optional = true
o:depends("nonwildcard", true)
o = s:taboption("general", DynamicList, "notinterface",
translate("Exclude interfaces"),
translate("Prevent listening on these interfaces."))
o.optional = true
o:depends("nonwildcard", true)
m:section(SimpleSection).template = "admin_network/lease_status"
s = m:section(TypedSection, "host", translate("Static Leases"),
translate("Static leases are used to assign fixed IP addresses and symbolic hostnames to " ..
"DHCP clients. They are also required for non-dynamic interface configurations where " ..
"only hosts with a corresponding lease are served.") .. "<br />" ..
translate("Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> " ..
"identifies the host, the <em>IPv4-Address</em> specifies the fixed address to " ..
"use, and the <em>Hostname</em> is assigned as a symbolic name to the requesting host. " ..
"The optional <em>Lease time</em> can be used to set non-standard host-specific " ..
"lease time, e.g. 12h, 3d or infinite."))
s.addremove = true
s.anonymous = true
s.template = "cbi/tblsection"
name = s:option(Value, "name", translate("Hostname"))
name.datatype = "hostname('strict')"
name.rmempty = true
function name.write(self, section, value)
Value.write(self, section, value)
m:set(section, "dns", "1")
end
function name.remove(self, section)
Value.remove(self, section)
m:del(section, "dns")
end
mac = s:option(Value, "mac", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
mac.datatype = "list(macaddr)"
mac.rmempty = true
function mac.cfgvalue(self, section)
local val = Value.cfgvalue(self, section)
return ipc.checkmac(val) or val
end
ip = s:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
ip.datatype = "or(ip4addr,'ignore')"
time = s:option(Value, "leasetime", translate("Lease time"))
time.rmempty = true
duid = s:option(Value, "duid", translate("<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"))
duid.datatype = "and(rangelength(20,36),hexstring)"
fp = io.open("/var/hosts/odhcpd")
if fp then
for line in fp:lines() do
local net_val, duid_val = string.match(line, "# (%S+)%s+(%S+)")
if duid_val then
duid:value(duid_val, duid_val)
end
end
fp:close()
end
hostid = s:option(Value, "hostid", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Suffix (hex)"))
sys.net.host_hints(function(m, v4, v6, name)
if m and v4 then
ip:value(v4)
mac:value(m, "%s (%s)" %{ m, name or v4 })
end
end)
function ip.validate(self, value, section)
local m = mac:formvalue(section) or ""
local n = name:formvalue(section) or ""
if value and #n == 0 and #m == 0 then
return nil, translate("One of hostname or mac address must be specified!")
end
return Value.validate(self, value, section)
end
return m

View file

@ -296,6 +296,11 @@ if not net:is_virtual() then
translate("Enables the Spanning Tree Protocol on this bridge"))
stp:depends("type", "bridge")
stp.rmempty = true
igmp = s:taboption("physical", Flag, "igmp_snooping", translate("Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> snooping"),
translate("Enables IGMP snooping on this bridge"))
igmp:depends("type", "bridge")
igmp.rmempty = true
-- macsource = s:taboption("physical", DynamicList, "vlanmacs", translate("Add MACs address to enable source mode"))
-- macsource:depends("type", "macvlan")
-- macsource.rmempty = true

View file

@ -0,0 +1,562 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2008-2011 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
local fs = require "nixio.fs"
local ut = require "luci.util"
local pt = require "luci.tools.proto"
local nw = require "luci.model.network"
local fw = require "luci.model.firewall"
arg[1] = arg[1] or ""
local has_dnsmasq = fs.access("/etc/config/dhcp")
local has_firewall = fs.access("/etc/config/firewall")
m = Map("network", translate("Interfaces") .. " - " .. arg[1]:upper(), translate("On this page you can configure the network interfaces. You can bridge several interfaces by ticking the \"bridge interfaces\" field and enter the names of several network interfaces separated by spaces. You can also use <abbr title=\"Virtual Local Area Network\">VLAN</abbr> notation <samp>INTERFACE.VLANNR</samp> (<abbr title=\"for example\">e.g.</abbr>: <samp>eth0.1</samp>)."))
m.redirect = luci.dispatcher.build_url("admin", "network", "network")
m:chain("wireless")
m:chain("luci")
if has_firewall then
m:chain("firewall")
end
nw.init(m.uci)
fw.init(m.uci)
local net = nw:get_network(arg[1])
local function set_ifstate(name, option, value)
local found = false
m.uci:foreach("luci", "ifstate", function (s)
if s.interface == name then
m.uci:set("luci", s[".name"], option, value)
found = true
return false
end
end)
if not found then
local sid = m.uci:add("luci", "ifstate")
m.uci:set("luci", sid, "interface", name)
m.uci:set("luci", sid, option, value)
end
m.uci:save("luci")
end
local function get_ifstate(name, option)
local val
m.uci:foreach("luci", "ifstate", function (s)
if s.interface == name then
val = m.uci:get("luci", s[".name"], option)
return false
end
end)
return val
end
local function backup_ifnames(is_bridge)
if not net:is_floating() and not get_ifstate(net:name(), "ifname") then
local ifcs = net:get_interfaces() or { net:get_interface() }
if ifcs then
local _, ifn
local ifns = { }
for _, ifn in ipairs(ifcs) do
local wif = ifn:get_wifinet()
ifns[#ifns+1] = wif and wif:id() or ifn:name()
end
if #ifns > 0 then
set_ifstate(net:name(), "ifname", table.concat(ifns, " "))
set_ifstate(net:name(), "bridge", tostring(net:is_bridge()))
end
end
end
end
-- redirect to overview page if network does not exist anymore (e.g. after a revert)
if not net then
luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
return
end
-- protocol switch was requested, rebuild interface config and reload page
if m:formvalue("cbid.network.%s._switch" % net:name()) then
-- get new protocol
local ptype = m:formvalue("cbid.network.%s.proto" % net:name()) or "-"
local proto = nw:get_protocol(ptype, net:name())
if proto then
-- backup default
backup_ifnames()
-- if current proto is not floating and target proto is not floating,
-- then attempt to retain the ifnames
--error(net:proto() .. " > " .. proto:proto())
if not net:is_floating() and not proto:is_floating() then
-- if old proto is a bridge and new proto not, then clip the
-- interface list to the first ifname only
if net:is_bridge() and proto:is_virtual() then
local _, ifn
local first = true
for _, ifn in ipairs(net:get_interfaces() or { net:get_interface() }) do
if first then
first = false
else
net:del_interface(ifn)
end
end
m:del(net:name(), "type")
end
-- if the current proto is floating, the target proto not floating,
-- then attempt to restore ifnames from backup
elseif net:is_floating() and not proto:is_floating() then
-- if we have backup data, then re-add all orphaned interfaces
-- from it and restore the bridge choice
local br = (get_ifstate(net:name(), "bridge") == "true")
local ifn
local ifns = { }
for ifn in ut.imatch(get_ifstate(net:name(), "ifname")) do
ifn = nw:get_interface(ifn)
if ifn and not ifn:get_network() then
proto:add_interface(ifn)
if not br then
break
end
end
end
if br then
m:set(net:name(), "type", "bridge")
end
-- in all other cases clear the ifnames
else
local _, ifc
for _, ifc in ipairs(net:get_interfaces() or { net:get_interface() }) do
net:del_interface(ifc)
end
m:del(net:name(), "type")
end
-- clear options
local k, v
for k, v in pairs(m:get(net:name())) do
if k:sub(1,1) ~= "." and
k ~= "type" and
k ~= "ifname"
then
m:del(net:name(), k)
end
end
-- set proto
m:set(net:name(), "proto", proto:proto())
m.uci:save("network")
m.uci:save("wireless")
-- reload page
luci.http.redirect(luci.dispatcher.build_url("admin/network/network", arg[1]))
return
end
end
-- dhcp setup was requested, create section and reload page
if m:formvalue("cbid.dhcp._enable._enable") then
m.uci:section("dhcp", "dhcp", arg[1], {
interface = arg[1],
start = "100",
limit = "150",
leasetime = "12h"
})
m.uci:save("dhcp")
luci.http.redirect(luci.dispatcher.build_url("admin/network/network", arg[1]))
return
end
local ifc = net:get_interface()
s = m:section(NamedSection, arg[1], "interface", translate("Common Configuration"))
s.addremove = false
s:tab("general", translate("General Setup"))
s:tab("advanced", translate("Advanced Settings"))
s:tab("physical", translate("Physical Settings"))
if has_firewall then
s:tab("firewall", translate("Firewall Settings"))
end
st = s:taboption("general", DummyValue, "__status", translate("Status"))
local function set_status()
-- if current network is empty, print a warning
if not net:is_floating() and net:is_empty() then
st.template = "cbi/dvalue"
st.network = nil
st.value = translate("There is no device assigned yet, please attach a network device in the \"Physical Settings\" tab")
else
st.template = "admin_network/iface_status"
st.network = arg[1]
st.value = nil
end
end
m.on_init = set_status
m.on_after_save = set_status
p = s:taboption("general", ListValue, "proto", translate("Protocol"))
p.default = net:proto()
if not net:is_installed() then
p_install = s:taboption("general", Button, "_install")
p_install.title = translate("Protocol support is not installed")
p_install.inputtitle = translate("Install package %q" % net:opkg_package())
p_install.inputstyle = "apply"
p_install:depends("proto", net:proto())
function p_install.write()
return luci.http.redirect(
luci.dispatcher.build_url("admin/system/packages") ..
"?submit=1&install=%s" % net:opkg_package()
)
end
end
p_switch = s:taboption("general", Button, "_switch")
p_switch.title = translate("Really switch protocol?")
p_switch.inputtitle = translate("Switch protocol")
p_switch.inputstyle = "apply"
local _, pr
for _, pr in ipairs(nw:get_protocols()) do
p:value(pr:proto(), pr:get_i18n())
if pr:proto() ~= net:proto() then
p_switch:depends("proto", pr:proto())
end
end
auto = s:taboption("advanced", Flag, "auto", translate("Bring up on boot"))
auto.default = (net:proto() == "none") and auto.disabled or auto.enabled
delegate = s:taboption("advanced", Flag, "delegate", translate("Use builtin IPv6-management"))
delegate.default = delegate.enabled
force_link = s:taboption("advanced", Flag, "force_link",
translate("Force link"),
translate("Set interface properties regardless of the link carrier (If set, carrier sense events do not invoke hotplug handlers)."))
force_link.default = (net:proto() == "static") and force_link.enabled or force_link.disabled
if not net:is_virtual() then
br = s:taboption("physical", Flag, "type", translate("Bridge interfaces"), translate("creates a bridge over specified interface(s)"))
br.enabled = "bridge"
br.rmempty = true
br:depends("proto", "static")
br:depends("proto", "dhcp")
br:depends("proto", "none")
stp = s:taboption("physical", Flag, "stp", translate("Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"),
translate("Enables the Spanning Tree Protocol on this bridge"))
stp:depends("type", "bridge")
stp.rmempty = true
igmp = s:taboption("physical", Flag, "igmp_snooping", translate("Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> snooping"),
translate("Enables IGMP snooping on this bridge"))
igmp:depends("type", "bridge")
igmp.rmempty = true
end
if not net:is_floating() then
ifname_single = s:taboption("physical", Value, "ifname_single", translate("Interface"))
ifname_single.template = "cbi/network_ifacelist"
ifname_single.widget = "radio"
ifname_single.nobridges = true
ifname_single.rmempty = false
ifname_single.network = arg[1]
ifname_single:depends("type", "")
function ifname_single.cfgvalue(self, s)
-- let the template figure out the related ifaces through the network model
return nil
end
function ifname_single.write(self, s, val)
local i
local new_ifs = { }
local old_ifs = { }
for _, i in ipairs(net:get_interfaces() or { net:get_interface() }) do
old_ifs[#old_ifs+1] = i:name()
end
for i in ut.imatch(val) do
new_ifs[#new_ifs+1] = i
-- if this is not a bridge, only assign first interface
if self.option == "ifname_single" then
break
end
end
table.sort(old_ifs)
table.sort(new_ifs)
for i = 1, math.max(#old_ifs, #new_ifs) do
if old_ifs[i] ~= new_ifs[i] then
backup_ifnames()
for i = 1, #old_ifs do
net:del_interface(old_ifs[i])
end
for i = 1, #new_ifs do
net:add_interface(new_ifs[i])
end
break
end
end
end
end
if not net:is_virtual() then
ifname_multi = s:taboption("physical", Value, "ifname_multi", translate("Interface"))
ifname_multi.template = "cbi/network_ifacelist"
ifname_multi.nobridges = true
ifname_multi.rmempty = false
ifname_multi.network = arg[1]
ifname_multi.widget = "checkbox"
ifname_multi:depends("type", "bridge")
ifname_multi.cfgvalue = ifname_single.cfgvalue
ifname_multi.write = ifname_single.write
end
if has_firewall then
fwzone = s:taboption("firewall", Value, "_fwzone",
translate("Create / Assign firewall-zone"),
translate("Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>create</em> field to define a new zone and attach the interface to it."))
fwzone.template = "cbi/firewall_zonelist"
fwzone.network = arg[1]
fwzone.rmempty = false
function fwzone.cfgvalue(self, section)
self.iface = section
local z = fw:get_zone_by_network(section)
return z and z:name()
end
function fwzone.write(self, section, value)
local zone = fw:get_zone(value)
if not zone and value == '-' then
value = m:formvalue(self:cbid(section) .. ".newzone")
if value and #value > 0 then
zone = fw:add_zone(value)
else
fw:del_network(section)
end
end
if zone then
fw:del_network(section)
zone:add_network(section)
end
end
end
function p.write() end
function p.remove() end
function p.validate(self, value, section)
if value == net:proto() then
if not net:is_floating() and net:is_empty() then
local ifn = ((br and (br:formvalue(section) == "bridge"))
and ifname_multi:formvalue(section)
or ifname_single:formvalue(section))
for ifn in ut.imatch(ifn) do
return value
end
return nil, translate("The selected protocol needs a device assigned")
end
end
return value
end
local form, ferr = loadfile(
ut.libpath() .. "/model/cbi/admin_network/proto_%s.lua" % net:proto()
)
if not form then
s:taboption("general", DummyValue, "_error",
translate("Missing protocol extension for proto %q" % net:proto())
).value = ferr
else
setfenv(form, getfenv(1))(m, s, net)
end
local _, field
for _, field in ipairs(s.children) do
if field ~= st and field ~= p and field ~= p_install and field ~= p_switch then
if next(field.deps) then
local _, dep
for _, dep in ipairs(field.deps) do
dep.proto = net:proto()
end
else
field:depends("proto", net:proto())
end
end
end
--
-- Display DNS settings if dnsmasq is available
--
if has_dnsmasq and net:proto() == "static" then
m2 = Map("dhcp", "", "")
local has_section = false
m2.uci:foreach("dhcp", "dhcp", function(s)
if s.interface == arg[1] then
has_section = true
return false
end
end)
if not has_section and has_dnsmasq then
s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
s.anonymous = true
s.cfgsections = function() return { "_enable" } end
x = s:option(Button, "_enable")
x.title = translate("No DHCP Server configured for this interface")
x.inputtitle = translate("Setup DHCP Server")
x.inputstyle = "apply"
elseif has_section then
s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
s.addremove = false
s.anonymous = true
s:tab("general", translate("General Setup"))
s:tab("advanced", translate("Advanced Settings"))
s:tab("ipv6", translate("IPv6 Settings"))
function s.filter(self, section)
return m2.uci:get("dhcp", section, "interface") == arg[1]
end
local ignore = s:taboption("general", Flag, "ignore",
translate("Ignore interface"),
translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
"this interface."))
local start = s:taboption("general", Value, "start", translate("Start"),
translate("Lowest leased address as offset from the network address."))
start.optional = true
start.datatype = "or(uinteger,ip4addr)"
start.default = "100"
local limit = s:taboption("general", Value, "limit", translate("Limit"),
translate("Maximum number of leased addresses."))
limit.optional = true
limit.datatype = "uinteger"
limit.default = "150"
local ltime = s:taboption("general", Value, "leasetime", translate("Lease time"),
translate("Expiry time of leased addresses, minimum is 2 minutes (<code>2m</code>)."))
ltime.rmempty = true
ltime.default = "12h"
local dd = s:taboption("advanced", Flag, "dynamicdhcp",
translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
"clients having static leases will be served."))
dd.default = dd.enabled
s:taboption("advanced", Flag, "force", translate("Force"),
translate("Force DHCP on this network even if another server is detected."))
-- XXX: is this actually useful?
--s:taboption("advanced", Value, "name", translate("Name"),
-- translate("Define a name for this network."))
mask = s:taboption("advanced", Value, "netmask",
translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
translate("Override the netmask sent to clients. Normally it is calculated " ..
"from the subnet that is served."))
mask.optional = true
mask.datatype = "ip4addr"
s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
"192.168.2.2</code>\" which advertises different DNS servers to clients."))
for i, n in ipairs(s.children) do
if n ~= ignore then
n:depends("ignore", "")
end
end
o = s:taboption("ipv6", ListValue, "ra", translate("Router Advertisement-Service"))
o:value("", translate("disabled"))
o:value("server", translate("server mode"))
o:value("relay", translate("relay mode"))
o:value("hybrid", translate("hybrid mode"))
o = s:taboption("ipv6", ListValue, "dhcpv6", translate("DHCPv6-Service"))
o:value("", translate("disabled"))
o:value("server", translate("server mode"))
o:value("relay", translate("relay mode"))
o:value("hybrid", translate("hybrid mode"))
o = s:taboption("ipv6", ListValue, "ndp", translate("NDP-Proxy"))
o:value("", translate("disabled"))
o:value("relay", translate("relay mode"))
o:value("hybrid", translate("hybrid mode"))
o = s:taboption("ipv6", ListValue, "ra_management", translate("DHCPv6-Mode"),
translate("Default is stateless + stateful"))
o:value("0", translate("stateless"))
o:value("1", translate("stateless + stateful"))
o:value("2", translate("stateful-only"))
o:depends("dhcpv6", "server")
o:depends("dhcpv6", "hybrid")
o.default = "1"
o = s:taboption("ipv6", Flag, "ra_default", translate("Always announce default router"),
translate("Announce as default router even if no public prefix is available."))
o:depends("ra", "server")
o:depends("ra", "hybrid")
s:taboption("ipv6", DynamicList, "dns", translate("Announced DNS servers"))
s:taboption("ipv6", DynamicList, "domain", translate("Announced DNS domains"))
else
m2 = nil
end
end
return m, m2

View file

@ -5,6 +5,7 @@
m = Map("network", translate("Switch"), translate("The network ports on this device can be combined to several <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s in which computers can communicate directly with each other. <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s are often used to separate different network segments. Often there is by default one Uplink port for a connection to the next greater network like the internet and other ports for a local network."))
local fs = require "nixio.fs"
local ut = require "luci.util"
local nw = require "luci.model.network"
local switches = { }
@ -74,7 +75,7 @@ m.uci:foreach("network", "switch",
end
-- Parse some common switch properties from swconfig help output.
local swc = io.popen("swconfig dev %q help 2>/dev/null" % switch_name)
local swc = io.popen("swconfig dev %s help 2>/dev/null" % ut.shellquote(switch_name))
if swc then
local is_port_attr = false

View file

@ -7,6 +7,17 @@ local ut = require "luci.util"
local nt = require "luci.sys".net
local fs = require "nixio.fs"
local acct_port, acct_secret, acct_server, anonymous_identity, ant1, ant2,
auth, auth_port, auth_secret, auth_server, bssid, cacert, cacert2,
cc, ch, cipher, clientcert, clientcert2, ea, eaptype, en, encr,
ft_protocol, ft_psk_generate_local, hidden, htmode, identity,
ieee80211r, ieee80211w, ifname, isolate, key_retries,
legacyrates, max_timeout, meshfwd, meshid, ml, mobility_domain, mode,
mp, nasid, network, password, pmk_r1_push, privkey, privkey2, privkeypwd,
privkeypwd2, r0_key_lifetime, r0kh, r1_key_holder, r1kh,
reassociation_deadline, retry_timeout, ssid, st, tp, wepkey, wepslot,
wmm, wpakey, wps
arg[1] = arg[1] or ""
m = Map("wireless", "",
@ -19,16 +30,6 @@ m:chain("network")
m:chain("firewall")
m.redirect = luci.dispatcher.build_url("admin/network/wireless")
local ifsection
function m.on_commit(map)
local wnet = nw:get_wifinet(arg[1])
if ifsection and wnet then
ifsection.section = wnet.sid
m.title = luci.util.pcdata(wnet:get_i18n())
end
end
nw.init(m.uci)
local wnet = nw:get_wifinet(arg[1])
@ -40,38 +41,6 @@ if not wnet or not wdev then
return
end
-- wireless toggle was requested, commit and reload page
function m.parse(map)
local new_cc = m:formvalue("cbid.wireless.%s.country" % wdev:name())
local old_cc = m:get(wdev:name(), "country")
if m:formvalue("cbid.wireless.%s.__toggle" % wdev:name()) then
if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then
wnet:set("disabled", nil)
else
wnet:set("disabled", "1")
end
wdev:set("disabled", nil)
nw:commit("wireless")
luci.sys.call("(env -i /bin/ubus call network reload) >/dev/null 2>/dev/null")
luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1]))
return
end
Map.parse(map)
if m:get(wdev:name(), "type") == "mac80211" and new_cc and new_cc ~= old_cc then
luci.sys.call("iw reg set %q" % new_cc)
luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1]))
return
end
end
m.title = luci.util.pcdata(wnet:get_i18n())
local function txpower_list(iw)
local list = iw.txpwrlist or { }
local off = tonumber(iw.txpower_offset) or 0
@ -112,6 +81,57 @@ local hw_modes = iw.hwmodelist or { }
local tx_power_list = txpower_list(iw)
local tx_power_cur = txpower_current(wdev:get("txpower"), tx_power_list)
-- wireless toggle was requested, commit and reload page
function m.parse(map)
local new_cc = m:formvalue("cbid.wireless.%s.country" % wdev:name())
local old_cc = m:get(wdev:name(), "country")
if m:formvalue("cbid.wireless.%s.__toggle" % wdev:name()) then
if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then
wnet:set("disabled", nil)
else
wnet:set("disabled", "1")
end
wdev:set("disabled", nil)
m.apply_needed = true
m.redirect = nil
end
Map.parse(map)
if m:get(wdev:name(), "type") == "mac80211" and new_cc and new_cc ~= old_cc then
luci.sys.call("iw reg set %s" % ut.shellquote(new_cc))
local old_ch = tonumber(m:formvalue("cbid.wireless.%s._mode_freq.channel" % wdev:name()) or "")
if old_ch then
local _, c, new_ch
for _, c in ipairs(iw.freqlist) do
if c.channel > old_ch or (old_ch <= 14 and c.channel > 14) then
break
end
new_ch = c.channel
end
if new_ch ~= old_ch then
wdev:set("channel", new_ch)
m.message = translatef("Channel %d is not available in the %s regulatory domain and has been auto-adjusted to %d.",
old_ch, new_cc, new_ch)
end
end
end
if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then
en.title = translate("Wireless network is disabled")
en.inputtitle = translate("Enable")
en.inputstyle = "apply"
else
en.title = translate("Wireless network is enabled")
en.inputtitle = translate("Disable")
en.inputstyle = "reset"
end
end
m.title = luci.util.pcdata(wnet:get_i18n())
s = m:section(NamedSection, wdev:name(), "wifi-device", translate("Device Configuration"))
s.addremove = false
@ -119,29 +139,12 @@ s:tab("general", translate("General Setup"))
s:tab("macfilter", translate("MAC-Filter"))
s:tab("advanced", translate("Advanced Settings"))
--[[
back = s:option(DummyValue, "_overview", translate("Overview"))
back.value = ""
back.titleref = luci.dispatcher.build_url("admin", "network", "wireless")
]]
st = s:taboption("general", DummyValue, "__status", translate("Status"))
st.template = "admin_network/wifi_status"
st.ifname = arg[1]
en = s:taboption("general", Button, "__toggle")
if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then
en.title = translate("Wireless network is disabled")
en.inputtitle = translate("Enable")
en.inputstyle = "apply"
else
en.title = translate("Wireless network is enabled")
en.inputtitle = translate("Disable")
en.inputstyle = "reset"
end
local hwtype = wdev:get("type")
-- NanoFoo
@ -170,9 +173,7 @@ if found_sta then
found_sta.channel or "(auto)", table.concat(found_sta.names, ", "))
else
ch = s:taboption("general", Value, "_mode_freq", '<br />'..translate("Operating frequency"))
ch.hwmodes = hw_modes
ch.htmodes = iw.htmodelist
ch.freqlist = iw.freqlist
ch.iwinfo = iw
ch.template = "cbi/wireless_modefreq"
function ch.cfgvalue(self, section)
@ -341,7 +342,6 @@ end
----------------------- Interface -----------------------
s = m:section(NamedSection, wnet.sid, "wifi-iface", translate("Interface Configuration"))
ifsection = s
s.addremove = false
s.anonymous = true
s.defaults.device = wdev:name()
@ -1049,7 +1049,7 @@ if hwtype == "mac80211" then
retry_timeout.rmempty = true
end
local key_retries = s:taboption("encryption", Flag, "wpa_disable_eapol_key_retries",
key_retries = s:taboption("encryption", Flag, "wpa_disable_eapol_key_retries",
translate("Enable key reinstallation (KRACK) countermeasures"),
translate("Complicates key reinstallation attacks on the client side by disabling retransmission of EAPOL-Key frames that are used to install keys. This workaround might cause interoperability issues and reduced robustness of key negotiation especially in environments with heavy traffic load."))

View file

@ -54,6 +54,9 @@
</div>
</form>
</div>
<% if reset_avail then %>
<div class="alert-message warning"><%:Custom files (certificates, scripts) may remain on the system. To prevent this, perform a factory-reset first.%></div>
<% end %>
</fieldset>
<br />

View file

@ -69,7 +69,7 @@ end
<% if querypat then %>
<div class="cbi-value">
<%:Displaying only packages containing%> <strong>"<%=pcdata(query)%>"</strong>
<input type="button" onclick="location.href='?display=<%=pcdata(display)%>'" href="#" class="cbi-button cbi-button-reset" style="margin-left:1em" value="<%:Reset%>" />
<input type="button" onclick="location.href='?display=<%=luci.http.urlencode(display)%>'" href="#" class="cbi-button cbi-button-reset" style="margin-left:1em" value="<%:Reset%>" />
<br style="clear:both" />
</div>
<% end %>

View file

@ -1,23 +0,0 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<%+header%>
<h2 name="content"><%:Configuration%> / <%:Apply%></h2>
<% if changes then %>
<%+cbi/apply_xhr%>
<%+admin_uci/changelog%>
<%- cbi_apply_xhr('uci-apply', configs) -%>
<p><strong><%:The following changes have been committed%>:</strong></p>
<%- uci_changelog(changes) -%>
<% else %>
<p><strong><%:There are no pending changes to apply!%></strong></p>
<% end %>
<%+footer%>

View file

@ -1,40 +1,41 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008-2015 Jo-Philipp Wich <jow@openwrt.org>
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
Licensed to the public under the Apache License 2.0.
-%>
<%+header%>
<%-
local node, redir_url = luci.dispatcher.lookup(luci.http.formvalue("redir"))
include("cbi/apply_widget")
include("admin_uci/changelog")
cbi_apply_widget(redir_url or url("admin/uci/changes"))
-%>
<h2 name="content"><%:Configuration%> / <%:Changes%></h2>
<% if changes then %>
<%+admin_uci/changelog%>
<%- uci_changelog(changes) -%>
<% else %>
<p><strong><%:There are no pending changes!%></strong></p>
<% end %>
<div class="alert-message" id="cbi_apply_status" style="display:none"></div>
<div class="cbi-page-actions">
<% local r = luci.http.formvalue("redir"); if r and #r > 0 then %>
<% if redir_url then %>
<div style="float:left">
<form class="inline" method="get" action="<%=luci.util.pcdata(r)%>">
<form class="inline" method="get" action="<%=luci.util.pcdata(redir_url)%>">
<input class="cbi-button cbi-button-link" style="float:left; margin:0" type="submit" value="<%:Back%>" />
</form>
</div>
<% end %>
<div style="text-align:right">
<form class="inline" method="post" action="<%=controller%>/admin/uci/apply">
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />
<input class="cbi-button cbi-button-apply" type="submit" value="<%:Apply%>" />
</form>
<form class="inline" method="post" action="<%=controller%>/admin/uci/saveapply">
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />
<input class="cbi-button cbi-button-save" type="submit" value="<%:Save & Apply%>" />
</form>
<input class="cbi-button cbi-button-save" type="button" id="apply_button" value="<%:Save & Apply%>" onclick="uci_apply(true); this.blur()" />
<form class="inline" method="post" action="<%=controller%>/admin/uci/revert">
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />

View file

@ -1,27 +1,42 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
Licensed to the public under the Apache License 2.0.
-%>
<%+header%>
<%-
local node, redir_url = luci.dispatcher.lookup(luci.http.formvalue("redir"))
include("cbi/apply_widget")
include("admin_uci/changelog")
cbi_apply_widget(redir_url or url("admin/uci/revert"))
-%>
<h2 name="content"><%:Configuration%> / <%:Revert%></h2>
<% if changes then %>
<%+cbi/apply_xhr%>
<%+admin_uci/changelog%>
<p><strong><%:The following changes have been reverted%>:</strong></p>
<%- uci_changelog(changes) -%>
<% else %>
<p><strong><%:There are no pending changes to revert!%></strong></p>
<% end %>
<div class="cbi-page-actions">
<form class="inline" method="get" action="<%=luci.util.pcdata(luci.http.formvalue("redir"))%>">
<input class="cbi-button cbi-button-link" style="margin:0" type="submit" value="<%:Back%>" />
</form>
</div>
<div class="alert-message" id="cbi_apply_status" style="display:none"></div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
uci_apply(true);
});
</script>
<% if redir_url then %>
<div class="cbi-page-actions">
<form class="inline" method="get" action="<%=luci.util.pcdata(redir_url)%>">
<input class="cbi-button cbi-button-link" style="margin:0" type="submit" value="<%:Back%>" />
</form>
</div>
<% end %>
<%+footer%>

View file

@ -1,9 +1,9 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
var freqlist = <%= luci.http.write_json(self.freqlist) %>;
var hwmodes = <%= luci.http.write_json(self.hwmodes) %>;
var htmodes = <%= luci.http.write_json(self.htmodes) %>;
var freqlist = <%= luci.http.write_json(self.iwinfo.freqlist) %>;
var hwmodes = <%= luci.http.write_json(self.iwinfo.hwmodelist or {}) %>;
var htmodes = <%= luci.http.write_json(self.iwinfo.htmodelist) %>;
var channels = {
'11g': [

0
luci-mod-admin-full/root/etc/init.d/macvlan Executable file → Normal file
View file

View file

@ -0,0 +1,22 @@
#!/bin/sh
if [ "$(uci -q get luci.diag)" != "internal" ]; then
host=""
if [ -s /etc/os-release ]; then
. /etc/os-release
host="${HOME_URL:-${BUG_URL:-$LEDE_DEVICE_MANUFACTURER_URL}}"
host="${host#*://}"
host="${host%%/*}"
fi
uci -q batch <<-EOF >/dev/null
set luci.diag=internal
set luci.diag.dns='${host:-openwrt.org}'
set luci.diag.ping='${host:-openwrt.org}'
set luci.diag.route='${host:-openwrt.org}'
commit luci
EOF
fi
exit 0

0
luci-mod-admin-full/root/etc/uci-defaults/51_macvlan Executable file → Normal file
View file