diff options
author | Phil Davis <phil.davis@inf.org> | 2015-04-10 17:59:46 +0545 |
---|---|---|
committer | Phil Davis <phil.davis@inf.org> | 2015-04-10 17:59:46 +0545 |
commit | 3490b8ddaea5944d9dd4b93ab1f28398170ee181 (patch) | |
tree | 83644afbaa36e44ea46db8a26433bfb9f0c65f58 /usr/local/www/interfaces.php | |
parent | 5fba3e9563b13150d666e639121f92483757f4dc (diff) | |
download | pfsense-3490b8ddaea5944d9dd4b93ab1f28398170ee181.zip pfsense-3490b8ddaea5944d9dd4b93ab1f28398170ee181.tar.gz |
Check for overlapping subnets when saving interface addresses
This checks if a static IP address entered for an interface has a subnet
that overlaps with any other configured subnet. e.g.:
LAN is IPv4 10.10.12.1/24
Then try to set OPT1 to 10.10.13.1/23 - it overlaps with LAN because
"/23" covers the "12" and "13" together.
In the input errors message, display to the user the other interfaces
and subnets that overlap/conflict. Then the user has some idea what it
is that conflicts and can easily go looking in the right place for the
problem.
Do the same thing for IPv6 address/CIDR.
Note: I have not enhanced any of the checks for conflicts with static
routes - there could be cases where a user has a static route like
10.0.0.0/8 pointing to some internal router that has the rest of
10.0.0.0/8 behind it, but the user has some direct-attached subnet
inside that - e.g. 10.1.2.0/24 - the routing table should cope with
this, delivering directly to 10.1.2.0/24 and routing for the rest of
10.0.0.0/8. So we cannot invalidate all overlaps with static routes.
I think this validation will not invalidate any exotic-but-valid use
cases. I can't think of when the interface subnets on 2 interfaces can
overlap and still be a valid/useful configuration.
This should stop people setting up dumb mixes of LAN/OPT1/OPT2... with
random addresses and CIDR prefix that overlap each other.
Diffstat (limited to 'usr/local/www/interfaces.php')
-rw-r--r-- | usr/local/www/interfaces.php | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/usr/local/www/interfaces.php b/usr/local/www/interfaces.php index 62cf658..89cff44 100644 --- a/usr/local/www/interfaces.php +++ b/usr/local/www/interfaces.php @@ -636,8 +636,14 @@ if ($_POST['apply']) { if (!is_ipaddrv4($_POST['ipaddr'])) $input_errors[] = gettext("A valid IPv4 address must be specified."); else { - if (is_ipaddr_configured($_POST['ipaddr'], $if, true)) - $input_errors[] = gettext("This IPv4 address is being used by another interface or VIP."); + $where_ipaddr_configured = where_is_ipaddr_configured($_POST['ipaddr'], $if, true, true, $_POST['subnet']); + if (count($where_ipaddr_configured)) { + $subnet_conflict_text = sprintf(gettext("IPv4 address %s is being used by or overlaps with:"), $_POST['ipaddr'] . "/" . $_POST['subnet']); + foreach ($where_ipaddr_configured as $subnet_conflict) { + $subnet_conflict_text .= " " . convert_friendly_interface_to_friendly_descr($subnet_conflict['if']) . " (" . $subnet_conflict['ip_or_subnet'] . ")"; + } + $input_errors[] = $subnet_conflict_text; + } /* Do not accept network or broadcast address, except if subnet is 31 or 32 */ if ($_POST['subnet'] < 31) { @@ -661,8 +667,14 @@ if ($_POST['apply']) { if (!is_ipaddrv6($_POST['ipaddrv6'])) $input_errors[] = gettext("A valid IPv6 address must be specified."); else { - if (is_ipaddr_configured($_POST['ipaddrv6'], $if, true)) - $input_errors[] = gettext("This IPv6 address is being used by another interface or VIP."); + $where_ipaddr_configured = where_is_ipaddr_configured($_POST['ipaddrv6'], $if, true, true, $_POST['subnetv6']); + if (count($where_ipaddr_configured)) { + $subnet_conflict_text = sprintf(gettext("IPv6 address %s is being used by or overlaps with:"), $_POST['ipaddrv6'] . "/" . $_POST['subnetv6']); + foreach ($where_ipaddr_configured as $subnet_conflict) { + $subnet_conflict_text .= " " . convert_friendly_interface_to_friendly_descr($subnet_conflict['if']) . " (" . $subnet_conflict['ip_or_subnet'] . ")"; + } + $input_errors[] = $subnet_conflict_text; + } foreach ($staticroutes as $route_subnet) { list($network, $subnet) = explode("/", $route_subnet); |