⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classifier-addr-mpls.cc

📁 c++编写应用于ns环境下的关于MPLS网络中的多播路由算法
💻 CC
📖 第 1 页 / 共 4 页
字号:
// -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-//// Time-stamp: <2000-09-11 15:24:28 haoboy>//// Copyright (c) 2000 by the University of Southern California// All rights reserved.//// Permission to use, copy, modify, and distribute this software and its// documentation in source and binary forms for non-commercial purposes// and without fee is hereby granted, provided that the above copyright// notice appear in all copies and that both the copyright notice and// this permission notice appear in supporting documentation. and that// any documentation, advertising materials, and other materials related// to such distribution and use acknowledge that the software was// developed by the University of Southern California, Information// Sciences Institute.  The name of the University may not be used to// endorse or promote products derived from this software without// specific prior written permission.//// THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about// the suitability of this software for any purpose.  THIS SOFTWARE IS// PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// Other copyrights might apply to parts of this software and are so// noted when applicable.//// Original source contributed by Gaeil Ahn. See below.//// $Header: /nfs/jade/vint/CVSROOT/ns-2/mpls/classifier-addr-mpls.cc,v 1.5 2001/03/06 20:53:41 haldar Exp $// XXX//// - Because MPLS header contains pointers, it cannot be used WITH multicast //   routing which replicates packets// - Currently it works only with flat routing./************************************************************************** * Copyright (c) 2000 by Gaeil Ahn                                   	  * * Everyone is permitted to copy and distribute this software.		  * * Please send mail to fog1@ce.cnu.ac.kr when you modify or distribute    * * this sources.							  * **************************************************************************//************************************************************ *                                                          * *    File: File for packet switching in MPLS node          * *    Author: Gaeil Ahn (fog1@ce.cnu.ac.kr), Dec. 1999      * *                                                          * ************************************************************/#include "packet.h"#include "trace.h"#include "classifier-addr-mpls.h"#include <iostream>#include <unistd.h>int hdr_mpls::offset_;static class shimhdreaderClass : public PacketHeaderClass {public:	shimhdreaderClass() : PacketHeaderClass("PacketHeader/MPLS", 						sizeof(hdr_mpls)) {		bind_offset(&hdr_mpls::offset_);	}} class_shimhdreader;static class MPLSAddrClassifierClass : public TclClass {public:	MPLSAddrClassifierClass() : TclClass("Classifier/Addr/MPLS") {}	virtual TclObject* create(int, const char*const*) {		return (new MPLSAddressClassifier());	}	virtual void bind();	virtual int method(int argc, const char*const* argv);} class_mpls_addr_classifier;void MPLSAddrClassifierClass::bind(){	TclClass::bind();	add_method("minimum-lspid");	add_method("dont-care");	add_method("ordered-control?");	add_method("on-demand?");	add_method("enable-ordered-control");	add_method("enable-on-demand");}int MPLSAddrClassifierClass::method(int ac, const char*const* av){	Tcl& tcl = Tcl::instance();	int argc = ac - 2;	const char*const* argv = av + 2;	if (argc == 2) {		if (strcmp(argv[1], "minimum-lspid") == 0) {			tcl.resultf("%d", MPLS_MINIMUM_LSPID);			return (TCL_OK);		} else if (strcmp(argv[1], "dont-care") == 0) {			tcl.resultf("%d", MPLS_DONTCARE);			return (TCL_OK);		} if (strcmp(argv[1], "ordered-control?") == 0) {			tcl.resultf("%d", 				    MPLSAddressClassifier::ordered_control_);			return (TCL_OK);		} else if (strcmp(argv[1], "on-demand?") == 0) {			tcl.resultf("%d", MPLSAddressClassifier::on_demand_);			return (TCL_OK);		} else if (strcmp(argv[1], "enable-ordered-control") == 0) {			MPLSAddressClassifier::ordered_control_ = 1;			return (TCL_OK);		} else if (strcmp(argv[1], "enable-on-demand") == 0) {			MPLSAddressClassifier::on_demand_ = 1;			return (TCL_OK);		}	}	return TclClass::method(ac, av);}int MPLSAddressClassifier::on_demand_ = 0;int MPLSAddressClassifier::ordered_control_ = 0;MPLSAddressClassifier::MPLSAddressClassifier() : 	data_driven_(0), control_driven_(0){	PFT_.NB_   = 0;	ERB_.NB_   = 0;	LIB_.NB_   = 0;	LSG_.NB_   = 0;	DnNM_      = 0;	Lptr_      = 0;        //Sflag_     = 0;        //rec_       = 0;	ttl_ = 32;}void MPLSAddressClassifier::delay_bind_init_all(){	delay_bind_init_one("ttl_");	delay_bind_init_one("trace_mpls_");   	delay_bind_init_one("label_");	delay_bind_init_one("enable_reroute_");	delay_bind_init_one("reroute_option_");	delay_bind_init_one("data_driven_");	delay_bind_init_one("control_driven_");	AddressClassifier::delay_bind_init_all();}// Arguments: varName, localName, tracerint MPLSAddressClassifier::delay_bind_dispatch(const char *vn, 					       const char* ln, TclObject *t){	if (delay_bind(vn, ln, "ttl_", &ttl_, t))		return TCL_OK;	if (delay_bind(vn, ln, "trace_mpls_", &trace_mpls_, t)) 		return TCL_OK;	if (delay_bind(vn, ln, "label_", &label_, t)) 		return TCL_OK;	if (delay_bind(vn, ln, "enable_reroute_", &enable_reroute_, t))		return TCL_OK;	if (delay_bind(vn, ln, "reroute_option_", &reroute_option_, t))		return TCL_OK;	if (delay_bind(vn, ln, "data_driven_", &data_driven_, t))		return TCL_OK;	if (delay_bind(vn, ln, "control_driven_", &control_driven_, t))		return TCL_OK;	return AddressClassifier::delay_bind_dispatch(vn, ln, t);}//***************************************overload recv*****************************************void MPLSAddressClassifier::recv(Packet* p, Handler*h)
{printf("---------------------i am in recv function now----------------------\n");	NsObject* node;	Lptr_ = 0;	DnNM_ = 0;  //Sflag_ = 0;  Packet *tempPkt = p->copy();  GetIPInfo(p, PI_.dst_, PI_.phb_, PI_.srcnode_);
	PI_.shimhdr_ = GetShimHeader(tempPkt);        //size_ = size_ - Sflag_; 	if (size_ > 0)                         //labeled packet 	{     int iLabel = PI_.shimhdr_->label_;    int Group = PI_.dst_.addr_;    int source,group;    DnNM_ = LSGlabellookup(-1, iLabel, source, group) + 1;    //DnNM_ = LSGexist(Group);  /*printf("iLabel = %d\n",iLabel);printf("DnNM_=%d\n",DnNM_);printf("Group=%d\n",Group);printf("source=%d\n",source);printf("group=%d\n",group);*/  }  //size_ = size_ - Sflag_;   Packet::free(tempPkt);    if (DnNM_ <= 1)                                            //unicast or nonbranch  { printf("there is not branch node\n");
	  node = find(p);
	  if (node == NULL) {
		  /*
		   * XXX this should be "dropped" somehow.  Right now,
		   * these events aren't traced.
		   */
		  Packet::free(p);
		  return;
	  }
	  node->recv(p,h);	} else {                                                    //barnch node          Packet* q[10];          int hdrsize = sizeof(hdr_mpls);                          //hdr_mpls' size          hdr_mpls *newhdr, *newtop;          hdr_mpls *origshim = hdr_mpls::access(p);          if (origshim->top_ != 0) {             origshim = origshim->top_;                            //get original p->shimhdr->top_             for(int i = 1; i < DnNM_; i++){                       //set p->copy()'s top_                q[i] = p->copy();                newhdr = hdr_mpls::access(q[i]);                newtop = (hdr_mpls *) malloc(hdrsize);                memcpy(newtop, origshim, hdrsize);                newtop->top_ = newtop;                newtop->nexthdr_ = newhdr;                newhdr->top_ = newtop;                newhdr = 0;                newtop = 0;             }             origshim = 0;          }printf("there is the branch node\n");//sleep(1); 	  for(int i = 1; i < DnNM_; i++){            //q[i] = p->copy();printf("there is the copy operation and DnNM_ = %d, i = %d\n",DnNM_,i);	    node = find(q[i]);	    if (node != NULL) {printf("there is the node that is not last\n");
	      //node->recv(p->copy());              node->recv(q[i],h);//sleep(2);            }            else              Packet::free(q[i]);	  }printf("there is the last packet\n");	  node = find(p);              //loop just less one than fact ,so there is the last node
	  if (node == NULL) {
		  Packet::free(p);
		  return;
	  }//sleep(3);
	  node->recv(p,h);printf("the last packet is finished\n");	}
}


NsObject* MPLSAddressClassifier::find(Packet* p)
{if (DnNM_ > 1)  printf("i am in find functionn, and this node is a branch now\n");
	NsObject* node = NULL;
	int cl = classify(p);
	if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0) { 
		if (default_target_) 
			return default_target_;
		/*
		 * Sigh.  Can't pass the pkt out to tcl because it's
		 * not an object.
		 */
		Tcl::instance().evalf("%s no-slot %ld", name(), cl);
		if (cl == TWICE) {
			/*
			 * Try again.  Maybe callback patched up the table.
			 */
			cl = classify(p);
			if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0)
				return (NULL);
		}
	}
	return (node);
}//**********************************************************************************************int MPLSAddressClassifier::classify(Packet* p){if (DnNM_ > 1)  printf("i am in classify functionn, and this node is a branch now\n");	int nexthop = MPLSclassify(p);	if ((enable_reroute_ == 1) && (size_ > 0) && 	    (is_link_down(nexthop)))		// Use alternative path if it exist		nexthop = do_reroute(p);	if (nexthop == MPLS_GOTO_L3)		return AddressClassifier::classify(p);	// XXX Do NOT return -1, which lets the classifier to process this 	// packet twice!!	return (nexthop == -1) ? Classifier::ONCE : nexthop;}int MPLSAddressClassifier::is_link_down(int node){	Tcl& tcl = Tcl::instance();   	tcl.evalf("[%s set mpls_mod_] get-link-status %d", name(), node);	return (strcmp(tcl.result(), "down") == 0) ? 1 : 0;}int MPLSAddressClassifier::do_reroute(Packet* p){	int oIface, oLabel, LIBptr;	PI_.shimhdr_ = GetShimHeader(p);	int iLabel = PI_.shimhdr_->label_;	if (aPathLookup(PI_.dst_.addr_, PI_.phb_, oIface, oLabel, LIBptr) == 0)		return convertL2toL2(iLabel, oIface, oLabel, LIBptr);	else {		PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);		trace("L", size_, iLabel, "Drop(linkFail)", -1, -1, -1);		switch (reroute_option_) {		case MPLS_DROPPACKET:			return -1;		case MPLS_L3FORWARDING:			return MPLS_GOTO_L3;		case MPLS_MAKENEWLSP:			Tcl& tcl = Tcl::instance();   			if (!control_driven_)				tcl.evalf("%s ldp-trigger-by-switch %d", 					  name(), PI_.dst_.addr_);			return -1;		}		return -1;	}}int MPLSAddressClassifier::convertL3toL2(int oIface, int oLabel, int LIBptr){	int iLabel= -1;	int ptr;              	while (oLabel >= 0) {		/* penultimate hop */		if (oLabel == 0)  {			/* no operation */			trace("U",size_, iLabel, "Push(penultimate)", 			      oIface, oLabel, ttl_);		} else {			/* push operation in ingerss LSR */			PI_.shimhdr_ = push(PI_.shimhdr_,oLabel);			trace("U",size_, iLabel, "Push(ingress)", 			      oIface, oLabel, ttl_);		}		if (LIBptr >= 0) {			/* stack operation */			iLabel = oLabel;			ptr = LIBptr;			LIBlookup(ptr, oIface, oLabel, LIBptr);		} else			break;	}	if (oLabel < 0) {		if (size_ > 0)			PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);		trace("U",size_, iLabel , "L3(errorLabel)", -1,-1, -1);		return MPLS_GOTO_L3;	}	if (oIface < 0) {  		PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);		trace("U", size_, iLabel, "L3(errorOIF)", -1 , -1, -1);		return MPLS_GOTO_L3;	} else		// Guaranteed returned oIface is >= 0 or MPLS_GOTO_L3		return oIface;}int MPLSAddressClassifier::convertL2toL2(int iLabel, int oIface, 					 int oLabel, int LIBptr){	int  ttl = PI_.shimhdr_->ttl_;	int  ptr;	// push(stack) operation after swap or pop	if (oLabel == 0) {		// in penultimate hop		PI_.shimhdr_ = pop(PI_.shimhdr_);		trace("L", size_, iLabel, "Pop(penultimate)", 		      oIface, oLabel, ttl);	} else if (oLabel > 0) {		// swap operation 		swap(PI_.shimhdr_,oLabel);		trace("L", size_, iLabel, "Swap", oIface, oLabel, ttl);	} else {		// Errored Label		PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);		trace("L", size_, iLabel, "L3(errorLabel)", -1, -1, -1);		return MPLS_GOTO_L3;	}	while (LIBptr >= 0) {		// stack operation		iLabel= oLabel;		ptr = LIBptr;		LIBlookup(ptr, oIface, oLabel, LIBptr);		PI_.shimhdr_ = push(PI_.shimhdr_,oLabel);		trace("L", size_, iLabel, "Push(tunnel)", 		      oIface, oLabel, ttl_);	}   	if (oIface < 0) {  		if (size_ > 0)			PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);		trace("L",size_, iLabel , "L3(errorOIf)", -1 , -1, -1);		return MPLS_GOTO_L3;	}	// Guaranteed returned oIface >= 0	return oIface;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -