⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsvp_llkern.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * @(#) $Id: rsvp_LLkern.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_LLkern.c  ***************************** *                                                                   * *      Link-layer-dependent adaptation layer (LLDAL) routines	     * *	for interfacing to a "kernel" traffic control mechanism.     * *	This supports QoS over passive media such as leased lines or * *	(today's) shared LAN media.                                  * *                                                                   * *                                                                   * *********************************************************************//****************************************************************************            RSVPD -- ReSerVation Protocol Daemon                USC Information Sciences Institute                Marina del Rey, California            Original Version: Shai Herzog, Nov. 1993.	    Current Version:  Steven Berson & Bob Braden, may 1996.  Copyright (c) 1996 by the University of Southern California  All rights reserved.  Permission to use, copy, modify, and distribute this software and its  documentation in source and binary forms for any purpose and without  fee is hereby granted, provided that both the above copyright notice  and this permission notice appear in all copies, and that any  documentation, advertising materials, and other materials related to  such distribution and use acknowledge that the software was developed  in part by the University of Southern California, Information  Sciences Institute.  The name of the University may not be used to  endorse or promote products derived from this software without  specific prior written permission.  THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about  the suitability of this software for any purpose.  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.  Other copyrights might apply to parts of this software and are so  noted when applicable.********************************************************************/#include "rsvp_daemon.h"#include "rsvp_TCif.h"/* *	External declarations */int		Compute_Path_Props(Session *, RSB *, FiltSpecStar *,					 SENDER_TSPEC *, ADSPEC **, int *);int		Is_B_Police(Session *, RSB *);Object_header *	copy_object(Object_header *);int		match_filter(FILTER_SPEC *, FILTER_SPEC *);int		Compare_Flowspecs(FLOWSPEC *, FLOWSPEC *);FLOWSPEC  *	LUB_of_Flowspecs(FLOWSPEC *, FLOWSPEC *);int		Compare_Tspecs(SENDER_TSPEC *, SENDER_TSPEC *);void		send_confirm(Session *, RSB *);int		find_fstar(FILTER_SPEC *, FiltSpecStar *);FiltSpecStar *	Get_FiltSpecStar(int);char	*	fmt_flowspec(FLOWSPEC *);char	*	fmt_tspec(SENDER_TSPEC *);char	*	cnv_flags(char *, u_char);/* *	Forward declarations */TCSB	*	locate_TCSB(Session *, int, FiltSpecStar *, style_t);/* *	RSBs4_sameLL(rp1, rp2): Predicate true if two RSBs map into *		the same link layer reservation block. */#define RSBs4_sameLL(rp1, rp2) ((rp1->rs_OIf == rp2->rs_OIf) && \		( Style_is_Shared(rp1->rs_style) || \		  match_filter(rp1->rs_filter0, rp2->rs_filter0)))/*	Call-back routines. * *	External references to the core-RSVP routines that do processing *	that must follow completion of a corresponding LLDAL call. *	This is because LLDAL calls may invoke link-layer control *	functions that will not complete immediately, and avoids *	internal threading of rsvpd.  When an LLDAL call is *	asynchronous, it will return an immediate code indicating *	that, and then the LLDAL will invoke the call-back routine *	with the real return code when the function does complete. */extern int	Complete_NewFlow(Session *, RSB *, int);extern int	Complete_ModFlowspec(Session *, RSB *, int);extern int	Complete_ModFilter(Session *, RSB *, int);extern int	Complete_DelFlow(Session *, RSB *, int);/** extern int	Complete_Advertise(Session *, PSB *, int); **//** extern int	Complete_BugDump(Session *, int); **//* *	Forward declarations: LLDAL Interface Routines */void    	KernTC_if_init(int OIf);int		KernTC_NewFlow(Session *, RSB *);int		KernTC_ModFlowspec(Session *, RSB *);int		KernTC_ModFilter(Session *, RSB *);int		KernTC_DelFlow(Session *, RSB *);int		KernTC_Advertise(int, Session *, PSB *);int		KernTC_GetInfo(Session *, RSB *);int		KernTC_BugDump(int OIf, Session *);/* *	Forward declarations: Internal Routines */int		Kernel_SetFilters(Session *, TCSB *, FiltSpecStar *);int		Kernel_Merge(Session *, RSB *, FLOWSPEC **, FiltSpecStar **);int		Kernel_Return_Spec(Session *, RSB *, FLOWSPEC *);int		union_filtstar(FiltSpecStar *, FiltSpecStar **);TCSB	*	make_TCSB(Session *, int, int);TCSB	*	trade_TCSB(Session *, TCSB *, int);void		kill_TCSB(Session *, TCSB *);void		log_K(int, Session *, TCSB *);/*  *  Initialize transfer vector for a given interface */voidKernTC_if_init(int OIf)	{	if_vec[OIf].if_LLifv.LL_NewFlow_p = &KernTC_NewFlow;	if_vec[OIf].if_LLifv.LL_ModFlowspec_p = &KernTC_ModFlowspec;	if_vec[OIf].if_LLifv.LL_ModFilter_p = &KernTC_ModFilter;	if_vec[OIf].if_LLifv.LL_DelFlow_p = &KernTC_DelFlow;	if_vec[OIf].if_LLifv.LL_Advertise_p = &KernTC_Advertise;	if_vec[OIf].if_LLifv.LL_GetInfo_p = &KernTC_GetInfo;	if_vec[OIf].if_LLifv.LL_BugDump_p = &KernTC_BugDump;#ifdef SCHEDULE	TC_init(OIf);#endif /* SCHEDULE */}/* *  KernTC_NewFlow(Session, active RSB [=> Interface, NextHop, *				FiltSpecList, Flowspec, Style) * *      Add a new flow reservation request.  RSB is used as a parameter *	list to pass (interface, NHOP, style, flowspec, filter_spec_list). */intKernTC_NewFlow(Session *destp, RSB *rp)	{	TCSB		*kp = NULL;	FLOWSPEC	*Fwd_specp = NULL;	SENDER_TSPEC	 Path_Te;	ADSPEC		*adspecp = NULL;	int		 TC_kflags = 0, s_count;	u_long		 handle;	/*	Assume memory error	 */	rsvp_errno = Set_Errno( RSVP_Err_RSVP_SYS_ERROR, RSVP_Erv_MEMORY);	/*	Compute Branch_Merge flag from RSBs [This might be better	 *	be done in core RSVP].	 */	TC_kflags |= Is_B_Police(destp, rp);	/*	Find out if there is already a matching reservation in	 *	place for different NHOPs: search for a TCSB matching	 *	(OI, session, [filter_spec_list (distinct style)]).	 */ 	kp = locate_TCSB(destp, rp->rs_OIf, rp->rs_filtstar, rp->rs_style);	if (!kp) {		/*	This is first reservation.  Build TCSB, send flowspec,		 *	filter_spec_list, etc. to traffic control, and if there		 *	is no error, fill in TCSB.		 */		kp = make_TCSB(destp, rp->rs_OIf, rp->rs_fcount);		if (!kp)			goto TC_add_error;		/*  Compute path properties -- 		 *	Path_Te = sum of sender Tspecs,		 *    	[composed] Adspecs (for Guaranteed Service Slack Calc)		 *	Entry_Police and Merge_Police flags --		 *  from PSBs that match this request.		 *		 *  Note: this calculation will generally be independent of		 *  the particular next hop, so it could be done in core RSVP.		 *  However, there is at least a theoretical possibility of		 *  further routing in the link layer driver, in which case		 *  the selection of matching PSBs can only be done in the 		 *  LLDAL.  Therefore, we execute it in the LLDAL (although		 *  code currently defined in rsvp_resv.c).		 */		s_count = Compute_Path_Props(destp, rp, 			rp->rs_filtstar, &Path_Te, &adspecp, &TC_kflags);		assert(s_count > 0);			 /* Caller checked: there are matching senders*/#ifdef SCHEDULE		handle = TC_AddFlowspec(kp->tcs_OIf, rp->rs_spec,				 &Path_Te, adspecp, TC_kflags, &Fwd_specp);		kp->tcs_rhandle = handle;#endif		if (IsDebug(DEBUG_ALL)) {			char out[80];			log_K(LOGEV_TC_addflow, destp, kp);			if (IsDebug(DEBUG_EVENTS)) {				strncpy(out, fmt_tspec(&Path_Te), 80);				log(LOG_DEBUG, 0,					"    flowspec= %s  Tspec=%s\n",					fmt_flowspec(rp->rs_spec), out);			}		}		if (handle == TC_ERROR)   /* Failed. rsvp_errno is set. */			goto TC_add_error;		if (Fwd_specp) {			/*	An updated flowspec was returned.  Pass			 *	it back to the core.			 */			if (Kernel_Return_Spec(destp, rp, Fwd_specp) == 								LLDAL_RC_ERROR)				goto TC_add_error;		}		/*	Copy filter spec list into TCSB and install filters		 *	in traffic control.		 */		if (Kernel_SetFilters(destp, kp, rp->rs_filtstar) == 								LLDAL_RC_ERROR)			goto TC_add_error;   /* Error; rsvp_errno set */ 		/*	Flowspec and filter spec(s) installed OK.  Set		 *	TCSB and return.		 */		kp->tcs_spec = copy_spec(rp->rs_spec);		kp->tcs_tspec = copy_tspec(&Path_Te);		kp->tcs_kflags = TC_kflags;		if (!kp->tcs_spec || !kp->tcs_tspec)			goto TC_add_error;		/* out of memory */		return(LLDAL_RC_OK);	}	/*	A reservation is already in place.  Change it if necessary.	 *	For simplicity (and at the cost of some efficiency) just use	 *	LL_ModFlowspec. 	 */	if (adspecp)		free(adspecp);  /* (KernTC_ModFlowspec will recompute */	/*	 * 	Note: we could avoid calling KernTC_ModFlowspec if new	 *	flowspec LEQ against tcs_spec, and we could avoid calling	 *	KernTC_ModFilter if new filter spec list is identical to	 *	that in the TCSB.  Leave those optimizations for later.	 */	return(KernTC_ModFlowspec(destp, rp));TC_add_error:	/*	 *	Error cases: release resources and free TCSB as necessary.	 */	if (kp && kp->tcs_rhandle && kp->tcs_rhandle != TC_ERROR) {#ifdef SCHEDULE		TC_DelFlowspec(kp->tcs_OIf, kp->tcs_rhandle);#endif		if (IsDebug(DEBUG_ALL)) {			log_K(LOGEV_TC_delflow, destp, kp);			if (IsDebug(DEBUG_EVENTS))				log(LOG_DEBUG, 0,					"    flowspec= %s\n",					fmt_flowspec(rp->rs_spec));		}	}	if (kp)		kill_TCSB(destp, kp);	if (adspecp)		free(adspecp);	return(LLDAL_RC_ERROR);	}/* *  KernTC_ModFlowspec(Session, active RSB) * *	Modify an existing reservation because a component flowspec, *	sender Tspec, or Adspec has changed.  RSB *rp specifies NHOP, OIf, *	OIf, and (for Distinct) the filter spec. */intKernTC_ModFlowspec(Session *destp, RSB *rp)	{	TCSB		*kp;	FLOWSPEC	*TC_specp, *Fwd_specp;	FiltSpecStar	*TC_FiltSp;	SENDER_TSPEC	 Path_Te;	ADSPEC		*adspecp;	int		 TC_kflags = 0;	u_long		 rc;		/*	Scan RSBs and merge:	 *		flowspecs -> TC_specp	 *		filter specs -> TC_FiltSp.	 */	rc = Kernel_Merge(destp, rp, &TC_specp, &TC_FiltSp);	if (rc != LLDAL_RC_OK)		return(rc);	assert(TC_specp && TC_FiltSp);	/*	Compute path properties -- Path_Te = sum of sender Tspecs,	 *	[composed] Adspecs, Entry_Police and Merge_Police flags --	 *	from PSBs that match this request.	 */	if (Compute_Path_Props(destp, rp, TC_FiltSp,				&Path_Te, &adspecp, &TC_kflags) == 0)		return(LLDAL_RC_OK);	/* ??? Can this ever happen? */	/*	Compute Branch_Merge flag from RSBs [This might better	 *	be done in core RSVP?  Or in Kernel_Merge?]	 */	TC_kflags |= Is_B_Police(destp, rp);	/*	Find matching TCSB for reservation in place; match	 *	(OI, session, [filter_spec_list (distinct style)]).	 *	 *	XXX we could be cleverer, save A(TCSB) in RSB (except	 *	this makes problems if we have to trade TCSBs!)	 */ 	kp = locate_TCSB(destp, rp->rs_OIf, rp->rs_filtstar, rp->rs_style);	assert(kp);	/*	Record merged flag in TCSB	 */	kp->tcs_flags &= ~TCF_MERGED;	if (rp->rs_flags & RSB_FLAG_MERGED)		kp->tcs_flags |= TCF_MERGED;	/*	 *	If TC_Flowspec, Path_Te, or police flags have changed,	 *	modify reservation.	 */	if (Compare_Flowspecs(TC_specp, kp->tcs_spec) != SPECS_EQL ||	   Compare_Tspecs(&Path_Te, kp->tcs_tspec) != SPECS_EQL ||		TC_kflags != kp->tcs_kflags) {#ifdef SCHEDULE                rc = TC_ModFlowspec(kp->tcs_OIf, kp->tcs_rhandle, TC_specp,				&Path_Te, adspecp, TC_kflags, &Fwd_specp);#endif		if (IsDebug(DEBUG_ALL)) {			log_K(LOGEV_TC_modflow, destp, kp);			if (IsDebug(DEBUG_EVENTS)) {				char out[80];				strncpy(out, fmt_tspec(kp->tcs_tspec), 80);				log(LOG_DEBUG, 0,					"    Old: flowspec=%s  Tspec=%s\n",					fmt_flowspec(kp->tcs_spec), out);				strncpy(out, fmt_tspec(&Path_Te), 80);				log(LOG_DEBUG, 0,					"    New: flowspec=%s  Tspec=%s\n",					fmt_flowspec(TC_specp), out);			}		}		if (rc == TC_ERROR)  /* Failed. rsvp_errno is set. */			return(LLDAL_RC_ERROR);	}	/*	Set filters if necessary, too.	 */	rc  = Kernel_SetFilters(destp, kp, TC_FiltSp);	if (rc == LLDAL_RC_ERROR)		goto TC_mod_error;	/*	 *	Since TC calls succeeded, update TCSB now.	 */	free(kp->tcs_spec);	kp->tcs_spec = copy_spec(TC_specp);	if (kp->tcs_tspec)		free(kp->tcs_tspec);	kp->tcs_tspec = copy_tspec(&Path_Te);	kp->tcs_kflags = TC_kflags;	if (!kp->tcs_spec || !kp->tcs_tspec) {		rsvp_errno = Set_Errno( RSVP_Err_RSVP_SYS_ERROR, 							RSVP_Erv_MEMORY);		rc = LLDAL_RC_ERROR;	}TC_mod_error:	free(TC_FiltSp);	free(TC_specp);	if (adspecp)		free(adspecp);	return(rc);}/* *  KernTC_ModFilter(Session *, active RSB *) * *	Modify the filter spec list for an existing reservation */intKernTC_ModFilter(Session *destp, RSB *rp)	{	FiltSpecStar	*TC_FiltSp;	FLOWSPEC	*TC_specp;	TCSB		*kp;	int		rc; 	kp = locate_TCSB(destp, rp->rs_OIf, rp->rs_filtstar, rp->rs_style);	if (!kp)		return(LLDAL_RC_OK);	rc = Kernel_Merge(destp, rp, &TC_specp, &TC_FiltSp);	if (rc != LLDAL_RC_OK)		return(rc);	return(Kernel_SetFilters(destp, kp, TC_FiltSp));}/* *  KernTC_DelFlow(Session, active RSB) * *	Active RSB has been deleted; update Kernel TC state to correspond. * *	FF (distinct style) case is a little tricky: the RSB parameter must *	specify the filter spec to define the flow to be deleted; yet this *	RSB must not itself appear in the list of current RSBs. */intKernTC_DelFlow(Session *destp, RSB *rp)	{	TCSB		*kp;	FLOWSPEC	*TC_specp;	FiltSpecStar	*TC_FiltSp;	u_long		 rc = TC_OK;		/*	Find matching TCSB for reservation in place; match	 *	(OI, session, [filter_spec_list (distinct style)]).	 */ 	kp = locate_TCSB(destp, rp->rs_OIf, rp->rs_filtstar, rp->rs_style);	if (!kp)		return(LLDAL_RC_OK);	rc = Kernel_Merge(destp, rp, &TC_specp, &TC_FiltSp);	assert(rc == LLDAL_RC_OK);	/*	Record merged flag in TCSB	 */	kp->tcs_flags &= ~TCF_MERGED;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -