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:
parent
61601fe1e3
commit
d24c42edd7
@ -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
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user