📄 nodes.tex
字号:
\begin{program} /* *{\cf objects only ever see "packet" events, which come either} *{\cf from an incoming link or a local agent (i.e., packet source).} */ void Classifier::recv(Packet* p, Handler*) \{ NsObject* node; int cl = classify(p); if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0) \{ Tcl::instance().evalf("%s no-slot %d", name(), cl); Packet::free(p); return; \} node->recv(p); \} int Classifier::command(int argc, const char*const* argv) \{ Tcl& tcl = Tcl::instance(); if (argc == 3) \{ /* * $classifier clear $slot */ if (strcmp(argv[1], "clear") == 0) \{ int slot = atoi(argv[2]); clear(slot); return (TCL_OK); \} /* * $classifier installNext $node */ if (strcmp(argv[1], "installNext") == 0) \{ int slot = maxslot_ + 1; NsObject* node = (NsObject*)TclObject::lookup(argv[2]); install(slot, node); tcl.resultf("%u", slot); return TCL_OK; \} if (strcmp(argv[1], "slot") == 0) \{ int slot = atoi(argv[2]); if ((slot >= 0) || (slot < nslot_)) \{ tcl.resultf("%s", slot_[slot]->name()); return TCL_OK; \} tcl.resultf("Classifier: no object at slot %d", slot); return (TCL_ERROR); \} \} else if (argc == 4) \{ /* * $classifier install $slot $node */ if (strcmp(argv[1], "install") == 0) \{ int slot = atoi(argv[2]); NsObject* node = (NsObject*)TclObject::lookup(argv[3]); install(slot, node); return (TCL_OK); \} \} return (NsObject::command(argc, argv)); \}\end{program}When a classifier \fcn[]{recv}'s a packet,it hands it to the \fcn[]{classify} method.This is defined differently in each type of classifierderived from the base class.The usual format is for the \fcn[]{classify} method todetermine and return a slot index into the table of slots.If the index is valid, and points to a valid TclObject,the classifier will hand the packet to that object using that object's \fcn[]{recv} method.If the index is not valid, the classifier will invokethe instance procedure \proc[]{no-slot} to attempt to populate the table correctly.However, in the base class \proc[]{Classifier::no-slot} printsand error message and terminates execution.The \fcnref{\fcn[]{command} method}{../ns-2/classifier.cc}{Classifier::command}provides the following instproc-likes to the interpreter:\begin{itemize}\itemsep0pt\item \proc[\tup{slot}]{clear} clears the entry in a particular slot.\item \proc[\tup{object}]{installNext} installs the object in the next available slot, and returns the slot number. Note that this instproc-like is \fcnref{overloaded by an instance procedure of the same name}{% ../ns-2/ns-lib.tcl}{Classifier::installNext} that stores a reference to the object stored. This then helps quick query of the objects installed in the classifier from OTcl.\item \proc[\tup{index}]{slot} returns the object stored in the specified slot.\item \proc[\tup{index}, \tup{object}]{install} installs the specified \tup{object} at the slot \tup{index}. Note that this instproc-like too is \fcnref{overloaded by an instance procedure of the same name}{% ../ns-2/ns-lib.tcl}{Classifier::install} that stores a reference to the object stored. This is also to quickly query of the objects installed in the classifier from OTcl.\end{itemize}\subsection{Address Classifiers}\label{sec:node:addr-classifier}An address classifier is used in supporting unicast packet forwarding.It applies a bitwise shift and mask operation to a packet's destinationaddress to produce a slot number.The slot number is returned from the \fcn[]{classify} method.The \clsref{AddressClassifier}{../ns-2/classifier-addr.cc}(defined in \nsf{classifier-addr.cc}) ide defined as follows:\begin{program} class AddressClassifier : public Classifier \{ public: AddressClassifier() : mask_(~0), shift_(0) \{ bind("mask_", (int*)&mask_); bind("shift_", &shift_); \} protected: int classify(Packet *const p) \{ IPHeader *h = IPHeader::access(p->bits()); return ((h->dst() >> shift_) & mask_); \} nsaddr_t mask_; int shift_; \};\end{program}The class imposes no direct semantic meaningon a packet's destination address field.Rather, it returns some number of bits from the packet's\code{dst_} field as the slot number usedin the \fcnref{\fcn[]{Classifier::recv}}{../ns-2/classifier.cc}{Classifier::recv} method.The \code{mask_} and \code{shift_} values are set through OTcl.\subsection{Multicast Classifiers}\label{sec:node:mcast-classifier}The multicast classifier classifies packetsaccording to both source and destination (group) addresses.It maintains a (chained hash) table mapping source/group pairs to slot numbers.When a packet arrives containing a source/group unknown to the classifier,it invokes an Otcl procedure \proc[]{Node::new-group}to add an entry to its table.This OTcl procedure may use the method \code{set-hash} to addnew (source, group, slot) 3-tuples to the classifier's table.The multicast classifier is defined in \nsf{classifier-mcast.cc}as follows:\begin{program} static class MCastClassifierClass : public TclClass \{ public: MCastClassifierClass() : TclClass("Classifier/Multicast") \{\} TclObject* create(int argc, const char*const* argv) \{ return (new MCastClassifier()); \} \} class_mcast_classifier; class MCastClassifier : public Classifier \{ public: MCastClassifier(); ~MCastClassifier(); protected: int command(int argc, const char*const* argv); int classify(Packet *const p); int findslot(); void set_hash(nsaddr_t src, nsaddr_t dst, int slot); int hash(nsaddr_t src, nsaddr_t dst) const \{ u_int32_t s = src ^ dst; s ^= s >> 16; s ^= s >> 8; return (s & 0xff); \} struct hashnode \{ int slot; nsaddr_t src; nsaddr_t dst; hashnode* next; \}; hashnode* ht_[256]; const hashnode* lookup(nsaddr_t src, nsaddr_t dst) const; \}; int MCastClassifier::classify(Packet *const pkt) \{ IPHeader *h = IPHeader::access(pkt->bits()); nsaddr_t src = h->src() >> 8; /*XXX*/ nsaddr_t dst = h->dst(); const hashnode* p = lookup(src, dst); if (p == 0) \{ /* * Didn't find an entry. * Call tcl exactly once to install one. * If tcl doesn't come through then fail. */ Tcl::instance().evalf("%s new-group %u %u", name(), src, dst); p = lookup(src, dst); if (p == 0) return (-1); \} return (p->slot); \}\end{program}The \clsref{MCastClassifier} implements a chained hash tableand applies a hash function on both the packet source anddestination addresses.The hash function returns the slot numberto index the \code{slot_} table in the underlying object.A hash miss implies packet delivery to a previously-unknown group;OTcl is called to handle the situation.The OTcl code is expected to insert an appropriate entry into the hash table.\subsection{MultiPath Classifier}\label{sec:node:mpath-classifier}This object is devised to support equal cost multipathforwarding, where the node has multiple equal cost routesto the same destination, and would like to use all of themsimultaneously.This object does not look at any field in the packet.With every succeeding packet, it simply returns the next filled slot in round robin fashion.The definitions for this classifier are in \nsf{classifier-mpath.cc},and are shown below:\begin{program}class MultiPathForwarder : public Classifier \{public: MultiPathForwarder() : ns_(0), Classifier() \{\} virtual int classify(Packet* const) \{ int cl; int fail = ns_; do \{ cl = ns_++; ns_ %= (maxslot_ + 1); \} while (slot_[cl] == 0 && ns_ != fail); return cl; \}private: int ns_; \* next slot to be used. Probably a misnomer? */\};\end{program}\subsection{Hash Classifier}\label{sec:node:hash-classifier}This object is used to classify a packet as a member of aparticular {\em flow}.As their name indicates,hash classifiers use a hash table internally to assignpackets to flows.These objects are used where flow-level information isrequired (e.g. in flow-specific queuing disciplines and statisticscollection).Several ``flow granularities'' are available. In particular,packets may be assigned to flows based on flow ID, destination address,source/destination addresses, or the combination of source/destinationaddresses plus flow ID.The fields accessed by the hash classifier are limited tothe {\tt ip} header: {\tt src(), dst(), flowid()} (see {\tt ip.h}).The hash classifier is created with an integer argument specifyingthe initial size of its hash table. The current hash table size maybe subsequently altered with the {\tt resize} method (see below).When created, the instance variables \code{shift_} and \code{mask_}are initialized with the simulator's current {\sf NodeShift} and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -