1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-21 18:57:14 +01:00

fixed bug 2054755 ] Duplicate Chain

This commit is contained in:
Vadim Kurland 2008-08-18 03:05:45 +00:00
parent 61601fe1e3
commit d24c42edd7
12 changed files with 132 additions and 43 deletions

View File

@ -1,5 +1,9 @@
2008-08-17 Vadim Kurland <vadim@vk.crocodile.org>
* ipt.cpp (main): fixed bug #2054755: "Duplicate Chain". Compiler
for iptables used to generate duplicate "iptables -N chain"
commands for the same chain in some cases.
* Preprocessor_pf.cpp (Preprocessor_pf::convertObject): fixed bug
#2056510 "Compile time" address tables objects dont
work. Preprocessor in compiler for PF for some reason used to

View File

@ -47,8 +47,10 @@ namespace fwcompiler {
MangleTableCompiler_ipt(libfwbuilder::FWObjectDatabase *_db,
const std::string &fwname,
bool ipv6_policy,
fwcompiler::OSConfigurator *_oscnf) :
PolicyCompiler_ipt(_db, fwname, ipv6_policy, _oscnf)
fwcompiler::OSConfigurator *_oscnf,
std::map<const std::string, bool> *m_n_cmd_map
) :
PolicyCompiler_ipt(_db, fwname, ipv6_policy, _oscnf, m_n_cmd_map)
{
my_table = "mangle";
}

View File

@ -68,16 +68,35 @@ using namespace std;
*-----------------------------------------------------------------------
* Methods for printing
*/
void NATCompiler_ipt::PrintRule::InitializeMinusNTracker()
{
NATCompiler_ipt *ipt_comp = dynamic_cast<NATCompiler_ipt*>(compiler);
for (list<string>::const_iterator i =
NATCompiler_ipt::getStandardChains().begin();
i != NATCompiler_ipt::getStandardChains().end(); ++i)
{
(*(ipt_comp->minus_n_commands))[*i] = true;
}
minus_n_tracker_initialized = true;
}
/*
* check and create new chain if needed
*/
string NATCompiler_ipt::PrintRule::_createChain(const string &chain)
{
NATCompiler_ipt *ipt_comp = dynamic_cast<NATCompiler_ipt*>(compiler);
ostringstream res;
if ( ! chains[chain] )
if (!minus_n_tracker_initialized) InitializeMinusNTracker();
if ( ipt_comp->minus_n_commands->count(chain)==0 )
{
res << "$IPTABLES -t nat -N " << chain << endl;
chains[chain]=true;
(*(ipt_comp->minus_n_commands))[chain] = true;
}
return res.str();
}
@ -502,19 +521,12 @@ string NATCompiler_ipt::PrintRule::_printAddr(Address *o,
return ostr.str();
}
NATCompiler_ipt::PrintRule::PrintRule(const std::string &name) :
NATRuleProcessor(name)
{
init=true;
print_once_on_top=true;
for (list<string>::const_iterator i =
NATCompiler_ipt::getStandardChains().begin();
i != NATCompiler_ipt::getStandardChains().end(); ++i)
{
chains[*i] = true;
}
init = true;
print_once_on_top = true;
minus_n_tracker_initialized = false;
}
bool NATCompiler_ipt::PrintRule::processNext()

View File

@ -59,10 +59,14 @@ using namespace std;
string NATCompiler_ipt::PrintRuleIptRst::_createChain(const string &chain)
{
string res;
if ( ! chains[chain] )
NATCompiler_ipt *ipt_comp = dynamic_cast<NATCompiler_ipt*>(compiler);
if (!minus_n_tracker_initialized) InitializeMinusNTracker();
if ( ipt_comp->minus_n_commands->count(chain)==0 )
{
res = ":" + chain + " - [0:0]\n";
chains[chain]=true;
(*(ipt_comp->minus_n_commands))[chain] = true;
}
return res;
}

View File

@ -59,10 +59,14 @@ using namespace std;
string NATCompiler_ipt::PrintRuleIptRstEcho::_createChain(const string &chain)
{
string res;
if ( ! chains[chain] )
NATCompiler_ipt *ipt_comp = dynamic_cast<NATCompiler_ipt*>(compiler);
if (!minus_n_tracker_initialized) InitializeMinusNTracker();
if ( ipt_comp->minus_n_commands->count(chain)==0 )
{
res = "echo \":" + chain + " - [0:0]\"\n";
chains[chain]=true;
(*(ipt_comp->minus_n_commands))[chain] = true;
}
return res;
}

View File

@ -60,6 +60,12 @@ namespace fwcompiler {
bool have_dynamic_interfaces;
std::map<std::string, int> chain_usage_counter;
// use minus_n_commands map to track creation of chains.
// Using external map object for this to be able to track
// new chains across different compiler runs (used to process
// rules in different policy or nat objects)
std::map<const std::string, bool> *minus_n_commands;
static const std::list<std::string>& getStandardChains();
std::string getInterfaceVarName(libfwbuilder::FWObject *iface,
bool v6=false);
@ -443,9 +449,11 @@ namespace fwcompiler {
bool init;
bool print_once_on_top;
bool minus_n_tracker_initialized;
std::string current_rule_label;
std::map<const std::string,bool> chains;
void InitializeMinusNTracker();
virtual std::string _createChain(const std::string &chain);
virtual std::string _startRuleLine();
virtual std::string _endRuleLine();
@ -524,11 +532,13 @@ namespace fwcompiler {
NATCompiler_ipt(libfwbuilder::FWObjectDatabase *_db,
const std::string &fwname,
bool ipv6_policy,
fwcompiler::OSConfigurator *_oscnf) :
fwcompiler::OSConfigurator *_oscnf,
std::map<const std::string, bool> *m_n_commands_map) :
NATCompiler(_db, fwname, ipv6_policy, _oscnf)
{
have_dynamic_interfaces=false;
printRule=NULL;
minus_n_commands = m_n_commands_map;
}

View File

@ -80,6 +80,19 @@ using namespace std;
* Methods for printing
*/
void PolicyCompiler_ipt::PrintRule::InitializeMinusNTracker()
{
PolicyCompiler_ipt *ipt_comp = dynamic_cast<PolicyCompiler_ipt*>(compiler);
for (list<string>::const_iterator i =
PolicyCompiler_ipt::getStandardChains().begin();
i != PolicyCompiler_ipt::getStandardChains().end(); ++i)
{
(*(ipt_comp->minus_n_commands))[*i] = true;
}
minus_n_tracker_initialized = true;
}
/*
* check and create new chain if needed
*/
@ -88,13 +101,15 @@ string PolicyCompiler_ipt::PrintRule::_createChain(const string &chain)
string res;
PolicyCompiler_ipt *ipt_comp = dynamic_cast<PolicyCompiler_ipt*>(compiler);
if ( ! chains[chain] )
if (!minus_n_tracker_initialized) InitializeMinusNTracker();
if ( ipt_comp->minus_n_commands->count(chain)==0 )
{
res = string((ipt_comp->ipv6) ? "$IP6TABLES -N " : "$IPTABLES -N ") +
chain;
if (ipt_comp->my_table != "filter") res += " -t " + ipt_comp->my_table;
res += "\n";
chains[chain]=true;
(*(ipt_comp->minus_n_commands))[chain] = true;
}
return res;
}
@ -1239,17 +1254,15 @@ string PolicyCompiler_ipt::PrintRule::_printTimeInterval(PolicyRule *r)
return ostr.str();
}
PolicyCompiler_ipt::PrintRule::PrintRule(const std::string &name) : PolicyRuleProcessor(name)
PolicyCompiler_ipt::PrintRule::PrintRule(const std::string &name) :
PolicyRuleProcessor(name)
{
init=true;
print_once_on_top=true;
for (list<string>::const_iterator i =
PolicyCompiler_ipt::getStandardChains().begin();
i != PolicyCompiler_ipt::getStandardChains().end(); ++i)
{
chains[*i] = true;
}
init = true;
print_once_on_top = true;
// use delayed initialization for ipt_comp->minus_n_commands
// because it requires pointer to the compiler which has not been
// initialized yet when this constructor is executed.
minus_n_tracker_initialized = false;
}
bool PolicyCompiler_ipt::PrintRule::processNext()
@ -1261,7 +1274,6 @@ bool PolicyCompiler_ipt::PrintRule::processNext()
string chain = rule->getStr("ipt_chain");
if (ipt_comp->chain_usage_counter[chain] > 0)
{
tmp_queue.push_back(rule);
compiler->output << _printRuleLabel(rule);

View File

@ -60,10 +60,14 @@ using namespace std;
string PolicyCompiler_ipt::PrintRuleIptRst::_createChain(const string &chain)
{
string res;
if ( ! chains[chain] )
PolicyCompiler_ipt *ipt_comp = dynamic_cast<PolicyCompiler_ipt*>(compiler);
if (!minus_n_tracker_initialized) InitializeMinusNTracker();
if ( ipt_comp->minus_n_commands->count(chain)==0 )
{
res = ":" + chain + " - [0:0]\n";
chains[chain]=true;
(*(ipt_comp->minus_n_commands))[chain] = true;
}
return res;
}

View File

@ -60,10 +60,14 @@ using namespace std;
string PolicyCompiler_ipt::PrintRuleIptRstEcho::_createChain(const string &chain)
{
string res;
if ( ! chains[chain] )
PolicyCompiler_ipt *ipt_comp = dynamic_cast<PolicyCompiler_ipt*>(compiler);
if (!minus_n_tracker_initialized) InitializeMinusNTracker();
if ( ipt_comp->minus_n_commands->count(chain)==0 )
{
res = "echo \":" + chain + " - [0:0]\"\n";
chains[chain]=true;
(*(ipt_comp->minus_n_commands))[chain] = true;
}
return res;
}

View File

@ -4192,7 +4192,9 @@ PolicyCompiler_ipt::PrintRule* PolicyCompiler_ipt::createPrintRuleProcessor()
printRule = new PrintRuleIptRstEcho(
"generate code for iptables-restore using echo");
} else
printRule = new PrintRule("generate shell script" );
{
printRule = new PrintRule("generate shell script");
}
printRule->setContext(this);
}
return printRule;

View File

@ -79,6 +79,11 @@ namespace fwcompiler {
std::map<std::string, int> tmp_chain_no;
std::map<std::string, int> chain_usage_counter;
// use minus_n_commands map to track creation of chains.
// Using external map object for this to be able to track
// new chains across different compiler runs (used to process
// rules in different policy or nat objects)
std::map<const std::string, bool> *minus_n_commands;
static const std::list<std::string>& getStandardChains();
@ -832,9 +837,11 @@ namespace fwcompiler {
bool init;
bool print_once_on_top;
bool minus_n_tracker_initialized;
std::string current_rule_label;
std::map<const std::string,bool> chains;
void InitializeMinusNTracker();
virtual std::string _createChain(const std::string &chain);
virtual std::string _printRuleLabel(libfwbuilder::PolicyRule *r);
@ -946,7 +953,9 @@ namespace fwcompiler {
PolicyCompiler_ipt(libfwbuilder::FWObjectDatabase *_db,
const std::string &fwname,
bool ipv6_policy,
fwcompiler::OSConfigurator *_oscnf) :
fwcompiler::OSConfigurator *_oscnf,
std::map<const std::string, bool> *m_n_commands_map
) :
PolicyCompiler(_db, fwname, ipv6_policy, _oscnf)
{
have_dynamic_interfaces = false;
@ -954,6 +963,7 @@ namespace fwcompiler {
have_connmark_in_output = false;
printRule = NULL;
my_table = "filter";
minus_n_commands = m_n_commands_map;
}

View File

@ -568,6 +568,17 @@ _("Dynamic interface %s should not have an IP address object attached to it. Thi
int routing_rules_count = 0;
bool have_nat = false;
// track chains in each table separately. Can we have the same
// chain in filter and mangle tables ? Would it be the same
// chain, i.e. do we need to create it only once or do we create
// it twice, in each table separately ?
// Using separate trackers we track and create chain in each
// table separately.
std::map<const std::string, bool> minus_n_commands_filter;
std::map<const std::string, bool> minus_n_commands_mangle;
std::map<const std::string, bool> minus_n_commands_nat;
vector<bool> ipv4_6_runs;
string generated_script;
@ -597,6 +608,13 @@ _("Dynamic interface %s should not have an IP address object attached to it. Thi
{
bool ipv6_policy = *i;
// clear chain tracker map only between ipv4/ipv6 runs
// Don't clear it between compiler runs for different
// policy or nat objects for the same address family.
minus_n_commands_filter.clear();
minus_n_commands_mangle.clear();
minus_n_commands_nat.clear();
Preprocessor* prep = new Preprocessor(
objdb , fwobjectname, ipv6_policy);
if (test_mode) prep->setTestMode();
@ -621,7 +639,8 @@ _("Dynamic interface %s should not have an IP address object attached to it. Thi
// compile NAT rules before policy rules because policy
// compiler needs to know the number of virtual addresses
// being created for NAT
NATCompiler_ipt n(objdb, fwobjectname, ipv6_policy, oscnf);
NATCompiler_ipt n(objdb, fwobjectname, ipv6_policy, oscnf,
&minus_n_commands_nat);
n.setSourceRuleSet( nat );
n.setRuleSetName(branch_name);
@ -671,7 +690,8 @@ _("Dynamic interface %s should not have an IP address object attached to it. Thi
if (policy->isV6()!=ipv6_policy) continue;
MangleTableCompiler_ipt m(
objdb , fwobjectname, ipv6_policy , oscnf );
objdb , fwobjectname, ipv6_policy , oscnf,
&minus_n_commands_mangle );
if (!policy->isTop())
m.registerRuleSetChain(branch_name);
@ -723,7 +743,8 @@ _("Dynamic interface %s should not have an IP address object attached to it. Thi
}
PolicyCompiler_ipt c(objdb, fwobjectname, ipv6_policy, oscnf);
PolicyCompiler_ipt c(objdb, fwobjectname, ipv6_policy, oscnf,
&minus_n_commands_filter);
if (!policy->isTop())
c.registerRuleSetChain(branch_name);