00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef lint
00036 static const char rcsid[] =
00037 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/classifier/classifier.cc,v 1.41 2002/03/21 01:46:02 johnh Exp $";
00038 #endif
00039
00040 #include <stdlib.h>
00041 #include "config.h"
00042 #include "classifier.h"
00043 #include "packet.h"
00044
00045 static class ClassifierClass : public TclClass {
00046 public:
00047 ClassifierClass() : TclClass("Classifier") {}
00048 TclObject* create(int, const char*const*) {
00049 return (new Classifier());
00050 }
00051 } class_classifier;
00052
00053
00054 Classifier::Classifier() :
00055 slot_(0), nslot_(0), maxslot_(-1), shift_(0), mask_(0xffffffff), nsize_(0)
00056 {
00057 default_target_ = 0;
00058
00059 bind("offset_", &offset_);
00060 bind("shift_", &shift_);
00061 bind("mask_", &mask_);
00062 }
00063
00064 int Classifier::classify(Packet *p)
00065 {
00066 return (mshift(*((int*) p->access(offset_))));
00067 }
00068
00069 Classifier::~Classifier()
00070 {
00071 delete [] slot_;
00072 }
00073
00074 void Classifier::set_table_size(int nn)
00075 {
00076 nsize_ = nn;
00077 }
00078
00079 void Classifier::alloc(int slot)
00080 {
00081 NsObject** old = slot_;
00082 int n = nslot_;
00083 if (old == 0)
00084 if (nsize_ != 0) {
00085
00086 nslot_ = nsize_;
00087 }
00088 else {
00089
00090 nslot_ = 32;
00091 }
00092 while (nslot_ <= slot)
00093 nslot_ <<= 1;
00094 slot_ = new NsObject*[nslot_];
00095 memset(slot_, 0, nslot_ * sizeof(NsObject*));
00096 for (int i = 0; i < n; ++i)
00097 slot_[i] = old[i];
00098 delete [] old;
00099 }
00100
00101
00102 void Classifier::install(int slot, NsObject* p)
00103 {
00104 if (slot >= nslot_)
00105 alloc(slot);
00106 slot_[slot] = p;
00107 if (slot >= maxslot_)
00108 maxslot_ = slot;
00109 }
00110
00111 void Classifier::clear(int slot)
00112 {
00113 slot_[slot] = 0;
00114 if (slot == maxslot_) {
00115 while (--maxslot_ >= 0 && slot_[maxslot_] == 0)
00116 ;
00117 }
00118 }
00119
00120 int Classifier::getnxt(NsObject *nullagent)
00121 {
00122 int i;
00123 for (i=0; i < nslot_; i++)
00124 if (slot_[i]==0 || slot_[i]==nullagent)
00125 return i;
00126 i=nslot_;
00127 alloc(nslot_);
00128 return i;
00129 }
00130
00131
00132
00133
00134
00135 void Classifier::recv(Packet* p, Handler*h)
00136 {
00137 NsObject* node = find(p);
00138 if (node == NULL) {
00139
00140
00141
00142
00143 Packet::free(p);
00144 return;
00145 }
00146 node->recv(p,h);
00147 }
00148
00149
00150
00151
00152
00153
00154 NsObject* Classifier::find(Packet* p)
00155 {
00156 NsObject* node = NULL;
00157 int cl = classify(p);
00158 if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0) {
00159 if (default_target_)
00160 return default_target_;
00161
00162
00163
00164
00165 Tcl::instance().evalf("%s no-slot %ld", name(), cl);
00166 if (cl == TWICE) {
00167
00168
00169
00170 cl = classify(p);
00171 if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0)
00172 return (NULL);
00173 }
00174 }
00175 return (node);
00176 }
00177
00178 int Classifier::install_next(NsObject *node) {
00179 int slot = maxslot_ + 1;
00180 install(slot, node);
00181 return (slot);
00182 }
00183
00184 int Classifier::command(int argc, const char*const* argv)
00185 {
00186 Tcl& tcl = Tcl::instance();
00187 if(argc == 2) {
00188 if (strcmp(argv[1], "defaulttarget") == 0) {
00189 if (default_target_ != 0)
00190 tcl.result(default_target_->name());
00191 return (TCL_OK);
00192 }
00193 } else if (argc == 3) {
00194
00195
00196
00197 if (strcmp(argv[1],"alloc-port") == 0) {
00198 int slot;
00199 NsObject* nullagent =
00200 (NsObject*)TclObject::lookup(argv[2]);
00201 slot = getnxt(nullagent);
00202 tcl.resultf("%u",slot);
00203 return(TCL_OK);
00204 }
00205
00206
00207
00208 if (strcmp(argv[1], "clear") == 0) {
00209 int slot = atoi(argv[2]);
00210 clear(slot);
00211 return (TCL_OK);
00212 }
00213
00214
00215
00216 if (strcmp(argv[1], "installNext") == 0) {
00217
00218 NsObject* node = (NsObject*)TclObject::lookup(argv[2]);
00219 if (node == NULL) {
00220 tcl.resultf("Classifier::installNext attempt "
00221 "to install non-object %s into classifier", argv[2]);
00222 return TCL_ERROR;
00223 };
00224 int slot = install_next(node);
00225 tcl.resultf("%u", slot);
00226 return TCL_OK;
00227 }
00228
00229
00230
00231
00232 if (strcmp(argv[1], "slot") == 0) {
00233 int slot = atoi(argv[2]);
00234 if (slot >= 0 && slot < nslot_ && slot_[slot] != NULL) {
00235 tcl.resultf("%s", slot_[slot]->name());
00236 return TCL_OK;
00237 }
00238 tcl.resultf("Classifier: no object at slot %d", slot);
00239 return (TCL_ERROR);
00240 }
00241
00242
00243
00244
00245 if (strcmp(argv[1], "findslot") == 0) {
00246 int slot = 0;
00247 NsObject* node = (NsObject*)TclObject::lookup(argv[2]);
00248 if (node == NULL) {
00249 return (TCL_ERROR);
00250 }
00251 while (slot < nslot_) {
00252
00253
00254
00255 if (slot_[slot] &&
00256 strcmp(slot_[slot]->name(), argv[2]) == 0){
00257 tcl.resultf("%u", slot);
00258 return (TCL_OK);
00259 }
00260 slot++;
00261 }
00262 tcl.result("-1");
00263 return (TCL_OK);
00264 }
00265 if (strcmp(argv[1], "defaulttarget") == 0) {
00266 default_target_=(NsObject*)TclObject::lookup(argv[2]);
00267 if (default_target_ == 0)
00268 return TCL_ERROR;
00269 return TCL_OK;
00270 }
00271 } else if (argc == 4) {
00272
00273
00274
00275 if (strcmp(argv[1], "install") == 0) {
00276 int slot = atoi(argv[2]);
00277 NsObject* node = (NsObject*)TclObject::lookup(argv[3]);
00278 install(slot, node);
00279 return (TCL_OK);
00280 }
00281 }
00282 return (NsObject::command(argc, argv));
00283 }