/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ /* * Copyright (c) 1997 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Network Research * Group at Lawrence Berkeley National Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static const char rcsid[] = "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/classifier/classifier-hash.cc,v 1.30 2005/09/18 23:33:31 tomh Exp $ (LBL)"; #endif // // a generalized classifier for mapping (src/dest/flowid) fields // to a bucket. "buckets_" worth of hash table entries are created // at init time, and other entries in the same bucket are created when // needed // // extern "C" { #include } #include #include "config.h" #include "packet.h" #include "ip.h" #include "classifier.h" #include "classifier-hash.h" /****************** HashClassifier Methods ************/ int HashClassifier::classify(Packet * p) { int slot= lookup(p); if (slot >= 0 && slot <=maxslot_) return (slot); else if (default_ >= 0) return (default_); return (unknown(p)); } // HashClassifier::classify int HashClassifier::command(int argc, const char*const* argv) { Tcl& tcl = Tcl::instance(); /* * $classifier set-hash $hashbucket src dst fid $slot */ if (argc == 7) { if (strcmp(argv[1], "set-hash") == 0) { //xxx: argv[2] is ignored for now nsaddr_t src = atoi(argv[3]); nsaddr_t dst = atoi(argv[4]); int fid = atoi(argv[5]); int slot = atoi(argv[6]); if (0 > set_hash(src, dst, fid, slot)) return TCL_ERROR; return TCL_OK; } } else if (argc == 6) { /* $classifier lookup $hashbuck $src $dst $fid */ if (strcmp(argv[1], "lookup") == 0) { nsaddr_t src = atoi(argv[3]); nsaddr_t dst = atoi(argv[4]); int fid = atoi(argv[5]); int slot= get_hash(src, dst, fid); if (slot>=0 && slot <=maxslot_) { tcl.resultf("%s", slot_[slot]->name()); return (TCL_OK); } tcl.resultf(""); return (TCL_OK); } // Added by Yun Wang to set rate for TBFlow or TSWFlow if (strcmp(argv[1], "set-flowrate") == 0) { int fid = atoi(argv[2]); nsaddr_t src = 0; // only use fid nsaddr_t dst = 0; // to classify flows int slot = get_hash( src, dst, fid ); if ( slot >= 0 && slot <= maxslot_ ) { Flow* f = (Flow*)slot_[slot]; tcl.evalf("%u set target_rate_ %s", f, argv[3]); tcl.evalf("%u set bucket_depth_ %s", f, argv[4]); tcl.evalf("%u set tbucket_ %s", f, argv[5]); return (TCL_OK); } else { tcl.evalf("%s set-rate %u %u %u %u %s %s %s", name(), src, dst, fid, slot, argv[3], argv[4],argv[5]) ; return (TCL_OK); } } } else if (argc == 5) { /* $classifier del-hash src dst fid */ if (strcmp(argv[1], "del-hash") == 0) { nsaddr_t src = atoi(argv[2]); nsaddr_t dst = atoi(argv[3]); int fid = atoi(argv[4]); Tcl_HashEntry *ep= Tcl_FindHashEntry(&ht_, hashkey(src, dst, fid)); if (ep) { long slot = (long)Tcl_GetHashValue(ep); Tcl_DeleteHashEntry(ep); tcl.resultf("%lu", slot); return (TCL_OK); } return (TCL_ERROR); } } return (Classifier::command(argc, argv)); } /************** TCL linkage ****************/ static class SrcDestHashClassifierClass : public TclClass { public: SrcDestHashClassifierClass() : TclClass("Classifier/Hash/SrcDest") {} TclObject* create(int, const char*const*) { return new SrcDestHashClassifier; } } class_hash_srcdest_classifier; static class FidHashClassifierClass : public TclClass { public: FidHashClassifierClass() : TclClass("Classifier/Hash/Fid") {} TclObject* create(int, const char*const*) { return new FidHashClassifier; } } class_hash_fid_classifier; static class DestHashClassifierClass : public TclClass { public: DestHashClassifierClass() : TclClass("Classifier/Hash/Dest") {} TclObject* create(int, const char*const*) { return new DestHashClassifier; } } class_hash_dest_classifier; static class SrcDestFidHashClassifierClass : public TclClass { public: SrcDestFidHashClassifierClass() : TclClass("Classifier/Hash/SrcDestFid") {} TclObject* create(int, const char*const*) { return new SrcDestFidHashClassifier; } } class_hash_srcdestfid_classifier; // DestHashClassifier methods int DestHashClassifier::classify(Packet *p) { int slot= lookup(p); if (slot >= 0 && slot <=maxslot_) return (slot); else if (default_ >= 0) return (default_); return -1; } // HashClassifier::classify void DestHashClassifier::do_install(char* dst, NsObject *target) { nsaddr_t d = atoi(dst); int slot = getnxt(target); install(slot, target); if (set_hash(0, d, 0, slot) < 0) fprintf(stderr, "DestHashClassifier::set_hash from within DestHashClassifier::do_install returned value < 0"); } int DestHashClassifier::command(int argc, const char*const* argv) { if (argc == 4) { // $classifier install $dst $node if (strcmp(argv[1], "install") == 0) { char dst[SMALL_LEN]; strcpy(dst, argv[2]); NsObject *node = (NsObject*)TclObject::lookup(argv[3]); //nsaddr_t dst = atoi(argv[2]); do_install(dst, node); return TCL_OK; //int slot = getnxt(node); //install(slot, node); //if (set_hash(0, dst, 0, slot) >= 0) //return TCL_OK; //else //return TCL_ERROR; } // if } return(HashClassifier::command(argc, argv)); } // command