Firewall, IPv6/stf, generate _stf interface and link to parent while parsing rules, for https://github.com/opnsense/core/issues/2546

The general idea here is to make it explicit that _stf generated another interface for IPv6 traffic, so we can use this knowledge when parsing rules easily.
This commit is contained in:
Ad Schellevis 2018-07-16 10:27:06 +02:00
parent ac35e91dee
commit 445ffd1f79
3 changed files with 19 additions and 25 deletions

View File

@ -38,7 +38,7 @@ class NptRule extends Rule
'binat_1' => array(
'disabled' => 'parseIsComment',
'binat' => 'parseStaticText,binat ',
'interface' => 'parseInterface6',
'interface' => 'parseInterface',
'from' => 'parsePlain,from , to any',
'to' => 'parsePlain, -> ',
'descr' => 'parseComment'
@ -46,7 +46,7 @@ class NptRule extends Rule
'binat_2' => array(
'disabled' => 'parseIsComment',
'binat' => 'parseStaticText,binat ',
'interface' => 'parseInterface6',
'interface' => 'parseInterface',
'to' => 'parsePlain,from , to any',
'from' => 'parsePlain, -> ',
'descr' => 'parseComment'

View File

@ -78,6 +78,18 @@ class Plugin
$this->interfaceMapping = array();
$this->interfaceMapping['loopback'] = array('if' => 'lo0', 'descr' => 'loopback');
$this->interfaceMapping = array_merge($this->interfaceMapping, $mapping);
// generate virtual IPv6 interfaces
foreach ($this->interfaceMapping as $key => &$intf) {
if (!empty($intf['ipaddrv6']) && ($intf['ipaddrv6'] == '6rd' || $intf['ipaddrv6'] == '6to4')) {
// create new interface
$this->interfaceMapping[$key . '_stf'] = array();
$this->interfaceMapping[$key . '_stf']['if'] = $key . '_stf'; // TODO: rename to technical name
$this->interfaceMapping[$key . '_stf']['ifconfig']['ipv6'] = $intf['ifconfig']['ipv6'];
$this->interfaceMapping[$key . '_stf']['gatewayv6'] = $intf['gatewayv6'];
// link original interface
$intf['IPv6_override'] = $key . '_stf';
}
}
}
/**

View File

@ -168,7 +168,11 @@ abstract class Rule
foreach ($ipprotos as $ipproto) {
$rule = $this->rule;
$rule['interface'] = $interface;
if ($rule['ipprotocol'] == 'inet6' && !empty($this->interfaceMapping[$interface]['IPv6_override'])) {
$rule['interface'] = $this->interfaceMapping[$interface]['IPv6_override'];
} else {
$rule['interface'] = $interface;
}
$rule['ipprotocol'] = $ipproto;
$this->convertAddress($rule);
// disable rule when interface not found
@ -285,28 +289,6 @@ abstract class Rule
}
}
/**
* parse IPv6 interface (name to interface with special considerations)
* @param string|array $value field value
* @param string $prefix prefix interface tag
* @return string
*/
protected function parseInterface6($value, $prefix = "on ", $suffix = "")
{
if (empty($value)) {
return '';
} elseif (empty($this->interfaceMapping[$value]['if'])) {
return "{$prefix}##{$value}##{$suffix} ";
} elseif (!empty($this->interfaceMapping[$value]['ipaddrv6']) &&
($this->interfaceMapping[$value]['ipaddrv6'] == '6rd' ||
$this->interfaceMapping[$value]['ipaddrv6'] == '6to4')) {
return "{$prefix}". "{$value}_stf" ."{$suffix} ";
} else {
/* XXX 'dhcp6usev4iface' is not handled correctly as well: uses PPPoE interface! */
return "{$prefix}". $this->interfaceMapping[$value]['if']."{$suffix} ";
}
}
/**
* Validate if the provided rule looks like an ipv4 address.
* This method isn't bulletproof (if only aliases are used and we don't know the protocol, this might fail to