/* -*- 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 <tcl.h>
}
#include <stdlib.h>
#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
syntax highlighted by Code2HTML, v. 0.9.1