luci-base: datatypes: add cidr, ipnet validator type

- Rewrite ipmask to use these subtypes
- Add ip{4,6}prefix validators to cbi.js

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
This commit is contained in:
Yousong Zhou 2017-08-21 21:33:02 +08:00
parent 5e022ade5c
commit 3809bd6ffb
2 changed files with 96 additions and 54 deletions

View file

@ -118,6 +118,70 @@ var cbi_validators = {
return false; return false;
}, },
'ip4prefix': function()
{
return !isNaN(this) && this >= 0 && this <= 32;
},
'ip6prefix': function()
{
return !isNaN(this) && this >= 0 && this <= 128;
},
'cidr': function()
{
return cbi_validators.cidr4.apply(this) ||
cbi_validators.cidr6.apply(this);
},
'cidr4': function()
{
if (this.match(/^(\S+)\/(\S+)$/))
{
ip = RegExp.$1;
mask = RegExp.$2;
return cbi_validators.ip4addr.apply(ip) &&
cbi_validators.ip4prefix.apply(mask);
}
return false;
},
'cidr6': function()
{
if (this.match(/^(\S+)\/(\S+)$/))
{
ip = RegExp.$1;
mask = RegExp.$2;
return cbi_validators.ip6addr.apply(ip) &&
cbi_validators.ip6prefix.apply(mask);
}
return false;
},
'ipnet4': function()
{
if (this.match(/^(\S+)\/(\S+)$/))
{
ip = RegExp.$1;
net = RegExp.$2;
return cbi_validators.ip4addr.apply(ip) &&
cbi_validators.ip4addr.apply(net);
}
return false;
},
'ipnet6': function()
{
if (this.match(/^(\S+)\/(\S+)$/))
{
ip = RegExp.$1;
net = RegExp.$2;
return cbi_validators.ip6addr.apply(ip) &&
cbi_validators.ip6addr.apply(net);
}
return false;
},
'ipmask': function() 'ipmask': function()
{ {
return cbi_validators.ipmask4.apply(this) || return cbi_validators.ipmask4.apply(this) ||
@ -126,40 +190,16 @@ var cbi_validators = {
'ipmask4': function() 'ipmask4': function()
{ {
var ip = this, mask = 32; return cbi_validators.cidr4.apply(this) ||
cbi_validators.ipnet4.apply(this) ||
if (ip.match(/^(\S+)\/(\S+)$/)) cbi_validators.ip4addr.apply(this);
{
ip = RegExp.$1;
mask = RegExp.$2;
}
if (!isNaN(mask) && (mask < 0 || mask > 32))
return false;
if (isNaN(mask) && !cbi_validators.ip4addr.apply(mask))
return false;
return cbi_validators.ip4addr.apply(ip);
}, },
'ipmask6': function() 'ipmask6': function()
{ {
var ip = this, mask = 128; return cbi_validators.cidr6.apply(this) ||
cbi_validators.ipnet6.apply(this) ||
if (ip.match(/^(\S+)\/(\S+)$/)) cbi_validators.ip6addr.apply(this);
{
ip = RegExp.$1;
mask = RegExp.$2;
}
if (!isNaN(mask) && (mask < 0 || mask > 128))
return false;
if (isNaN(mask) && !cbi_validators.ip6addr.apply(mask))
return false;
return cbi_validators.ip6addr.apply(ip);
}, },
'port': function() 'port': function()

View file

@ -132,38 +132,40 @@ function ip6prefix(val)
return ( val and val >= 0 and val <= 128 ) return ( val and val >= 0 and val <= 128 )
end end
function cidr4(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
return ip4addr(ip) and ip4prefix(mask)
end
function cidr6(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
return ip6addr(ip) and ip6prefix(mask)
end
function ipnet4(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
return ip4addr(ip) and ip4addr(mask)
end
function ipnet6(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
return ip6addr(ip) and ip6addr(mask)
end
function ipmask(val) function ipmask(val)
return ipmask4(val) or ipmask6(val) return ipmask4(val) or ipmask6(val)
end end
function ipmask4(val) function ipmask4(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$") return cidr4(val) or ipnet4(val) or ip4addr(val)
local bits = tonumber(mask)
if bits and (bits < 0 or bits > 32) then
return false
end
if not bits and mask and not ip4addr(mask) then
return false
end
return ip4addr(ip or val)
end end
function ipmask6(val) function ipmask6(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$") return cidr6(val) or ipnet6(val) or ip6addr(val)
local bits = tonumber(mask)
if bits and (bits < 0 or bits > 128) then
return false
end
if not bits and mask and not ip6addr(mask) then
return false
end
return ip6addr(ip or val)
end end
function ip6hostid(val) function ip6hostid(val)