for _, v in ipairs(section:variables()) do
local ok, err = self:_validate_option( v )
- if not ok then
+ if not ok and (
+ v:scheme('required') or v:scheme('type') == "enum" or (
+ not err:is(ERR.ERR_DEP_NOTEQUAL) and
+ not err:is(ERR.ERR_DEP_NOVALUE)
+ )
+ ) then
section:error(err)
end
end
for k, v in pairs(section:config()) do
local oo = section:option(k)
if k:sub(1,1) ~= "." and not self.beenthere[oo:cid()] then
- section:error(ERR.OPT_NOTFOUND(oo))
+ section:error(ERR.OPT_UNKNOWN(oo))
end
end
end
not option:scheme('values')[val]
then
return false, option:error( ERR.OPT_BADVALUE(
- option, { val, table.concat(
- luci.util.keys(option:scheme('values') or {}), ", "
- ) }
+ option, luci.util.serialize_data(
+ luci.util.keys(option:scheme('values') or {})
+ )
) )
end
elseif option:scheme('type') == "list" then
for i, v in ipairs(val) do
if not self.datatypes[dt]( v ) then
return false, option:error(
- ERR.OPT_INVVALUE(option, {v, dt})
+ ERR.OPT_INVVALUE(option, dt)
)
end
end
{ 'SCHEME', 'Error in scheme "%p":\n%c' },
{ 'CONFIG', 'Error in config "%p":\n%c' },
- { 'SECTION', 'Error in section "%p.%s":\n%c' },
- { 'OPTION', 'Error in option "%p.%s.%o":\n%c' },
+ { 'SECTION', 'Error in section "%i" (%I):\n%c' },
+ { 'OPTION', 'Error in option "%i" (%I):\n%c' },
{ 'REFERENCE', 'Option "%p.%s.%o" has invalid reference specification %1:\n%c' },
{ 'DEPENDENCY', 'In dependency check for %t "%i":\n%c' },
{ 'SME_EBADTYPE', 'Enum "%v" in scheme "%p" references non-enum option "%p.%s.%o"' },
{ 'SME_EBADDEF', 'Enum "%v" in scheme "%p" redeclares the default value of "%p.%s.%o"' },
- { 'SECT_UNKNOWN', 'Section "%p.%s" not found in scheme' },
+ { 'SECT_UNKNOWN', 'Section "%i" (%I) not found in scheme' },
{ 'SECT_REQUIRED', 'Required section "%p.%S" not found in config' },
{ 'SECT_UNIQUE', 'Unique section "%p.%S" occurs multiple times in config' },
{ 'SECT_NAMED', 'The section of type "%p.%S" is stored anonymously in config but must be named' },
{ 'SECT_NOTFOUND', 'Section "%p.%s" not found in config' },
- { 'OPT_UNKNOWN', 'Option "%1" not found in scheme' },
+ { 'OPT_UNKNOWN', 'Option "%i" (%I) not found in scheme' },
{ 'OPT_REQUIRED', 'Required option "%i" has no value' },
- { 'OPT_BADVALUE', 'Value "%1" of option "%i" is not defined in %t { %2 }' },
- { 'OPT_INVVALUE', 'Value "%1" of given option "%i" does not validate as datatype "%2"' },
+ { 'OPT_BADVALUE', 'Value "%v" of option "%i" is not defined in enum %1' },
+ { 'OPT_INVVALUE', 'Value "%v" of given option "%i" does not validate as datatype "%1"' },
{ 'OPT_NOTLIST', 'Option "%i" is defined as list but stored as plain value' },
{ 'OPT_DATATYPE', 'Option "%i" has unknown datatype "%1"' },
{ 'OPT_NOTFOUND', 'Option "%p.%s.%o" not found in config' },
( self.option and '.' .. self.option or '' ) ..
( self.value and '.' .. self.value or '' )
end
+
+function error.is(self, code)
+ if self.code == code then
+ return true
+ elseif self.childs then
+ for _, c in ipairs(self.childs) do
+ if c:is(code) then
+ return true
+ end
+ end
+ end
+ return false
+end
--- /dev/null
+package network
+
+config section
+ option name 'interface'
+ option title 'Network interface definition'
+ option package 'network'
+ list depends 'proto=static, ipaddr, netmask'
+ list depends 'proto=pppoe, username, password'
+ list depends 'proto=pptp, username, password, server'
+ list depends 'proto=dhcp'
+ option named true
+ option required true
+
+config variable
+ option name 'ifname'
+ option title 'Physical interface name'
+ option section 'network.interface'
+ option required true
+
+config variable
+ option name 'ipaddr'
+ option title 'IPv4 host address'
+ option section 'network.interface'
+ option datatype 'ip4addr'
+
+config variable
+ option name 'netmask'
+ option title 'IPv4 network mask'
+ option section 'network.interface'
+ option datatype 'ip4addr'
+
+config variable
+ option name 'proto'
+ option title 'Option proto'
+ option section 'network.interface'
+ option type 'enum'
+ option required true
+
+config enum
+ option variable 'network.interface.proto'
+ option value 'dhcp'
+ option title 'Retrieve IP address via DHCP'
+
+config enum
+ option variable 'network.interface.proto'
+ option value 'pptp'
+ option title 'Interface is a PPTP tunnel endpoint'
+
+config enum
+ option variable 'network.interface.proto'
+ option value 'static'
+ option title 'Interface has static network configuration'
+
+config enum
+ option variable 'network.interface.proto'
+ option value 'pppoe'
+ option title 'Retrieve IP address via PPPoE'
+
+config variable
+ option name 'type'
+ option title 'Option type'
+ option section 'network.interface'
+ option type 'enum'
+
+config enum
+ option variable 'network.interface.type'
+ option value 'bridge'
+ option title 'This is a bridge interface'
+
+
+config section
+ option name 'switch'
+ option title 'Section switch'
+ option package 'network'
+ option named true
+ option dynamic true
+ option required true
--- /dev/null
+package qos
+
+config section
+ option name 'interface'
+ option title 'QoS interface section'
+ option package 'qos'
+ option named true
+ option required true
+
+config variable
+ option name 'enabled'
+ option title 'Enable QoS on this interface'
+ option section 'qos.interface'
+ option datatype 'boolean'
+
+config variable
+ option name 'overhead'
+ option title 'Calculate overhead bandwidth'
+ option section 'qos.interface'
+ option datatype 'boolean'
+
+config variable
+ option name 'classgroup'
+ option title 'QoS classification'
+ option section 'qos.interface'
+ option valueof 'qos.classgroup'
+
+config variable
+ option name 'download'
+ option title 'Maximum download speed in kBits/s'
+ option section 'qos.interface'
+ option datatype 'integer'
+
+config variable
+ option name 'upload'
+ option title 'Maximum upload speed in kBits/s'
+ option section 'qos.interface'
+ option datatype 'integer'
+
+
+config section
+ option name 'class'
+ option title 'QoS traffic class definition'
+ option package 'qos'
+ option named true
+ option required true
+
+config variable
+ option name 'avgrate'
+ option title 'Average rate'
+ option section 'qos.class'
+ option datatype 'integer'
+
+config variable
+ option name 'maxsize'
+ option title 'Maximum size'
+ option section 'qos.class'
+ option datatype 'integer'
+
+config variable
+ option name 'packetdelay'
+ option title 'Packet delay'
+ option section 'qos.class'
+ option datatype 'integer'
+
+config variable
+ option name 'packetsize'
+ option title 'Packet size'
+ option section 'qos.class'
+ option datatype 'integer'
+
+config variable
+ option name 'priority'
+ option title 'QoS priority'
+ option section 'qos.class'
+ option datatype 'integer'
+
+
+config section
+ option name 'classgroup'
+ option title 'QoS classification group'
+ option package 'qos'
+ option named true
+
+config variable
+ option name 'classes'
+ option title 'Defined QoS classes in group'
+ option section 'qos.classgroup'
+
+config variable
+ option name 'default'
+ option title 'Default QoS class in group'
+ option section 'qos.classgroup'
+ option valueof 'qos.class'
+
+
+config section
+ option name 'default'
+ option title 'QoS default classification'
+ option package 'qos'
+ list depends 'target, pktsize'
+ list depends 'target, portrange'
+ list depends 'target, proto'
+
+config variable
+ option name 'pktsize'
+ option title 'Match by packet size'
+ option section 'qos.default'
+ option datatype 'integer'
+
+config variable
+ option name 'portrange'
+ option title 'Match by port range'
+ option section 'qos.default'
+
+config variable
+ option name 'proto'
+ option title 'Match by layer 3 protocol'
+ option section 'qos.default'
+
+config variable
+ option name 'target'
+ option title 'Option target'
+ option section 'qos.default'
+ option valueof 'qos.class'
+
+
+config section
+ option name 'classify'
+ option title 'QoS classification rule'
+ option package 'qos'
+ list depends 'target, ipp2p'
+ list depends 'target, layer7'
+ list depends 'target, ports'
+ list depends 'target, proto'
+ list depends 'target, tcpflags'
+
+config variable
+ option name 'ipp2p'
+ option title 'Match by ipp2p'
+ option section 'qos.classify'
+
+config variable
+ option name 'layer7'
+ option title 'Match by layer 7 protocol'
+ option section 'qos.classify'
+
+config variable
+ option name 'ports'
+ option title 'Match by ports'
+ option section 'qos.classify'
+
+config variable
+ option name 'proto'
+ option title 'Match by layer 3 protocol'
+ option section 'qos.classify'
+
+config variable
+ option name 'tcpflags'
+ option title 'Match by TCP flags'
+ option section 'qos.classify'
+
+config variable
+ option name 'target'
+ option title 'QoS target class'
+ option section 'qos.classify'
+ option valueof 'qos.class'
+
+
+config section
+ option name 'reclassify'
+ option title 'QoS reclassification rule'
+ option package 'qos'
+ list depends 'target, ipp2p'
+ list depends 'target, layer7'
+ list depends 'target, ports'
+ list depends 'target, proto'
+ list depends 'target, pktsize'
+ list depends 'target, tcpflags'
+
+config variable
+ option name 'mark'
+ option title 'Match by classification mark'
+ option section 'qos.reclassify'
+
+config variable
+ option name 'pktsize'
+ option title 'Match by packet size'
+ option section 'qos.reclassify'
+ option datatype 'integer'
+
+config variable
+ option name 'proto'
+ option title 'Match by layer 3 protocol'
+ option section 'qos.reclassify'
+
+config variable
+ option name 'tcpflags'
+ option title 'Match by TCP flags'
+ option section 'qos.reclassify'
+
+config variable
+ option name 'target'
+ option title 'QoS classification target'
+ option section 'qos.reclassify'
+ option valueof 'qos.class'