From ceb6fc88654670fd41fa72df64d8d95b2efc3ca3 Mon Sep 17 00:00:00 2001 From: Vadim Kurland Date: Fri, 4 Feb 2011 16:32:08 -0800 Subject: [PATCH] fixes #2031 FreeBSD - firewall script command to delete existing routes fails --- src/pflib/RoutingCompiler_freebsd_writers.cpp | 1 + src/pflib/RoutingCompiler_openbsd.h | 3 +- src/pflib/RoutingCompiler_openbsd_writers.cpp | 83 +++---- src/res/configlets/freebsd/routing_functions | 59 +++++ .../{bsd => openbsd}/routing_functions | 7 +- test/pf/objects-for-regression-tests.fwb | 207 +++++++++++++++++- 6 files changed, 312 insertions(+), 48 deletions(-) create mode 100644 src/res/configlets/freebsd/routing_functions rename src/res/configlets/{bsd => openbsd}/routing_functions (89%) diff --git a/src/pflib/RoutingCompiler_freebsd_writers.cpp b/src/pflib/RoutingCompiler_freebsd_writers.cpp index 73446ac5e..4029c8584 100644 --- a/src/pflib/RoutingCompiler_freebsd_writers.cpp +++ b/src/pflib/RoutingCompiler_freebsd_writers.cpp @@ -69,6 +69,7 @@ bool RoutingCompiler_freebsd::PrintRule::processNext() FWOptions* options = compiler->fw->getOptionsObject(); if (options->getBool("generate_rc_conf_file")) { + slurp(); if (tmp_queue.size()==0) return false; diff --git a/src/pflib/RoutingCompiler_openbsd.h b/src/pflib/RoutingCompiler_openbsd.h index 84bea7d46..59208aff7 100644 --- a/src/pflib/RoutingCompiler_openbsd.h +++ b/src/pflib/RoutingCompiler_openbsd.h @@ -77,9 +77,8 @@ namespace fwcompiler class PrintRule : public RoutingRuleProcessor { protected: - bool print_once_on_top; std::string current_rule_label; - + virtual std::string _printAddr(libfwbuilder::Address *o); public: diff --git a/src/pflib/RoutingCompiler_openbsd_writers.cpp b/src/pflib/RoutingCompiler_openbsd_writers.cpp index 490dea53a..da10d51a7 100644 --- a/src/pflib/RoutingCompiler_openbsd_writers.cpp +++ b/src/pflib/RoutingCompiler_openbsd_writers.cpp @@ -116,7 +116,6 @@ string RoutingCompiler_openbsd::PrintRule::_printAddr(Address *o) RoutingCompiler_openbsd::PrintRule::PrintRule(const std::string &name) : RoutingRuleProcessor(name) { - print_once_on_top = true; } @@ -124,15 +123,16 @@ bool RoutingCompiler_openbsd::PrintRule::processNext() { RoutingCompiler_openbsd *bsd_comp = dynamic_cast(compiler); - RoutingRule *rule = getNext(); - if (rule==NULL) return false; - tmp_queue.push_back(rule); - - if (print_once_on_top && !compiler->inSingleRuleCompileMode()) + slurp(); + if (tmp_queue.size()==0) return false; + + + if (!compiler->inSingleRuleCompileMode()) { Configlet routing_functions(compiler->fw, - "bsd", "routing_functions"); + compiler->fw->getStr("host_OS"), + "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 @@ -154,48 +154,51 @@ bool RoutingCompiler_openbsd::PrintRule::processNext() 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) + for (deque::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { - 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; - } + RoutingRule *rule = RoutingRule::cast( *k ); + + string rl = rule->getLabel(); - 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; + 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; } - - string err = rule->getStr(".error_msg"); - if (!err.empty()) compiler->output << "# " << err << endl; - - string command_line = RoutingRuleToString(rule); - compiler->output << command_line; + 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; } diff --git a/src/res/configlets/freebsd/routing_functions b/src/res/configlets/freebsd/routing_functions new file mode 100644 index 000000000..e5acf1e3f --- /dev/null +++ b/src/res/configlets/freebsd/routing_functions @@ -0,0 +1,59 @@ +## -*- 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=`mktemp -d /tmp/.fwbuilder.XXXXXXXXXX` || exit 1 +TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" + +# +# 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 + netstat -rn -f inet | awk '$3 ~ /S/ && $NF !~ /lo0/ { print $0;}' | \ + 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=$(netstat -rn -f inet | awk '/^$|Destination|Routing tables|Internet:/ {next;} {printf "route add %s %s\n",$1,$2;}') + +echo "Deleting routing rules previously set by user space processes..." +netstat -rn -f inet | awk '$3 ~ /S/ { print $0;}' | grep -Ev {{$route_filter}} | \ + while read route gw rest; do route delete $route $gw; done + +echo "Activating routing rules..." + diff --git a/src/res/configlets/bsd/routing_functions b/src/res/configlets/openbsd/routing_functions similarity index 89% rename from src/res/configlets/bsd/routing_functions rename to src/res/configlets/openbsd/routing_functions index 868bdf4f1..3427f2bea 100644 --- a/src/res/configlets/bsd/routing_functions +++ b/src/res/configlets/openbsd/routing_functions @@ -14,9 +14,8 @@ # ============== ROUTING RULES ============== -TMPDIRNAME="/tmp/.fwbuilder.tempdir.$$" +TMPDIRNAME=`mktemp -d /tmp/.fwbuilder.XXXXXXXXXX` || exit 1 TMPFILENAME="$TMPDIRNAME/.fwbuilder.out" -(umask 077 && mkdir $TMPDIRNAME) || exit 1 # # This function stops stdout redirection @@ -34,7 +33,7 @@ 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' | \ + route -n show -inet | awk '$3 ~ /S/ && $NF !~ /lo0/ { print $0;}' | \ while read route gw rest; do route delete $route $gw; done # restore old routing rules (IFS=" @@ -53,7 +52,7 @@ 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}} | \ +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..." diff --git a/test/pf/objects-for-regression-tests.fwb b/test/pf/objects-for-regression-tests.fwb index c4f08e72a..53a988aee 100644 --- a/test/pf/objects-for-regression-tests.fwb +++ b/test/pf/objects-for-regression-tests.fwb @@ -1,6 +1,6 @@ - + @@ -20194,7 +20194,7 @@ - + @@ -20298,6 +20298,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +