/* 
 * $Id: idrp_out_list.c,v 1.3 1995/10/08 17:04:55 skh Exp $ 
 * Merit IDRP release 1.1 (gated 3.5.4).  Copyright (c) 1994 by Merit Network, Inc. 
 */

#include "include.h"
#include "iso.h"
#include "idrp.h"


/* idrp_out_list.c - 
 * 
 * 1) create_idrp_out_att - create idrp outbound attribute
 * 2) free_out_att - free secondary storage on the attribute
 * 3) idrp_free_out_list - free the outbound list
 * 4) link_out_att - link attribute on the attribute list
 * 5) unlink_out_att - unlink the attribute from the attribute list 	
 */


idrp_attribute_record *
create_idrp_out_att(p_idrp_rt,peer)
idrpRoute	*p_idrp_rt;
idrpPeer	*peer;
{
idrp_attribute_record *p_attr;
idrp_attribute_record *p_att;

/*
 *  copy into a new attribute record -
 *   1) point to existing attribute record
 *      for data fields in normal attribute
 *   2) user attributes
 *   3) transitive attributes
 */


	p_attr = p_idrp_rt->p_attr;
	p_att = (idrp_attribute_record *) idrp_local_mem_fit(sizeof(idrp_attribute_record));
	p_att->peer_alloc = peer;
	p_att->local_mask = IDRP_LOCAL_OUTPUT_ATTR;

	p_att->rib_id = p_attr->rib_id;
	p_att->idrp_mask = p_attr->idrp_mask;
	p_att->p_transitive = p_attr->p_transitive;

	bcopy(&p_attr->attrib[0],&p_att->attrib[0],(sizeof(idrp_attribute_entry)*IDRP_ATTR_NO)); 
	bcopy(&p_attr->usr_attrib[0],&p_att->usr_attrib[0],(sizeof(idrp_attribute_entry)*IDRP_ATTR_NO));
	return(p_att);
}

free_out_att(p_att)
idrp_attribute_record	*p_att;
{
	/* free the things listed under the 
	 * local mask for the outboud 
	 * 	
	 */

	if (p_att->local_mask)
		{
		if (p_att->local_mask & IDRP_OATT_MULTI_EXIT_DISC)
			{
			/* free the multi_exit space */

				
			}

		if (p_att->local_mask & (IDRP_OATT_RDPATH_CONFED | IDRP_OATT_RDPATH_CONFED_POL | IDRP_OATT_RDPATH_AGGR ))
			{
			/* free the new rdpath 
			*/

			}

		if (p_att->local_mask & (IDRP_OATT_DIST_LIST_NEW | IDRP_OATT_DIST_LIST_EXIST))
			{
			/* free the DIST_LIST space for the attribute 
			 * and the dist list
			 */

			}
  
		if (p_att->local_mask & (IDRP_OATT_CAPACITY))
			{
			/* free the attribute for the capacity
			 */

			}
		}  
			 
	
	/* free the idrp_attribute record itself
	 */

	IDRP_MEM_FIT_FREE(p_att);

}

void
idrp_free_outatt_list()
{
idrp_attribute_record *p_att;
int	rib_id = 0;


	QOS_RIB_LIST(rib_id)
		{
		OATT_LIST_NULL(rib_id)
			{
                       trace_tf(idrp_trace_options,0,TR_NORMAL,  ("idrp_free_outatt_list null  %x", rib_id));
			}
		else OATT_LIST_EMPTY(rib_id) 
		 	{
			/*
			 * - empty list
			 */
                       trace_tf(idrp_trace_options,0,TR_NORMAL,  ("idrp_free_outatt_list empty rib id %x", rib_id));
		    	}
		else
		   	{		
			OATTR_LIST(p_att,rib_id)	
				{
				unlink_out_att(p_att);
				free_out_att(p_att);
				} OATTR_LIST_END;

			}
		} QOS_RIB_LIST_END;
}



void
link_out_att(p_att)
idrp_attribute_record *p_att;
{
int	rib_id = p_att->rib_id;

	OATT_LIST_EMPTY(rib_id)
		{
		OATT_LIST_HEAD(rib_id) = OATT_LIST_END(rib_id) = p_att;
		}
	else	
		{
		OATT_LIST_END(rib_id)->next = p_att;
		p_att->prev = OATT_LIST_END(rib_id);
		OATT_LIST_END(rib_id) = p_att;
		}
   
}		

void
unlink_out_att(p_att)
idrp_attribute_record *p_att;
{
int	rib_id = p_att->rib_id;

	/* if the start of the attribute record
	 */
	
	
	if (OATT_LIST_HEAD(rib_id) == p_att)
		{
		OATT_LIST_HEAD(rib_id) = p_att->next;
		if (p_att->next)
			{
			p_att->next->prev = (idrp_attribute_record *) 0;
			}
		else
			{
			assert(OATT_LIST_END(rib_id) == p_att);
			OATT_LIST_END(rib_id) = (idrp_attribute_record *) NULL;
			}
	
		}
	else
		{
		p_att->prev->next = p_att->next;
		if (p_att->next)
			{
			p_att->next->prev = p_att->prev;
			}
		else
			{
			assert(OATT_LIST_END(rib_id) == p_att);
			OATT_LIST_END(rib_id) = p_att->prev;
			}
		}	
	
}

