/*
 * bgp4+_var.h from bgp_var.h
 */

/*
 * ------------------------------------------------------------------------
 * 
 * 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.
 */


/*
 *	BGP4+ Private Definitions
 */

#undef BGPCONN_DONE
#define	BGPCONN_DONE(bnp) \
    do { \
	if (bnp->bgp_connect_slot != 0) { \
	    bgp4mp_connect_slots[bnp->bgp_connect_slot - 1]--; \
	    bnp->bgp_connect_slot = 0; \
	} \
    } while (0)

/*
 * Find the first entry on the queue
 */
#undef	BGP_ADV_FIRST
#define	BGP_ADV_FIRST(vqp)	(((vqp)->bgpv_next == (vqp)->bgpv_prev) \
    ? ((bgp_adv_entry6 *) 0) : ((bgp_adv_entry6 *)((vqp)->bgpv_next)))

/*
 * Find the next entry on the queue
 */
#undef	BGP_ADV_NEXT
#define	BGP_ADV_NEXT(vqp, entp)	(((entp)->bgpe_next == (vqp)) \
    ? ((bgp_adv_entry6 *) 0) : ((bgp_adv_entry6 *)((entp)->bgpe_next)))

/*
 * Macro to unlink an rto entry
 */
#undef	BGP_RTO_UNLINK
#ifdef	BGPDEBUG
#define	BGP_RTO_UNLINK(rto) \
    do { \
	register bgp_rto_entry6 *Xrto = (rto); \
	assert(Xrto->bgpo_prev->bgpo_next == Xrto \
	    && Xrto->bgpo_next->bgpo_prev == Xrto); \
	Xrto->bgpo_prev->bgpo_next = Xrto->bgpo_next; \
	Xrto->bgpo_next->bgpo_prev = Xrto->bgpo_prev; \
	Xrto->bgpo_next = Xrto->bgpo_prev = (bgp_rto_entry6 *) 0; \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_RTO_UNLINK(rto) \
    do { \
	register bgp_rto_entry6 *Xrto = (rto); \
	Xrto->bgpo_prev->bgpo_next = Xrto->bgpo_next; \
	Xrto->bgpo_next->bgpo_prev = Xrto->bgpo_prev; \
    } while (0)
#endif	/* BGPDEBUG */


/*
 * Macro to unlink a grto entry
 */
#undef	BGP_GRTO_UNLINK
#ifdef	BGPDEBUG
#define	BGP_GRTO_UNLINK(grto) \
    do { \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	assert(Xgrto->bgpgo_prev->bgpgo_next == Xgrto \
	    && Xgrto->bgpgo_next->bgpgo_prev == Xgrto); \
	Xgrto->bgpgo_prev->bgpgo_next = Xgrto->bgpgo_next; \
	Xgrto->bgpgo_next->bgpgo_prev = Xgrto->bgpgo_prev; \
	Xgrto->bgpgo_next = Xgrto->bgpgo_prev = (bgpg_rto_entry6 *) 0; \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_GRTO_UNLINK(grto) \
    do { \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	Xgrto->bgpgo_prev->bgpgo_next = Xgrto->bgpgo_next; \
	Xgrto->bgpgo_next->bgpgo_prev = Xgrto->bgpgo_prev; \
    } while (0)
#endif	/* BGPDEBUG */

/*
 * Macro to remove a group rtinfo entry
 */
#undef	BGP_RTINFO_UNLINK
#ifdef	BGPDEBUG
#define	BGP_RTINFO_UNLINK(grto, rtinfo) \
    do { \
	register bgpg_rtinfo_entry6 *Xinfo = (rtinfo); \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	if (Xgrto->bgpgo_info == Xinfo) { \
	    Xgrto->bgpgo_info = Xinfo->bgp_info_next; \
	} else { \
	    register bgpg_rtinfo_entry6 *Xinfo_prev = Xgrto->bgpgo_info; \
	    do { \
		if (Xinfo_prev->bgp_info_next == Xinfo) { \
		    Xinfo_prev->bgp_info_next = Xinfo->bgp_info_next; \
		    break; \
		} \
	    } while ((Xinfo_prev = Xinfo_prev->bgp_info_next)); \
	    assert(Xinfo_prev); \
	} \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_RTINFO_UNLINK(grto, rtinfo) \
    do { \
	register bgpg_rtinfo_entry6 *Xinfo = (rtinfo); \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	if (Xgrto->bgpgo_info == Xinfo) { \
	    Xgrto->bgpgo_info = Xinfo->bgp_info_next; \
	} else { \
	    register bgpg_rtinfo_entry6 *Xinfo_prev = Xgrto->bgpgo_info; \
	    do { \
		if (Xinfo_prev->bgp_info_next == Xinfo) { \
		    Xinfo_prev->bgp_info_next = Xinfo->bgp_info_next; \
		    break; \
		} \
	    } while ((Xinfo_prev = Xinfo_prev->bgp_info_next)); \
	} \
    } while (0)
#endif	/* BGPDEBUG */




/*
 * Given an rt queue pointer, determine the asp list address
 */
#undef	ASPL_FROM_QUEUE
#define	ASPL_FROM_QUEUE(qp) \
    ((bgp_asp_list6 *)((void_t)(((byte *)(qp)) \
    - offsetof(bgp_asp_list6, bgpl_asp_queue))))

/*
 * Initialize an asp list
 */
#undef	BGP_ASPL_INIT
#define	BGP_ASPL_INIT(aspl) \
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	Xaspl->bgpl_rto_prev = Xaspl->bgpl_rto_next \
	  = (bgp_rto_entry6 *)Xaspl; \
    } while (0)

/*
 * Remove an AS path list from the queue, making sure the hash
 * is up to date.
 */
#undef	BGP_ASPL_REMOVE
#ifdef	BGPDEBUG
#define	BGP_ASPL_REMOVE(qp, aspl) \
    do { \
	register bgp_rt_queue *Xqp = (qp); \
	register bgp_asp_list6 *Xaspl = (aspl); \
	assert(Xaspl->bgpl_q_prev->bgpq_next == &Xaspl->bgpl_asp_queue \
	    && Xaspl->bgpl_q_next->bgpq_prev == &Xaspl->bgpl_asp_queue); \
	if (Xaspl->bgpl_asp) { \
	    register int Xhash = Xaspl->bgpl_asp->path_hash; \
	    assert(Xaspl->bgpl_asp_hash_check == Xhash \
		&& (Xqp->bgpq_asp_hash)[Xhash]); \
	    if ((Xqp->bgpq_asp_hash)[Xhash] == (bgp_asp_list *)Xaspl) { \
		if (Xaspl->bgpl_q_next == Xqp \
		  || Xaspl->bgpl_q_next->bgpq_asp->path_hash != Xhash) { \
		    (Xqp->bgpq_asp_hash)[Xhash] = (bgp_asp_list *) 0; \
		} else { \
		    assert(Xaspl->bgpl_q_next->bgpq_asp_hash_check == Xhash); \
		    (Xqp->bgpq_asp_hash)[Xhash] \
		       = (bgp_asp_list *)ASPL_FROM_QUEUE(Xaspl->bgpl_q_next); \
		} \
	    } \
	} else { \
	    assert(Xaspl->bgpl_asp_hash_check == (-1)); \
	} \
	Xaspl->bgpl_q_next->bgpq_prev = Xaspl->bgpl_q_prev; \
	Xaspl->bgpl_q_prev->bgpq_next = Xaspl->bgpl_q_next; \
	Xaspl->bgpl_q_prev = Xaspl->bgpl_q_next = (bgp_rt_queue *) 0; \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_ASPL_REMOVE(qp, aspl) \
    do { \
	register bgp_rt_queue *Xqp = (qp); \
	register bgp_asp_list6 *Xaspl = (aspl); \
	if (Xaspl->bgpl_asp) { \
	    register int Xhash = Xaspl->bgpl_asp->path_hash; \
	    if ((Xqp->bgpq_asp_hash)[Xhash] == (bgp_asp_list *)Xaspl) { \
		if (Xaspl->bgpl_q_next == Xqp \
		  || Xaspl->bgpl_q_next->bgpq_asp->path_hash != Xhash) { \
		    (Xqp->bgpq_asp_hash)[Xhash] = (bgp_asp_list *) 0; \
		} else { \
		    (Xqp->bgpq_asp_hash)[Xhash] \
		       = (bgp_asp_list *)ASPL_FROM_QUEUE(Xaspl->bgpl_q_next); \
		} \
	    } \
	} \
	Xaspl->bgpl_q_next->bgpq_prev = Xaspl->bgpl_q_prev; \
	Xaspl->bgpl_q_prev->bgpq_next = Xaspl->bgpl_q_next; \
    } while (0)
#endif	/* BGPDEBUG */

/*
 * True when an asp list has no queued routes
 */
#undef	BGP_ASPL_EMPTY
#define	BGP_ASPL_EMPTY(aspl) \
	((aspl)->bgpl_rto_next == ((bgp_rto_entry6 *)(aspl)))

/*
 * Return the first AS path list on a queue, null if none
 */
#undef	BGP_ASPL_FIRST
#ifdef	BGPDEBUG
#define	BGP_ASPL_FIRST(qp)	(((qp)->bgpq_next == (qp)) \
    ? ((bgp_asp_list6 *) 0) : (((qp)->bgpq_prev && \
    (qp)->bgpq_next->bgpq_prev == (qp)) \
    ? ASPL_FROM_QUEUE((qp)->bgpq_next) : ((bgp_asp_list6 *)BGP_BLEWIT())))
#else	/* BGPDEBUG */
#define	BGP_ASPL_FIRST(qp)	(((qp)->bgpq_next == (qp)) \
    ? ((bgp_asp_list6 *) 0) : ASPL_FROM_QUEUE((qp)->bgpq_next))
#endif	/* BGPDEBUG */

/*
 * Return the next AS path list on a queue, null if none
 */
#undef	BGP_ASPL_NEXT
#ifdef	BGPDEBUG
#define	BGP_ASPL_NEXT(qp, aspl)	(((aspl)->bgpl_q_next == (qp)) \
    ? ((bgp_asp_list6 *) 0) : (((aspl)->bgpl_q_prev \
    && ASPL_FROM_QUEUE((aspl)->bgpl_q_next->bgpq_prev) == (aspl)) \
    ? ASPL_FROM_QUEUE((aspl)->bgpl_q_next) : ((bgp_asp_list6 *)BGP_BLEWIT())))
#else	/* BGPDEBUG */
#define	BGP_ASPL_NEXT(qp, aspl)	(((aspl)->bgpl_q_next == (qp)) \
    ? ((bgp_asp_list6 *) 0) : ASPL_FROM_QUEUE((aspl)->bgpl_q_next))
#endif	/* BGPDEBUG */


/*
 * Add an rto entry to the end of the aspl list.
 */
#undef	BGP_RTO_ADD_END
#ifdef	BGPDEBUG
#define	BGP_RTO_ADD_END(aspl, rto) \
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	register bgp_rto_entry6 *Xrto = (rto); \
	assert(!Xrto->bgpo_prev && !Xrto->bgpo_next); \
	Xrto->bgpo_next = (bgp_rto_entry6 *)Xaspl; \
	(Xrto->bgpo_prev = Xaspl->bgpl_rto_prev)->bgpo_next = Xrto; \
	Xaspl->bgpl_rto_prev = Xrto; \
    } while (0)
#else	/* BGPDEBUG */
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	register bgp_rto_entry6 *Xrto = (rto); \
	Xrto->bgpo_next = (bgp_rto_entry6 *)Xaspl; \
	(Xrto->bgpo_prev = Xaspl->bgpl_rto_prev)->bgpo_next = Xrto; \
	Xaspl->bgpl_rto_prev = Xrto; \
    } while (0)
#endif	/* BGPDEBUG */

/*
 * Add a grto entry to the end of the aspl list.
 */
#undef	BGP_GRTO_ADD_END
#ifdef	BGPDEBUG
#define	BGP_GRTO_ADD_END(aspl, grto) \
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	assert(!Xgrto->bgpgo_prev && !Xgrto->bgpgo_next); \
	Xgrto->bgpgo_next = (bgpg_rto_entry6 *)Xaspl; \
	(Xgrto->bgpgo_prev = Xaspl->bgpl_grto_prev)->bgpgo_next = Xgrto; \
	Xaspl->bgpl_grto_prev = Xgrto; \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_GRTO_ADD_END(aspl, grto) \
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	Xgrto->bgpgo_next = (bgpg_rto_entry6 *)Xaspl; \
	(Xgrto->bgpgo_prev = Xaspl->bgpl_grto_prev)->bgpgo_next = Xgrto; \
	Xaspl->bgpl_grto_prev = Xgrto; \
    } while (0)
#endif	/* BGPDEBUG */

/*
 * Add an rto entry to the head of the aspl list.
 */
#undef	BGP_RTO_ADD_HEAD
#ifdef	BGPDEBUG
#define	BGP_RTO_ADD_HEAD(aspl, rto) \
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	register bgp_rto_entry6 *Xrto = (rto); \
	assert(!Xrto->bgpo_prev && !Xrto->bgpo_next); \
	Xrto->bgpo_prev = (bgp_rto_entry6 *)Xaspl; \
	(Xrto->bgpo_next = Xaspl->bgpl_rto_next)->bgpo_prev = Xrto; \
	Xaspl->bgpl_rto_next = Xrto; \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_RTO_ADD_HEAD(aspl, rto) \
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	register bgp_rto_entry6 *Xrto = (rto); \
	Xrto->bgpo_prev = (bgp_rto_entry6 *)Xaspl; \
	(Xrto->bgpo_next = Xaspl->bgpl_rto_next)->bgpo_prev = Xrto; \
	Xaspl->bgpl_rto_next = Xrto; \
    } while (0)
#endif	/* BGPDEBUG */

/*
 * Add a grto entry to the head of the aspl list.
 */
#undef	BGP_GRTO_ADD_HEAD
#ifdef	BGPDEBUG
#define	BGP_GRTO_ADD_HEAD(aspl, grto) \
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	assert(!Xgrto->bgpgo_prev && !Xgrto->bgpgo_next); \
	Xgrto->bgpgo_prev = (bgpg_rto_entry6 *)Xaspl; \
	(Xgrto->bgpgo_next = Xaspl->bgpl_grto_next)->bgpgo_prev = Xgrto; \
	Xaspl->bgpl_grto_next = Xgrto; \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_GRTO_ADD_HEAD(aspl, grto) \
    do { \
	register bgp_asp_list6 *Xaspl = (aspl); \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	Xgrto->bgpgo_prev = (bgpg_rto_entry6 *)Xaspl; \
	(Xgrto->bgpgo_next = Xaspl->bgpl_grto_next)->bgpgo_prev = Xgrto; \
	Xaspl->bgpl_grto_next = Xgrto; \
    } while (0)
#endif	/* BGPDEBUG */

/*
 * Add an rto entry after the current entry
 */
#undef	BGP_RTO_ADD_AFTER
#ifdef	BGPDEBUG
#define	BGP_RTO_ADD_AFTER(rtoprev, rto) \
    do { \
	register bgp_rto_entry6 *Xrto = (rto); \
	register bgp_rto_entry6 *Xrtoprev = (rtoprev); \
	assert(!Xrto->bgpo_prev && !Xrto->bgpo_next && Xrtoprev->bgpo_prev); \
	Xrto->bgpo_prev = Xrtoprev; \
	(Xrto->bgpo_next = Xrtoprev->bgpo_next)->bgpo_prev = Xrto; \
	Xrtoprev->bgpo_next = Xrto; \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_RTO_ADD_AFTER(rtoprev, rto) \
    do { \
	register bgp_rto_entry6 *Xrto = (rto); \
	register bgp_rto_entry6 *Xrtoprev = (rtoprev); \
	Xrto->bgpo_prev = Xrtoprev; \
	(Xrto->bgpo_next = Xrtoprev->bgpo_next)->bgpo_prev = Xrto; \
	Xrtoprev->bgpo_next = Xrto; \
    } while (0)
#endif	/* BGPDEBUG */


/*
 * Add a grto entry after the current entry
 */
#undef	BGP_GRTO_ADD_AFTER
#ifdef	BGPDEBUG
#define	BGP_GRTO_ADD_AFTER(grtoprev, grto) \
    do { \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	register bgpg_rto_entry6 *Xgrtoprev = (grtoprev); \
	assert(!Xgrto->bgpgo_prev \
	    && !Xgrto->bgpgo_next \
	    && Xgrtoprev->bgpgo_prev); \
	Xgrto->bgpgo_prev = Xgrtoprev; \
	(Xgrto->bgpgo_next = Xgrtoprev->bgpgo_next)->bgpgo_prev = Xgrto; \
	Xgrtoprev->bgpgo_next = Xgrto; \
    } while (0)
#else	/* BGPDEBUG */
#define	BGP_GRTO_ADD_AFTER(grtoprev, grto) \
    do { \
	register bgpg_rto_entry6 *Xgrto = (grto); \
	register bgpg_rto_entry6 *Xgrtoprev = (grtoprev); \
	Xgrto->bgpgo_prev = Xgrtoprev; \
	(Xgrto->bgpgo_next = Xgrtoprev->bgpgo_next)->bgpgo_prev = Xgrto; \
	Xgrtoprev->bgpgo_next = Xgrto; \
    } while (0)
#endif	/* BGPDEBUG */



/*
 * Same than BGPB_CLEAR but return allclear only. Evaluates len twice.
 */
#define	BGPB_WILL_CLEAR(bits, bits2clear, len, allclear) \
    do { \
	if ((len) == 1) { \
	    (allclear) = ((*(bits) & ~(*(bits2clear))) == 0); \
	} else { \
	    register bgp_bits *Xb = (bits); \
	    register bgp_bits *Xb2c = (bits2clear); \
	    register bgp_bits *Xbend = Xb + (len); \
	    register int Xstillset = 0; \
	    while (Xb < Xbend) { \
		if ((*Xb & ~(*Xb2c)) != 0) { \
		    Xstillset++; \
		} \
		Xb++; \
		Xb2c++; \
	    } \
	    (allclear) = (Xstillset == 0); \
	} \
    } while (0)

/*
 * Collect all the bits in the rtinfo entries connected to a group
 * rto entry.
 */
#undef	BGPB_INFOBITS
#define	BGPB_INFOBITS(bits, rtop, bitlen) \
    do { \
	register bgpg_rtinfo_entry6 *Xinfop = (rtop)->bgpgo_info; \
	register bgp_bits *Xbits = (bits); \
	if ((bitlen) == 1) { \
	    *Xbits = *(Xinfop->bgp_info_bits); \
	    while ((Xinfop = Xinfop->bgp_info_next) \
	      != (bgpg_rtinfo_entry6 *) 0) { \
		*Xbits |= *(Xinfop->bgp_info_bits); \
	    } \
	} else { \
	    register bgp_bits *Xb2add; \
	    register bgp_bits *Xb; \
	    register bgp_bits *Xbend = Xbits + (bitlen); \
	    Xb = Xbits; \
	    Xb2add = Xinfop->bgp_info_bits; \
	    do { \
		*Xb++ = *Xb2add++; \
	    } while (Xb < Xbend); \
	    while ((Xinfop = Xinfop->bgp_info_next) \
	      != (bgpg_rtinfo_entry6 *) 0) { \
		Xb = Xbits; \
		Xb2add = Xinfop->bgp_info_bits; \
		do { \
		    *Xb++ |= *Xb2add++; \
		} while (Xb < Xbend); \
	    } \
	} \
    } while (0)


/*
 * Variables in bgp4+_init.c
 */
extern bgpPeerGroup *bgp4mp_groups;	/* group list */
extern int bgp4mp_n_groups;		/* number of groups in list */
extern int bgp4mp_n_peers;		/* total number of peers */
extern int bgp4mp_n_unconfigured;	/* number of unconfigured peers */
extern int bgp4mp_n_established;	/* number of established peers */

/*
 * Routines in bgp4+_rt.c
 */
PROTOTYPE(bgp4mp_rt_unsync,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_rt_sync,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_rt_if_terminate,
	  extern void,
	  (bgpPeerGroup *,
	   if_addr *));
PROTOTYPE(bgp4mp_aux_flash,
	  extern void,
	  (task *,
	   rt_list *));
PROTOTYPE(bgp4mp_aux_newpolicy,
	  extern void,
	  (task *,
	  rt_list *));
PROTOTYPE(bgp4mp_rt_group_delete,
	  extern void,
	  (bgpPeerGroup *));
PROTOTYPE(bgp4mp_rt_send_init,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_rt_terminate,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_rt_send_ready,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_rt_peer_timer,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_rt_group_timer,
	  extern void,
	  (bgpPeerGroup *));
PROTOTYPE(bgp4mp_rt_init,
	  extern void,
	  (void));

/*
 * Routines in bgp4+_init.c
 */
PROTOTYPE(bgp4mp_pp_delete,
	  extern void,
	  (bgpProtoPeer *));
PROTOTYPE(bgp4mp_recv_change,
	  extern void,
	  (bgpPeer *,
	  _PROTOTYPE(recv_rtn,
		     void,
		     (task *)),
	  const char *));
PROTOTYPE(bgp4mp_write_message,
	  extern void,
	  (bgpPeer *,
	   byte *,
	   size_t,
	   int));
PROTOTYPE(bgp4mp_force_write,
	  extern int,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_set_write,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_set_flash,
	  extern void,
	  (task *,
	   _PROTOTYPE(flash_rtn,
		      void,
		      (task *,
		       rt_list *)),
	   _PROTOTYPE(newpolicy_rtn,
		      void,
		      (task *,
		       rt_list *))));
PROTOTYPE(bgp4mp_reset_flash,
	  extern void,
	  (task *));
PROTOTYPE(bgp4mp_set_reinit,
	  extern void,
	  (task *,
	   _PROTOTYPE(reinit_rtn,
		      void,
		      (task *))));
PROTOTYPE(bgp4mp_reset_reinit,
	  extern void,
	  (task *));
PROTOTYPE(bgp4mp_find_group,
	  extern bgpPeerGroup *,
	  (sockaddr_un *,
	   sockaddr_un *,
	   as_t,
	   as_t,
	   int,
	   byte *,
	   int));
PROTOTYPE(bgp4mp_find_group_by_addr,
	  extern bgpPeerGroup *,
	  (sockaddr_un *,
	   sockaddr_un *));
PROTOTYPE(bgp4mp_new_peer,
	  extern bgpPeer *,
	  (bgpPeerGroup *,
	   bgpProtoPeer *,
	   size_t));
PROTOTYPE(bgp4mp_use_protopeer,
	  extern void,
	  (bgpPeer *,
	   bgpProtoPeer *,
	   size_t));
PROTOTYPE(bgp4mp_peer_close,
	  extern void,
	  (bgpPeer *,
	   int));
PROTOTYPE(bgp4mp_peer_established,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_route_timer_set,
	  extern void,
	  (bgpPeer *));
PROTOTYPE(bgp4mp_group_route_timer_set,
	  extern void,
	  (bgpPeerGroup *));

/*
 * Routines in bgp4+.c
 */
PROTOTYPE(bgp4mp_send,
	  extern int,
	  (bgpPeer *,
	   byte *,
	   size_t,
	   int));
PROTOTYPE(bgp4mp_send_open,
	  extern int,
	  (bgpPeer *,
	   int));
PROTOTYPE(bgp4mp_send_keepalive,
	  extern int,
	  (bgpPeer *,
	   int));
PROTOTYPE(bgp4mp_send_notify,
	  extern void,
	  (bgpPeer *,
	   int,
	   int,
	   byte *,
	   int));
PROTOTYPE(bgp4mp_send_notify_none, extern void, (bgpPeer *, int, int));
PROTOTYPE(bgp4mp_send_notify_byte, extern void, (bgpPeer *, int, int, int));
PROTOTYPE(bgp4mp_send_notify_word, extern void, (bgpPeer *, int, int, int));
PROTOTYPE(bgp4mp_pp_notify_none, extern void,
	 (bgpProtoPeer *, bgpPeerGroup *, bgpPeer *, int, int));
PROTOTYPE(bgp4mp_recv_open, extern void, (task *));
PROTOTYPE(bgp4mp_pp_recv, extern void, (task *));

/*
 * Stuff in bgp4+_sync.c
 */
PROTOTYPE(bgp4mp_sync_rt_add,
	  extern rt_entry *,
	  (bgp_sync6 *,
	   bgpPeer *,
	   rt_head *,
	   rt_parms *));
PROTOTYPE(bgp4mp_sync_rt_change,
	  extern rt_entry *,
	  (bgp_sync6 *,
	   bgpPeer *,
	   rt_entry *,
	   metric_t,
	   metric_t,
	   tag_t,
	   pref_t,
	   pref_t,
	   int,
	   sockaddr_un **,
	   as_path *));
PROTOTYPE(bgp4mp_sync_rt_delete,
	  extern void,
	  (bgp_sync6 *,
	   rt_entry *));
PROTOTYPE(bgp4mp_sync_igp_rt,
	  extern void,
	  (bgp_sync6 *,
	   rt_head *));
PROTOTYPE(bgp4mp_sync_terminate,
	  extern void,
	  (bgp_sync6 *));
PROTOTYPE(bgp4mp_sync_init,
	  extern bgp_sync6 *,
	  (bgpPeerGroup *));
