Project

General

Profile

Actions

Bug #8693

closed

Filter rules error after deleting VIP

Added by Seth Mos over 6 years ago. Updated about 6 years ago.

Status:
Duplicate
Priority:
Normal
Assignee:
-
Category:
Rules / NAT
Target version:
-
Start date:
07/26/2018
Due date:
% Done:

0%

Estimated time:
1.00 h
Plus Target Version:
Release Notes:
Affected Version:
2.4.3_1
Affected Architecture:
All

Description

On 2.4.2 and 2.4.3p1 I ran into a rules.debug error, making it fail to load rules.

I deleted 2 Carp vips which resulted in the following rule errors.

There were error(s) loading the rules: /tmp/rules.debug:599: syntax error - The line in question reads [599]: pass out  route-to ( igb0 192.168.27.33 ) from  to !/ tracker 1000009063 keep state allow-opts label "let out anything from firewall host itself" 

This appears to be coming from filter.inc where it is parsing the vips. For the actual real interface we check all the required data.
if (is_ipaddrv4($gw) && is_ipaddrv4($ifcfg['ip']) && is_subnetv4("{$ifcfg['sa']}/{$ifcfg['sn']}")) {

However, we then add rules for the vips, and there is no validation on the vip address there.
 if (ip_in_subnet($vip['ip'], "{$ifcfg['sa']}/{$ifcfg['sn']}")) {
                                                $ipfrules .= "pass out {$log['pass']} route-to ( {$ifcfg['if']} {$gw} ) from {$vip['ip']} to !{$ifcfg['sa']}/{$ifcfg['sn']} tracker {$increment_tracker($tracker)} keep state allow-opts labe
l \"let out anything from firewall host itself\"\n";

Adding a print_r($ifcfg) show this
Array
(
    [if] => igb0
    [ifv6] => igb0
    [ip] => 192.168.27.35
    [ipv6] => 2001:db8:db8:ff00::35
    [sn] => 27
    [snv6] => 96
    [mtu] => 1500
    [mss] =>
    [descr] => BGPWAN
    [sa] => 192.168.27.32
    [sav6] => 2001:db8:db8:ff00::
    [nonat] =>
    [alias-address] =>
    [alias-subnet] =>
    [gateway] => BGPWAN
    [gatewayv6] => BGPWAN6
    [spoofcheck] => yes
    [bridge] =>
    [vips] => Array
        (
            [0] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.34
                    [sn] => 27
                )

            [1] => Array
                (
                    [mode] => carp
                )

            [2] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.44
                    [sn] => 27
                )

            [3] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.49
                    [sn] => 27
                )

            [4] => Array
                (
                    [mode] => carp
                )

            [5] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.51
                    [sn] => 27
                )

            [6] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.45
                    [sn] => 27
                )

            [7] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.52
                    [sn] => 27
                )

        )


The deleted entries appear to persist in $FilterIflist;

Testing this with the following code

global $config;
print_r(get_configured_vip_list());
print_r(link_interface_to_vips('opt1'));
include("/etc/inc/filter.inc");
print_r(filter_generate_optcfg_array());
print_r($FilterIflist);

I see that the configured vip list has no phantom entries (nor in the xml)
I see link interface to vips for that interface doing what it should
I see phantom entries originating from filter generate optcfg array

I suspected this error should be starting around line 1164 in filter.inc

        $vips = link_interface_to_vips($if);
        if (!empty($vips)) {
            foreach ($vips as $vipidx => $vip) {
                if (is_ipaddrv4($vip['subnet'])) {
                    if (!is_array($oic['vips'])) {
                        $oic['vips'] = array();
                    }
                    $oic['vips'][$vipidx]['mode'] = $vip['mode'];
                    $oic['vips'][$vipidx]['ip'] = $vip['subnet'];
                    if (empty($vip['subnet_bits'])) {
                        $oic['vips'][$vipidx]['sn'] = 32;
                    } else {
                        $oic['vips'][$vipidx]['sn'] = $vip['subnet_bits'];
                    }
                } else if (is_ipaddrv6($vip['subnet'])) {
                    if (!is_array($oic['vips6'])) {
                        $oic['vips6'] = array();
                    }
                    $oic['vips6'][$vipidx]['mode'] = $vip['mode'];
                    $oic['vips6'][$vipidx]['ip'] = $vip['subnet'];
                    if (empty($vip['subnet_bits'])) {
                        $oic['vips6'][$vipidx]['sn'] = 128;
                    } else {
                        $oic['vips6'][$vipidx]['sn'] = $vip['subnet_bits'];
                    }
                }
            }
        }

But testing that ruled it out. It only show the correct entries, no phantom entries.
global $config;
$if = 'opt1';

        $vips = link_interface_to_vips($if);
        if (!empty($vips)) {
            foreach ($vips as $vipidx => $vip) {
                if (is_ipaddrv4($vip['subnet'])) {
                    if (!is_array($oic['vips'])) {
                        $oic['vips'] = array();
                    }
                    $oic['vips'][$vipidx]['mode'] = $vip['mode'];
                    $oic['vips'][$vipidx]['ip'] = $vip['subnet'];
                    if (empty($vip['subnet_bits'])) {
                        $oic['vips'][$vipidx]['sn'] = 32;
                    } else {
                        $oic['vips'][$vipidx]['sn'] = $vip['subnet_bits'];
                    }
                } else if (is_ipaddrv6($vip['subnet'])) {
                    if (!is_array($oic['vips6'])) {
                        $oic['vips6'] = array();
                    }
                    $oic['vips6'][$vipidx]['mode'] = $vip['mode'];
                    $oic['vips6'][$vipidx]['ip'] = $vip['subnet'];
                    if (empty($vip['subnet_bits'])) {
                        $oic['vips6'][$vipidx]['sn'] = 128;
                    } else {
                        $oic['vips6'][$vipidx]['sn'] = $vip['subnet_bits'];
                    }
                }
            }
        }

print_r($oic);
Array
(
    [vips] => Array
        (
            [0] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.34
                    [sn] => 27
                )

            [2] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.44
                    [sn] => 27
                )

            [3] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.49
                    [sn] => 27
                )

            [5] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.51
                    [sn] => 27
                )

            [6] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.45
                    [sn] => 27
                )

            [7] => Array
                (
                    [mode] => carp
                    [ip] => 192.168.27.52
                    [sn] => 27
                )

        )
)

However, key 1 and key 4 are the deleted vips. So something is not iterating the array, but taking the highest key value instead of using count();
Actions

Also available in: Atom PDF