1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-24 04:07:55 +01:00
group and addresses table object names" is in effect. This happened if
the same user-defined group was used in multiple rules or different
rule element of the same rule. In this case generated PF table would
have several copies of the same addresses.

not work right when the same object is used in several different
groups. If the same object was a member of multiple groups and these
groups were used in the same or different rules of the same PF
firewall, compiler used all groups in all rules.
This commit is contained in:
Vadim Kurland 2011-11-21 17:55:53 -08:00
parent c7bfbfe2d2
commit e681556c0f
12 changed files with 932 additions and 54 deletions

View File

@ -1,5 +1,32 @@
2011-11-21 Vadim Kurland <vadim@netcitadel.com>
* TableFactory.cpp (TableFactory::createTablesForRE): see #2671
Duplicate objects appear in PF table when option "preserve group
and addresses table object names" is in effect. This happened if
the same user-defined group was used in multiple rules or
different rule element of the same rule. In this case generated PF
table would have several copies of the same addresses.
* TableFactory.cpp (TableFactory::createTablesForRE): see #2672 PF
option "preserve group and addresses table object names" does not
work right when the same object is used in several different
groups. If the same object was a member of multiple groups and
these groups were used in the same or different rules of the same
PF firewall, compiler used all groups in all rules. This could
create match for objects that were not intended to be part of some
rules. This problem has been fixed. Note that configuration with
a combination of ipv4 and ipv6 objects as members of the same
user-defined group when group is used in mixed ipv4+ipv6 rule
set still does not work right. In this case compiler generates
table that exactly reflects configuration user created in the
GUI (i.e. includes both ipv4 and ipv6 addresses) and then uses
this table in both "inet" and "inet6" rules.
* PolicyCompiler_pf.cpp (createTables): With this fix, when option
"preserve group and addresses table object names" is in effect,
compiler for PF will create named tables for the user-defined
object group even if it contains just one object.
* PolicyCompiler_PrintRule.cpp (_printDirectionAndInterface): SF
bug #3439613. physdev module does not allow --physdev-out for
non-bridged traffic anymore. We should add --physdev-is-bridged to

View File

@ -950,7 +950,7 @@ bool Compiler::RegisterGroupsAndTablesInRE::processNext()
FWObject *obj = FWReference::getObject(*i);
if (ObjectGroup::cast(obj)!=NULL && obj->size() > 0)
{
compiler->registerGroupObject(ObjectGroup::cast(obj));
compiler->registerGroupObject(re, ObjectGroup::cast(obj));
}
}
}
@ -959,12 +959,13 @@ bool Compiler::RegisterGroupsAndTablesInRE::processNext()
return true;
}
void Compiler::registerGroupObject(ObjectGroup *grp)
void Compiler::registerGroupObject(RuleElement *re, ObjectGroup *grp)
{
assert(group_registry!=NULL);
list<FWObject*> objects;
expandGroup(grp, objects);
group_registry->registerGroup(grp, objects);
group_registry->registerGroupInRE(re, grp);
}
bool Compiler::equalObj::operator()(FWObject *o)

View File

@ -243,7 +243,8 @@ public:
std::stringstream output;
void registerGroupObject(libfwbuilder::ObjectGroup *grp);
void registerGroupObject(libfwbuilder::RuleElement *re,
libfwbuilder::ObjectGroup *grp);
void registerIPv6Rule() { countIPv6Rules++; }
bool haveIPv6Rules() { return countIPv6Rules > 0; }

View File

@ -25,6 +25,9 @@
#include "fwbuilder/FWObjectDatabase.h"
#include "fwbuilder/FWReference.h"
#include "fwbuilder/Rule.h"
#include "fwbuilder/RuleElement.h"
using namespace libfwbuilder;
using namespace std;
@ -33,6 +36,17 @@ using namespace std;
GroupRegistry::GroupRegistry()
{}
/*
* Generate stable key to be used as a key in rule_element_groups map.
* This key should not change when rule processors create copies of
* rules, this means we can't use rule and rule element ID.
*/
string GroupRegistry::getREKey(libfwbuilder::RuleElement *re)
{
Rule *rule = Rule::cast(re->getParent());
return rule->getLabel() + "_" + re->getTypeName();
}
void GroupRegistry::registerGroup(FWObject *grp, const list<FWObject*> &objects)
{
for (list<FWObject*>::const_iterator it=objects.begin();
@ -45,6 +59,21 @@ void GroupRegistry::registerGroup(FWObject *grp, const list<FWObject*> &objects)
}
}
/*
* register a group as a member of given rule element.
*/
void GroupRegistry::registerGroupInRE(RuleElement *re, FWObject *grp)
{
string key_str = getREKey(re);
rule_element_groups[key_str].insert(grp->getName());
}
set<string> GroupRegistry::getGroupsForRE(RuleElement *re)
{
string key_str = getREKey(re);
return rule_element_groups[key_str];
}
set<string> GroupRegistry::getGroupsForObject(FWObject *obj)
{
return group_registry[getGroupRegistryKey(obj)];

View File

@ -31,16 +31,31 @@
#include <map>
namespace libfwbuilder
{
class RuleElement;
};
class GroupRegistry
{
// key: object Id, value: a set of names of groups it belongs to
std::map<std::string, std::set<std::string> > group_registry;
// key: rule element id, value: a set of names of groups that belonged to it
std::map<std::string, std::set<std::string> > rule_element_groups;
std::string getREKey(libfwbuilder::RuleElement *re);
public:
GroupRegistry();
void registerGroup(libfwbuilder::FWObject *grp,
const std::list<libfwbuilder::FWObject*> &objects);
void registerGroupInRE(libfwbuilder::RuleElement *re, libfwbuilder::FWObject *grp);
std::set<std::string> getGroupsForRE(libfwbuilder::RuleElement *re);
std::set<std::string> getGroupsForObject(libfwbuilder::FWObject *obj);
std::string getGroupRegistryKey(libfwbuilder::FWObject *obj);

View File

@ -780,16 +780,14 @@ bool PolicyCompiler_pf::splitIfInterfaceInRE::processNext()
bool PolicyCompiler_pf::createTables::processNext()
{
PolicyCompiler_pf *pf_comp=dynamic_cast<PolicyCompiler_pf*>(compiler);
PolicyRule *rule=getNext(); if (rule==NULL) return false;
PolicyCompiler_pf *pf_comp = dynamic_cast<PolicyCompiler_pf*>(compiler);
PolicyRule *rule = getNext(); if (rule==NULL) return false;
RuleElementSrc *src=rule->getSrc();
RuleElementDst *dst=rule->getDst();
// RuleElementSrv *srv=rule->getSrv();
RuleElementSrc *src = rule->getSrc();
RuleElementDst *dst = rule->getDst();
if (src->size()!=1) pf_comp->tables->createTablesForRE(src,rule);
if (dst->size()!=1) pf_comp->tables->createTablesForRE(dst,rule);
// if (srv->size()!=1) createTablesForRE(srv,rule);
if (!src->isAny()) pf_comp->tables->createTablesForRE(src, rule);
if (!dst->isAny()) pf_comp->tables->createTablesForRE(dst, rule);
tmp_queue.push_back(rule);
return true;

View File

@ -47,6 +47,13 @@ using namespace libfwbuilder;
using namespace fwcompiler;
using namespace std;
void print_string(const string &s)
{
cerr << s << " ";
}
TableFactory::TableFactory(BaseCompiler *comp, Firewall *fwall,
Library *persistent_objects,
GroupRegistry *_group_registry)
@ -108,6 +115,7 @@ void TableFactory::registerTable(const string& tblname, const string& tblid,
tblnames[tblname] = tblid;
tables[tblid] = tbl;
table_deduplicator[tblname] = set<int>();
}
FWObject* TableFactory::createTableObject(const string &tblname,
@ -129,6 +137,21 @@ FWObject* TableFactory::createTableObject(const string &tblname,
return tblgrp;
}
/*
* Add object to the table group, but perform a check to make sure we
* do not add it again if it is already there. See #2671
*/
void TableFactory::addObjectToTable(FWObject *tblgrp, FWObject *obj)
{
int obj_id = obj->getId();
string tblname = tblgrp->getName();
if (table_deduplicator[tblname].count(obj_id) == 0)
{
tblgrp->addRef(obj);
table_deduplicator[tblname].insert(obj_id);
}
}
void TableFactory::createTablesForRE(RuleElement *re, Rule *rule)
{
// sanity checks
@ -136,9 +159,10 @@ void TableFactory::createTablesForRE(RuleElement *re, Rule *rule)
assert(dbroot==rule->getRoot());
/*
* Before we create a new table, we scan tables and try to find
* the one that already exists and contains the same objects.
* get the list of groups that used to be in this rule element
* when we started
*/
set<string> original_groups = group_registry->getGroupsForRE(re);
string tblID = generateTblID(re);
@ -146,6 +170,13 @@ void TableFactory::createTablesForRE(RuleElement *re, Rule *rule)
list<FWObject*> objects_in_groups;
list<FWObject*> objects;
set<FWObject*> table_objects;
/*
* separate objects that should be in a user-defined groups
* (tables) and those that dont
*/
for (FWObject::iterator i=re->begin(); i!=re->end(); i++)
{
FWObject *o = FWReference::getObject(*i);
@ -157,56 +188,106 @@ void TableFactory::createTablesForRE(RuleElement *re, Rule *rule)
re->clearChildren();
set<FWObject*> table_objects;
for (FWObject::iterator i=objects_in_groups.begin(); i!=objects_in_groups.end(); i++)
if (original_groups.size() > 0)
{
set<string> groups = group_registry->getGroupsForObject(*i);
for (set<string>::iterator it=groups.begin(); it!=groups.end(); ++it)
for (FWObject::iterator i=objects_in_groups.begin(); i!=objects_in_groups.end(); i++)
{
string tblname = *it;
if (tables.count(tblname)!=0)
FWObject *obj = *i;
set<string> groups = group_registry->getGroupsForObject(obj);
set<string> groups_in_this_re;
/*
* an object can be a member of multiple groups, but not all
* of these groups belong to the given RE.
*
* set_intersection requires both sets to be sorted, but STL class set is
* always sorted automatically.
*/
std::set_intersection(
original_groups.begin(), original_groups.end(),
groups.begin(), groups.end(),
std::insert_iterator< set<string> >(
groups_in_this_re, groups_in_this_re.begin() ));
for (set<string>::iterator it=groups_in_this_re.begin(); it!=groups_in_this_re.end(); ++it)
{
tblgrp = tables[tblname];
} else
{
tblgrp = createTableObject(tblname, tblname);
string tblname = *it;
if (tables.count(tblname)!=0)
{
tblgrp = tables[tblname];
} else
{
tblgrp = createTableObject(tblname, tblname);
}
/*
* Add object to the table but first check if this object
* already belongs to the group. If RE had two groups and
* this object used to belong to both, set
* groups_in_this_re will have two items.
*
* See #2671
*/
addObjectToTable(tblgrp, obj);
table_objects.insert(tblgrp);
}
tblgrp->addRef(*i);
table_objects.insert(tblgrp);
}
} else
{
// if RE never had any groups to begin with
for (FWObject::iterator i=re->begin(); i!=re->end(); i++)
{
FWObject *obj = FWReference::getObject(*i);
objects.push_back(obj);
}
}
/*
* Deal with objects that weren't part of any user-defined group
*/
if (objects.size() > 0)
{
if (tables.count(tblID)!=0)
if (objects.size() == 1)
{
tblgrp = tables[tblID];
re->addRef(objects.front());
} else
{
// TODO: can two rules yeild the same name for the group using this method?
std::ostringstream tblname;
if (!ruleSetName.empty()) tblname << ruleSetName << ":";
int rp = rule->getPosition();
tblname << "tbl.r";
tblname << ((rp>0)?rp:0);
//if (rule_iface) tblname << rule_iface->getName()+".";
// tblname=tblname+rule->getId();
if (RuleElementSrc::isA(re)) tblname << ".s";
if (RuleElementDst::isA(re)) tblname << ".d";
while (tblnames.count(tblname.str())>0) tblname << "x";
tblgrp = createTableObject(tblname.str(), tblID);
for (FWObject::iterator i=objects.begin(); i!=objects.end(); i++)
// objects.size() > 1
if (tables.count(tblID)!=0)
{
tblgrp->addRef(*i);
}
}
tblgrp = tables[tblID];
} else
{
// TODO: can two rules yeild the same name for the group using this method?
std::ostringstream tblname;
if (!ruleSetName.empty()) tblname << ruleSetName << ":";
int rp = rule->getPosition();
tblname << "tbl.r";
tblname << ((rp>0)?rp:0);
table_objects.insert(tblgrp);
//if (rule_iface) tblname << rule_iface->getName()+".";
// tblname=tblname+rule->getId();
if (RuleElementSrc::isA(re)) tblname << ".s";
if (RuleElementDst::isA(re)) tblname << ".d";
while (tblnames.count(tblname.str())>0) tblname << "x";
tblgrp = createTableObject(tblname.str(), tblID);
for (FWObject::iterator i=objects.begin(); i!=objects.end(); i++)
{
addObjectToTable(tblgrp, *i);
// tblgrp->addRef(*i);
}
}
table_objects.insert(tblgrp);
}
}
for (set<FWObject*>::iterator i=table_objects.begin(); i!=table_objects.end(); i++)

View File

@ -36,6 +36,8 @@
#include <list>
#include <map>
#include <set>
namespace libfwbuilder
{
@ -57,7 +59,8 @@ namespace fwcompiler
std::map<std::string,libfwbuilder::FWObject*> tables;
std::map<std::string,std::string> tblnames;
std::string ruleSetName;
std::map<std::string, std::set<int> > table_deduplicator;
std::string generateTblID(libfwbuilder::RuleElement *re);
libfwbuilder::FWObject* createTableObject(const std::string &tblname,
const std::string &tblid);
@ -77,7 +80,8 @@ public:
libfwbuilder::FWObject *tbl) throw(libfwbuilder::FWException);
void createTablesForRE(libfwbuilder::RuleElement *re,
libfwbuilder::Rule *rule);
void addObjectToTable(libfwbuilder::FWObject *tblgrp,
libfwbuilder::FWObject *obj);
std::string PrintTables();
};

View File

@ -397,6 +397,13 @@
</p>
</li>
<li>
<p>
Several fixes in the algorithms used to process rules when
option "preserve group and addresses table object names" is in
effect
</p>
</li>
</ul>

View File

@ -0,0 +1,93 @@
set timeout udp.single 5
#
# Scrub rules
#
match all scrub (reassemble tcp no-df )
match out all scrub (random-id min-ttl 1 max-mss 1460)
# Tables: (7)
table <fw93_group_1> { 22.22.22.0/28 , 192.168.1.10 }
table <fw93_group_1-copy> { 22.22.22.0/28 , 192.168.1.10 }
table <fw93_group_2> { 192.168.171.2 }
table <fw93_group_3> { 192.168.1.1 , 192.168.1.2 , 192.168.1.3/30 , 192.168.1.200 , 192.168.1.201 , 192.168.2.0/24 , 192.168.2.128/25 }
table <fw93_group_4_ipv6> { 3ffe:1200:2001:1:8000::1 , fe80::/64 }
table <fw93_group_5_mix> { 192.168.1.0/24 , 192.168.2.0/24 , ::ffff:0:0:0/96 , fc00::/7 , fe80::/64 }
table <fw93_group_6> { 192.168.1.0/24 , 192.168.1.10 }
#
# Rule 0 (NAT)
match out on em0 from 10.1.1.0/24 to any nat-to (em0)
# Policy compiler errors and warnings:
# firewall93:Policy:0: warning: Changing rule direction due to self reference
#
# Rule backup ssh access rule
# backup ssh access rule
pass in quick inet proto tcp from 10.3.14.30 to self port 22 label "RULE -1 -- ACCEPT"
#
# Rule 0 (global)
# firewall93:Policy:0: warning: Changing rule direction due to self reference
pass in quick inet proto tcp from 10.3.14.0/24 to self port 22 label "RULE 0 -- ACCEPT"
#
# Rule 1 (global)
pass quick inet from <fw93_group_1> to any label "RULE 1 -- ACCEPT"
#
# Rule 2 (global)
# see #2671
pass quick inet proto tcp from <fw93_group_1> to any port 3128 label "RULE 2 -- ACCEPT"
pass quick inet proto udp from <fw93_group_1> to any port 53 label "RULE 2 -- ACCEPT"
#
# Rule 3 (global)
# using the same group second time,
# objects should not get duplicated
# in the generated table. See #2671
pass quick inet from any to <fw93_group_1> label "RULE 3 -- ACCEPT"
#
# Rule 4 (global)
# just one object in the group
pass quick inet from <fw93_group_2> to any label "RULE 4 -- ACCEPT"
#
# Rule 5 (global)
# object a-192.168.1.10 is a member
# of at least two groups used in this rule
pass quick inet from { <fw93_group_1> , <fw93_group_2> , <fw93_group_6> } to any label "RULE 5 -- ACCEPT"
#
# Rule 6 (global)
# the same rule, same objects as rule 3,
# but different group with the same objects
pass quick inet from <fw93_group_1-copy> to any label "RULE 6 -- ACCEPT"
#
# Rule 7 (global)
block in quick inet from <fw93_group_6> to any no state label "RULE 7 -- DROP"
#
# Rule 8 (global)
# group uses address table object
pass quick inet from any to <fw93_group_3> label "RULE 8 -- ACCEPT"
#
# Rule 11 (global)
block in quick inet from <fw93_group_5_mix> to any no state label "RULE 11 -- DROP"
#
# Rule fallback rule
# fallback rule
block quick inet from any to any no state label "RULE 10000 -- DROP"
#
# Rule 9 (global)
block in quick inet6 from <fw93_group_4_ipv6> to any no state label "RULE 9 -- DROP"
#
# Rule 10 (global)
# the same group second time,
# check for duplicates. See #2671
block in quick inet6 from any to <fw93_group_4_ipv6> no state label "RULE 10 -- DROP"
#
# Rule 11 (global)
block in quick inet6 from <fw93_group_5_mix> to any no state label "RULE 11 -- DROP"
#
# Rule fallback rule
# fallback rule
block quick inet6 from any to any no state label "RULE 10000 -- DROP"

181
test/pf/firewall93.fw.orig Executable file
View File

@ -0,0 +1,181 @@
#!/bin/sh
#
# This is automatically generated file. DO NOT MODIFY !
#
# Firewall Builder fwb_pf v5.0.1.3589
#
# Generated Mon Nov 21 17:30:19 2011 PST by vadim
#
# files: * firewall93.fw /etc/fw/pf.fw
# files: firewall93.conf /etc/fw/path\ with\ space/pf.conf
#
# Compiled for pf 4.7
#
# testing option “preserve group and addresses table object names”
# firewall93:Policy:0: warning: Changing rule direction due to self reference
FWDIR=`dirname $0`
IFCONFIG="/sbin/ifconfig"
PFCTL="/sbin/pfctl"
SYSCTL="/sbin/sysctl"
LOGGER="/usr/bin/logger"
log() {
echo "$1"
command -v "$LOGGER" >/dev/null 2>&1 && $LOGGER -p info "$1"
}
diff_intf() {
func=$1
list1=$2
list2=$3
cmd=$4
for intf in $list1
do
echo $list2 | grep -q $intf || {
# $vlan is absent in list 2
$func $intf $cmd
}
done
}
missing_address() {
address=$1
cmd=$2
oldIFS=$IFS
IFS="@"
set $address
addr=$1
interface=$2
IFS=$oldIFS
if echo "$addr" | grep -q ':'
then
inet="inet6"
addr=$(echo "$addr" | sed 's!/! prefixlen !')
else
inet="inet"
addr=$(echo "$addr" | sed 's!/! netmask !')
fi
parameter=""
test "$cmd" = "add" && {
echo "# Adding ip address: $interface $addr"
parameter="alias"
}
test "$cmd" = "del" && {
echo "# Removing ip address: $interface $addr"
parameter="delete"
}
$FWBDEBUG $IFCONFIG $interface $inet $addr $parameter || exit 1
$FWBDEBUG $IFCONFIG $interface up
}
list_addresses_by_scope() {
interface=$1
scope=$2
ignore_list=$3
scope_regex="1"
if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi
$IFCONFIG $interface | sed "s/%$interface//" | \
awk -v IGNORED="$ignore_list" \
"BEGIN {
split(IGNORED,ignored_arr);
for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;}
}
(/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \
while read addr; do
echo "${addr}@$interface"
done | sort
}
update_addresses_of_interface() {
ignore_list=$2
set $1
interface=$1
shift
FWB_ADDRS=$(
for addr in $*; do
echo "${addr}@$interface"
done | sort
)
CURRENT_ADDRS_ALL_SCOPES=""
CURRENT_ADDRS_GLOBAL_SCOPE=""
$IFCONFIG $interface >/dev/null 2>&1 && {
CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list")
CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list")
} || {
echo "# Interface $interface does not exist"
# Stop the script if we are not in test mode
test -z "$FWBDEBUG" && exit 1
}
echo "$interface" | grep -q carp && {
diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del
diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add
} || {
diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add
diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del
}
}
verify_interfaces() {
:
}
set_kernel_vars() {
:
$SYSCTL -w net.inet.ip.forwarding=1
}
prolog_commands() {
:
}
epilog_commands() {
:
}
run_epilog_and_exit() {
epilog_commands
exit $1
}
configure_interfaces() {
:
update_addresses_of_interface "em0 10.3.14.81/0xffffff00" ""
update_addresses_of_interface "em1 10.1.1.81/0xffffff00" ""
}
log "Activating firewall script generated Mon Nov 21 17:30:19 2011 by vadim"
set_kernel_vars
configure_interfaces
prolog_commands
$PFCTL -f /etc/fw/path\ with\ space/pf.conf || exit 1
epilog_commands

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE FWObjectDatabase SYSTEM "fwbuilder.dtd">
<FWObjectDatabase xmlns="http://www.fwbuilder.org/1.0/" version="22" lastModified="1309899399" id="root">
<FWObjectDatabase xmlns="http://www.fwbuilder.org/1.0/" version="22" lastModified="1321911969" id="root">
<Library id="syslib000" color="#d4f8ff" name="Standard" comment="Standard objects" ro="True">
<AnyNetwork id="sysid0" name="Any" comment="Any Network" ro="False" address="0.0.0.0" netmask="0.0.0.0"/>
<AnyIPService id="sysid1" protocol_num="0" name="Any" comment="Any IP Service" ro="False"/>
@ -92,6 +92,13 @@
<NetworkIPv6 id="id2383X75851" name="link-local ipv6" comment="RFC4291 Link-local unicast net" ro="False" address="fe80::" netmask="10"/>
<NetworkIPv6 id="id2685X75851" name="multicast ipv6" comment="RFC4291 ipv6 multicast addresses" ro="False" address="ff00::" netmask="8"/>
<NetworkIPv6 id="id2986X75851" name="experimental ipv6" comment="RFC2928, RFC4773 &#10;&#10;&quot;The block of Sub-TLA IDs assigned to the IANA&#10;(i.e., 2001:0000::/29 - 2001:01F8::/29) is for&#10;assignment for testing and experimental usage to&#10;support activities such as the 6bone, and&#10;for new approaches like exchanges.&quot; [RFC2928]&#10;&#10;" ro="False" address="2001::" netmask="23"/>
<Network id="id3289X12564" name="TEST-NET-2" comment="RFC 5735&#10;RFC 5737&#10;" ro="False" address="198.51.100.0" netmask="255.255.255.0"/>
<Network id="id3300X12564" name="TEST-NET-3" comment="RFC 5735&#10;RFC 5737" ro="False" address="203.0.113.0" netmask="255.255.255.0"/>
<Network id="id3311X12564" name="Benchmark tests network" comment="RFC 5735" ro="False" address="198.18.0.0" netmask="255.254.0.0"/>
<NetworkIPv6 id="id3326X12564" name="mapped-ipv4" comment="" ro="False" address="::ffff:0.0.0.0" netmask="96"/>
<NetworkIPv6 id="id3341X12564" name="translated-ipv4" comment="" ro="False" address="::ffff:0:0:0" netmask="96"/>
<NetworkIPv6 id="id3350X12564" name="Teredo" comment="" ro="False" address="2001::" netmask="32"/>
<NetworkIPv6 id="id3359X12564" name="unique-local" comment="" ro="False" address="fc00::" netmask="7"/>
</ObjectGroup>
<ObjectGroup id="stdid15" name="Address Ranges" comment="" ro="False">
<AddressRange id="id3F6D115C" name="broadcast" comment="" ro="False" start_address="255.255.255.255" end_address="255.255.255.255"/>
@ -1685,7 +1692,7 @@
<IPv4 id="id33008X21143" name="addr-10.1.1.1" comment="" ro="False" address="10.1.1.1" netmask="0.0.0.0"/>
<IPv4 id="id518129X21143" name="addr-10.1.1.2" comment="" ro="False" address="10.1.1.2" netmask="0.0.0.0"/>
<IPv4 id="id134690X19225" name="addr-222.222.222.40" comment="" ro="False" address="222.222.222.40" netmask="0.0.0.0"/>
<IPv4 id="id135048X19225" name="a-192.168.1.10" comment="" ro="False" address="192.168.1.10" netmask="0.0.0.0"/>
<IPv4 id="id135048X19225" name="a-192.168.1.10-copy" comment="" ro="False" address="192.168.1.10" netmask="0.0.0.0"/>
<IPv4 id="id41167X11081" name="a-192.168.1.11" comment="" ro="False" address="255.255.255.255" netmask="0.0.0.0"/>
</ObjectGroup>
<ObjectGroup id="stdid04_1" name="Groups" comment="" ro="False">
@ -1750,6 +1757,36 @@
<ObjectRef ref="id134567X19225"/>
<ObjectRef ref="id134570X19225"/>
</ObjectGroup>
<ObjectGroup id="id59240X22951" name="fw93_group_1" comment="" ro="False">
<ObjectRef ref="id80198X23273"/>
<ObjectRef ref="id43F7DCF631316"/>
</ObjectGroup>
<ObjectGroup id="id59256X22951" name="fw93_group_2" comment="" ro="False">
<ObjectRef ref="id79492X23273"/>
</ObjectGroup>
<ObjectGroup id="id59274X22951" name="fw93_group_3" comment="" ro="False">
<ObjectRef ref="id4389EE9018346"/>
<ObjectRef ref="id4733FFE419714"/>
</ObjectGroup>
<ObjectGroup id="id59769X22951" name="fw93_group_4_ipv6" comment="" ro="False">
<ObjectRef ref="id79830X23273"/>
<ObjectRef ref="id48416A7116880"/>
</ObjectGroup>
<ObjectGroup id="id59939X22951" name="fw93_group_5_mix" comment="" ro="False">
<ObjectRef ref="id79830X23273"/>
<ObjectRef ref="id3CEBFDFC"/>
<ObjectRef ref="id3359X12564"/>
<ObjectRef ref="id3341X12564"/>
<ObjectRef ref="id4733FFE419714"/>
</ObjectGroup>
<ObjectGroup id="id60030X22951" name="fw93_group_6" comment="this group uses the same object as fw93_group_1" ro="False">
<ObjectRef ref="id3CEBFDFC"/>
<ObjectRef ref="id80198X23273"/>
</ObjectGroup>
<ObjectGroup id="id60070X22951" name="fw93_group_1-copy" comment="" ro="False">
<ObjectRef ref="id80198X23273"/>
<ObjectRef ref="id43F7DCF631316"/>
</ObjectGroup>
</ObjectGroup>
<ObjectGroup id="stdid02_1" name="Hosts" comment="" ro="False">
<Host id="id3B64FFAC" name="broadcast" comment="broadcast on internal subnet" ro="False">
@ -25180,7 +25217,7 @@
<Option name="sshArgs"></Option>
</FirewallOptions>
</Firewall>
<Firewall id="id134556X19225" host_OS="freebsd" inactive="False" lastCompiled="1272404353" lastInstalled="1142003872" lastModified="1297994826" platform="pf" version="" name="firewall2-6" comment="tests for nat rules with inbound and outbound interfaces" ro="False">
<Firewall id="id134556X19225" host_OS="freebsd" inactive="False" lastCompiled="1272404353" lastInstalled="1142003872" lastModified="1321921721" platform="pf" version="" name="firewall2-6" comment="tests for nat rules with inbound and outbound interfaces" ro="False">
<NAT id="id134616X19225" name="NAT" comment="" ro="False" ipv4_rule_set="False" ipv6_rule_set="False" top_rule_set="True">
<NATRule id="id134618X19225" disabled="False" group="" position="0" action="Translate" comment="NETMAP and no -o itf">
<OSrc neg="False">
@ -28031,6 +28068,410 @@
<Option name="verify_interfaces">true</Option>
</FirewallOptions>
</Firewall>
<Firewall id="id58699X22951" host_OS="openbsd" inactive="False" lastCompiled="1321910391" lastInstalled="1271995582" lastModified="1321921833" platform="pf" version="4.7" name="firewall93" comment="testing option “preserve group and addresses table object names”" ro="False">
<NAT id="id58860X22951" name="NAT" comment="" ro="False" ipv4_rule_set="False" ipv6_rule_set="False" top_rule_set="True">
<NATRule id="id58862X22951" disabled="False" group="" position="0" action="Translate" comment="">
<OSrc neg="False">
<ObjectRef ref="id22061X58767"/>
</OSrc>
<ODst neg="False">
<ObjectRef ref="sysid0"/>
</ODst>
<OSrv neg="False">
<ServiceRef ref="sysid1"/>
</OSrv>
<TSrc neg="False">
<ObjectRef ref="id58707X22951"/>
</TSrc>
<TDst neg="False">
<ObjectRef ref="sysid0"/>
</TDst>
<TSrv neg="False">
<ServiceRef ref="sysid1"/>
</TSrv>
<ItfInb neg="False">
<ObjectRef ref="sysid0"/>
</ItfInb>
<ItfOutb neg="False">
<ObjectRef ref="sysid0"/>
</ItfOutb>
<NATRuleOptions/>
</NATRule>
<RuleSetOptions/>
</NAT>
<Policy id="id58717X22951" name="Policy" comment="" ro="False" ipv4_rule_set="True" ipv6_rule_set="True" top_rule_set="True">
<PolicyRule id="id58719X22951" disabled="False" group="" log="False" position="0" action="Accept" direction="Both" comment="">
<Src neg="False">
<ObjectRef ref="id79551X23273"/>
</Src>
<Dst neg="False">
<ObjectRef ref="id58699X22951"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="tcp-SSH"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="pf_classify_str"></Option>
<Option name="stateless">False</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id58747X22951" disabled="False" group="" log="False" position="1" action="Accept" direction="Both" comment="">
<Src neg="False">
<ObjectRef ref="id59240X22951"/>
</Src>
<Dst neg="False">
<ObjectRef ref="sysid0"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="pf_classify_str"></Option>
<Option name="stateless">False</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id60209X22951" disabled="False" group="" log="False" position="2" action="Accept" direction="Both" comment="see #2671">
<Src neg="False">
<ObjectRef ref="id59240X22951"/>
</Src>
<Dst neg="False">
<ObjectRef ref="sysid0"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="id3B5009F7"/>
<ServiceRef ref="id80157X23273"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="pf_classify_str"></Option>
<Option name="stateless">False</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id59336X22951" disabled="False" group="" log="False" position="3" action="Accept" direction="Both" comment="using the same group second time,&#10;objects should not get duplicated&#10;in the generated table. See #2671">
<Src neg="False">
<ObjectRef ref="sysid0"/>
</Src>
<Dst neg="False">
<ObjectRef ref="id59240X22951"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="pf_classify_str"></Option>
<Option name="stateless">False</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id59392X22951" disabled="False" group="" log="False" position="4" action="Accept" direction="Both" comment="just one object in the group">
<Src neg="False">
<ObjectRef ref="id59256X22951"/>
</Src>
<Dst neg="False">
<ObjectRef ref="sysid0"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="pf_classify_str"></Option>
<Option name="stateless">False</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id59491X22951" disabled="False" group="" log="False" position="5" action="Accept" direction="Both" comment="object a-192.168.1.10 is a member&#10;of at least two groups used in this rule">
<Src neg="False">
<ObjectRef ref="id59240X22951"/>
<ObjectRef ref="id59256X22951"/>
<ObjectRef ref="id60030X22951"/>
</Src>
<Dst neg="False">
<ObjectRef ref="sysid0"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="pf_classify_str"></Option>
<Option name="stateless">False</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id60089X22951" disabled="False" group="" log="False" position="6" action="Accept" direction="Both" comment="the same rule, same objects as rule 3,&#10;but different group with the same objects">
<Src neg="False">
<ObjectRef ref="id60070X22951"/>
</Src>
<Dst neg="False">
<ObjectRef ref="sysid0"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="stateless">False</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id60043X22951" disabled="False" group="" log="False" position="7" action="Deny" direction="Inbound" comment="">
<Src neg="False">
<ObjectRef ref="id60030X22951"/>
</Src>
<Dst neg="False">
<ObjectRef ref="sysid0"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="stateless">True</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id59548X22951" disabled="False" group="" log="False" position="8" action="Accept" direction="Both" comment="group uses address table object">
<Src neg="False">
<ObjectRef ref="sysid0"/>
</Src>
<Dst neg="False">
<ObjectRef ref="id59274X22951"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="stateless">False</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id59757X22951" disabled="False" group="" log="False" position="9" action="Deny" direction="Inbound" comment="">
<Src neg="False">
<ObjectRef ref="id59769X22951"/>
</Src>
<Dst neg="False">
<ObjectRef ref="sysid0"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="color">#7694C0</Option>
<Option name="stateless">True</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id59823X22951" disabled="False" group="" log="False" position="10" action="Deny" direction="Inbound" comment="the same group second time,&#10;check for duplicates. See #2671">
<Src neg="False">
<ObjectRef ref="sysid0"/>
</Src>
<Dst neg="False">
<ObjectRef ref="id59769X22951"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="color">#7694C0</Option>
<Option name="stateless">True</Option>
</PolicyRuleOptions>
</PolicyRule>
<PolicyRule id="id59971X22951" disabled="False" group="" log="False" position="11" action="Deny" direction="Inbound" comment="">
<Src neg="False">
<ObjectRef ref="id59939X22951"/>
</Src>
<Dst neg="False">
<ObjectRef ref="sysid0"/>
</Dst>
<Srv neg="False">
<ServiceRef ref="sysid1"/>
</Srv>
<Itf neg="False">
<ObjectRef ref="sysid0"/>
</Itf>
<When neg="False">
<IntervalRef ref="sysid2"/>
</When>
<PolicyRuleOptions>
<Option name="color">#A37EC0</Option>
<Option name="stateless">True</Option>
</PolicyRuleOptions>
</PolicyRule>
<RuleSetOptions/>
</Policy>
<Routing id="id59121X22951" name="Routing" comment="" ro="False" ipv4_rule_set="False" ipv6_rule_set="False" top_rule_set="True">
<RuleSetOptions/>
</Routing>
<Interface id="id58707X22951" dedicated_failover="False" dyn="False" label="" mgmt="True" security_level="100" unnum="False" unprotected="False" name="em0" comment="" ro="False">
<IPv4 id="id58710X22951" name="firewall93:em0:ip" comment="" ro="False" address="10.3.14.81" netmask="255.255.255.0"/>
<InterfaceOptions/>
</Interface>
<Interface id="id58712X22951" dedicated_failover="False" dyn="False" label="" security_level="100" unnum="False" unprotected="False" name="em1" comment="" ro="False">
<IPv4 id="id58715X22951" name="firewall93:em1:ip" comment="" ro="False" address="10.1.1.81" netmask="255.255.255.0"/>
<InterfaceOptions/>
</Interface>
<Management address="0.0.0.0">
<SNMPManagement enabled="False" snmp_read_community="" snmp_write_community=""/>
<FWBDManagement enabled="False" identity="" port="-1"/>
<PolicyInstallScript arguments="" command="" enabled="False"/>
</Management>
<FirewallOptions>
<Option name="accept_new_tcp_with_no_syn">False</Option>
<Option name="activationCmd"></Option>
<Option name="admUser">root</Option>
<Option name="altAddress"></Option>
<Option name="check_shading">False</Option>
<Option name="cmdline">-xt</Option>
<Option name="compiler"></Option>
<Option name="conf1_file"></Option>
<Option name="conf_file_name_on_firewall">/etc/fw/path with space/pf.conf</Option>
<Option name="configure_bridge_interfaces">False</Option>
<Option name="configure_carp_interfaces">False</Option>
<Option name="configure_interfaces">True</Option>
<Option name="configure_pfsync_interfaces">False</Option>
<Option name="configure_vlan_interfaces">False</Option>
<Option name="debug">False</Option>
<Option name="epilog_script"></Option>
<Option name="fallback_log">False</Option>
<Option name="firewall_dir">/etc</Option>
<Option name="generate_rc_conf_file">False</Option>
<Option name="generate_shell_script">True</Option>
<Option name="ignore_empty_groups">False</Option>
<Option name="in_out_code">true</Option>
<Option name="ipv4_6_order">ipv4_first</Option>
<Option name="log_prefix">RULE %N -- %A</Option>
<Option name="loopback_interface">lo0</Option>
<Option name="manage_virtual_addr">True</Option>
<Option name="mgmt_addr">10.3.14.30</Option>
<Option name="mgmt_ssh">True</Option>
<Option name="openbsd_ip_forward">1</Option>
<Option name="output_file"></Option>
<Option name="pass_all_out">false</Option>
<Option name="pf_adaptive_end">0</Option>
<Option name="pf_adaptive_start">0</Option>
<Option name="pf_block_policy"></Option>
<Option name="pf_do_limit_frags">False</Option>
<Option name="pf_do_limit_src_nodes">False</Option>
<Option name="pf_do_limit_states">False</Option>
<Option name="pf_do_limit_table_entries">False</Option>
<Option name="pf_do_limit_tables">False</Option>
<Option name="pf_do_scrub">True</Option>
<Option name="pf_do_timeout_frag">False</Option>
<Option name="pf_do_timeout_interval">False</Option>
<Option name="pf_flush_states">False</Option>
<Option name="pf_icmp_error">0</Option>
<Option name="pf_icmp_first">0</Option>
<Option name="pf_limit_frags">5000</Option>
<Option name="pf_limit_src_nodes">0</Option>
<Option name="pf_limit_states">10000</Option>
<Option name="pf_limit_table_entries">0</Option>
<Option name="pf_limit_tables">0</Option>
<Option name="pf_modulate_state">False</Option>
<Option name="pf_optimization"></Option>
<Option name="pf_other_first">0</Option>
<Option name="pf_other_multiple">0</Option>
<Option name="pf_other_single">0</Option>
<Option name="pf_scrub_fragm_crop">False</Option>
<Option name="pf_scrub_fragm_drop_ovl">False</Option>
<Option name="pf_scrub_maxmss">1460</Option>
<Option name="pf_scrub_minttl">1</Option>
<Option name="pf_scrub_no_df">True</Option>
<Option name="pf_scrub_random_id">True</Option>
<Option name="pf_scrub_reassemble">False</Option>
<Option name="pf_scrub_reassemble_tcp">True</Option>
<Option name="pf_scrub_use_maxmss">True</Option>
<Option name="pf_scrub_use_minttl">True</Option>
<Option name="pf_set_adaptive">False</Option>
<Option name="pf_set_debug"></Option>
<Option name="pf_set_icmp_error">False</Option>
<Option name="pf_set_icmp_first">False</Option>
<Option name="pf_set_other_first">False</Option>
<Option name="pf_set_other_multiple">False</Option>
<Option name="pf_set_other_single">False</Option>
<Option name="pf_set_tcp_closed">False</Option>
<Option name="pf_set_tcp_closing">False</Option>
<Option name="pf_set_tcp_established">False</Option>
<Option name="pf_set_tcp_finwait">False</Option>
<Option name="pf_set_tcp_first">False</Option>
<Option name="pf_set_tcp_opening">False</Option>
<Option name="pf_set_udp_first">False</Option>
<Option name="pf_set_udp_multiple">False</Option>
<Option name="pf_set_udp_single">True</Option>
<Option name="pf_state_policy"></Option>
<Option name="pf_tcp_closed">0</Option>
<Option name="pf_tcp_closing">0</Option>
<Option name="pf_tcp_established">0</Option>
<Option name="pf_tcp_finwait">0</Option>
<Option name="pf_tcp_first">0</Option>
<Option name="pf_tcp_opening">0</Option>
<Option name="pf_timeout_frag">30</Option>
<Option name="pf_timeout_interval">10</Option>
<Option name="pf_udp_first">0</Option>
<Option name="pf_udp_multiple">0</Option>
<Option name="pf_udp_single">5</Option>
<Option name="preserve_group_names">True</Option>
<Option name="prolog_place">fw_file</Option>
<Option name="prolog_script"></Option>
<Option name="scpArgs"></Option>
<Option name="script_name_on_firewall">/etc/fw/pf.fw</Option>
<Option name="sshArgs"></Option>
</FirewallOptions>
</Firewall>
</ObjectGroup>
<IntervalGroup id="stdid11_1" name="Time" comment="" ro="False"/>
</Library>