Project

General

Profile

Bug #8693

Filter rules error after deleting VIP

Added by Seth Mos almost 2 years ago. Updated almost 2 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
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();

History

#1 Updated by Seth Mos almost 2 years ago

It appears to be fixed in mainline. Inserting the extra address checks that are in current filter.inc on line 3657 and 3677 fix this issue.

Also, the missing keys 1 and 4 are actually the IPv6 vips on the interface. I still can't explain why the phantom mode variables are set though.

#2 Updated by Jim Pingle almost 2 years ago

  • Status changed from New to Duplicate
  • Priority changed from Very High to Normal
  • Target version deleted (2.4.4)

Hey Seth, long time no see!

We fixed this in #8518 -- if you look at the last commit referenced on that ticket ( c9159949e06cc91f6931bf2326672df7cad706f4 ) you'll see the mode was being set by a couple lines of code that didn't get removed on RELENG_2_4_3 so the problem didn't appear in master, only in 2.4.3-p1. The added safety belts will prevent similar issues from causing invalid rules, and we've fixed a couple other edge cases that could land in similar trouble.

#3 Updated by Brian Candler almost 2 years ago

FYI, I just got caught by this same problem, also on 2.4.3-p1. However in my case it was on my WAN interface where I had two IPv4 CARPs and one IPv6 CARP.

In this situation I got the same error message as reported by the OP; adding some debugging to filter.inc showed:

# $vips => array (
  0 =>
    'mode' => 'carp',
    'ip' => 'x.x.x.237',
    'sn' => '28',
  1 =>
    'mode' => 'carp',
    'ip' => 'x.x.x.234',
    'sn' => '28',
  2 =>
    'mode' => 'carp',

After removing the WAN CARP interface it was OK. So I made the change in commit c9159949, added back the IPv6 CARP, and now it generates the rules without this error.

Also available in: Atom PDF