From 0790bb85093dce32fb5af4b497bd50f963878f25 Mon Sep 17 00:00:00 2001 From: Vadim Kurland Date: Mon, 11 Jul 2011 18:43:29 -0700 Subject: [PATCH] see #2513 "Group and Address Table name persistence in generated config". Compiler for PF can now preserve names of object groups, dynamic groups, compile-time AddressTable and compile-time DNSName objects in the generated pf.conf file. This is optional and is controlled by a checkbox in the firewall settings dialog. --- doc/ChangeLog | 9 ++ src/libfwbuilder/src/fwcompiler/Compiler.cpp | 65 ++++++++- src/libfwbuilder/src/fwcompiler/Compiler.h | 23 ++++ .../src/fwcompiler/GroupRegistry.cpp | 63 +++++++++ .../src/fwcompiler/GroupRegistry.h | 50 +++++++ src/libfwbuilder/src/fwcompiler/NATCompiler.h | 17 +++ .../src/fwcompiler/PolicyCompiler.h | 16 +++ .../src/fwcompiler/fwcompiler.pro | 6 +- src/libgui/pfAdvancedDialog.cpp | 2 + src/libgui/pfadvanceddialog_q.ui | 44 ++++--- src/pflib/CompilerDriver_pf_run.cpp | 11 +- src/pflib/NATCompiler_pf.cpp | 8 ++ src/pflib/NATCompiler_pf.h | 1 - src/pflib/NATCompiler_pf_writers.cpp | 32 ++--- src/pflib/PolicyCompiler_pf.cpp | 8 ++ src/pflib/PolicyCompiler_pf.h | 8 +- src/pflib/PolicyCompiler_pf_writers.cpp | 49 +++---- src/pflib/TableFactory.cpp | 124 +++++++++++++----- src/pflib/TableFactory.h | 20 ++- test/pf/pf_cluster_4_rc.conf.local | 4 +- 20 files changed, 435 insertions(+), 125 deletions(-) create mode 100644 src/libfwbuilder/src/fwcompiler/GroupRegistry.cpp create mode 100644 src/libfwbuilder/src/fwcompiler/GroupRegistry.h diff --git a/doc/ChangeLog b/doc/ChangeLog index 5e6792496..503ed351e 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,12 @@ +2011-07-11 Vadim Kurland + + * TableFactory.cpp (createTablesForRE): see #2513 "Group and + Address Table name persistence in generated config". Compiler for + PF can now preserve names of object groups, dynamic groups, + compile-time AddressTable and compile-time DNSName objects in + the generated pf.conf file. This is optional and is controlled + by a checkbox in the firewall settings dialog. + 2011-07-09 vadim * pf.g (rule_extended): see #2551 Importer should parse PF rules diff --git a/src/libfwbuilder/src/fwcompiler/Compiler.cpp b/src/libfwbuilder/src/fwcompiler/Compiler.cpp index b4b856330..649322c41 100644 --- a/src/libfwbuilder/src/fwcompiler/Compiler.cpp +++ b/src/libfwbuilder/src/fwcompiler/Compiler.cpp @@ -136,6 +136,7 @@ void Compiler::_init(FWObjectDatabase *_db, Firewall *_fw) { initialized = false; _cntr_ = 1; + group_registry = NULL; temp_ruleset = NULL; @@ -326,6 +327,21 @@ void Compiler::_expand_group_recursive(FWObject *o, list &ol) } } +/* + * Common interface to the operation of expanding of a group + * recursively. This just calls internal function + * _expand_group_recursive() + */ +void Compiler::expandGroup(FWObject *grp, list &ol) +{ + for (FWObject::iterator i1=grp->begin(); i1!=grp->end(); ++i1) + { + FWObject *o = FWReference::getObject(*i1); + assert(o); + _expand_group_recursive(o, ol); + } +} + /** * object 's' here is really src or dst or srv. Its children objects * should all be references @@ -333,12 +349,7 @@ void Compiler::_expand_group_recursive(FWObject *o, list &ol) void Compiler::expandGroupsInRuleElement(RuleElement *s) { list cl; - for (FWObject::iterator i1=s->begin(); i1!=s->end(); ++i1) - { - FWObject *o = FWReference::getObject(*i1); - assert(o); - _expand_group_recursive(o, cl); - } + expandGroup(s, cl); s->clearChildren(); //s->setAnyElement(); @@ -610,7 +621,14 @@ void Compiler::_expandAddressRanges(Rule *rule, FWObject *re) h->setAddress(*(i->getAddressPtr())); persistent_objects->add(h, false); cl.push_back(h); - } + + // see GroupRegistry::registerGroupObject() + if (group_registry != NULL) + { + group_registry->setGroupRegistryKey( + h, group_registry->getGroupRegistryKey(aro)); + } + } } } else { @@ -912,6 +930,37 @@ bool Compiler::ReplaceFirewallObjectWithSelfInRE::processNext() return true; } +bool Compiler::RegisterGroupsAndTablesInRE::processNext() +{ + Rule *rule = prev_processor->getNextRule(); + if (rule==NULL) return false; + + if (compiler->group_registry != NULL) + { + RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type)); + + for (FWObject::iterator i=re->begin(); i!=re->end(); i++) + { + FWObject *obj = FWReference::getObject(*i); + if (ObjectGroup::cast(obj)!=NULL && obj->size() > 0) + { + compiler->registerGroupObject(ObjectGroup::cast(obj)); + } + } + } + + tmp_queue.push_back(rule); + return true; +} + +void Compiler::registerGroupObject(ObjectGroup *grp) +{ + assert(group_registry!=NULL); + list objects; + expandGroup(grp, objects); + group_registry->registerGroup(grp, objects); +} + bool Compiler::equalObj::operator()(FWObject *o) { return o->getId()==obj->getId(); @@ -1811,3 +1860,5 @@ bool Compiler::DropRulesByAddressFamilyAndServiceType::processNext() return true; } + + diff --git a/src/libfwbuilder/src/fwcompiler/Compiler.h b/src/libfwbuilder/src/fwcompiler/Compiler.h index b9e233d47..0bceceb44 100644 --- a/src/libfwbuilder/src/fwcompiler/Compiler.h +++ b/src/libfwbuilder/src/fwcompiler/Compiler.h @@ -33,6 +33,7 @@ #include "fwcompiler/BaseCompiler.h" #include "fwcompiler/RuleProcessor.h" #include "fwcompiler/exceptions.h" +#include "fwcompiler/GroupRegistry.h" #include #include @@ -229,6 +230,10 @@ public: libfwbuilder::Library *persistent_objects; libfwbuilder::Firewall *fw; + // group registry is optional, the object shuld be created outside + // of the compiler and set using function setGroupRegistry(). + GroupRegistry *group_registry; + std::string ruleSetName;; libfwbuilder::RuleSet *source_ruleset; @@ -238,6 +243,8 @@ public: std::stringstream output; + void registerGroupObject(libfwbuilder::ObjectGroup *grp); + void registerIPv6Rule() { countIPv6Rules++; } bool haveIPv6Rules() { return countIPv6Rules > 0; } @@ -858,6 +865,17 @@ public: virtual bool processNext(); }; + class RegisterGroupsAndTablesInRE : public BasicRuleProcessor + { + std::string re_type; + public: + RegisterGroupsAndTablesInRE(const std::string &n, + const std::string _type) : + BasicRuleProcessor(n) { re_type = _type; } + virtual bool processNext(); + }; + friend class Compiler::RegisterGroupsAndTablesInRE; + /** * prints rule in some universal format (close to that visible * to user in the GUI). Used for debugging purposes @@ -1014,6 +1032,11 @@ public: std::string getCompiledScript(); int getCompiledScriptLength(); + void setGroupRegistry(GroupRegistry *gr) { group_registry = gr; } + + void expandGroup(libfwbuilder::FWObject *grp, + std::list &ol); + void expandGroupsInRuleElement(libfwbuilder::RuleElement *s); /** diff --git a/src/libfwbuilder/src/fwcompiler/GroupRegistry.cpp b/src/libfwbuilder/src/fwcompiler/GroupRegistry.cpp new file mode 100644 index 000000000..7fefe349e --- /dev/null +++ b/src/libfwbuilder/src/fwcompiler/GroupRegistry.cpp @@ -0,0 +1,63 @@ +/* + + Firewall Builder + + Copyright (C) 2011 NetCitadel, LLC + + Author: Vadim Kurland vadim@fwbuilder.org + + This program is free software which we release under the GNU General Public + License. You may redistribute and/or modify this program under the terms + of that license as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + To get a copy of the GNU General Public License, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "GroupRegistry.h" + +#include "fwbuilder/FWObjectDatabase.h" +#include "fwbuilder/FWReference.h" + +using namespace libfwbuilder; +using namespace std; + + +GroupRegistry::GroupRegistry() +{} + +void GroupRegistry::registerGroup(FWObject *grp, const list &objects) +{ + for (list::const_iterator it=objects.begin(); + it!=objects.end(); ++it) + { + FWObject *o = FWReference::getObject(*it); + string str_id = FWObjectDatabase::getStringId(o->getId()); + group_registry[str_id].insert(grp->getName()); + setGroupRegistryKey(o, str_id); + } +} + +set GroupRegistry::getGroupsForObject(FWObject *obj) +{ + return group_registry[getGroupRegistryKey(obj)]; +} + +string GroupRegistry::getGroupRegistryKey(FWObject *obj) +{ + return obj->getStr(".group_registry_key"); +} + +void GroupRegistry::setGroupRegistryKey(FWObject *obj, const std::string &key) +{ + return obj->setStr(".group_registry_key", key); +} + + diff --git a/src/libfwbuilder/src/fwcompiler/GroupRegistry.h b/src/libfwbuilder/src/fwcompiler/GroupRegistry.h new file mode 100644 index 000000000..a8fd1e7c8 --- /dev/null +++ b/src/libfwbuilder/src/fwcompiler/GroupRegistry.h @@ -0,0 +1,50 @@ +/* + + Firewall Builder + + Copyright (C) 2011 NetCitadel, LLC + + Author: Vadim Kurland vadim@fwbuilder.org + + This program is free software which we release under the GNU General Public + License. You may redistribute and/or modify this program under the terms + of that license as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + To get a copy of the GNU General Public License, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef __GROUP_REGISTRY_HH__ +#define __GROUP_REGISTRY_HH__ + +#include "fwbuilder/FWObject.h" + +#include +#include +#include + + +class GroupRegistry +{ + // key: object Id, value: a set of names of groups it belongs to + std::map > group_registry; + +public: + GroupRegistry(); + + void registerGroup(libfwbuilder::FWObject *grp, + const std::list &objects); + std::set getGroupsForObject(libfwbuilder::FWObject *obj); + + std::string getGroupRegistryKey(libfwbuilder::FWObject *obj); + void setGroupRegistryKey(libfwbuilder::FWObject *obj, const std::string &key); +}; + +#endif diff --git a/src/libfwbuilder/src/fwcompiler/NATCompiler.h b/src/libfwbuilder/src/fwcompiler/NATCompiler.h index e97f17b16..575cdee3a 100644 --- a/src/libfwbuilder/src/fwcompiler/NATCompiler.h +++ b/src/libfwbuilder/src/fwcompiler/NATCompiler.h @@ -537,6 +537,23 @@ namespace fwcompiler { n, libfwbuilder::RuleElementTDst::TYPENAME) {} }; + class RegisterGroupsAndTablesInOSrc : public RegisterGroupsAndTablesInRE + { + public: + RegisterGroupsAndTablesInOSrc(const std::string &n) : + RegisterGroupsAndTablesInRE(n, libfwbuilder::RuleElementOSrc::TYPENAME) + {} + }; + + class RegisterGroupsAndTablesInODst : public RegisterGroupsAndTablesInRE + { + public: + RegisterGroupsAndTablesInODst(const std::string &n) : + RegisterGroupsAndTablesInRE(n, libfwbuilder::RuleElementODst::TYPENAME) + {} + }; + + }; diff --git a/src/libfwbuilder/src/fwcompiler/PolicyCompiler.h b/src/libfwbuilder/src/fwcompiler/PolicyCompiler.h index ce87e92bf..451f4eeb2 100644 --- a/src/libfwbuilder/src/fwcompiler/PolicyCompiler.h +++ b/src/libfwbuilder/src/fwcompiler/PolicyCompiler.h @@ -520,6 +520,22 @@ namespace fwcompiler { swapMultiAddressObjectsInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; + class RegisterGroupsAndTablesInSrc : public RegisterGroupsAndTablesInRE + { + public: + RegisterGroupsAndTablesInSrc(const std::string &n) : + RegisterGroupsAndTablesInRE(n, libfwbuilder::RuleElementSrc::TYPENAME) + {} + }; + + class RegisterGroupsAndTablesInDst : public RegisterGroupsAndTablesInRE + { + public: + RegisterGroupsAndTablesInDst(const std::string &n) : + RegisterGroupsAndTablesInRE(n, libfwbuilder::RuleElementDst::TYPENAME) + {} + }; + virtual int prolog(); diff --git a/src/libfwbuilder/src/fwcompiler/fwcompiler.pro b/src/libfwbuilder/src/fwcompiler/fwcompiler.pro index ca0785315..ea5aee222 100644 --- a/src/libfwbuilder/src/fwcompiler/fwcompiler.pro +++ b/src/libfwbuilder/src/fwcompiler/fwcompiler.pro @@ -16,7 +16,8 @@ SOURCES = BaseCompiler.cpp \ OSConfigurator.cpp \ PolicyCompiler.cpp \ ServiceRuleProcessors.cpp \ - RoutingCompiler.cpp + RoutingCompiler.cpp \ + GroupRegistry.cpp HEADERS = BaseCompiler.h \ Compiler.h \ @@ -26,7 +27,8 @@ HEADERS = BaseCompiler.h \ PolicyCompiler.h \ RuleProcessor.h \ RoutingCompiler.h \ - exceptions.h + exceptions.h \ + GroupRegistry.h TARGET = fwcompiler diff --git a/src/libgui/pfAdvancedDialog.cpp b/src/libgui/pfAdvancedDialog.cpp index 09a1c070d..5d1ae15aa 100644 --- a/src/libgui/pfAdvancedDialog.cpp +++ b/src/libgui/pfAdvancedDialog.cpp @@ -224,6 +224,8 @@ pfAdvancedDialog::pfAdvancedDialog(QWidget *parent,FWObject *o) data.registerOption( m_dialog->pf_check_shadowing,fwopt, "check_shading"); + data.registerOption( m_dialog->pf_preserve_group_names, fwopt, + "preserve_group_names"); data.registerOption( m_dialog->pf_ignore_empty_groups,fwopt, "ignore_empty_groups"); // data.registerOption( pf_use_tables, fwopt, "use_tables"); diff --git a/src/libgui/pfadvanceddialog_q.ui b/src/libgui/pfadvanceddialog_q.ui index 7619ac248..f6fb97212 100644 --- a/src/libgui/pfadvanceddialog_q.ui +++ b/src/libgui/pfadvanceddialog_q.ui @@ -94,7 +94,7 @@ - 2 + 0 @@ -286,30 +286,14 @@ false - - 9 - - + Accept TCP sessions opened prior to firewall restart - - - - - 0 - 0 - - - - Modulate state for all stateful rules (applies only to TCP services) - - - - + @@ -328,7 +312,20 @@ the prior rule. - + + + + + 0 + 0 + + + + Modulate state for all stateful rules (applies only to TCP services) + + + + @@ -349,6 +346,13 @@ this option only if you fully understand how it works! + + + + Preserve group and address table obects names in the generated pf configuration + + + diff --git a/src/pflib/CompilerDriver_pf_run.cpp b/src/pflib/CompilerDriver_pf_run.cpp index 6c3daaa9c..53f5f3528 100644 --- a/src/pflib/CompilerDriver_pf_run.cpp +++ b/src/pflib/CompilerDriver_pf_run.cpp @@ -67,6 +67,7 @@ #include "fwbuilder/XMLTools.h" #include "fwcompiler/Preprocessor.h" +#include "fwcompiler/GroupRegistry.h" #include "fwcompiler/exceptions.h" #include @@ -398,6 +399,8 @@ QString CompilerDriver_pf::run(const std::string &cluster_id, qDebug() << "rulesets_to_remote_file_names=" << rulesets_to_remote_file_names; #endif + GroupRegistry group_registry; + int routing_rules_count = 0; vector ipv4_6_runs; @@ -472,7 +475,8 @@ QString CompilerDriver_pf::run(const std::string &cluster_id, if (table_factories.count(ruleset_name) == 0) { table_factories[ruleset_name] = - new fwcompiler::TableFactory(this, persistent_objects); + new fwcompiler::TableFactory( + this, persistent_objects, &group_registry); } NATCompiler_pf n( objdb, fw, ipv6_policy, oscnf.get(), @@ -482,6 +486,7 @@ QString CompilerDriver_pf::run(const std::string &cluster_id, n.setSourceRuleSet( nat ); n.setRuleSetName(nat->getName()); n.setPersistentObjects(persistent_objects); + n.setGroupRegistry(&group_registry); n.setSingleRuleCompileMode(single_rule_id); n.setDebugLevel( dl ); @@ -547,7 +552,8 @@ QString CompilerDriver_pf::run(const std::string &cluster_id, if (table_factories.count(ruleset_name) == 0) { table_factories[ruleset_name] = - new fwcompiler::TableFactory(this, persistent_objects); + new fwcompiler::TableFactory( + this, persistent_objects, &group_registry); } PolicyCompiler_pf c( objdb, fw, ipv6_policy, oscnf.get(), @@ -558,6 +564,7 @@ QString CompilerDriver_pf::run(const std::string &cluster_id, c.setSourceRuleSet( policy ); c.setRuleSetName(policy->getName()); c.setPersistentObjects(persistent_objects); + c.setGroupRegistry(&group_registry); c.setSingleRuleCompileMode(single_rule_id); c.setDebugLevel( dl ); diff --git a/src/pflib/NATCompiler_pf.cpp b/src/pflib/NATCompiler_pf.cpp index 4f2eaba1c..156b4176e 100644 --- a/src/pflib/NATCompiler_pf.cpp +++ b/src/pflib/NATCompiler_pf.cpp @@ -1268,6 +1268,14 @@ void NATCompiler_pf::compile() add( new emptyGroupsInTDst( "check for empty groups in TDST" ) ); add( new emptyGroupsInTSrv( "check for empty groups in TSRV" ) ); + if (fw->getOptionsObject()->getBool("preserve_group_names")) + { + add(new RegisterGroupsAndTablesInOSrc( + "register object groups and tables in OSrc")); + add(new RegisterGroupsAndTablesInODst( + "register object groups and tables in ODst")); + } + add( new ExpandGroups( "expand groups" ) ); add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new eliminateDuplicatesInOSRC( "eliminate duplicates in OSRC") ); diff --git a/src/pflib/NATCompiler_pf.h b/src/pflib/NATCompiler_pf.h index f0bbce4a7..8afa0f299 100644 --- a/src/pflib/NATCompiler_pf.h +++ b/src/pflib/NATCompiler_pf.h @@ -320,7 +320,6 @@ namespace fwcompiler libfwbuilder::RuleElementTDst::TYPENAME) {} }; - /** * this processor is only called if we are using tables. It * creates two tables for each rule element Processor diff --git a/src/pflib/NATCompiler_pf_writers.cpp b/src/pflib/NATCompiler_pf_writers.cpp index d65e7c864..e9213f2b0 100644 --- a/src/pflib/NATCompiler_pf_writers.cpp +++ b/src/pflib/NATCompiler_pf_writers.cpp @@ -469,22 +469,16 @@ void NATCompiler_pf::PrintRule::_printREAddr(RuleElement *rel) FWObject *o=rel->front(); if (o && FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); - Address *addr= Address::cast(o); +// Address *addr= Address::cast(o); _printNegation(rel); - if (rel->size()==1 && ! o->getBool("pf_table") ) + if (rel->size()==1) { - _printAddr( addr ); + _printAddr(o); } else { - if (o->getBool("pf_table")) - { - compiler->output << "<" << o->getName() << "> "; - } else - { - _printAddrList(rel,rel->getNeg()); - } + _printAddrList(rel, rel->getNeg()); } } @@ -497,9 +491,7 @@ void NATCompiler_pf::PrintRule::_printAddrList(FWObject *grp,bool ) if (i!=grp->begin()) compiler->output << ", "; FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); - Address *s=Address::cast( o ); - assert(s); - _printAddr(s); + _printAddr(o); } compiler->output << "} "; } @@ -528,11 +520,19 @@ void NATCompiler_pf::PrintRule::_printAddr(FWObject *o) return; } - Address *a = Address::cast(o); - const InetAddr *addr = a->getAddressPtr(); + if (o->getBool("pf_table")) + { + compiler->output << "<" << o->getName() << "> "; + return; + } + + Address *addr_obj = Address::cast(o); + assert(addr_obj!=NULL); + + const InetAddr *addr = addr_obj->getAddressPtr(); if (addr) { - InetAddr mask = *(a->getNetmaskPtr()); + InetAddr mask = *(addr_obj->getNetmaskPtr()); if (Interface::cast(o)!=NULL || Address::cast(o)->dimension()==1) { diff --git a/src/pflib/PolicyCompiler_pf.cpp b/src/pflib/PolicyCompiler_pf.cpp index 198ee062f..462ec09b6 100644 --- a/src/pflib/PolicyCompiler_pf.cpp +++ b/src/pflib/PolicyCompiler_pf.cpp @@ -901,6 +901,14 @@ void PolicyCompiler_pf::compile() // add(new doDstNegation("process negation in Dst")); add(new doSrvNegation("process negation in Srv")); + if (fw->getOptionsObject()->getBool("preserve_group_names")) + { + add(new RegisterGroupsAndTablesInSrc( + "register object groups and tables in Src")); + add(new RegisterGroupsAndTablesInDst( + "register object groups and tables in Dst")); + } + // ExpandGroups opens groups, as well as groups in groups etc. add(new ExpandGroups("expand groups")); add(new dropRuleWithEmptyRE("drop rules with empty rule elements")); diff --git a/src/pflib/PolicyCompiler_pf.h b/src/pflib/PolicyCompiler_pf.h index 85e5062b0..70afdde38 100644 --- a/src/pflib/PolicyCompiler_pf.h +++ b/src/pflib/PolicyCompiler_pf.h @@ -144,8 +144,6 @@ namespace fwcompiler replaceFailoverInterfaceInRE(n, libfwbuilder::RuleElementItf::TYPENAME) {} }; - - /** * like standard processor swapMultiAddressObjectsInRE, * but swaps compile-time address tables @@ -291,7 +289,6 @@ namespace fwcompiler splitIfInterfaceInRE(n,libfwbuilder::RuleElementDst::TYPENAME) {} }; - /** * this processor is only called if we are using tables. It * creates two tables for each rule: one for source and @@ -303,7 +300,8 @@ namespace fwcompiler void createTablesForRE(libfwbuilder::RuleElement *re, libfwbuilder::Rule *rule); public: - createTables(const std::string &name) : PolicyRuleProcessor(name) {} + createTables(const std::string &name) : + PolicyRuleProcessor(name) { } virtual bool processNext(); }; friend class PolicyCompiler_pf::createTables; @@ -391,7 +389,7 @@ namespace fwcompiler virtual void _printAddrList(libfwbuilder::FWObject *o,bool negflag); virtual void _printSrcAddr(libfwbuilder::RuleElement *o); virtual void _printDstAddr(libfwbuilder::RuleElement *o); - virtual void _printAddr(libfwbuilder::Address *o,bool neg=false); + virtual void _printAddr(libfwbuilder::FWObject *o, bool neg=false); virtual void _printNegation(libfwbuilder::RuleElement *o); diff --git a/src/pflib/PolicyCompiler_pf_writers.cpp b/src/pflib/PolicyCompiler_pf_writers.cpp index 7bfaf3748..334b66cee 100644 --- a/src/pflib/PolicyCompiler_pf_writers.cpp +++ b/src/pflib/PolicyCompiler_pf_writers.cpp @@ -763,7 +763,7 @@ string PolicyCompiler_pf::PrintRule::_printTCPFlags(libfwbuilder::TCPService *sr return str; } -void PolicyCompiler_pf::PrintRule::_printAddr(Address *o, bool ) +void PolicyCompiler_pf::PrintRule::_printAddr(FWObject *o, bool ) { MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) @@ -787,7 +787,16 @@ void PolicyCompiler_pf::PrintRule::_printAddr(Address *o, bool ) assert(atrt==NULL); } - const InetAddr *addr = o->getAddressPtr(); + if (o->getBool("pf_table")) + { + compiler->output << "<" << o->getName() << "> "; + return; + } + + Address *addr_obj = Address::cast(o); + assert(addr_obj!=NULL); + + const InetAddr *addr = addr_obj->getAddressPtr(); InetAddr mask; if (Interface::cast(o)!=NULL) @@ -802,10 +811,10 @@ void PolicyCompiler_pf::PrintRule::_printAddr(Address *o, bool ) mask = InetAddr(InetAddr::getAllOnes()); } else { - mask = *(o->getNetmaskPtr()); + mask = *(addr_obj->getNetmaskPtr()); } - if (o->dimension()==1) + if (addr_obj->dimension()==1) { mask = InetAddr(InetAddr::getAllOnes()); } @@ -833,9 +842,7 @@ void PolicyCompiler_pf::PrintRule::_printAddrList(FWObject *grp,bool negflag) if (i!=grp->begin()) compiler->output << ", "; FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); - Address *s=Address::cast( o ); - assert(s); - _printAddr(s , negflag); + _printAddr(o , negflag); } compiler->output << "} "; } @@ -846,8 +853,6 @@ void PolicyCompiler_pf::PrintRule::_printSrcAddr(RuleElement *rel) FWReference *oref = FWReference::cast(o); if (o && oref!=NULL) o=oref->getPointer(); - Address *src= Address::cast(o); - _printNegation(rel); if (o==NULL) @@ -863,18 +868,12 @@ void PolicyCompiler_pf::PrintRule::_printSrcAddr(RuleElement *rel) compiler->abort(rel->getParent(), errstr.str()); } - if (rel->size()==1 && ! o->getBool("pf_table") ) + if (rel->size()==1) { - _printAddr( src , rel->getNeg() ); + _printAddr(o, rel->getNeg() ); } else { - if (o->getBool("pf_table")) - { - compiler->output << "<" << o->getName() << "> "; - } else - { - _printAddrList(rel,rel->getNeg()); - } + _printAddrList(rel,rel->getNeg()); } } @@ -885,8 +884,6 @@ void PolicyCompiler_pf::PrintRule::_printDstAddr(RuleElement *rel) FWReference *oref = FWReference::cast(o); if (o && oref!=NULL) o=oref->getPointer(); - Address *dst = Address::cast(o); - _printNegation(rel); if (o==NULL) @@ -902,18 +899,12 @@ void PolicyCompiler_pf::PrintRule::_printDstAddr(RuleElement *rel) compiler->abort(rel->getParent(), errstr.str()); } - if (rel->size()==1 && ! o->getBool("pf_table") ) + if (rel->size()==1) { - _printAddr( dst , rel->getNeg()); + _printAddr(o, rel->getNeg()); } else { - if (o->getBool("pf_table")) - { - compiler->output << "<" << o->getName() << "> "; - } else - { - _printAddrList(rel,rel->getNeg()); - } + _printAddrList(rel, rel->getNeg()); } } diff --git a/src/pflib/TableFactory.cpp b/src/pflib/TableFactory.cpp index acdab65b0..fb63fc63d 100644 --- a/src/pflib/TableFactory.cpp +++ b/src/pflib/TableFactory.cpp @@ -47,10 +47,13 @@ using namespace libfwbuilder; using namespace fwcompiler; using namespace std; -TableFactory::TableFactory(BaseCompiler *comp, Library *persistent_objects) +TableFactory::TableFactory(BaseCompiler *comp, + Library *persistent_objects, + GroupRegistry *_group_registry) { compiler = comp; ruleSetName = ""; + group_registry = _group_registry; dbroot = NULL; persistent_tables = new ObjectGroup(); persistent_tables->setName("PF Tables"); @@ -106,7 +109,26 @@ void TableFactory::registerTable(const string& tblname, const string& tblid, tables[tblid] = tbl; } -void TableFactory::createTablesForRE(RuleElement *re,Rule *rule) +FWObject* TableFactory::createTableObject(const string &tblname, + const string &tblid) +{ + FWObject *tblgrp = dbroot->createObjectGroup(); + + tblgrp->setName( tblname ); + tblgrp->setId(FWObjectDatabase::generateUniqueId()); // "id_" + tblname ); + + persistent_tables->add(tblgrp, false); + dbroot->addToIndex(tblgrp); + + tblgrp->setBool("pf_table", true); + tblgrp->setStr("pf_table_id", tblid); + + registerTable(tblname, tblid, tblgrp); + + return tblgrp; +} + +void TableFactory::createTablesForRE(RuleElement *re, Rule *rule) { // sanity checks assert(rule->getRoot()==re->getRoot()); @@ -116,48 +138,78 @@ void TableFactory::createTablesForRE(RuleElement *re,Rule *rule) * Before we create a new table, we scan tables and try to find * the one that already exists and contains the same objects. */ + string tblID = generateTblID(re); + FWObject *tblgrp = NULL; - if (tables.count(tblID)!=0) + list objects_in_groups; + list objects; + for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { - tblgrp = tables[tblID]; - } else + FWObject *o = FWReference::getObject(*i); + if ( ! group_registry->getGroupRegistryKey(o).empty()) + objects_in_groups.push_back(o); + else + objects.push_back(o); + } + + re->clearChildren(); + + set table_objects; + + for (FWObject::iterator i=objects_in_groups.begin(); i!=objects_in_groups.end(); i++) { - tblgrp = dbroot->createObjectGroup(); -// 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->setName( tblname.str() ); - tblgrp->setId(FWObjectDatabase::generateUniqueId()); // "id_" + tblname.str() ); - - persistent_tables->add(tblgrp,false); - dbroot->addToIndex(tblgrp); - - tblgrp->setBool("pf_table",true); - tblgrp->setStr("pf_table_id",tblID); - - registerTable(tblname.str(),tblID,tblgrp); - - for (FWObject::iterator i=re->begin(); i!=re->end(); i++) + set groups = group_registry->getGroupsForObject(*i); + for (set::iterator it=groups.begin(); it!=groups.end(); ++it) { - FWObject *o = FWReference::getObject(*i); - tblgrp->addRef( o ); + string tblname = *it; + if (tables.count(tblname)!=0) + { + tblgrp = tables[tblname]; + } else + { + tblgrp = createTableObject(tblname, tblname); + } + tblgrp->addRef(*i); + table_objects.insert(tblgrp); } } - re->clearChildren(); - re->addRef(tblgrp); + + if (objects.size() > 0) + { + if (tables.count(tblID)!=0) + { + 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); + + //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++) + { + tblgrp->addRef(*i); + } + } + + table_objects.insert(tblgrp); + } + + for (set::iterator i=table_objects.begin(); i!=table_objects.end(); i++) + re->addRef(*i); } string TableFactory::PrintTables() diff --git a/src/pflib/TableFactory.h b/src/pflib/TableFactory.h index 7b4295392..e5e2cd786 100644 --- a/src/pflib/TableFactory.h +++ b/src/pflib/TableFactory.h @@ -31,29 +31,39 @@ #include #include +#include #include #include -namespace libfwbuilder { +namespace libfwbuilder +{ class FWObject; class FWObjectDatabase; }; -namespace fwcompiler { +namespace fwcompiler +{ - class TableFactory { + class TableFactory + { BaseCompiler *compiler; libfwbuilder::FWObjectDatabase *dbroot; libfwbuilder::FWObject *persistent_tables; + GroupRegistry *group_registry; std::map tables; std::map tblnames; - std::string generateTblID(libfwbuilder::RuleElement *re); std::string ruleSetName; + std::string generateTblID(libfwbuilder::RuleElement *re); + libfwbuilder::FWObject* createTableObject(const std::string &tblname, + const std::string &tblid); + public: - TableFactory(BaseCompiler *comp, libfwbuilder::Library *persistent_objects); + TableFactory(BaseCompiler *comp, + libfwbuilder::Library *persistent_objects, + GroupRegistry *group_registry); void init(libfwbuilder::FWObjectDatabase *_dbroot); void detach(); diff --git a/test/pf/pf_cluster_4_rc.conf.local b/test/pf/pf_cluster_4_rc.conf.local index 523b35c73..0ff8fd890 100755 --- a/test/pf/pf_cluster_4_rc.conf.local +++ b/test/pf/pf_cluster_4_rc.conf.local @@ -1,9 +1,9 @@ # # This is automatically generated file. DO NOT MODIFY ! # -# Firewall Builder fwb_pf v5.0.0.3557 +# Firewall Builder fwb_pf v5.0.0.3561 # -# Generated Wed Jul 6 17:49:01 2011 PDT by vadim +# Generated Mon Jul 11 18:37:15 2011 PDT by vadim # # files: * pf_cluster_4_rc.conf.local /etc/pf_cluster_4_rc.conf.local # files: pf_cluster_4_pf.conf /etc/pf_cluster_4_pf.conf