Those are L2 options that are not part of interfaces (L3), should not be set there and don't work. Setting MAC and MTU should be done at device layer (config device) and is supported for basic types already. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
196 lines
6 KiB
JavaScript
196 lines
6 KiB
JavaScript
'use strict';
|
|
'require form';
|
|
'require network';
|
|
'require validation';
|
|
|
|
function isCIDR(value) {
|
|
return Array.isArray(value) || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/(\d{1,2}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.test(value);
|
|
}
|
|
|
|
function calculateBroadcast(s, use_cfgvalue) {
|
|
var readfn = use_cfgvalue ? 'cfgvalue' : 'formvalue',
|
|
addropt = s.children.filter(function(o) { return o.option == 'ipaddr'})[0],
|
|
addrvals = addropt ? L.toArray(addropt[readfn](s.section)) : [],
|
|
maskopt = s.children.filter(function(o) { return o.option == 'netmask'})[0],
|
|
maskval = maskopt ? maskopt[readfn](s.section) : null,
|
|
firstsubnet = maskval ? addrvals[0] + '/' + maskval : addrvals.filter(function(a) { return a.indexOf('/') > 0 })[0];
|
|
|
|
if (firstsubnet == null)
|
|
return null;
|
|
|
|
var addr_mask = firstsubnet.split('/'),
|
|
addr = validation.parseIPv4(addr_mask[0]),
|
|
mask = addr_mask[1];
|
|
|
|
if (!isNaN(mask))
|
|
mask = validation.parseIPv4(network.prefixToMask(+mask));
|
|
else
|
|
mask = validation.parseIPv4(mask);
|
|
|
|
var bc = [
|
|
addr[0] | (~mask[0] >>> 0 & 255),
|
|
addr[1] | (~mask[1] >>> 0 & 255),
|
|
addr[2] | (~mask[2] >>> 0 & 255),
|
|
addr[3] | (~mask[3] >>> 0 & 255)
|
|
];
|
|
|
|
return bc.join('.');
|
|
}
|
|
|
|
function validateBroadcast(section_id, value) {
|
|
var opt = this.map.lookupOption('broadcast', section_id),
|
|
node = opt ? this.map.findElement('id', opt[0].cbid(section_id)) : null,
|
|
addr = node ? calculateBroadcast(this.section, false) : null;
|
|
|
|
if (node != null) {
|
|
if (addr != null)
|
|
node.querySelector('input').setAttribute('placeholder', addr);
|
|
else
|
|
node.querySelector('input').removeAttribute('placeholder');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return network.registerProtocol('static', {
|
|
CBIIPValue: form.Value.extend({
|
|
handleSwitch: function(section_id, option_index, ev) {
|
|
var maskopt = this.map.lookupOption('netmask', section_id);
|
|
|
|
if (maskopt == null || !this.isValid(section_id))
|
|
return;
|
|
|
|
var maskval = maskopt[0].formvalue(section_id),
|
|
addrval = this.formvalue(section_id),
|
|
prefix = maskval ? network.maskToPrefix(maskval) : 32;
|
|
|
|
if (prefix == null)
|
|
return;
|
|
|
|
this.datatype = 'or(cidr4,ipmask4)';
|
|
|
|
var parent = L.dom.parent(ev.target, '.cbi-value-field');
|
|
L.dom.content(parent, form.DynamicList.prototype.renderWidget.apply(this, [
|
|
section_id,
|
|
option_index,
|
|
addrval ? '%s/%d'.format(addrval, prefix) : ''
|
|
]));
|
|
|
|
var masknode = this.map.findElement('id', maskopt[0].cbid(section_id));
|
|
if (masknode) {
|
|
parent = L.dom.parent(masknode, '.cbi-value');
|
|
parent.parentNode.removeChild(parent);
|
|
}
|
|
},
|
|
|
|
renderWidget: function(section_id, option_index, cfgvalue) {
|
|
var maskopt = this.map.lookupOption('netmask', section_id),
|
|
widget = isCIDR(cfgvalue) ? 'DynamicList' : 'Value';
|
|
|
|
if (widget == 'DynamicList') {
|
|
this.datatype = 'or(cidr4,ipmask4)';
|
|
this.placeholder = _('Add IPv4 address…');
|
|
}
|
|
else {
|
|
this.datatype = 'ip4addr("nomask")';
|
|
}
|
|
|
|
var node = form[widget].prototype.renderWidget.apply(this, [ section_id, option_index, cfgvalue ]);
|
|
|
|
if (widget == 'Value')
|
|
L.dom.append(node, E('button', {
|
|
'class': 'cbi-button cbi-button-neutral',
|
|
'title': _('Switch to CIDR list notation'),
|
|
'aria-label': _('Switch to CIDR list notation'),
|
|
'click': L.bind(this.handleSwitch, this, section_id, option_index)
|
|
}, '…'));
|
|
|
|
return node;
|
|
},
|
|
|
|
validate: validateBroadcast
|
|
}),
|
|
|
|
CBINetmaskValue: form.Value.extend({
|
|
render: function(option_index, section_id, in_table) {
|
|
var addropt = this.section.children.filter(function(o) { return o.option == 'ipaddr' })[0],
|
|
addrval = addropt ? addropt.cfgvalue(section_id) : null;
|
|
|
|
if (addrval != null && isCIDR(addrval))
|
|
return E([]);
|
|
|
|
this.value('255.255.255.0');
|
|
this.value('255.255.0.0');
|
|
this.value('255.0.0.0');
|
|
|
|
return form.Value.prototype.render.apply(this, [ option_index, section_id, in_table ]);
|
|
},
|
|
|
|
validate: validateBroadcast
|
|
}),
|
|
|
|
CBIGatewayValue: form.Value.extend({
|
|
datatype: 'ip4addr("nomask")',
|
|
|
|
render: function(option_index, section_id, in_table) {
|
|
return network.getWANNetworks().then(L.bind(function(wans) {
|
|
if (wans.length == 1) {
|
|
var gwaddr = wans[0].getGatewayAddr();
|
|
this.placeholder = gwaddr ? '%s (%s)'.format(gwaddr, wans[0].getName()) : '';
|
|
}
|
|
|
|
return form.Value.prototype.render.apply(this, [ option_index, section_id, in_table ]);
|
|
}, this));
|
|
},
|
|
|
|
validate: function(section_id, value) {
|
|
var addropt = this.section.children.filter(function(o) { return o.option == 'ipaddr' })[0],
|
|
addrval = addropt ? L.toArray(addropt.cfgvalue(section_id)) : null;
|
|
|
|
if (addrval != null) {
|
|
for (var i = 0; i < addrval.length; i++) {
|
|
var addr = addrval[i].split('/')[0];
|
|
if (value == addr)
|
|
return _('The gateway address must not be a local IP address');
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}),
|
|
|
|
CBIBroadcastValue: form.Value.extend({
|
|
datatype: 'ip4addr("nomask")',
|
|
|
|
render: function(option_index, section_id, in_table) {
|
|
this.placeholder = calculateBroadcast(this.section, true);
|
|
return form.Value.prototype.render.apply(this, [ option_index, section_id, in_table ]);
|
|
}
|
|
}),
|
|
|
|
getI18n: function() {
|
|
return _('Static address');
|
|
},
|
|
|
|
renderFormOptions: function(s) {
|
|
var o;
|
|
|
|
s.taboption('general', this.CBIIPValue, 'ipaddr', _('IPv4 address'));
|
|
s.taboption('general', this.CBINetmaskValue, 'netmask', _('IPv4 netmask'));
|
|
s.taboption('general', this.CBIGatewayValue, 'gateway', _('IPv4 gateway'));
|
|
s.taboption('general', this.CBIBroadcastValue, 'broadcast', _('IPv4 broadcast'));
|
|
|
|
o = s.taboption('general', form.DynamicList, 'ip6addr', _('IPv6 address'));
|
|
o.datatype = 'ip6addr';
|
|
o.placeholder = _('Add IPv6 address…');
|
|
o.depends('ip6assign', '');
|
|
|
|
o = s.taboption('general', form.Value, 'ip6gw', _('IPv6 gateway'));
|
|
o.datatype = 'ip6addr("nomask")';
|
|
o.depends('ip6assign', '');
|
|
|
|
o = s.taboption('general', form.Value, 'ip6prefix', _('IPv6 routed prefix'), _('Public prefix routed to this device for distribution to clients.'));
|
|
o.datatype = 'ip6addr';
|
|
o.depends('ip6assign', '');
|
|
}
|
|
});
|