Improved selection of DHCP ranges for macvlan networks

This commit is contained in:
bergware
2017-10-22 23:10:29 +02:00
parent d3b08826ea
commit d57b711ae8
@@ -7,7 +7,7 @@ Tag="docker"
/* Copyright 2005-2017, Lime Technology
* Copyright 2014-2017, Guilherme Jardim, Eric Schultz, Jon Panozzo.
*
* Additional updates by Bergware International (July 2017)
* Additional updates by Bergware International (October 2017)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
@@ -56,18 +56,42 @@ foreach ($custom as $network) {
if ($route = exec("ip -4 route show dev $network|grep -Po '^[12]\S+'")) $include[$network] = $route;
if ($route6 = exec("ip -6 route show dev $network|grep -Po '^[1-9]\S+'")) $include6[$network] = $route6;
}
function base_min($route) {
list($net,$mask) = explode('/',$route);
$mask = 32-$mask;
return explode('.',long2ip((ip2long($net)>>$mask)<<$mask));
}
function base_max($route) {
list($net,$mask) = explode('/',$route);
$mask = 32-$mask;
return explode('.',long2ip(((ip2long($net)>>$mask)<<$mask)+pow(2,$mask)-1));
}
function base_net($route) {
return substr(explode('/',$route)[0],0,-2);
}
?>
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.filetree.css">
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.switchbutton.css">
<style>
.errortext{color:#EF3D47;display:none;}
.fileTree{width:305px;max-height:150px;overflow:scroll;position:absolute;z-index:100;display:none;}
.basic{display: block;}
.advanced{display:none;white-space: nowrap;}
.errortext{color:#EF3D47;display:none}
.fileTree{width:305px;max-height:150px;overflow:scroll;position:absolute;z-index:100;display:none}
.basic{display:block}
.advanced{display:none;white-space:nowrap}
select.mask{min-width:0;margin:0 10px 0 4px}
select.net{min-width:0;margin:0 4px 0 0}
select option.hide{display:none}
span.net{margin-right:8px}
span.net6{margin-right:8px}
<?if (strstr('white,azure',$display['theme'])):?>
span.disabled{color:#B0B0B0}
<?else:?>
span.disabled{color:#404040}
<?endif;?>
input.net6{width:146px;margin:0 4px 0 0}
</style>
<span class="status"><input type="checkbox" class="advancedview"></span>
<span class="status" style="margin-top:<?=strstr('gray,azure',$display['theme'])?0:-10?>px;"><input type="checkbox" class="advancedview"></span>
<form markdown="1" id="settingsForm" name="settingsForm" method="POST" action="/update.php" target="progressFrame">
<form markdown="1" id="settingsForm" name="settingsForm" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareDocker(this)">
<input type="hidden" name="#file" value="<?=$docker_cfgfile?>">
<input type="hidden" name="#command" value="/plugins/dynamix/scripts/emhttpd_update">
Enable Docker:
@@ -197,7 +221,40 @@ Template Authoring Mode:
<?if ($DockerStopped):?>
DHCPv4 pool of custom network <?=$network?> (optional):
: <input type="text" name="<?=$docker_dhcp?>" value="<?=$dockercfg[$docker_dhcp]?>" class="narrow">Subnet: <span id="<?=$docker_dhcp?>"><?=$route?></span>
<?
$dhcp = $dockercfg[$docker_dhcp] ?? false;
$disabled = $dhcp ? '':'disabled';
$net = base_min($route);
$max = base_max($route);
$mask = explode('/',$route)[1];
$net_user = $dhcp ? base_min($dhcp) : $net;
$mask_user = $dhcp ? explode('/',$dhcp)[1] : $mask;
$size = pow(2,32-$mask_user);
switch (true) {
case ($mask < 16): $prefix = $net[0]; $box = 1; break;
case ($mask < 24): $prefix = $net[0].'.'.$net[1]; $box = 2; break;
case ($mask < 32): $prefix = $net[0].'.'.$net[1].'.'.$net[2]; $box = 3 ;break;
}
?>
: <input type="checkbox" id="<?=$docker_dhcp?>_edit" onchange="changeEdit(this.id)"<?=$dhcp?'checked':''?>>
<span id="<?=$docker_dhcp?>_net" class="net <?=$disabled?>"><?=$prefix?>.</span><?
for ($b=$box; $b<=3; $b++) {
switch ($b) {
case 1: $step = $size/65536%256; break;
case 2: $step = $size/256%256; break;
case 3: $step = $size%256; break;
}
if ($step===0) $step = 256;
echo "<select id=\"{$docker_dhcp}_{$b}\" class=\"net\" $disabled>";
for ($n=$net[$b]; $n<=$max[$b]; $n++) echo mk_option($net_user[$b],$n,$n,$n%$step==0?'':'class="hide"');
echo "</select>";
}
echo "/";
echo "<select id=\"{$docker_dhcp}_mask\" class=\"mask\" onchange=\"changeMask(this.id)\" $disabled>";
for ($m=$mask; $m<=30; $m++) echo mk_option($mask_user,$m,$m);
echo "</select><span id=\"{$docker_dhcp}_size\" style=\"".($dhcp?'':'display:none')."\">(".($size-2)." hosts)</span>";
echo "<input type=\"hidden\" name=\"$docker_dhcp\" value=\"\">";
?>
<?elseif ($dockercfg[$docker_dhcp]):?>
DHCPv4 pool of custom network <?=$network?>:
: <?=$dockercfg[$docker_dhcp]?>
@@ -211,7 +268,21 @@ DHCPv4 pool of custom network <?=$network?>:
<?if ($DockerStopped):?>
DHCPv6 pool of custom network <?=$network?> (optional):
: <input type="text" name="<?=$docker_dhcp6?>" value="<?=$dockercfg[$docker_dhcp6]?>" class="narrow">Subnet: <span id="<?=$docker_dhcp6?>"><?=$route?></span>
<?
$dhcp = $dockercfg[$docker_dhcp6] ?? false;
$disabled = $dhcp ? '':'disabled';
$net = base_net($route);
$mask = explode('/',$route)[1];
$net_user = $dhcp ? str_replace("$net:","",base_net($dhcp)) : '';
$mask_user = $dhcp ? explode('/',$dhcp)[1] : $mask;
?>
: <input type="checkbox" id="<?=$docker_dhcp6?>_edit" onchange="changeEdit6(this.id)"<?=$dhcp?'checked':''?>>
<span id="<?=$docker_dhcp6?>_net" class="net6 <?=$disabled?>"><?=$net?>:</span><?
echo "<input type=\"text\" id=\"{$docker_dhcp6}_text\" value=\"$net_user\" class=\"net6\" $disabled>/";
echo "<select id=\"{$docker_dhcp6}_mask\" class=\"mask\" $disabled>";
for ($m=$mask; $m<=120; $m+=8) echo mk_option($mask_user,$m,$m);
echo "</select><input type=\"hidden\" name=\"$docker_dhcp6\" value=\"\">";
?>
<?elseif ($dockercfg[$docker_dhcp6]):?>
DHCPv6 pool of custom network <?=$network?>:
: <?=$dockercfg[$docker_dhcp6]?>
@@ -268,6 +339,67 @@ btrfs scrub status:
<script src="/webGui/javascript/jquery.filetree.js"></script>
<script src="/webGui/javascript/jquery.switchbutton.js"></script>
<script>
function prepareDocker(form) {
$(form).find('input:hidden[name^="DOCKER_DHCP_"]').each(function(){
var id = '#'+$(this).attr('name')+'_';
if ($(id+'edit').prop('checked')) {
var net = $(id+'net').text();
for (var b=1; b<=3; b++) if ($(id+b).length>0) net += $(id+b).val()+'.';
net = net.replace(/\.$/,'/')+$(id+'mask').val();
$(this).val(net);
}
});
$(form).find('input:hidden[name^="DOCKER_DHCP6_"]').each(function(){
var id = '#'+$(this).attr('name')+'_';
if ($(id+'edit').prop('checked')) {
var net = $(id+'net').text()+$(id+'text').val();
if (net.substr(-2)!='::') net += '::';
$(this).val(net+'/'+$(id+'mask').val());
}
});
}
function changeEdit(id) {
var checked = $('#'+id).prop('checked');
id = '#'+id.substr(0,id.length-4);
for (var b=1; b<=3; b++) if ($(id+b).length>0) $(id+b).prop('disabled',!checked);
$(id+'mask').prop('disabled',!checked);
if (checked) {
$(id+'size').show();
$(id+'net').removeClass('disabled');
} else {
$(id+'size').hide();
$(id+'net').addClass('disabled','disabled');
}
}
function changeEdit6(id) {
var checked = $('#'+id).prop('checked');
id = '#'+id.substr(0,id.length-4);
$(id+'text').prop('disabled',!checked);
$(id+'mask').prop('disabled',!checked);
if (checked) {
$(id+'net').removeClass('disabled');
} else {
$(id+'net').addClass('disabled','disabled');
}
}
function changeMask(id) {
var mask = Math.pow(2,32-$('#'+id).val());
id = '#'+id.substr(0,id.length-4);
$(id+'size').html('('+(mask-2)+' hosts)');
for (var b=1; b<=3; b++) {
var cell = id+b;
switch (b) {
case 1: var step = mask/65536%256; break;
case 2: var step = mask/256%256; break;
case 3: var step = mask%256; break;
}
if (step==0) step = 256;
if ($(cell).length==0) continue;
var max = $(cell+' option').size();
for (var i=0; i < max; i++) if (i%step==0) $(cell+' option:eq('+i+')').removeClass('hide'); else $(cell+' option:eq('+i+')').addClass('hide');
if ($(cell+' option:selected').val()%step!=0) $(cell+' option:selected').removeAttr('selected');
}
}
function ip2int(ip) {
return ip.split('.').reduce(function(ipInt,octet){return (ipInt<<8)+parseInt(octet,10)},0)>>>0;
}
@@ -284,8 +416,8 @@ function checkDHCPv4() {
if (typeof(base[1])=='undefined') base[1] = 32;
var toppool = ip2int(pool[0]);
var topbase = ip2int(base[0]);
var endpool = toppool+2**(32-pool[1]);
var endbase = topbase+2**(32-base[1]);
var endpool = toppool+Math.pow(2,32-pool[1]);
var endbase = topbase+Math.pow(2,32-base[1]);
if (good && (toppool < topbase || endpool > endbase)) {good = false; swal('Invalid pool address','Pool address is out of range','error');}
}
});
@@ -331,7 +463,7 @@ $(function() {
var image = $("#DOCKER_IMAGE_FILE").val();
target = $("#IMAGE_ERROR");
$.getJSON( "/plugins/dynamix.docker.manager/include/UpdateConfig.php?is_dir=" + image).done(function( json ) {
$.getJSON( "/plugins/dynamix.docker.manager/include/UpdateConfig.php?is_dir=" + image).done(function(json) {
if (json.is_dir === true){
target.fadeIn().html('Error: must be a file; directory provided.');
isError = true;
@@ -401,7 +533,7 @@ $(function() {
$('.advancedview').change(function () {
$('.advanced').toggle('slow');
$('.basic').toggle('slow');
$.cookie('dockersettings_view_mode', $('.advancedview').is(':checked') ? 'advanced' : 'basic', { expires: 3650 });
$.cookie('dockersettings_view_mode', $('.advancedview').is(':checked') ? 'advanced':'basic', {expires:3650});
});
showStatus('pid','dockerd');