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(); }
string RoutingCompiler_cisco::PrintRule::_printRItf(RoutingRule *rule) { FWObject *ref; RuleElementRItf *itfrel = rule->getRItf(); ref = itfrel->front(); Interface *itf = Interface::cast(FWReference::cast(ref)->getPointer()); if (itf != NULL) return itf->getLabel() + " "; else return ""; }
string RoutingCompiler_iosacl::PrintRule::_printRItf(RoutingRule *rule) { RuleElementRItf *itfrel = rule->getRItf(); if (!itfrel->isAny()) { Interface *itf = Interface::cast(FWObjectReference::getObject(itfrel->front())); if (itf != nullptr) return itf->getName() + " "; } return ""; }
bool RoutingCompiler::rItfChildOfFw::processNext() { RoutingRule *rule=getNext(); if (rule==NULL) return false; tmp_queue.push_back(rule); RuleElementRItf *itfrel = rule->getRItf(); if (itfrel->isAny()) return true; FWObject *o = FWReference::cast(itfrel->front())->getPointer(); // the interface is not a child of the firewall. Could be // cluster interface though. In that case make sure the // firewall is a member of that cluster. Interface *iface = Interface::cast(o); if (iface) { FWObject *parent = Host::getParentHost(iface); //FWObject *parent = iface->getParentHost(); if (parent->getId() == compiler->fw->getId()) return true; Cluster *cluster = Cluster::cast(parent); if (cluster) { list<Firewall*> members; cluster->getMembersList(members); list<Firewall*>::iterator it; for (it=members.begin(); it!=members.end(); ++it) { if ((*it)->getId() == compiler->fw->getId()) return true; } } } string msg; msg = "Object \"" + o->getName() + "\" used as interface in the routing rule " + rule->getLabel() + " is not a child of the firewall the rule belongs to"; compiler->abort(rule, msg.c_str()); // even though we call abort() here, it does not actually stop the // program if it runs in the test mode. 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; }