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;
},
'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()
{
return cbi_validators.ipmask4.apply(this) ||
@ -126,40 +190,16 @@ var cbi_validators = {
'ipmask4': function()
{
var ip = this, mask = 32;
if (ip.match(/^(\S+)\/(\S+)$/))
{
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);
return cbi_validators.cidr4.apply(this) ||
cbi_validators.ipnet4.apply(this) ||
cbi_validators.ip4addr.apply(this);
},
'ipmask6': function()
{
var ip = this, mask = 128;
if (ip.match(/^(\S+)\/(\S+)$/))
{
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);
return cbi_validators.cidr6.apply(this) ||
cbi_validators.ipnet6.apply(this) ||
cbi_validators.ip6addr.apply(this);
},
'port': function()

View file

@ -132,38 +132,40 @@ function ip6prefix(val)
return ( val and val >= 0 and val <= 128 )
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)
return ipmask4(val) or ipmask6(val)
end
function ipmask4(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
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)
return cidr4(val) or ipnet4(val) or ip4addr(val)
end
function ipmask6(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
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)
return cidr6(val) or ipnet6(val) or ip6addr(val)
end
function ip6hostid(val)