/*
 * Public Release 3
 * 
 * $Id: isis_lsp.h,v 1.2 1997/07/17 22:42:16 chopps Exp $
 */

/*
 * ------------------------------------------------------------------------
 * 
 * Copyright (c) 1996, 1997 The Regents of the University of Michigan
 * All Rights Reserved
 *  
 * Royalty-free licenses to redistribute GateD Release
 * 3 in whole or in part may be obtained by writing to:
 * 
 * 	Merit GateDaemon Project
 * 	4251 Plymouth Road, Suite C
 * 	Ann Arbor, MI 48105
 *  
 * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE
 * UNIVERSITY OF MICHIGAN AND MERIT DO NOT WARRANT THAT THE
 * FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR
 * THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE. The Regents of the
 * University of Michigan and Merit shall not be liable for
 * any special, indirect, incidental or consequential damages with respect
 * to any claim by Licensee or any third party arising from use of the
 * software. GateDaemon was originated and developed through release 3.0
 * by Cornell University and its collaborators.
 * 
 * Please forward bug fixes, enhancements and questions to the
 * gated mailing list: gated-people@gated.merit.edu.
 * 
 * ------------------------------------------------------------------------
 * 
 * Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University.
 *     All rights reserved.
 * 
 * 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.
 * 
 * GateD is based on Kirton's EGP, UC Berkeley's routing
 * daemon	 (routed), and DCN's HELLO routing Protocol.
 * Development of GateD has been supported in part by the
 * National Science Foundation.
 * 
 * ------------------------------------------------------------------------
 * 
 * Portions of this software may fall under the following
 * copyrights:
 * 
 * Copyright (c) 1988 Regents of the University of California.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms are
 * permitted provided that the above copyright notice and
 * this paragraph are duplicated in all such forms 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 California, Berkeley.  The name of the
 * University may not be used to endorse or promote
 * products derived from this software without specific
 * prior written permission.  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.
 * ------------------------------------------------------------------------
 * 
 * 	Copyright 1991 D.L.S. Associates
 * 
 * 	Permission to use, copy, modify, distribute, and sell this software
 * 	and its documentation for any purpose is hereby granted without
 * 	fee, provided that the above copyright notice appear in all copies
 * 	and that both that copyright notice and this permission notice
 * 	appear in supporting documentation, and that the name of D.L.S. not
 * 	be used in advertising or publicity pertaining to distribution of
 * 	the software without specific, written prior permission.  D.L.S.
 * 	makes no representations about the suitability of this software for
 * 	any purpose.  It is provided "as is" without express or implied
 * 	warranty.
 * 
 * 	D.L.S. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * 	INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 * 	NO EVENT SHALL D.L.S.  BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * 	CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * 	OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * 	NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * 	CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * 
 * 	Authors:  Robert Hagens and Dan Schuh
 * 
 * 
 */


#include "isis_dll.h"

struct _LSPDesc;

#include "isis_flood.h"

/*
 *	
 *	The following structures are used to represent a system's own LSP.
 *
 *	The idea to this whole mess is to keep adjacencies from migrating
 *	from one LSP to another. The scheme is that LSP 0 is special and
 *	only contains one or two options. Other options (ES neighbors
 *	IS neighbors, etc) are placed in their own individual LSPs.
 *
 *	Each LSP to be generated is described by the LSPDesc structure. This
 *	represents a single LSP with a list of options. The 'order' parameter
 *	is used to constrain the order in which the LSPDesc structs are mapped
 *	to LSP numbers: a lower value in the 'order' field indicates that the
 *	LSPDesc should be sent as a lower numbered LSP number. (This field
 *	is used to keep the IS options before the ES options and the
 *	IS options before the Prefix neighbor options. The use of this field
 *	implies that ES options/IS options/Prefix neighbor options are
 *	not placed in the same individual LSP.
 */

#define MaxOptLen		256

typedef enum {LSPzero, LSPlow, LSPhigh} LSPOrder;

/* 
 * These are new structures to deal with large numbers of prefixes.  We
 * use these to optimize prefix additions, deletions, and changes rather 
 * than LSP construction.  Eventually, similar prefixes (e.g., aspath,
 * rdpath, nexthop) will be lumped together in the same LSP in order
 * to reduce the amount of flooding necessary during "steady-state" 
 * operation.  Note that these structures are not identical to the PDU
 * formats.
 *
 * In the future, the as_path structure will be able to hold TSI which
 * I'll use to index the first LSPDesc containing that info.  Each LSPDesc
 * may contain 0 or more as_paths.  Each prefix LSPOption will contain
 * exactly 1 as_path.  Each LSPPrefixNeighborCode LSPOption will contain
 * exactly 1 (as_path, MetricList) tuple.  This makes it possible that
 * two different LSPDesc's will list the same as_path among their attributes,
 * with the MetricList being different among the options in each.  This
 * can also occur as a result of an LSPOption filling up, in turn filling
 * and LSPDesc, thereby bumping an LSPOption with a similar as_path - or 
 * even (as_path, MetricList) tuple - into another LSPDesc.  As for the 
 * difficulty related to prefix movement caused by metric changes, I expect
 * in the common case for the metric to be policy-based (slowly changing)
 * rather than eGP-derived (changing at the whim of external domains).  
 * This complexity exists only for ISO prefixes, because the metric is 
 * carried with the entire option rather than with each prefix.
 */

/* 
 * This guy keeps track of the path attributes referenced in a 
 * given LSPDesc's options. 
 */
typedef struct _LSPattr {
	as_path	*path;			/* path attributes */
	int refcount;			/* number of prefixes in a given option with these attributes */
	struct _LSPOption *idrpiOpt;	/* the IDRPi option for this set of attributes */
} LSPattr;

/* 
 * A single LSPDesc can have many LSPOptions (though we try to optimize
 * in the prefix case - see above).
 */
typedef struct _LSPOption {
	DLList		links;			/* must be first */
	struct _LSPDesc	*lspDesc;		/* ptr to parent LSPDesc */
	LSPOrder	key;			/* sort criteria for insertion with parent */
	LSPattr		*attr;			/* back pointer to the path attributes */
	int		refcount;		/* number of prefix options referring to this option (used by IDRPi option) */
	int		type;			/* type of option */
	int		len;			/* bytes of 'data' used so far */
	u_char 		*data;			/* pointer to the data */
} LSPOption;
#define LSPOptionSize(opt) 	 (opt->len+2)
#define LSPOptionUnused(opt) 	 (255-(LSPOptionSize(opt)))
#define	LSPOptionUnusedData(opt) (opt->data + opt->len)

typedef struct _prefIP {
	struct _prefIP	*prev, *next;
	LSPOption	*opt;		/* back pointer to the option */
	MetricList	metrics;			
	u_long		addr;
	u_long		mask;
} prefIP;

typedef struct _prefISO {
	struct _prefISO	*prev, *next;
	LSPOption	*opt;		/* back pointer to the option */
	MetricList	metrics;		
	int		len;		/* prefix length, in semi-octets */
	byte		addr[20];
} prefISO;

typedef struct _isis_asp {
	byte	code;		/* == 1, local format */
	u_long	version;	/* == 1 */
	u_long	data;		/* encoded path attributes */
} isis_asp;

/*
 *	This structure is used to identify a location in a LSPOption.
 */
typedef struct _LSPOptPtr {
	LSPOption	*opt;	/* ptr to option */
	u_char		off;	/* offset within option to start of entry data */
} LSPOptPtr;

/*
 *	a collection of individual LSPs together represent one "logical" LSP
 *	the LSPDesc structures are kept in order of increasing LSP number.
 */
typedef struct _LSPgroup {
	DLList		list;		/* list of individual LSPs */
	u_char		type;			/* type of LSP */
} LSPGroup;

/*
 *	Identifies an individual LSP
 */
typedef struct _LSPDesc {
	DLList		links;			/* must be first */
	u_char		lspNumber;
	u_char		lspPseudoID;		/* pseudonode ID */
	u_char		lspType;		/* type of LSP (L1 vs. L2) */
	u_short		lspInitLifetime;	/* initial value of the lifetime field */
	long		seqNumber;
	DLList		options;
	DLList		paths;			/* path attributes for prefixes in this LSPDesc's options */
	Boolean		schedRegenerate;	/* true if the LSP is scheduled to be regenerated (via timer) */
	Boolean		mustRegenerate;		/* true if the LSP must be regenerated (because it has changed) */
	time_t		lastGenerated;		/* used for generation throttle */
	short		spaceLeft;		/* remaining space in LSPDesc */
	u_char		*pktBuf;		/* buffer to build actual LSP in */
	u_short		pktSize;		/* size of pktBuf */
	LSEntry		*lspEntry;		/* place holder in LSP database */
	LSPGroup	*group;			/* back pointer to group */
        int		timer;			/* index of timer set for this LSP */
} LSPDesc;
