/* 
 * $Id: idrp_policy.h,v 1.6 1995/11/06 16:30:07 skh Exp $
 * Merit IDRP release 1.1 (gated 3.5.4).  Copyright (c) 1994 by Merit Network, Inc. 
 */

#ifndef _idrp_policy_h
#define _idrp_policy_h
/* idrp_policy.h
 * policy variables for idrp distribution
 */

#define	IDRP_DIST_PEER_UP_DUMP		0		/* peer is up, this is a first time dump */ 
#define	IDRP_DIST_REFRESH		1		/* peer is up, this is rib refresh */ 
#define	IDRP_DIST_FLASH			2		/* DIST_FLASH - flash processing of changes */
#define IDRP_DIST_NEWPOLICY_FLASH       3		/* flash processing after reconfiguration */
#define IDRP_DIST_LOCAL_FLASH		4		/* flash processing of locally configged static routes */

#define IDRP_DIST_PH1_BEST_EXT		5		/* flash processing of locally configged static routes */

#define	IDRP_RUN_PREF			1		/* preference is run */
#define	IDRP_NORUN_PREF			0		/* preference is not run */

/* definitions for default policy 
 *  
 * internal to domain  (whether received from internal
 *                      peers or external)
 *
 * RTPREF_IDRP_INT + IDRP_INT_MULTIPLIER * pref_calc
 *
 * external to domain (received from external peers
 * 		       or internal peers but
 * 			RD path outside domain)
 *		  
 */

#define IDRP_INT_PREF_MULTI		2
#define	IDRP_EXT_PREF_MULTI	 	5	


/* typedef for idrp_pref_t
 *
 */
 
typedef		int		idrp_pref_t;
	

/*
 * #defines, etc., for import/export policy--SJR
 */

/*
 * These #defines are for values of the 'ps_flag' in the following
 * structure and are meant to be analogous to the ADVFT_* #defines
 * for the adv structure which is found in policy.h.
 */
#define IDRP_PSFT_RIBID             BIT(0x01) /* test on Rib ID--useful??? */
#define IDRP_PSFT_EXTINFO           BIT(0x02) /* test on external info */
#define IDRP_PSFT_EXTERNAL_INFO     IDRP_PSFT_EXTINFO
#define IDRP_PSFT_NEXTHOP_NET       BIT(0x03) /* test on NET of NEXT_HOP */
#define IDRP_PSFT_NEXTHOP_SNPA      BIT(0x04) /* test on SNPA/SNPA list of NEXT_HOP */
#define IDRP_PSFT_NEXTHOP_IPGW      BIT(0x05) /* test on IP address of Gateway */
#define IDRP_PSFT_NEXTHOP_IPINTF    BIT(0x06) /* test on IP address of interface */
#define IDRP_PSFT_DISTINCL          BIT(0x07) /* test on DIST_INCL_LIST */
#define IDRP_PSFT_DIST_LIST_INCL    IDRP_PSFT_DISTINCL
#define IDRP_PSFT_DIST_LIST_INCLUDE IDRP_PSFT_DISTINCL
#define IDRP_PSFT_DISTEXCL          BIT(0x08) /* test on DIST_EXCL_LIST */
#define IDRP_PSFT_DIST_LIST_EXCL    IDRP_PSFT_DISTEXCL
#define IDRP_PSFT_DIST_LIST_EXCLUDE IDRP_PSFT_DISTEXCL
#define IDRP_PSFT_MULTIEXIT	    BIT(0x09) /* test on MULTI_EXIT_DISCriminator */
#define IDRP_PSFT_MULTI_EXIT	    IDRP_PSFT_MULTIEXIT
#define IDRP_PSFT_MULTI_EXIT_DISC   IDRP_PSFT_MULTIEXIT
#define IDRP_PSFT_M_E_D    	    IDRP_PSFT_MULTIEXIT
#define IDRP_PSFT_MED    	    IDRP_PSFT_MULTIEXIT
#define IDRP_PSFT_ROUTESERV	    BIT(0x0a) /* test on Route_Server */
#define IDRP_PSFT_ROUTE_SERVER	    IDRP_PSFT_ROUTESERV
#define IDRP_PSFT_ROUTESERVER	    IDRP_PSFT_ROUTESERV
#define IDRP_PSFT_ROUTE_SERVER	    IDRP_PSFT_ROUTESERV
#define IDRP_PSFT_RS		    IDRP_PSFT_ROUTESERV
#define IDRP_PSFT_HIERARCH          BIT(0x0b) /* test on hierarchical recording */
#define IDRP_PSFT_HIERARCH_RECORDING        IDRP_PSFT_HIERARCH
#define IDRP_PSFT_HIERARCHICAL_REC          IDRP_PSFT_HIERARCH
#define IDRP_PSFT_HIER_REC          IDRP_PSFT_HIERARCH
#define IDRP_PSFT_HOPCNT            BIT(0x0c) /* test on hop count */
#define IDRP_PSFT_HOP_COUNT         IDRP_PSFT_HOPCNT
#define IDRP_PSFT_HOPCOUNT          IDRP_PSFT_HOPCNT
#define IDRP_PSFT_RD_HOP_COUNT      IDRP_PSFT_HOPCNT
#define IDRP_PSFT_CAPACITY	    BIT(0x0d) /* test on capacity */
#define IDRP_PSFT_DISTATT           BIT(0x0e) /* test on distinguished att's */
#define IDRP_PSFT_DIST_ATT          IDRP_PSFT_DISTATT
#define IDRP_PSFT_DIST_ATTRIBUTE    IDRP_PSFT_DISTATT
#define IDRP_PSFT_DISTINGUISHING_ATT        IDRP_PSFT_DISTATT
#define IDRP_PSFT_DIST_ATT          IDRP_PSFT_DISTATT
#define IDRP_PSFT_TRANSIT_DELAY     BIT(0x0f) /* test on Transit_Delay */
#define IDRP_PSFT_RESIDUAL_ERROR    BIT(0x10) /* test on Residual_Error */
#define IDRP_PSFT_EXPENSE 	    BIT(0x11) /* test on Expense */
#define IDRP_PSFT_PRIORITY 	    BIT(0x12) /* test on priority */
#define IDRP_PSFT_LOCALLY_DEF_QOS   BIT(0x13) /* test on Local QOS */
#define IDRP_PSFT_SECURITY          BIT(0x14) /* test on source-specific security */

#define IDRP_PSFT_LOCAL_IP_INTF     BIT(0x20) /* test on local interface */
#define IDRP_PSFT_LOCAL_SNPA        BIT(0x21) /* test on local interface */

#define IDRP_PSFT_RESTRICT	BIT(0x80) /* this is for use for 'no' route server, etc. */

#define IDRP_PSFT_TYPE		0x7f 	/* to get value of the flag (1 of the above) */

/*
 * This structure is the proposed form of IDRP's version of the
 * adv_ps field of the "struct _adv_entry" in policy.h *only*.
 * Just as adv's are linked together with a -single- test in each
 * adv, I propose to link together the following structures (with
 * a single test in each one) to store the information of 'import'
 * and 'export' statements.
 *
 * This is NOT the structure to be passed in as the route attribute
 * information for the route being tested in 'import' or 'export'; 
 * i.e., this is NOT the structure for the third parameter of
 * 'idrp_ps_dstmatch()', below.
 */
typedef struct _idrp_ps_t {
	flag_t ps_flag;
	union {
    	int     	psu_rib_id;         /* rib id of routes */
#define ps_rib_id ps_u.psu_rib_id
/* sjr-- skh : check to see if we want to change this next_hop to sockaddr_un * */
    	struct iso_net_addr     *psu_nexthop_net;       /* NET of next hop */
#define ps_iso_net_addr ps_u.psu_nexthop_net
#define ps_nexthop_net  ps_u.psu_nexthop_net
#define ps_nexthop_NET  ps_u.psu_nexthop_net
    	snpa_list       *psu_nexthop_snpas;     /* SNPA of next hop (or of local intf) */
#define ps_nexthop_snpas ps_u.psu_nexthop_snpas
#define ps_nexthop_SNPAs ps_u.psu_nexthop_snpas
#define ps_snpas 	 ps_u.psu_nexthop_snpas
#define ps_SNPAs 	 ps_u.psu_nexthop_snpas
    	sockaddr_un     *psu_p_nexthop_ipaddr;  /* ip address--for gateway or intf */
#define ps_gw           ps_u.psu_p_nexthop_ipaddr
#define ps_nexthop_gw   ps_u.psu_p_nexthop_ipaddr
#define ps_intf   	ps_u.psu_p_nexthop_ipaddr
#define ps_nexthop_intf	ps_u.psu_p_nexthop_ipaddr
	flag_t		psu_status;	    /* status flags - from route options */
#define ps_status ps_u.psu_status
    	qos_operator   	*psu_multi_exit;    /* multi_exit value on this route */
#define ps_multi_exit ps_u.psu_multi_exit
#define ps_multiexit  ps_u.psu_multi_exit
    	idrp_canon_rdpath       *psu_p_DIST_LIST_INCL;  /* list RDs to pass route to */
#define ps_DIST_LIST_INCL ps_u.psu_p_DIST_LIST_INCL
#define ps_dist_list_incl ps_u.psu_p_DIST_LIST_INCL
    	idrp_canon_rdpath       *psu_p_DIST_LIST_EXCL;  /* distribute list exclude */
#define ps_DIST_LIST_EXCL ps_u.psu_p_DIST_LIST_EXCL
#define ps_dist_list_excl ps_u.psu_p_DIST_LIST_EXCL
    	idrp_distinguish_att    *psu_p_qos; /* associated dist atts */
#define	ps_qos	ps_u.psu_p_qos
    	qos_operator   	*psu_hopcnt_pref;    /* hopcount function */
#define ps_hopcnt_pref	ps_u.psu_hopcnt_pref
#define ps_hopcount_pref ps_u.psu_hopcnt_pref
#define ps_hopcount	ps_u.psu_hopcnt_pref
    	qos_operator    *psu_capacity;      /* value for capacity */
#define ps_capacity	ps_u.psu_capacity
	idrp_pref_t psu_pref_calc;	    /* where we'll store _IDRP_ calculated preference */ 
#define	ps_pref_calc ps_u.psu_pref_calc
	} ps_u;
} idrp_ps_t;

/*
 * This is the proposed structure for use in externally representing the
 * route options, *and* in passing back the idrp CALCULATED pref.
 *
 * So, the third arg. of idrp_ps_dstmatch() would be cast to type
 * "idrpRoute_info *"; this means that the latter type would be
 * the structure passed in by the user when using 'import' (last arg), and
 * cast to "void *".
 *
 * NOTE:  If there is an actual preference, it will be in the idrp_pref
 * 	field.  If, however, there is only a hopcount offset value--i.e.,
 *	to be used in some calculation of preference--it will be in the 
 *    	Route_options->hopcount field.
 */
typedef struct _idrpRoute_info {
	idrp_pref_t idrp_pref;	/* The IDRP pref value returned by 'import'. */
	idrpRoute *p_idrp_rt;
/* How you get the p_opts out of the p_idrp_rt:
	p_idrp_rt->p_attr->p_opts
*/
	idrpRoute_options *route_options;
} idrpRoute_info;

/* Global invalid preference settings for
 * the idrp policy calcultion in idrp and gated
 */

#define		IDRP_INVALID_ROUTE_PREF		-1

/* was:
#define		IDRP_INVALID_ROUTE_PREF		300
*/
#define		IDRP_GATED_INVALID_ROUTE_PREF	255
#define		IDRP_GATED_INIT_ROUTE_PREF	0	

/* idrp definitions for Route Option 
 * values
 */

#define		IDRP_LOCAL_STATIC		0
#define		IDRP_LOCAL_EXTERIOR_OSISTATIC	1	
#define		IDRP_LOCAL_EXTERIOR_STATIC	2
#define		IDRP_LOCAL_SPECIAL_STATIC	3

extern adv_psfunc idrp_adv_psfunc;

/* Values of "status" are the flags in idrp.h. */
typedef struct _policy_rdpath {
	struct _policy_rdpath *p_next;	/* Next element */
	flag_t status;			/* Type of path element */
	struct _rdi *p_rdi;		/* RDI, if any */
} policy_rdpath;

typedef struct _policy_actual_path_tracking {
	int count; 	/* RDIs left to process for this path segment */
	int index; 	/* Index of current RDI in the rdi_array of this segment. */
	rdi_array *p_array; 	/* Current rdi_array in use for this segment. */
	rdpath *p_path;	/* The current element + rest of the RD path. */
} policy_actual_path_tracking;

#define FIND_POLICY_RDPATH_END(p_rdp) while ((p_rdp)->p_next) (p_rdp) = (p_rdp)->p_next
#endif /* idrp_policy_h */

