mirror of
https://github.com/fwbuilder/fwbuilder
synced 2026-09-12 16:13:13 +02:00
see #1890 "Add
support for configuring static routes on BSD". Implemented support for simple static routing rules. ECMP and routing via interface (routing to directly reachable subnets) are not supported. Generated script preserves static routing entries that existed before and attempts to recover in case of error. Needs testing.
This commit is contained in:
@@ -1,3 +1,13 @@
|
||||
2011-01-31 Vadim Kurland <vadim@netcitadel.com>
|
||||
|
||||
* RoutingCompiler_bsd_writers.cpp (_printAddr): see #1890 "Add
|
||||
support for configuring static routes on BSD". Implemented support
|
||||
for simple static routing rules. ECMP and routing via interface
|
||||
(routing to directly reachable subnets) are not
|
||||
supported. Generated script preserves static routing entries that
|
||||
existed before and attempts to recover in case of error. Needs
|
||||
testing.
|
||||
|
||||
2011-01-30 vadim <vadim@netcitadel.com>
|
||||
|
||||
* FWWindow_editor.cpp (clearEditorAndSearchPanels): see #2006
|
||||
|
||||
@@ -501,7 +501,24 @@ bool RoutingCompiler::contradictionRGtwAndRItf::processNext()
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RoutingCompiler::interfaceOrGateway::processNext()
|
||||
{
|
||||
RoutingRule *rule = getNext(); if (rule==NULL) return false;
|
||||
tmp_queue.push_back(rule);
|
||||
|
||||
RuleElementRItf *itfrel = rule->getRItf();
|
||||
RuleElementRGtw *gtwrel = rule->getRGtw();
|
||||
|
||||
if (!itfrel->isAny() && !gtwrel->isAny())
|
||||
{
|
||||
compiler->abort(rule,
|
||||
"Use either gateway or interface in a routing rule "
|
||||
"but not both at the same time");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RoutingCompiler::rItfChildOfFw::processNext()
|
||||
@@ -527,7 +544,8 @@ bool RoutingCompiler::rItfChildOfFw::processNext()
|
||||
{
|
||||
list<Firewall*> members;
|
||||
cluster->getMembersList(members);
|
||||
if (std::find(members.begin(), members.end(), compiler->fw) != members.end())
|
||||
if (std::find(members.begin(), members.end(),
|
||||
compiler->fw) != members.end())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -542,6 +560,55 @@ bool RoutingCompiler::rItfChildOfFw::processNext()
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this after converting to atomic rules by DST to be sure there
|
||||
* is just one object in DST.
|
||||
*/
|
||||
bool RoutingCompiler::sameDestinationDifferentGateways::processNext()
|
||||
{
|
||||
slurp();
|
||||
if (tmp_queue.size()==0) return false;
|
||||
|
||||
// map destination to gateway.
|
||||
std::map<string, string> dst_to_gw;
|
||||
std::map<string, string> dst_to_rule;
|
||||
|
||||
for (deque<Rule*>::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k)
|
||||
{
|
||||
RoutingRule *rule = RoutingRule::cast( *k );
|
||||
|
||||
RuleElementRDst *dstrel = rule->getRDst();
|
||||
Address *dst = Address::cast(FWReference::getObject(dstrel->front()));
|
||||
const InetAddr* dst_addr = dst->getAddressPtr();
|
||||
const InetAddr* dst_netm = dst->getNetmaskPtr();
|
||||
string key = dst_addr->toString() + "/" + dst_netm->toString();
|
||||
|
||||
RuleElementRItf *itfrel = rule->getRItf();
|
||||
FWObject *itf = FWReference::cast(itfrel->front())->getPointer();
|
||||
|
||||
RuleElementRGtw *gtwrel = rule->getRGtw();
|
||||
Address *gtw = Address::cast(FWReference::getObject(gtwrel->front()));
|
||||
const InetAddr* gtw_addr = gtw->getAddressPtr();
|
||||
const InetAddr* gtw_netm = gtw->getNetmaskPtr();
|
||||
string val = gtw_addr->toString() + "/" + gtw_netm->toString();
|
||||
|
||||
if (!dst_to_gw[key].empty() && dst_to_gw[key] != val)
|
||||
{
|
||||
compiler->abort(
|
||||
rule,
|
||||
"Rules " + dst_to_rule[key] + " and " + rule->getLabel() +
|
||||
" define routes to the same destination " + key +
|
||||
" via different gateways. This configuration is not supported"
|
||||
" for " + compiler->fw->getStr("host_OS"));
|
||||
} else
|
||||
{
|
||||
dst_to_gw[key] = val;
|
||||
dst_to_rule[key] = rule->getLabel();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RoutingCompiler::competingRules::processNext()
|
||||
{
|
||||
@@ -611,10 +678,16 @@ bool RoutingCompiler::competingRules::processNext()
|
||||
|
||||
if(false)
|
||||
{
|
||||
// TODO_lowPrio: if ( !compiler->fw->getOptionsObject()->getBool ("equal_cost_multi_path") ) ...If multipath is turned off, perform this check.
|
||||
// iterate all gtwitf combis in the map dest_it->second and search for the current metric
|
||||
// TODO_lowPrio: if (
|
||||
// !compiler->fw->getOptionsObject()->getBool
|
||||
// ("equal_cost_multi_path") ) ...If multipath is
|
||||
// turned off, perform this check.
|
||||
|
||||
// iterate all gtwitf combis in the map
|
||||
// dest_it->second and search for the current metric
|
||||
|
||||
// ... but has the same metric => what route should I use for this destination? => abort
|
||||
// ... but has the same metric => what route should I
|
||||
// use for this destination? => abort
|
||||
|
||||
string msg;
|
||||
msg = "Routing rules " + gtwitf_it->second.second + " and " +
|
||||
@@ -625,14 +698,14 @@ bool RoutingCompiler::competingRules::processNext()
|
||||
"enable ECMP (Equal Cost MultiPath) routing";
|
||||
compiler->abort( msg.c_str() );
|
||||
|
||||
} else {
|
||||
|
||||
} else
|
||||
{
|
||||
// ... and different metric OR equal_cost_multi_path enabled => OK
|
||||
|
||||
tmp_queue.push_back(rule);
|
||||
}
|
||||
|
||||
dest_it->second[combiId] = pair< string, string>( metric, rule->getLabel());
|
||||
dest_it->second[combiId] =
|
||||
pair< string, string>( metric, rule->getLabel());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -140,6 +140,19 @@ namespace fwcompiler {
|
||||
*/
|
||||
DECLARE_ROUTING_RULE_PROCESSOR(rItfChildOfFw);
|
||||
|
||||
/**
|
||||
* some OS (e.g. BSD) allow me to set up static route via
|
||||
* gateway or via interface, but not both in one rule.
|
||||
*/
|
||||
DECLARE_ROUTING_RULE_PROCESSOR(interfaceOrGateway);
|
||||
|
||||
/**
|
||||
* for OS where we do not support ECMP, detect rules that
|
||||
* define routes for the same destination via different
|
||||
* gateways and abort.
|
||||
*/
|
||||
DECLARE_ROUTING_RULE_PROCESSOR(sameDestinationDifferentGateways);
|
||||
|
||||
/**
|
||||
* checks for competing rules
|
||||
*/
|
||||
|
||||
@@ -1554,13 +1554,16 @@ void RoutingModel::configure()
|
||||
{
|
||||
//if (fwbdebug) qDebug() << "RoutingModel::configure";
|
||||
supports_routing_itf = false;
|
||||
supports_metric = false;
|
||||
|
||||
if (getFirewall())
|
||||
{
|
||||
try {
|
||||
supports_routing_itf =
|
||||
Resources::getTargetCapabilityBool(
|
||||
getFirewall()->getStr("platform"), "supports_routing_itf");
|
||||
getFirewall()->getStr("host_OS"), "supports_routing_itf");
|
||||
supports_metric = Resources::getTargetCapabilityBool(
|
||||
getFirewall()->getStr("host_OS"), "supports_metric");
|
||||
} catch(FWException &ex) { }
|
||||
}
|
||||
|
||||
@@ -1570,9 +1573,11 @@ void RoutingModel::configure()
|
||||
if (supports_routing_itf)
|
||||
header << ColDesc(RuleElementRItf::TYPENAME, ColDesc::Object);
|
||||
|
||||
header << ColDesc("Metric", ColDesc::Metric)
|
||||
<< ColDesc("Options", ColDesc::Options)
|
||||
<< ColDesc("Comment", ColDesc::Comment);
|
||||
if (supports_metric)
|
||||
header << ColDesc("Metric", ColDesc::Metric);
|
||||
|
||||
header << ColDesc("Options", ColDesc::Options)
|
||||
<< ColDesc("Comment", ColDesc::Comment);
|
||||
}
|
||||
|
||||
QVariant RoutingModel::getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const
|
||||
|
||||
+13
-12
@@ -45,9 +45,9 @@ namespace libfwbuilder
|
||||
|
||||
class RuleSetModel;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// RuleSetModelIterator
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class RuleSetModelIterator
|
||||
{
|
||||
@@ -76,9 +76,9 @@ private:
|
||||
QModelIndex parent;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// ActionDesc
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ActionDesc
|
||||
{
|
||||
@@ -91,9 +91,9 @@ class ActionDesc
|
||||
|
||||
Q_DECLARE_METATYPE(ActionDesc)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// RuleSetModel
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class RuleSetModel : public QAbstractItemModel
|
||||
{
|
||||
@@ -208,9 +208,9 @@ private:
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// PolicyModel
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PolicyModel : public RuleSetModel
|
||||
{
|
||||
@@ -232,9 +232,9 @@ private:
|
||||
void configure();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// NatModel
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class NatModel : public RuleSetModel
|
||||
{
|
||||
@@ -252,9 +252,9 @@ private:
|
||||
void configure();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// RoutingModel
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class RoutingModel : public RuleSetModel
|
||||
{
|
||||
@@ -266,6 +266,7 @@ public:
|
||||
|
||||
private:
|
||||
bool supports_routing_itf;
|
||||
bool supports_metric;
|
||||
|
||||
QVariant getRuleDataForDisplayRole(const QModelIndex &index, RuleNode* node) const;
|
||||
QStringList getRuleOptions(libfwbuilder::Rule* r) const;
|
||||
|
||||
@@ -68,7 +68,8 @@ class MapTableFactory : public std::map<std::string, fwcompiler::TableFactory*>
|
||||
|
||||
namespace fwcompiler {
|
||||
|
||||
class CompilerDriver_pf : public CompilerDriver {
|
||||
class CompilerDriver_pf : public CompilerDriver
|
||||
{
|
||||
|
||||
// Note that in the following maps ruleset name will be
|
||||
// "__main__" for both main Policy and NAT rulesets.
|
||||
@@ -100,6 +101,8 @@ namespace fwcompiler {
|
||||
const std::string &remote_file_name);
|
||||
|
||||
protected:
|
||||
|
||||
std::string routing_script;
|
||||
|
||||
std::string getConfFileName(const std::string &ruleset_name,
|
||||
const std::string &fwobjectname,
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "NATCompiler_pf.h"
|
||||
#include "TableFactory.h"
|
||||
#include "Preprocessor_pf.h"
|
||||
#include "RoutingCompiler_bsd.h"
|
||||
|
||||
#include "OSConfigurator_openbsd.h"
|
||||
#include "OSConfigurator_freebsd.h"
|
||||
@@ -56,6 +57,7 @@
|
||||
#include "fwbuilder/Interface.h"
|
||||
#include "fwbuilder/Policy.h"
|
||||
#include "fwbuilder/NAT.h"
|
||||
#include "fwbuilder/Routing.h"
|
||||
|
||||
#include "fwcompiler/Preprocessor.h"
|
||||
#include "fwcompiler/exceptions.h"
|
||||
@@ -172,14 +174,19 @@ QString CompilerDriver_pf::assembleFwScript(Cluster *cluster,
|
||||
Configlet script_skeleton(fw, "pf", "script_skeleton");
|
||||
Configlet top_comment(fw, "pf", "top_comment");
|
||||
|
||||
script_skeleton.setVariable("routing_script",
|
||||
QString::fromUtf8(routing_script.c_str()));
|
||||
|
||||
assembleFwScriptInternal(
|
||||
cluster, fw, cluster_member, oscnf, &script_skeleton, &top_comment, "#");
|
||||
|
||||
if (fw->getStr("platform") == "pf")
|
||||
{
|
||||
script_skeleton.setVariable("pf_flush_states", options->getBool("pf_flush_states"));
|
||||
script_skeleton.setVariable("pf_version_ge_4_x", // fw->getStr("version")=="4.x");
|
||||
XMLTools::version_compare(fw->getStr("version"), "4.0")>=0);
|
||||
script_skeleton.setVariable(
|
||||
"pf_flush_states", options->getBool("pf_flush_states"));
|
||||
script_skeleton.setVariable(
|
||||
"pf_version_ge_4_x", // fw->getStr("version")=="4.x");
|
||||
XMLTools::version_compare(fw->getStr("version"), "4.0")>=0);
|
||||
|
||||
} else
|
||||
{
|
||||
@@ -268,6 +275,8 @@ QString CompilerDriver_pf::run(const std::string &cluster_id,
|
||||
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
|
||||
list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME);
|
||||
|
||||
int routing_rules_count = 0;
|
||||
|
||||
findImportedRuleSets(fw, all_policies);
|
||||
findImportedRuleSets(fw, all_nat);
|
||||
|
||||
@@ -511,6 +520,35 @@ QString CompilerDriver_pf::run(const std::string &cluster_id,
|
||||
}
|
||||
}
|
||||
|
||||
std::auto_ptr<RoutingCompiler_bsd> routing_compiler(
|
||||
new RoutingCompiler_bsd(objdb, fw, false, oscnf.get()));
|
||||
|
||||
RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME));
|
||||
if (routing)
|
||||
{
|
||||
routing_compiler->setSourceRuleSet(routing);
|
||||
routing_compiler->setRuleSetName(routing->getName());
|
||||
|
||||
routing_compiler->setSingleRuleCompileMode(single_rule_id);
|
||||
routing_compiler->setDebugLevel( dl );
|
||||
if (rule_debug_on) routing_compiler->setDebugRule(drp);
|
||||
routing_compiler->setVerbose( verbose );
|
||||
if (inTestMode()) routing_compiler->setTestMode();
|
||||
if (inEmbeddedMode()) routing_compiler->setEmbeddedMode();
|
||||
|
||||
if ( (routing_rules_count=routing_compiler->prolog()) > 0 )
|
||||
{
|
||||
routing_compiler->compile();
|
||||
routing_compiler->epilog();
|
||||
}
|
||||
|
||||
if (routing_compiler->haveErrorsAndWarnings())
|
||||
all_errors.push_back(routing_compiler->getErrors("").c_str());
|
||||
|
||||
routing_script += routing_compiler->getCompiledScript();
|
||||
}
|
||||
|
||||
|
||||
if (haveErrorsAndWarnings())
|
||||
{
|
||||
all_errors.push_front(getErrors("").c_str());
|
||||
@@ -529,6 +567,7 @@ QString CompilerDriver_pf::run(const std::string &cluster_id,
|
||||
ostringstream *strm = fi->second;
|
||||
pf_str << table_factories[ruleset_name]->PrintTables();
|
||||
pf_str << QString::fromUtf8(strm->str().c_str());
|
||||
pf_str << QString::fromUtf8(routing_script.c_str());
|
||||
}
|
||||
|
||||
// clear() calls destructors of all elements in the container
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
|
||||
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 "RoutingCompiler_bsd.h"
|
||||
|
||||
#include "fwbuilder/Resources.h"
|
||||
#include "fwbuilder/FWObjectDatabase.h"
|
||||
#include "fwbuilder/RuleElement.h"
|
||||
#include "fwbuilder/Routing.h"
|
||||
#include "fwbuilder/Interface.h"
|
||||
#include "fwbuilder/IPv4.h"
|
||||
#include "fwbuilder/Firewall.h"
|
||||
#include "fwbuilder/Network.h"
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
|
||||
using namespace libfwbuilder;
|
||||
using namespace fwcompiler;
|
||||
using namespace std;
|
||||
|
||||
static std::map<std::string,int> tmp_chain_no;
|
||||
|
||||
string RoutingCompiler_bsd::myPlatformName() { return "pf"; }
|
||||
|
||||
|
||||
void RoutingCompiler_bsd::verifyOS()
|
||||
{
|
||||
QStringList supported_os = QString(
|
||||
Resources::platform_res[fw->getStr("platform")]->
|
||||
getResourceStr("/FWBuilderResources/Target/supported_os").c_str())
|
||||
.split(",");
|
||||
|
||||
QString host_os = fw->getStr("host_OS").c_str();
|
||||
if (!supported_os.contains(host_os))
|
||||
abort("Unsupported host OS " + host_os.toStdString());
|
||||
|
||||
}
|
||||
|
||||
int RoutingCompiler_bsd::prolog()
|
||||
{
|
||||
int n = RoutingCompiler::prolog();
|
||||
|
||||
verifyOS();
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
bool RoutingCompiler_bsd::addressRangesInDst::processNext()
|
||||
{
|
||||
RoutingRule *rule;
|
||||
rule=getNext(); if (rule==NULL) return false;
|
||||
|
||||
RuleElementRDst *dstrel = rule->getRDst();
|
||||
compiler->_expandAddressRanges(rule, dstrel);
|
||||
|
||||
tmp_queue.push_back(rule);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool RoutingCompiler_bsd::FindDefaultRoute::processNext()
|
||||
{
|
||||
RoutingCompiler_bsd *bsd_comp = dynamic_cast<RoutingCompiler_bsd*>(compiler);
|
||||
RoutingRule *rule;
|
||||
rule=getNext(); if (rule==NULL) return false;
|
||||
|
||||
RuleElementRDst *dstrel = rule->getRDst();
|
||||
FWObject *ref = dstrel->front();
|
||||
Address *dst = Address::cast(FWReference::cast(ref)->getPointer());
|
||||
if (dst->isAny()) bsd_comp->have_default_route = true;
|
||||
|
||||
tmp_queue.push_back(rule);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
void RoutingCompiler_bsd::compile()
|
||||
{
|
||||
string banner = " Compiling routing rules for " + fw->getName();
|
||||
info(banner);
|
||||
|
||||
Compiler::compile();
|
||||
//bool check_for_recursive_groups=true;
|
||||
|
||||
add(new RoutingCompiler::Begin());
|
||||
add(new printTotalNumberOfRules());
|
||||
|
||||
add( new singleRuleFilter());
|
||||
|
||||
add(new recursiveGroupsInRDst("Check for recursive Groups in RDst"));
|
||||
add(new emptyGroupsInRDst("Check for empty Groups in RDst"));
|
||||
add(new emptyRDstAndRItf("Check if RDst and RItf are both empty"));
|
||||
add(new singleAdressInRGtw(
|
||||
"Check if RGtw object has exactly one IP adress"));
|
||||
add(new rItfChildOfFw("Check if RItf is an Iterface of this firewall"));
|
||||
add(new interfaceOrGateway(
|
||||
"Check that the rule has either gw or interface but not both"));
|
||||
add(new validateNetwork("Validate network addresses"));
|
||||
add(new reachableAddressInRGtw(
|
||||
"Check if RGtw is reachable via local networks"));
|
||||
add(new contradictionRGtwAndRItf(
|
||||
"Check if RGtw is in a network of RItf"));
|
||||
|
||||
add(new ExpandGroups("Expand groups in DST"));
|
||||
add(new ExpandMultipleAddresses(
|
||||
"Expand objects with multiple addresses in DST"));
|
||||
|
||||
add(new addressRangesInDst("process address ranges"));
|
||||
|
||||
//add(new eliminateDuplicatesInDST("Eliminate duplicates in DST"));
|
||||
|
||||
add(new FindDefaultRoute("Find rules that install default route"));
|
||||
|
||||
#ifdef ECMP_SUPPORT_OLD_STYLE
|
||||
add(new createSortedDstIdsLabel(
|
||||
"Create label with a sorted dst-id-list for 'competingRules'"));
|
||||
add(new competingRules("Check for competing rules"));
|
||||
#endif
|
||||
|
||||
add(new ConvertToAtomicForDST(
|
||||
"Convert to atomic rules by dst address elements"));
|
||||
|
||||
add(new sameDestinationDifferentGateways(
|
||||
"detect rules with the same destination but different gateways. We do not "
|
||||
"support ECMP at this time"));
|
||||
|
||||
// add(new createSortedDstIdsLabel(
|
||||
// "Create label with a sorted dst-id-list for 'classifyRoutingRules'"));
|
||||
// add(new classifyRoutingRules(
|
||||
// "Classify into single path or part of a multi path rule"));
|
||||
|
||||
#ifdef ECMP_SUPPORT_OLD_STYLE
|
||||
add(new optimize3(
|
||||
"Eliminate duplicate rules generated from a single gui-rule"));
|
||||
add(new eliminateDuplicateRules(
|
||||
"Eliminate duplicate rules over the whole table"));
|
||||
#endif
|
||||
|
||||
add( new checkForObjectsWithErrors(
|
||||
"check if we have objects with errors in rule elements"));
|
||||
|
||||
add(new PrintRule("generate ip code"));
|
||||
add(new simplePrintProgress());
|
||||
|
||||
runRuleProcessors();
|
||||
|
||||
}
|
||||
|
||||
string RoutingCompiler_bsd::debugPrintRule(Rule *r)
|
||||
{
|
||||
RoutingRule *rule=RoutingRule::cast(r);
|
||||
|
||||
string s= RoutingCompiler::debugPrintRule(rule);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void RoutingCompiler_bsd::epilog()
|
||||
{
|
||||
///int total = ecmp_comments_buffer.size();
|
||||
int nb = 0;
|
||||
|
||||
// ecmp roules can only be generated after all the rules have been
|
||||
// parsed, that is the reason for putting this code in the epilog
|
||||
// function
|
||||
if (ecmp_rules_buffer.size() > 0)
|
||||
{
|
||||
output << "\n#\n# ============== EQUAL COST MULTI PATH ============\n#"
|
||||
<< endl;
|
||||
|
||||
output << "echo \"Activating ecmp routing rules...\"" << endl;
|
||||
|
||||
for (map<string,string>::iterator
|
||||
ecmp_comments_buffer_it = ecmp_comments_buffer.begin();
|
||||
ecmp_comments_buffer_it != ecmp_comments_buffer.end();
|
||||
++ecmp_comments_buffer_it)
|
||||
{
|
||||
output << ecmp_comments_buffer_it->second << "#\n" << flush;
|
||||
|
||||
output << ecmp_rules_buffer[ecmp_comments_buffer_it->first] << flush;
|
||||
|
||||
output << " \\\n|| route_command_error " << "\"" << ++nb << "\"" << endl;
|
||||
|
||||
//echo \"Error: The ECMP routing rule #" << ++nb <<" couldn't be activated! Please make sure your kernel is compiled with the CONFIG_IP_ROUTE_MULTIPATH option.\"" << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!inSingleRuleCompileMode() && defined_restore_script_output)
|
||||
{
|
||||
// function restore_script_output may not be defined if we
|
||||
// have no rules or all rules are disabled
|
||||
output << endl;
|
||||
output << "restore_script_output" << endl;
|
||||
output << "echo \"...done.\"" << endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
|
||||
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 __ROUTINGCOMPILER_BSD_HH__
|
||||
#define __ROUTINGCOMPILER_BSD_HH__
|
||||
|
||||
#include <fwbuilder/libfwbuilder-config.h>
|
||||
|
||||
#include "fwcompiler/RoutingCompiler.h"
|
||||
#include "fwbuilder/RuleElement.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
namespace libfwbuilder {
|
||||
class RuleElementRDst;
|
||||
class RuleElementRItf;
|
||||
class RuleElementRGtw;
|
||||
};
|
||||
|
||||
|
||||
namespace fwcompiler
|
||||
{
|
||||
|
||||
class RoutingCompiler_bsd : public RoutingCompiler
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* prints rule in some universal format (close to that visible
|
||||
* to user in the GUI). Used for debugging purposes. This method
|
||||
* calls RoutingCompiler::debugPrintRule
|
||||
*/
|
||||
virtual std::string debugPrintRule(libfwbuilder::Rule *rule);
|
||||
|
||||
/**
|
||||
* expand address range objects in destination
|
||||
*/
|
||||
DECLARE_ROUTING_RULE_PROCESSOR(addressRangesInDst);
|
||||
|
||||
/**
|
||||
* check if we have to install default route
|
||||
*/
|
||||
DECLARE_ROUTING_RULE_PROCESSOR(FindDefaultRoute);
|
||||
|
||||
/**
|
||||
* prints single policy rule, assuming all groups have been
|
||||
* expanded, destination holds exactly one object, and this
|
||||
* object is not a group. Negation should also have been taken
|
||||
* care of before this method is called.
|
||||
*
|
||||
* This processor is not necessarily the last in the
|
||||
* conveyor, so it should push rules back to tmp_queue (for
|
||||
* example there could be progress indicator processor after
|
||||
* this one)
|
||||
*/
|
||||
class PrintRule : public RoutingRuleProcessor
|
||||
{
|
||||
bool print_once_on_top;
|
||||
std::string current_rule_label;
|
||||
|
||||
virtual std::string _printAddr(libfwbuilder::Address *o);
|
||||
|
||||
public:
|
||||
|
||||
PrintRule(const std::string &name);
|
||||
virtual bool processNext();
|
||||
|
||||
std::string RoutingRuleToString(libfwbuilder::RoutingRule *r);
|
||||
std::string _printRGtw(libfwbuilder::RoutingRule *r);
|
||||
std::string _printRItf(libfwbuilder::RoutingRule *r);
|
||||
std::string _printRDst(libfwbuilder::RoutingRule *r);
|
||||
|
||||
};
|
||||
friend class RoutingCompiler_bsd::PrintRule;
|
||||
|
||||
virtual std::string myPlatformName();
|
||||
|
||||
// These buffers are needed to collect output generated from
|
||||
// the single ECMP rules belonging to one destination,
|
||||
// because all these routes have to be activated with a single
|
||||
// ip command. So ECMP ip commands are built up gradually
|
||||
// during compilation and inserted in the shell script after
|
||||
// all rules are processed.
|
||||
|
||||
|
||||
std::map< std::string, std::string> ecmp_rules_buffer; // sortedDstId+metric-->nexthops
|
||||
std::map< std::string, std::string> ecmp_comments_buffer; // sortedDstId+metric-->rule's info for the fw script
|
||||
bool have_default_route;
|
||||
bool defined_restore_script_output;
|
||||
|
||||
public:
|
||||
|
||||
RoutingCompiler_bsd(libfwbuilder::FWObjectDatabase *_db,
|
||||
libfwbuilder::Firewall *fw, bool ipv6_policy,
|
||||
fwcompiler::OSConfigurator *_oscnf) :
|
||||
RoutingCompiler(_db, fw, ipv6_policy, _oscnf)
|
||||
{
|
||||
have_default_route = false;
|
||||
defined_restore_script_output = false;
|
||||
}
|
||||
|
||||
virtual void verifyOS();
|
||||
virtual int prolog();
|
||||
virtual void compile();
|
||||
virtual void epilog();
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
|
||||
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 "RoutingCompiler_bsd.h"
|
||||
#include "Configlet.h"
|
||||
|
||||
#include "fwbuilder/RuleElement.h"
|
||||
#include "fwbuilder/Routing.h"
|
||||
#include "fwbuilder/Network.h"
|
||||
#include "fwbuilder/FWObjectDatabase.h"
|
||||
#include "fwbuilder/RuleElement.h"
|
||||
#include "fwbuilder/Routing.h"
|
||||
#include "fwbuilder/Interface.h"
|
||||
#include "fwbuilder/IPv4.h"
|
||||
#include "fwbuilder/Firewall.h"
|
||||
#include "fwbuilder/FWOptions.h"
|
||||
#include "fwbuilder/Resources.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
using namespace libfwbuilder;
|
||||
using namespace fwcompiler;
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*-----------------------------------------------------------------------
|
||||
* Methods for printing
|
||||
*/
|
||||
string RoutingCompiler_bsd::PrintRule::_printAddr(Address *o)
|
||||
{
|
||||
ostringstream ostr;
|
||||
|
||||
if (Interface::cast(o)!=NULL)
|
||||
{
|
||||
Interface *iface = Interface::cast(o);
|
||||
if (iface->isDyn())
|
||||
ostr << "$interface_" << iface->getName() << " ";
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
const InetAddr *addr;
|
||||
const InetAddr *mask;
|
||||
addr = o->getAddressPtr();
|
||||
mask = o->getNetmaskPtr();
|
||||
|
||||
if (addr==NULL)
|
||||
{
|
||||
FWObject *obj=o;
|
||||
/*
|
||||
* check if this is object of class Address. since we want to
|
||||
* distinguish between Host, Interface and Address, and both Host and
|
||||
* Interface are inherited from Address, we can't use cast. Use isA
|
||||
* instead
|
||||
*/
|
||||
while (obj!=NULL &&
|
||||
!Host::isA(obj) &&
|
||||
!Firewall::isA(obj) &&
|
||||
!Network::isA(obj)) obj=obj->getParent();
|
||||
|
||||
compiler->abort(
|
||||
"Problem with address or netmask in the object or "
|
||||
"one of its interfaces: '" + obj->getName() + "'");
|
||||
}
|
||||
|
||||
|
||||
if (addr->isAny() && mask->isAny())
|
||||
{
|
||||
ostr << "default ";
|
||||
} else
|
||||
{
|
||||
ostr << addr->toString();
|
||||
|
||||
if (Interface::cast(o)==NULL &&
|
||||
Address::cast(o)->dimension() > 1 &&
|
||||
!mask->isHostMask())
|
||||
{
|
||||
ostr << "/" << mask->getLength();
|
||||
}
|
||||
ostr << " ";
|
||||
}
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RoutingCompiler_bsd::PrintRule::PrintRule(const std::string &name) :
|
||||
RoutingRuleProcessor(name)
|
||||
{
|
||||
print_once_on_top = true;
|
||||
}
|
||||
|
||||
|
||||
bool RoutingCompiler_bsd::PrintRule::processNext()
|
||||
{
|
||||
RoutingCompiler_bsd *bsd_comp =
|
||||
dynamic_cast<RoutingCompiler_bsd*>(compiler);
|
||||
RoutingRule *rule = getNext();
|
||||
if (rule==NULL) return false;
|
||||
|
||||
tmp_queue.push_back(rule);
|
||||
|
||||
if (print_once_on_top && !compiler->inSingleRuleCompileMode())
|
||||
{
|
||||
Configlet routing_functions(compiler->fw,
|
||||
"bsd", "routing_functions");
|
||||
|
||||
// we should delete default route if we have a new one to
|
||||
// install. IF user did not define any routes that look like
|
||||
// default (i.e. where destination is "any"), then we should
|
||||
// preserve default so that we won't leave machine with no
|
||||
// default at all.
|
||||
QString route_pattern = "";
|
||||
if (bsd_comp->have_default_route)
|
||||
{
|
||||
// If we will install default route, delete it now
|
||||
route_pattern = "'lo0'";
|
||||
} else
|
||||
{
|
||||
// do not delete default if we won't install new one
|
||||
route_pattern = "'lo0|default'";
|
||||
}
|
||||
|
||||
routing_functions.setVariable("route_filter", route_pattern);
|
||||
compiler->output << routing_functions.expand().toStdString();
|
||||
|
||||
bsd_comp->defined_restore_script_output = true;
|
||||
print_once_on_top = false;
|
||||
}
|
||||
|
||||
// TODO: convert this into virtual function RoutingCompiler::printComment()
|
||||
|
||||
string rl = rule->getLabel();
|
||||
|
||||
if (!compiler->inSingleRuleCompileMode() && rl!=current_rule_label)
|
||||
{
|
||||
compiler->output << "# " << endl;
|
||||
compiler->output << "# Rule " << rl << endl;
|
||||
//compiler->output << "# " << rule->getRuleTypeAsString() << endl;
|
||||
compiler->output << "# " << endl;
|
||||
compiler->output << "echo \"Routing rule " << rl << "\"" << endl;
|
||||
compiler->output << "# " << endl;
|
||||
}
|
||||
|
||||
if (rule->getRuleType() != RoutingRule::MultiPath )
|
||||
{
|
||||
if (!compiler->inSingleRuleCompileMode() && rl!=current_rule_label)
|
||||
{
|
||||
QStringList comment = QString::fromUtf8(
|
||||
rule->getComment().c_str()).split("\n");
|
||||
int comment_lines = 0;
|
||||
foreach (QString str, comment)
|
||||
{
|
||||
if (!str.isEmpty())
|
||||
{
|
||||
compiler->output << "# " << str.toUtf8().data() << endl;
|
||||
++comment_lines;
|
||||
}
|
||||
}
|
||||
if (comment_lines) compiler->output << "#" << endl;
|
||||
current_rule_label = rl;
|
||||
}
|
||||
|
||||
string err = rule->getStr(".error_msg");
|
||||
if (!err.empty()) compiler->output << "# " << err << endl;
|
||||
|
||||
string command_line = RoutingRuleToString(rule);
|
||||
compiler->output << command_line;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
string RoutingCompiler_bsd::PrintRule::RoutingRuleToString(RoutingRule *rule)
|
||||
{
|
||||
RuleElementRDst *dstrel = rule->getRDst();
|
||||
Address *dst = Address::cast(FWReference::getObject(dstrel->front()));
|
||||
RuleElementRItf *itfrel = rule->getRItf();
|
||||
Interface *itf = Interface::cast(FWReference::getObject(itfrel->front()));
|
||||
RuleElementRGtw *gtwrel = rule->getRGtw();
|
||||
Address *gtw = Address::cast(FWReference::getObject(gtwrel->front()));
|
||||
|
||||
if(dst==NULL) compiler->abort(rule, "Broken DST");
|
||||
|
||||
ostringstream command_line;
|
||||
|
||||
command_line << "route add ";
|
||||
|
||||
if (gtwrel->isAny() && itf != NULL) command_line << "-interface ";
|
||||
|
||||
command_line << _printRDst(rule);
|
||||
|
||||
if (gtw != NULL) command_line << _printRGtw(rule);
|
||||
if (itf != NULL) command_line << _printRItf(rule);
|
||||
|
||||
// to make generated script more readable in single rule compile mode,
|
||||
// skip the part that rolls back in case of an error
|
||||
if (!compiler->inSingleRuleCompileMode())
|
||||
{
|
||||
command_line << "|| ";
|
||||
|
||||
FWObject *opt_dummy =
|
||||
rule->getFirstByType(RoutingRuleOptions::TYPENAME);
|
||||
RoutingRuleOptions *opt =
|
||||
opt_dummy ? RoutingRuleOptions::cast(opt_dummy) : 0;
|
||||
if ( opt && opt->getBool("no_fail") )
|
||||
{
|
||||
command_line << "echo \"*** Warning: routing rule "
|
||||
<< rule->getLabel() << " failed. ignored. ***\"\n";
|
||||
} else
|
||||
{
|
||||
command_line << "route_command_error "
|
||||
<< "\"" << rule->getLabel() << "\"" << endl;;
|
||||
}
|
||||
}
|
||||
command_line << endl;
|
||||
|
||||
return command_line.str();
|
||||
}
|
||||
|
||||
string RoutingCompiler_bsd::PrintRule::_printRGtw(RoutingRule *rule)
|
||||
{
|
||||
RuleElementRGtw *gtwrel = rule->getRGtw();
|
||||
Address *gtw = Address::cast(FWReference::getObject(gtwrel->front()));
|
||||
if(gtw==NULL)
|
||||
compiler->abort(rule, "Broken GTW");
|
||||
|
||||
string gateway = _printAddr(gtw);
|
||||
|
||||
if( gateway != "default ") return gateway;
|
||||
else return "";
|
||||
}
|
||||
|
||||
string RoutingCompiler_bsd::PrintRule::_printRItf(RoutingRule *rule)
|
||||
{
|
||||
RuleElementRItf *itfrel = rule->getRItf();
|
||||
Interface *itf = Interface::cast(FWReference::getObject(itfrel->front()));
|
||||
if(itf != NULL)
|
||||
{
|
||||
IPv4 *addr = IPv4::cast(itf->getFirstByType(IPv4::TYPENAME));
|
||||
if (addr == NULL)
|
||||
{
|
||||
QString err("Can not configure static route via interface %1 "
|
||||
"because its address is unknown");
|
||||
compiler->abort(rule, err.arg(itf->getName().c_str()).toStdString());
|
||||
}
|
||||
const InetAddr* ia = addr->getAddressPtr();
|
||||
return ia->toString();
|
||||
}
|
||||
else return "";
|
||||
}
|
||||
|
||||
string RoutingCompiler_bsd::PrintRule::_printRDst(RoutingRule *rule)
|
||||
{
|
||||
RuleElementRDst *dstrel = rule->getRDst();
|
||||
Address *dst = Address::cast(FWReference::getObject(dstrel->front()));
|
||||
if(dst==NULL)
|
||||
compiler->abort(rule, "Broken DST");
|
||||
|
||||
return _printAddr(dst);
|
||||
}
|
||||
@@ -32,6 +32,8 @@ SOURCES = TableFactory.cpp \
|
||||
CompilerDriver_ipf_run.cpp \
|
||||
CompilerDriver_ipfw.cpp \
|
||||
CompilerDriver_ipfw_run.cpp \
|
||||
RoutingCompiler_bsd.cpp \
|
||||
RoutingCompiler_bsd_writers.cpp
|
||||
|
||||
HEADERS = ../../config.h \
|
||||
OSData.h \
|
||||
@@ -51,6 +53,7 @@ HEADERS = ../../config.h \
|
||||
CompilerDriver_pf.h \
|
||||
CompilerDriver_ipf.h \
|
||||
CompilerDriver_ipfw.h \
|
||||
RoutingCompiler_bsd.h
|
||||
|
||||
macx:LIBS += $$LIBS_FWCOMPILER
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
## -*- mode: shell-script; -*-
|
||||
##
|
||||
## To be able to make changes to the part of configuration created
|
||||
## from this configlet you need to copy this file to the directory
|
||||
## fwbuilder/configlets/bsd/ in your home directory and modify it.
|
||||
## Double "##" comments are removed during processing but single "#"
|
||||
## comments are be retained and appear in the generated script. Empty
|
||||
## lines are removed as well.
|
||||
##
|
||||
## Configlets support simple macro language with these constructs:
|
||||
## {{$var}} is variable expansion
|
||||
## {{if var}} is conditional operator.
|
||||
##
|
||||
|
||||
# ============== ROUTING RULES ==============
|
||||
|
||||
TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$"
|
||||
TMPFILENAME="$TMPDIRNAME/.fwbuilder.out"
|
||||
(umask 077 && mkdir $TMPDIRNAME) || exit 1
|
||||
|
||||
#
|
||||
# This function stops stdout redirection
|
||||
# and sends previously saved output to terminal
|
||||
restore_script_output()
|
||||
{
|
||||
exec 1>&3 2>&1
|
||||
cat $TMPFILENAME
|
||||
rm -rf $TMPDIRNAME
|
||||
}
|
||||
|
||||
# if any routing rule fails we do our best to prevent freezing the firewall
|
||||
route_command_error()
|
||||
{
|
||||
echo "Error: Routing rule $1 couldn't be activated"
|
||||
echo "Recovering previous routing configuration..."
|
||||
# delete current routing rules
|
||||
route -n show -inet | grep S | grep -Ev 'lo0' | \
|
||||
while read route gw rest; do route delete $route $gw; done
|
||||
# restore old routing rules
|
||||
(IFS="
|
||||
"; for route_cmd in $oldRoutes; do (IFS=' '; $route_cmd); done)
|
||||
echo "...done"
|
||||
restore_script_output
|
||||
epilog_commands
|
||||
exit 1
|
||||
}
|
||||
|
||||
# redirect output to prevent ssh session from stalling
|
||||
exec 3>&1
|
||||
exec 1> $TMPFILENAME
|
||||
exec 2>&1
|
||||
|
||||
oldRoutes=$(route -n show -inet | awk '{printf "route add %s %s\n",$1,$2;}')
|
||||
|
||||
echo "Deleting routing rules previously set by user space processes..."
|
||||
route -n show -inet | grep S | grep -Ev {{route_filter}} | \
|
||||
while read route gw rest; do route delete $route $gw; done
|
||||
|
||||
echo "Activating routing rules..."
|
||||
|
||||
@@ -67,4 +67,6 @@ $PFCTL -F states
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
|
||||
{{$routing_script}}
|
||||
|
||||
epilog_commands
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_subinterfaces>True</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>True</supports_cluster>
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_subinterfaces>True</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>True</supports_cluster>
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
</options>
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>False</supports_routing>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>False</supports_metric>
|
||||
<supports_routing_itf>False</supports_routing_itf>
|
||||
<supports_subinterfaces>True</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>True</supports_cluster>
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
</options>
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>False</supports_routing>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
</options>
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_subinterfaces>True</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>True</supports_cluster>
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>False</supports_routing>
|
||||
<supports_metric>False</supports_metric>
|
||||
<supports_routing_itf>False</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
</options>
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>False</supports_routing>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>False</supports_metric>
|
||||
<supports_routing_itf>False</supports_routing_itf>
|
||||
<supports_subinterfaces>True</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>True</supports_cluster>
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_subinterfaces>True</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>True</supports_cluster>
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
</options>
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>False</supports_routing>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_subinterfaces>True</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>True</supports_cluster>
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_subinterfaces>False</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>False</supports_cluster>
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_subinterfaces>True</supports_subinterfaces>
|
||||
<supports_advanced_interface_options>True</supports_advanced_interface_options>
|
||||
<supports_cluster>True</supports_cluster>
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>False</supports_routing>
|
||||
<supports_metric>False</supports_metric>
|
||||
<supports_routing_itf>False</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>True</supports_routing>
|
||||
<supports_metric>True</supports_metric>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
<capabilities>
|
||||
<supports_routing>False</supports_routing>
|
||||
<supports_metric>False</supports_metric>
|
||||
<supports_routing_itf>False</supports_routing_itf>
|
||||
<supports_advanced_interface_options>False</supports_advanced_interface_options>
|
||||
</capabilities>
|
||||
|
||||
|
||||
@@ -235,7 +235,6 @@ nameif %in %il security%sl
|
||||
<actions_in_nat>False</actions_in_nat>
|
||||
<supports_time>False</supports_time>
|
||||
<supports_accounting>False</supports_accounting>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<security_levels>True</security_levels>
|
||||
<network_zones>True</network_zones>
|
||||
<unprotected_interfaces>False</unprotected_interfaces>
|
||||
|
||||
@@ -111,7 +111,6 @@ interface %in
|
||||
<actions_in_nat>False</actions_in_nat>
|
||||
<supports_time>False</supports_time>
|
||||
<supports_accounting>False</supports_accounting>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<security_levels>False</security_levels>
|
||||
<network_zones>False</network_zones>
|
||||
<unprotected_interfaces>True</unprotected_interfaces>
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
<actions_in_nat>False</actions_in_nat>
|
||||
<supports_time>False</supports_time>
|
||||
<supports_accounting>True</supports_accounting>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<security_levels>False</security_levels>
|
||||
<network_zones>False</network_zones>
|
||||
<unprotected_interfaces>False</unprotected_interfaces>
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
<actions_in_nat>False</actions_in_nat>
|
||||
<supports_time>False</supports_time>
|
||||
<supports_accounting>True</supports_accounting>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<security_levels>False</security_levels>
|
||||
<network_zones>False</network_zones>
|
||||
<unprotected_interfaces>False</unprotected_interfaces>
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
<actions_in_nat>True</actions_in_nat>
|
||||
<supports_time>True</supports_time>
|
||||
<supports_accounting>True</supports_accounting>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<security_levels>False</security_levels>
|
||||
<network_zones>False</network_zones>
|
||||
<unprotected_interfaces>False</unprotected_interfaces>
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
<actions_in_nat>True</actions_in_nat>
|
||||
<supports_time>False</supports_time>
|
||||
<supports_accounting>True</supports_accounting>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<security_levels>False</security_levels>
|
||||
<network_zones>False</network_zones>
|
||||
<unprotected_interfaces>True</unprotected_interfaces>
|
||||
|
||||
@@ -641,7 +641,6 @@
|
||||
<actions_in_nat>False</actions_in_nat>
|
||||
<supports_time>False</supports_time>
|
||||
<supports_accounting>False</supports_accounting>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<security_levels>True</security_levels>
|
||||
<network_zones>True</network_zones>
|
||||
<unprotected_interfaces>True</unprotected_interfaces>
|
||||
|
||||
@@ -48,7 +48,6 @@ interface %in
|
||||
<actions_in_nat>False</actions_in_nat>
|
||||
<supports_time>False</supports_time>
|
||||
<supports_accounting>False</supports_accounting>
|
||||
<supports_routing_itf>True</supports_routing_itf>
|
||||
<security_levels>False</security_levels>
|
||||
<network_zones>False</network_zones>
|
||||
<unprotected_interfaces>True</unprotected_interfaces>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
<actions_in_nat>False</actions_in_nat>
|
||||
<supports_time>False</supports_time>
|
||||
<supports_accounting>False</supports_accounting>
|
||||
<supports_routing_itf>False</supports_routing_itf>
|
||||
<security_levels>False</security_levels>
|
||||
<network_zones>False</network_zones>
|
||||
<unprotected_interfaces>False</unprotected_interfaces>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user