/*											/*
 * Copyright (c) 2000 Nortel Networks							 * Copyright (c) 2000 Nortel Networks
 * All rights reserved.									 * All rights reserved.
 * 											 * 
 * Redistribution and use in source and binary forms, with or without			 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions			 * modification, are permitted provided that the following conditions
 * are met:										 * are met:
 * 1. Redistributions of source code must retain the above copyright			 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.			 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright			 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the		 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.		 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software		 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:					 *    must display the following acknowledgement:
 *      This product includes software developed by Nortel Networks.			 *      This product includes software developed by Nortel Networks.
 * 4. The name of the Nortel Networks may not be used					 * 4. The name of the Nortel Networks may not be used
 *    to endorse or promote products derived from this software without			 *    to endorse or promote products derived from this software without
 *    specific prior written permission.						 *    specific prior written permission.
 * 											 * 
 * THIS SOFTWARE IS PROVIDED BY NORTEL AND CONTRIBUTORS ``AS IS'' AND			 * THIS SOFTWARE IS PROVIDED BY NORTEL AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE		 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE		 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL NORTEL OR CONTRIBUTORS BE LIABLE			 * ARE DISCLAIMED.  IN NO EVENT SHALL NORTEL OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL		 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS		 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)		 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT		 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY		 * 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		 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.										 * SUCH DAMAGE.
 *											 *
 * Developed by: Farhan Shallwani, Jeremy Ethridge					 * Developed by: Farhan Shallwani, Jeremy Ethridge
 *               Peter Pieda, and Mandeep Baines					 *               Peter Pieda, and Mandeep Baines
 * Maintainer: Peter Pieda <ppieda@nortelnetworks.com>					 * Maintainer: Peter Pieda <ppieda@nortelnetworks.com>
 */											 */

#ifndef DS_POLICY_H									#ifndef DS_POLICY_H
#define DS_POLICY_H									#define DS_POLICY_H
#include "dsred.h"									#include "dsred.h"

#define ANY_HOST -1		// Add to enable point to multipoint policy		#define ANY_HOST -1		// Add to enable point to multipoint policy
#define FLOW_TIME_OUT 5.0      // The flow does not exist already.			#define FLOW_TIME_OUT 5.0      // The flow does not exist already.
#define MAX_POLICIES 20		// Max. size of Policy Table.				#define MAX_POLICIES 20		// Max. size of Policy Table.

#define DUMB 0										#define DUMB 0
#define TSW2CM 1									#define TSW2CM 1
#define TSW3CM 2									#define TSW3CM 2
#define TB 3										#define TB 3
#define SRTCM 4										#define SRTCM 4
#define TRTCM 5										#define TRTCM 5
#define SFD 6										#define SFD 6
#define EWP 7										#define EWP 7

enum policerType {dumbPolicer, TSW2CMPolicer, TSW3CMPolicer, tokenBucketPolicer, srTC	enum policerType {dumbPolicer, TSW2CMPolicer, TSW3CMPolicer, tokenBucketPolicer, srTC

enum meterType {dumbMeter, tswTagger, tokenBucketMeter, srTCMMeter, trTCMMeter, sfdTa	enum meterType {dumbMeter, tswTagger, tokenBucketMeter, srTCMMeter, trTCMMeter, sfdTa

class Policy;										class Policy;
class TBPolicy;										class TBPolicy;

//struct policyTableEntry								//struct policyTableEntry
struct policyTableEntry {								struct policyTableEntry {
  nsaddr_t sourceNode, destNode;	// Source-destination pair			  nsaddr_t sourceNode, destNode;	// Source-destination pair
  int policy_index;                     // Index to the policy table.			  int policy_index;                     // Index to the policy table.
  policerType policer;									  policerType policer;
  meterType meter;									  meterType meter;
  int codePt;		     // In-profile code point					  int codePt;		     // In-profile code point
  double cir;		     // Committed information rate (bytes per s) 		  double cir;		     // Committed information rate (bytes per s) 
  double cbs;		     // Committed burst size (bytes)		       		  double cbs;		     // Committed burst size (bytes)		       
  double cBucket;	     // Current size of committed bucket (bytes)     		  double cBucket;	     // Current size of committed bucket (bytes)     
  double ebs;		     // Excess burst size (bytes)		       		  double ebs;		     // Excess burst size (bytes)		       
  double eBucket;	     // Current size of excess bucket (bytes)			  double eBucket;	     // Current size of excess bucket (bytes)	
  double pir;		     // Peak information rate (bytes per s)			  double pir;		     // Peak information rate (bytes per s)
  double pbs;		     // Peak burst size (bytes)					  double pbs;		     // Peak burst size (bytes)			
  double pBucket;	     // Current size of peak bucket (bytes)	       		  double pBucket;	     // Current size of peak bucket (bytes)	       
  double arrivalTime;	     // Arrival time of last packet in TSW metering		  double arrivalTime;	     // Arrival time of last packet in TSW metering
  double avgRate, winLen;    // Used for TSW metering					  double avgRate, winLen;    // Used for TSW metering
};											};
												

// This struct specifies the elements of a policer table entry.				// This struct specifies the elements of a policer table entry.
struct policerTableEntry {								struct policerTableEntry {
  policerType policer;									  policerType policer;
  int initialCodePt;									  int initialCodePt;
  int downgrade1;									  int downgrade1;
  int downgrade2;									  int downgrade2;
  int policy_index;									  int policy_index;
};											};

// Class PolicyClassifier: keep the policy and polier tables.				// Class PolicyClassifier: keep the policy and polier tables.
class PolicyClassifier : public TclObject {						class PolicyClassifier : public TclObject {
 public:										 public:
  PolicyClassifier();									  PolicyClassifier();
  void addPolicyEntry(int argc, const char*const* argv);				  void addPolicyEntry(int argc, const char*const* argv);
  void addPolicerEntry(int argc, const char*const* argv);				  void addPolicerEntry(int argc, const char*const* argv);
  void updatePolicyRTT(int argc, const char*const* argv);				  void updatePolicyRTT(int argc, const char*const* argv);
  double getCBucket(const char*const* argv);						  double getCBucket(const char*const* argv);
  int mark(Packet *pkt);								  int mark(Packet *pkt);

  // prints the policy tables								  // prints the policy tables
  void printPolicyTable();								  void printPolicyTable();		
  void printPolicerTable();								  void printPolicerTable();
  											  
  // The table keeps pointers to the real policy					  // The table keeps pointers to the real policy
  // Added to support multiple policy per interface.					  // Added to support multiple policy per interface.
  Policy *policy_pool[MAX_POLICIES];							  Policy *policy_pool[MAX_POLICIES];

protected:										protected:
  // policy table and its pointer							  // policy table and its pointer
  policyTableEntry policyTable[MAX_POLICIES];						  policyTableEntry policyTable[MAX_POLICIES];
  int policyTableSize;									  int policyTableSize;
  // policer table and its pointer							  // policer table and its pointer
  policerTableEntry policerTable[MAX_CP];						  policerTableEntry policerTable[MAX_CP];
  int policerTableSize;									  int policerTableSize;	

  policyTableEntry* getPolicyTableEntry(nsaddr_t source, nsaddr_t dest);		  policyTableEntry* getPolicyTableEntry(nsaddr_t source, nsaddr_t dest);
  policerTableEntry* getPolicerTableEntry(int policy_index, int oldCodePt);		  policerTableEntry* getPolicerTableEntry(int policy_index, int oldCodePt);
};											};

// Below are actual policy classes.							// Below are actual policy classes.
// Supper class Policy can't do anything useful.					// Supper class Policy can't do anything useful.
class Policy : public TclObject {							class Policy : public TclObject {
 public:										 public:
  Policy(){};										  Policy(){};

  // Metering and policing methods:							  // Metering and policing methods:
  // Have to initialize all the pointers before actually do anything with them!		  // Have to initialize all the pointers before actually do anything with them!
  // If not, ok with gcc but not cc!!! Nov 29, xuanc					  // If not, ok with gcc but not cc!!! Nov 29, xuanc
  virtual void applyMeter(policyTableEntry *policy, Packet *pkt) = 0;			  virtual void applyMeter(policyTableEntry *policy, Packet *pkt) = 0;
  virtual int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Pack	  virtual int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Pack
};											};

// DumbPolicy will do nothing, but is a good example to show how to add 		// DumbPolicy will do nothing, but is a good example to show how to add 
// new policy.										// new policy.
class DumbPolicy : public Policy {							class DumbPolicy : public Policy {
 public:										 public:
  DumbPolicy() : Policy(){};								  DumbPolicy() : Policy(){};

  // Metering and policing methods:							  // Metering and policing methods:
  void applyMeter(policyTableEntry *policy, Packet *pkt);				  void applyMeter(policyTableEntry *policy, Packet *pkt);
  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)	  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)
};											};

class TSW2CMPolicy : public Policy {							class TSW2CMPolicy : public Policy {
 public:										 public:
  TSW2CMPolicy() : Policy(){};								  TSW2CMPolicy() : Policy(){};

  // protected:										  // protected:
  // Metering and policing methods:							  // Metering and policing methods:
  void applyMeter(policyTableEntry *policy, Packet *pkt);				  void applyMeter(policyTableEntry *policy, Packet *pkt);
  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)	  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)
};											};

class TSW3CMPolicy : public Policy {							class TSW3CMPolicy : public Policy {
 public:										 public:
  TSW3CMPolicy() : Policy(){};								  TSW3CMPolicy() : Policy(){};

  // Metering and policing methods:							  // Metering and policing methods:
  void applyMeter(policyTableEntry *policy, Packet *pkt);				  void applyMeter(policyTableEntry *policy, Packet *pkt);
  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)	  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)
};											};

class TBPolicy : public Policy {							class TBPolicy : public Policy {
 public:										 public:
  TBPolicy() : Policy(){};								  TBPolicy() : Policy(){};

  // protected:										  // protected:
  // Metering and policing methods:							  // Metering and policing methods:
  void applyMeter(policyTableEntry *policy, Packet *pkt);				  void applyMeter(policyTableEntry *policy, Packet *pkt);
  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)	  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)
};											};

class SRTCMPolicy : public Policy {							class SRTCMPolicy : public Policy {
 public:										 public:
  SRTCMPolicy() : Policy(){};								  SRTCMPolicy() : Policy(){};

  // Metering and policing methods:							  // Metering and policing methods:
  void applyMeter(policyTableEntry *policy, Packet *pkt);				  void applyMeter(policyTableEntry *policy, Packet *pkt);
  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)	  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)
};											};

class TRTCMPolicy : public Policy {							class TRTCMPolicy : public Policy {
 public:										 public:
  TRTCMPolicy() : Policy(){};								  TRTCMPolicy() : Policy(){};

  // Metering and policing methods:							  // Metering and policing methods:
  void applyMeter(policyTableEntry *policy, Packet *pkt);				  void applyMeter(policyTableEntry *policy, Packet *pkt);
  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)	  int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt)
};											};

struct flow_entry {									struct flow_entry {
  int fid;										  int fid;
										      >	  int src_id;
										      >	  int dst_id;
  double last_update;									  double last_update;
  int bytes_sent;									  int bytes_sent;
  int count;										  int count;
  struct flow_entry *next;								  struct flow_entry *next;
};											};

struct flow_list {									struct flow_list {
  struct flow_entry *head;								  struct flow_entry *head;
  struct flow_entry *tail;								  struct flow_entry *tail;
};											};

class SFDPolicy : public Policy {							class SFDPolicy : public Policy {
public:											public:
SFDPolicy();										SFDPolicy();
~SFDPolicy();										~SFDPolicy();

// Metering and policing methods:							// Metering and policing methods:
void applyMeter(policyTableEntry *policy, Packet *pkt);					void applyMeter(policyTableEntry *policy, Packet *pkt);
int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt);	int applyPolicer(policyTableEntry *policy, policerTableEntry *policer, Packet *pkt);

void printFlowTable();									void printFlowTable();

 protected:										 protected:
  // The table to keep the flow states.							  // The table to keep the flow states.
  struct flow_list flow_table;								  struct flow_list flow_table;
};											};

#endif											#endif
