rtmodule.cc

Go to the documentation of this file.
00001 // -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- 
00002 
00003 /*
00004  * Copyright (C) 2000 by the University of Southern California
00005  * $Id: rtmodule.cc,v 1.16 2005/08/25 18:58:12 johnh Exp $
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  *
00020  *
00021  * The copyright of this module includes the following
00022  * linking-with-specific-other-licenses addition:
00023  *
00024  * In addition, as a special exception, the copyright holders of
00025  * this module give you permission to combine (via static or
00026  * dynamic linking) this module with free software programs or
00027  * libraries that are released under the GNU LGPL and with code
00028  * included in the standard release of ns-2 under the Apache 2.0
00029  * license or under otherwise-compatible licenses with advertising
00030  * requirements (or modified versions of such code, with unchanged
00031  * license).  You may copy and distribute such a system following the
00032  * terms of the GNU GPL for this module and the licenses of the
00033  * other code concerned, provided that you include the source code of
00034  * that other code when and as the GNU GPL requires distribution of
00035  * source code.
00036  *
00037  * Note that people who make modified versions of this module
00038  * are not obligated to grant this special exception for their
00039  * modified versions; it is their choice whether to do so.  The GNU
00040  * General Public License gives permission to release a modified
00041  * version without this exception; this exception also makes it
00042  * possible to release a modified version which carries forward this
00043  * exception.
00044  *
00045  */
00046 
00047 // $Header: /nfs/jade/vint/CVSROOT/ns-2/routing/rtmodule.cc,v 1.16 2005/08/25 18:58:12 johnh Exp $
00048 
00049 
00050 #include "rtmodule.h"
00051 #include <assert.h>
00052 #include "node.h"
00053 
00054 
00055 static class RoutingModuleClass : public TclClass {
00056 public:
00057     RoutingModuleClass() : TclClass("RtModule") {}
00058     TclObject* create(int, const char*const*) {
00059         return (new RoutingModule);
00060     }
00061 } class_routing_module;
00062 
00063 static class BaseRoutingModuleClass : public TclClass {
00064 public:
00065     BaseRoutingModuleClass() : TclClass("RtModule/Base") {}
00066     TclObject* create(int, const char*const*) {
00067         return (new BaseRoutingModule);
00068     }
00069 } class_base_routing_module;
00070 
00071 static class McastRoutingModuleClass : public TclClass {
00072 public:
00073     McastRoutingModuleClass() : TclClass("RtModule/Mcast") {}
00074     TclObject* create(int, const char*const*) {
00075         return (new McastRoutingModule);
00076     }
00077 } class_mcast_routing_module;
00078 
00079 static class HierRoutingModuleClass : public TclClass {
00080 public:
00081     HierRoutingModuleClass() : TclClass("RtModule/Hier") {}
00082     TclObject* create(int, const char*const*) {
00083         return (new HierRoutingModule);
00084     }
00085 } class_hier_routing_module;
00086 
00087 
00088 static class ManualRoutingModuleClass : public TclClass {
00089 public:
00090     ManualRoutingModuleClass() : TclClass("RtModule/Manual") {}
00091     TclObject* create(int, const char*const*) {
00092         return (new ManualRoutingModule);
00093     }
00094 } class_manual_routing_module;
00095 
00096 static class SourceRoutingModuleClass : public TclClass {
00097 public:
00098         SourceRoutingModuleClass() : TclClass("RtModule/Source") {}
00099         TclObject* create(int, const char*const*) {
00100                 return (new SourceRoutingModule);
00101         }
00102 } class_source_routing_module;
00103 
00104 static class QSRoutingModuleClass : public TclClass {
00105 public:
00106         QSRoutingModuleClass() : TclClass("RtModule/QS") {}
00107         TclObject* create(int, const char*const*) {
00108                 return (new QSRoutingModule);
00109         }
00110 } class_qs_routing_module;
00111 
00112 static class VcRoutingModuleClass : public TclClass {
00113 public:
00114     VcRoutingModuleClass() : TclClass("RtModule/VC") {}
00115     TclObject* create(int, const char*const*) {
00116         return (new VcRoutingModule);
00117     }
00118 } class_vc_routing_module;
00119 
00120 
00121 #ifdef HAVE_STL
00122 static class PgmRoutingModuleClass : public TclClass {
00123 public:
00124         PgmRoutingModuleClass() : TclClass("RtModule/PGM") {}
00125         TclObject* create(int, const char*const*) {
00126                 return (new PgmRoutingModule);
00127         }
00128 } class_pgm_routing_module;
00129 #endif //STL
00130 
00131 // LMS
00132 static class LmsRoutingModuleClass : public TclClass {
00133 public:
00134         LmsRoutingModuleClass() : TclClass("RtModule/LMS") {}
00135         TclObject* create(int, const char*const*) {
00136                 return (new LmsRoutingModule);
00137         }
00138 } class_lms_routing_module;
00139 
00140 RoutingModule::RoutingModule() : 
00141     next_rtm_(NULL), n_(NULL), classifier_(NULL) {
00142     bind("classifier_", (TclObject**)&classifier_);
00143 }
00144 
00145 int RoutingModule::command(int argc, const char*const* argv)
00146 {
00147     Tcl& tcl = Tcl::instance();
00148     if (argc == 2) {
00149         if (strcmp(argv[1], "node") == 0) {
00150             assert(n_ != NULL);
00151             tcl.resultf("%s", n_->name());
00152             return TCL_OK;
00153         } else if (strcmp(argv[1], "module-name") == 0) {
00154             if (module_name() != NULL)
00155                 tcl.resultf("%s", module_name());
00156             else 
00157                 tcl.result("");
00158             return TCL_OK;
00159         }
00160         
00161     } else if (argc == 3) {
00162         if (strcmp(argv[1], "attach-node") == 0) {
00163             n_ = (Node*)TclObject::lookup(argv[2]);
00164             if (n_ == NULL) {
00165                 tcl.add_errorf("Wrong object name %s",argv[2]);
00166                 return TCL_ERROR;
00167             }
00168             return TCL_OK;
00169         }
00170         //if (strcmp(argv[1], "attach-classifier") == 0) {
00171         //classifier_ = (Classifier*)(TclObject::lookup(argv[2]));
00172         //if (classifier_ == NULL) {
00173         //tcl.add_errorf("Wrong object name %s",argv[2]);
00174         //return TCL_ERROR;
00175         //}
00176         //return TCL_OK;
00177         //}
00178     }
00179     return TclObject::command(argc, argv);
00180 }
00181 
00182 int BaseRoutingModule::command(int argc, const char*const* argv) {
00183     Tcl& tcl = Tcl::instance();
00184     if (argc == 3) {
00185         if (strcmp(argv[1] , "route-notify") == 0) {
00186             Node *node = (Node *)(TclObject::lookup(argv[2]));
00187             if (node == NULL) {
00188                 tcl.add_errorf("Invalid node object %s", argv[2]);
00189                 return TCL_ERROR;
00190             }
00191             if (node != n_) {
00192                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00193                 return TCL_ERROR;
00194             }
00195             n_->route_notify(this);
00196             return TCL_OK;
00197         }
00198         if (strcmp(argv[1] , "unreg-route-notify") == 0) {
00199             Node *node = (Node *)(TclObject::lookup(argv[2]));
00200             if (node == NULL) {
00201                 tcl.add_errorf("Invalid node object %s", argv[2]);
00202                 return TCL_ERROR;
00203             }
00204             if (node != n_) {
00205                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00206                 return TCL_ERROR;
00207             }
00208             n_->unreg_route_notify(this);
00209             return TCL_OK;
00210         }
00211     }
00212     return (RoutingModule::command(argc, argv));
00213 }
00214 
00215 int SourceRoutingModule::command(int argc, const char*const* argv) {
00216     Tcl& tcl = Tcl::instance();
00217     if (argc == 3) {
00218         if (strcmp(argv[1] , "route-notify") == 0) {
00219             Node *node = (Node *)(TclObject::lookup(argv[2]));
00220             if (node == NULL) {
00221                 tcl.add_errorf("Invalid node object %s", argv[2]);
00222                 return TCL_ERROR;
00223             }
00224             if (node != n_) {
00225                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00226                 return TCL_ERROR;
00227             }
00228             n_->route_notify(this);
00229             return TCL_OK;
00230         }
00231         if (strcmp(argv[1] , "unreg-route-notify") == 0) {
00232             Node *node = (Node *)(TclObject::lookup(argv[2]));
00233             if (node == NULL) {
00234                 tcl.add_errorf("Invalid node object %s", argv[2]);
00235                 return TCL_ERROR;
00236             }
00237             if (node != n_) {
00238                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00239                 return TCL_ERROR;
00240             }
00241             n_->unreg_route_notify(this);
00242             return TCL_OK;
00243         }
00244     }
00245     return (RoutingModule::command(argc, argv));
00246 }
00247 
00248 int QSRoutingModule::command(int argc, const char*const* argv) {
00249     Tcl& tcl = Tcl::instance();
00250     if (argc == 3) {
00251         if (strcmp(argv[1] , "route-notify") == 0) {
00252             Node *node = (Node *)(TclObject::lookup(argv[2]));
00253             if (node == NULL) {
00254                 tcl.add_errorf("Invalid node object %s", argv[2]);
00255                 return TCL_ERROR;
00256             }
00257             if (node != n_) {
00258                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00259                 return TCL_ERROR;
00260             }
00261             n_->route_notify(this);
00262             return TCL_OK;
00263         }
00264         if (strcmp(argv[1] , "unreg-route-notify") == 0) {
00265             Node *node = (Node *)(TclObject::lookup(argv[2]));
00266             if (node == NULL) {
00267                 tcl.add_errorf("Invalid node object %s", argv[2]);
00268                 return TCL_ERROR;
00269             }
00270             if (node != n_) {
00271                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00272                 return TCL_ERROR;
00273             }
00274             n_->unreg_route_notify(this);
00275             return TCL_OK;
00276         }
00277     }
00278     return (RoutingModule::command(argc, argv));
00279 }
00280 
00281 int McastRoutingModule::command(int argc, const char*const* argv) {
00282     Tcl& tcl = Tcl::instance();
00283     if (argc == 3) {
00284         if (strcmp(argv[1] , "route-notify") == 0) {
00285             Node *node = (Node *)(TclObject::lookup(argv[2]));
00286             if (node == NULL) {
00287                 tcl.add_errorf("Invalid node object %s", argv[2]);
00288                 return TCL_ERROR;
00289             }
00290             if (node != n_) {
00291                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00292                 return TCL_ERROR;
00293             }
00294             n_->route_notify(this);
00295             return TCL_OK;
00296         }
00297         if (strcmp(argv[1] , "unreg-route-notify") == 0) {
00298             Node *node = (Node *)(TclObject::lookup(argv[2]));
00299             if (node == NULL) {
00300                 tcl.add_errorf("Invalid node object %s", argv[2]);
00301                 return TCL_ERROR;
00302             }
00303             if (node != n_) {
00304                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00305                 return TCL_ERROR;
00306             }
00307             n_->unreg_route_notify(this);
00308             return TCL_OK;
00309         }
00310     }
00311     return (RoutingModule::command(argc, argv));
00312 }
00313 
00314 int HierRoutingModule::command(int argc, const char*const* argv) {
00315     Tcl& tcl = Tcl::instance();
00316     if (argc == 3) {
00317         //if (strcmp(argv[1], "attach-classifier") == 0) {
00318         //classifier_ = (HierClassifier*)(TclObject::lookup(argv[2]));
00319         //if (classifier_ == NULL) {
00320         //tcl.add_errorf("Wrong object name %s",argv[2]);
00321         //return TCL_ERROR;
00322         //}
00323         //return TCL_OK;
00324         //}
00325         if (strcmp(argv[1] , "route-notify") == 0) {
00326             Node *node = (Node *)(TclObject::lookup(argv[2]));
00327             if (node == NULL) {
00328                 tcl.add_errorf("Invalid node object %s", argv[2]);
00329                 return TCL_ERROR;
00330             }
00331             if (node != n_) {
00332                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00333                 return TCL_ERROR;
00334             }
00335             n_->route_notify(this);
00336             return TCL_OK;
00337         }
00338         if (strcmp(argv[1] , "unreg-route-notify") == 0) {
00339             Node *node = (Node *)(TclObject::lookup(argv[2]));
00340             if (node == NULL) {
00341                 tcl.add_errorf("Invalid node object %s", argv[2]);
00342                 return TCL_ERROR;
00343             }
00344             if (node != n_) {
00345                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00346                 return TCL_ERROR;
00347             }
00348             n_->unreg_route_notify(this);
00349             return TCL_OK;
00350         }
00351     }
00352     return (RoutingModule::command(argc, argv));
00353 }
00354 
00355 
00356 int ManualRoutingModule::command(int argc, const char*const* argv) {
00357     Tcl& tcl = Tcl::instance();
00358     if (argc == 3) {
00359         if (strcmp(argv[1] , "route-notify") == 0) {
00360             Node *node = (Node *)(TclObject::lookup(argv[2]));
00361             if (node == NULL) {
00362                 tcl.add_errorf("Invalid node object %s", argv[2]);
00363                 return TCL_ERROR;
00364             }
00365             if (node != n_) {
00366                 tcl.add_errorf("Node object %s different from node_", argv[2]);
00367                 return TCL_ERROR;
00368             }
00369             n_->route_notify(this);
00370             return TCL_OK;
00371         }
00372         if (strcmp(argv[1] , "unreg-route-notify") == 0) {
00373             Node *node = (Node *)(TclObject::lookup(argv[2]));
00374             if (node == NULL) {
00375                 tcl.add_errorf("Invalid node object %s", argv[2]);
00376                 return TCL_ERROR;
00377             }
00378             if (node != n_) {
00379                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00380                 return TCL_ERROR;
00381             }
00382             n_->unreg_route_notify(this);
00383             return TCL_OK;
00384         }
00385     }
00386     return (RoutingModule::command(argc, argv));
00387 }
00388 
00389 void VcRoutingModule::add_route(char *, NsObject *) { }
00390     
00391 
00392 int VcRoutingModule::command(int argc, const char*const* argv) {
00393     Tcl& tcl = Tcl::instance();
00394     if (argc == 3) {
00395         if (strcmp(argv[1] , "route-notify") == 0) {
00396             Node *node = (Node *)(TclObject::lookup(argv[2]));
00397             if (node == NULL) {
00398                 tcl.add_errorf("Invalid node object %s", argv[2]);
00399                 return TCL_ERROR;
00400             }
00401             if (node != n_) {
00402                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00403                 return TCL_ERROR;
00404             }
00405             n_->route_notify(this);
00406             return TCL_OK;
00407         }
00408         if (strcmp(argv[1] , "unreg-route-notify") == 0) {
00409             Node *node = (Node *)(TclObject::lookup(argv[2]));
00410             if (node == NULL) {
00411                 tcl.add_errorf("Invalid node object %s", argv[2]);
00412                 return TCL_ERROR;
00413             }
00414             if (node != n_) {
00415                 tcl.add_errorf("Node object %s different from n_", argv[2]);
00416                 return TCL_ERROR;
00417             }
00418             n_->unreg_route_notify(this);
00419             return TCL_OK;
00420         }
00421     }
00422     return (RoutingModule::command(argc, argv));
00423 }
00424 
00425 void RoutingModule::route_notify(RoutingModule *rtm) {
00426     if (next_rtm_ != NULL)
00427         next_rtm_->route_notify(rtm);
00428     else
00429         next_rtm_ = rtm;
00430 }
00431 
00432 void RoutingModule::unreg_route_notify(RoutingModule *rtm) {
00433     if (next_rtm_) {
00434         if (next_rtm_ == rtm) {
00435             //RoutingModule *tmp = next_rtm_;
00436             next_rtm_ = next_rtm_->next_rtm_;
00437             //free (tmp);
00438         }
00439         else {
00440             next_rtm_->unreg_route_notify(rtm);
00441         }
00442     }
00443 }
00444 
00445 void RoutingModule::add_route(char *dst, NsObject *target) 
00446 {
00447     if (classifier_) 
00448         classifier_->do_install(dst,target); 
00449     if (next_rtm_ != NULL)
00450         next_rtm_->add_route(dst, target); 
00451 }
00452 
00453 void RoutingModule::delete_route(char *dst, NsObject *nullagent)
00454 {
00455     if (classifier_) 
00456         classifier_->do_install(dst, nullagent); 
00457     if (next_rtm_)
00458         next_rtm_->add_route(dst, nullagent); 
00459 }
00460 
00461 void RoutingModule::set_table_size(int nn)
00462 {
00463     if (classifier_)
00464         classifier_->set_table_size(nn);
00465     if (next_rtm_)
00466         next_rtm_->set_table_size(nn);
00467 }
00468 
00469 void RoutingModule::set_table_size(int level, int size)
00470 {
00471     if (classifier_)
00472         classifier_->set_table_size(level, size);
00473     if (next_rtm_)
00474         next_rtm_->set_table_size(level, size);
00475 }
00476 
00477 //  void BaseRoutingModule::add_route(char *dst, NsObject *target) {
00478 //      if (classifier_) 
00479 //          ((DestHashClassifier *)classifier_)->do_install(dst, target);
00480 //      if (next_rtm_ != NULL)
00481 //          next_rtm_->add_route(dst, target); 
00482 //  }
00483 
00484 //  void McastRoutingModule::add_route(char *dst, NsObject *target) {
00485 //      if (classifier_) 
00486 //          ((DestHashClassifier *)classifier_)->do_install(dst, target);
00487 //      if (next_rtm_ != NULL)
00488 //          next_rtm_->add_route(dst, target); 
00489 //  }
00490 
00491 //  void HierRoutingModule::add_route(char *dst, NsObject *target) {
00492 //      if (classifier_) 
00493 //          ((HierClassifier *)classifier_)->do_install(dst, target);
00494 //      if (next_rtm_ != NULL)
00495 //          next_rtm_->add_route(dst, target); 
00496 //  }
00497 
00498 void ManualRoutingModule::add_route(char *dst, NsObject *target) {
00499     int slot = classifier_->install_next(target);
00500     if (strcmp(dst, "default") == 0) {
00501         classifier_->set_default(slot);
00502     } else {
00503         int encoded_dst_address = 
00504             (atoi(dst)) << (AddrParamsClass::instance().node_shift(1));
00505         if (0 > (classifier_->do_set_hash(0, encoded_dst_address, 0, slot))) {
00506             fprintf(stderr, "HashClassifier::set_hash() return value less than 0\n"); }
00507     }
00508     if (next_rtm_ != NULL)
00509         next_rtm_->add_route(dst, target); 
00510 }
00511 

Generated on Tue Mar 6 16:47:50 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6