/* * this processor eliminates duplicate atomic routing rules in one routing table */ bool RoutingCompiler_openbsd::eliminateDuplicateRules::processNext() { RoutingCompiler_openbsd *bsd_comp = dynamic_cast<RoutingCompiler_openbsd*>(compiler); RoutingRule *rule = getNext(); if (rule==NULL) return false; if (rule->isFallback() || rule->isHidden()) { tmp_queue.push_back(rule); return true; } assert (bsd_comp->printRule!=NULL); string thisRule = bsd_comp->printRule->RoutingRuleToString(rule, false); map<string, string>::iterator rules_it = rules_seen_so_far.find(thisRule); if (rules_it != rules_seen_so_far.end()) { QString msg = QObject::tr("Two of the routing commands created from the gui " "routing rules %1 and %2 " "are identical, skipping the second. " "Revise them to avoid this warning"); compiler->warning( rule, msg.arg(rules_it->second.c_str()).arg(rule->getLabel().c_str()).toStdString()); return true; } tmp_queue.push_back(rule); rules_seen_so_far[thisRule] = rule->getLabel(); return true; }
string RoutingCompiler::debugPrintRule(Rule *r) { RoutingRule *rule = RoutingRule::cast(r); RuleElementRDst *dstrel = rule->getRDst(); RuleElementRItf *itfrel = rule->getRItf(); RuleElementRGtw *gtwrel = rule->getRGtw(); ostringstream str; // str << setw(70) << setfill('-') << "-"; string dst, itf, gtw; FWObject *obj = FWReference::getObject(itfrel->front()); itf = (obj) ? obj->getName() : "NULL"; obj = FWReference::getObject(gtwrel->front()); gtw = (obj) ? obj->getName() : "NULL"; int no = 0; FWObject::iterator i1 = dstrel->begin(); while ( i1!=dstrel->end()) { str << endl; dst = " "; if (i1 != dstrel->end()) { FWObject *o = FWReference::getObject(*i1); dst = (o) ? o->getName() : "NULL"; } int w = 0; if (no==0) { str << rule->getLabel(); w = rule->getLabel().length(); } str << setw(10-w) << setfill(' ') << " "; str << setw(18) << setfill(' ') << dst.c_str() << " "; str << setw(18) << setfill(' ') << itf.c_str() << " "; str << setw(18) << setfill(' ') << gtw.c_str() << " "; str << setw(18) << setfill(' ') << " "; ++no; if ( i1 != dstrel->end() ) ++i1; } return str.str(); }
/* * 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_iosacl::PrintRule::processNext() { RoutingRule *rule = getNext(); if (rule == nullptr) return false; tmp_queue.push_back(rule); string rl = rule->getLabel(); string comm = rule->getComment(); string::size_type c1, c2; c1 = 0; if (!compiler->inSingleRuleCompileMode() && rl != current_rule_label) { compiler->output << "! " << endl; compiler->output << "! Rule " << rl << endl; compiler->output << "! " << endl; } // string err = rule->getCompilerMessage(); // if (!err.empty()) compiler->output << "# " << err << endl; if( rule->getRuleType() != RoutingRule::MultiPath ) { if (!compiler->inSingleRuleCompileMode() && rl != current_rule_label) { while ( (c2 = comm.find('\n',c1)) != string::npos ) { compiler->output << "! " << comm.substr(c1,c2-c1) << endl; c1 = c2 + 1; } compiler->output << "! " << comm.substr(c1) << endl; compiler->output << "! " << endl; string err = compiler->getErrorsForRule(rule, "! "); if (!err.empty()) compiler->output << err << endl; current_rule_label = rl; } string command_line = RoutingRuleToString(rule); compiler->output << command_line; } else { string err = compiler->getErrorsForRule(rule, "! "); if (!err.empty()) compiler->output << err << endl; compiler->abort(rule, "MultiPath routing not supported by platform"); } return true; }
/* * this processor eliminates duplicate routing rules, generated from the same * rule in the GUI */ bool RoutingCompiler_openbsd::optimize3::processNext() { RoutingCompiler_openbsd *bsd_comp = dynamic_cast<RoutingCompiler_openbsd*>(compiler); RoutingRule *rule = getNext(); if (rule==NULL) return false; if (rule->isFallback() || rule->isHidden()) { tmp_queue.push_back(rule); return true; } assert (bsd_comp->printRule!=NULL); string thisRule = rule->getLabel() + " " + bsd_comp->printRule->RoutingRuleToString(rule, false); if (rules_seen_so_far.count(thisRule)!=0) return true; tmp_queue.push_back(rule); rules_seen_so_far[thisRule] = true; return true; }
bool RoutingCompiler::competingRules::processNext() { RoutingRule *rule = getNext(); if (rule==NULL) return false; RuleElementRItf *itfrel = rule->getRItf(); FWObject *itf = FWReference::cast(itfrel->front())->getPointer(); RuleElementRGtw *gtwrel = rule->getRGtw(); FWObject *gtw = FWReference::cast(gtwrel->front())->getPointer(); string metric = rule->getMetricAsString(); string label = rule->getSortedDstIds(); ostringstream ostr; ostr << gtw->getId() << "_" << itf->getId(); string combiId = ostr.str(); if( label == "") compiler->abort( rule, "Place 'createSortedDstIdsLabel()' before 'competingRules()' " "in the rule processor chain"); dest_it = rules_seen_so_far.find(label); if( dest_it != rules_seen_so_far.end()) { // a rule with the same destination was already seen ///std::cout << "NO NEW DEST" << std::endl; gtwitf_it = dest_it->second.find(combiId); if( gtwitf_it != dest_it->second.end() ) { // ... this gateway and interface combination were already // seen for this destination ///std::cout << "NO NEW GTWITF" << std::endl; if( gtwitf_it->second.first == metric) { // ... and same metric => rule already exists, skip ///std::cout << "SAME METRIC" << std::endl; string msg; msg = "Routing rules " + gtwitf_it->second.second + " and " + rule->getLabel() + " are identical, skipping the second one. " + "Delete one of them to avoid this warning"; compiler->warning(rule, msg.c_str()); } else { // ... but different metric => what metric should I use? => abort ///std::cout << "DIFFERENT METRIC" << std::endl; string msg; msg = "Routing rules " + gtwitf_it->second.second + " and " + rule->getLabel() + " are identical except for the metric, " + "please delete one of them"; compiler->abort(rule, msg.c_str()); } } else { // ... this gateway and interface combination is new for // this destination ///std::cout << "NEW GTWITF" << std::endl;/// 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 // ... but has the same metric => what route should I // use for this destination? => abort string msg; msg = "Routing rules " + gtwitf_it->second.second + " and " + rule->getLabel() + " have the same destination and same metric," "but different gateway and interface combination. " "Set the metrics to different values or " "enable ECMP (Equal Cost MultiPath) routing"; compiler->abort( msg.c_str() ); } 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()); } } else { // this destination is new //std::cout << "NEW DEST" << std::endl; /// //ruleinfo tmpRuleInfo = { gtw->getStr("id") + itf->getStr("id"), metric, rule->getLabel()}; //rules_seen_so_far[label] = tmpRuleInfo; map< string, pair< string, string> > gtw_itf_tmp; gtw_itf_tmp[combiId] = pair< string, string>( metric, rule->getLabel()); rules_seen_so_far[label] = gtw_itf_tmp; tmp_queue.push_back(rule); } return true; }
bool RoutingCompiler_openbsd::PrintRule::processNext() { RoutingCompiler_openbsd *bsd_comp = dynamic_cast<RoutingCompiler_openbsd*>(compiler); slurp(); if (tmp_queue.size()==0) return false; if (!compiler->inSingleRuleCompileMode()) { Configlet routing_functions(compiler->fw, 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 // 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; } for (deque<Rule*>::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k) { RoutingRule *rule = RoutingRule::cast( *k ); 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; string err = compiler->getErrorsForRule(rule, "# "); if (!err.empty()) compiler->output << err << endl; current_rule_label = rl; } // string err = rule->getCompilerMessage(); // if (!err.empty()) compiler->output << "# " << err << endl; string command_line = RoutingRuleToString(rule); compiler->output << command_line; } }