Beispiel #1
0
static void ess_send_frame(struct s_smc *smc, SMbuf *mb)
{
	/*
	 * check if the frame must be send to the own ESS
	 */
	if (smc->ess.local_sba_active) {
		/*
		 * Send the Change Reply to the local SBA
		 */
		DB_ESS("ESS:Send to the local SBA\n",0,0) ;
		if (!smc->ess.sba_reply_pend)
			smc->ess.sba_reply_pend = mb ;
		else {
			DB_ESS("Frame is lost - another frame was pending\n",0,0);
			smt_free_mbuf(smc,mb) ;
		}
	}
	else {
		/*
		 * Send the SBA RAF Change Reply to the network
		 */
		DB_ESS("ESS:Send to the network\n",0,0) ;
		smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
	}
}
Beispiel #2
0
static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,
				u_long tid, int local)


{
	struct smt_sif_config	*sif ;
	SMbuf			*mb ;
	int			len ;
	if (!(mb = smt_build_frame(smc,SMT_SIF_CONFIG,SMT_REPLY,
		SIZEOF_SMT_SIF_CONFIG)))
		return ;

	sif = smtod(mb, struct smt_sif_config *) ;
	smt_fill_timestamp(smc,&sif->ts) ;	
	smt_fill_sde(smc,&sif->sde) ;		
	smt_fill_version(smc,&sif->version) ;	
	smt_fill_state(smc,&sif->state) ;	
	smt_fill_policy(smc,&sif->policy) ;	
	smt_fill_latency(smc,&sif->latency);	
	smt_fill_neighbor(smc,&sif->neighbor);	
	smt_fill_setcount(smc,&sif->setcount) ;	
	len = smt_fill_path(smc,&sif->path);	
	sif->smt.smt_dest = *dest ;		
	sif->smt.smt_tid = tid ;		
	smt_add_frame_len(mb,len) ;		
	dump_smt(smc,(struct smt_header *)sif,"SIF Configuration Reply") ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}
static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,
				u_long tid, int local)
/* struct fddi_addr *dest;	dest address */
/* u_long tid;			transaction id */
{
	struct smt_sif_config	*sif ;
	SMbuf			*mb ;
	int			len ;
	if (!(mb = smt_build_frame(smc,SMT_SIF_CONFIG,SMT_REPLY,
		SIZEOF_SMT_SIF_CONFIG)))
		return ;

	sif = smtod(mb, struct smt_sif_config *) ;
	smt_fill_timestamp(smc,&sif->ts) ;	/* set time stamp */
	smt_fill_sde(smc,&sif->sde) ;		/* set station descriptor */
	smt_fill_version(smc,&sif->version) ;	/* set version information */
	smt_fill_state(smc,&sif->state) ;	/* set state information */
	smt_fill_policy(smc,&sif->policy) ;	/* set station policy */
	smt_fill_latency(smc,&sif->latency);	/* set station latency */
	smt_fill_neighbor(smc,&sif->neighbor);	/* set station neighbor */
	smt_fill_setcount(smc,&sif->setcount) ;	/* set count */
	len = smt_fill_path(smc,&sif->path);	/* set station path descriptor*/
	sif->smt.smt_dest = *dest ;		/* destination address */
	sif->smt.smt_tid = tid ;		/* transaction ID */
	smt_add_frame_len(mb,len) ;		/* adjust length fields */
	dump_smt(smc,(struct smt_header *)sif,"SIF Configuration Reply") ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}
Beispiel #4
0
/*
 * build and send SMT SRF frame
 */
static void smt_send_srf(struct s_smc *smc)
{

	struct smt_header	*smt ;
	struct s_srf_evc	*evc ;
	SK_LOC_DECL(struct s_pcon,pcon) ;
	SMbuf			*mb ;
	int			i ;

	static const struct fddi_addr SMT_SRF_DA = {
		{ 0x80, 0x01, 0x43, 0x00, 0x80, 0x08 }
	} ;

	/*
	 * build SMT header
	 */
	if (!smc->r.sm_ma_avail)
		return ;
	if (!(mb = smt_build_frame(smc,SMT_SRF,SMT_ANNOUNCE,0)))
		return ;

	RS_SET(smc,RS_SOFTERROR) ;

	smt = smtod(mb, struct smt_header *) ;
	smt->smt_dest = SMT_SRF_DA ;		/* DA == SRF multicast */

	/*
	 * setup parameter status
	 */
	pcon.pc_len = SMT_MAX_INFO_LEN ;	/* max para length */
	pcon.pc_err = 0 ;			/* no error */
	pcon.pc_badset = 0 ;			/* no bad set count */
	pcon.pc_p = (void *) (smt + 1) ;	/* paras start here */

	smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ;
	smt_add_para(smc,&pcon,(u_short) SMT_P1034,0,0) ;

	for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) {
		if (evc->evc_rep_required) {
			smt_add_para(smc,&pcon,evc->evc_para,
				(int)evc->evc_index,0) ;
		}
	}
	smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ;
	mb->sm_len = smt->smt_len + sizeof(struct smt_header) ;

	DB_SMT("SRF: sending SRF at %x, len %d \n",smt,mb->sm_len) ;
	DB_SMT("SRF: state SR%d Threshold %d\n",
		smc->srf.sr_state,smc->srf.SRThreshold/TICKS_PER_SECOND) ;
#ifdef	DEBUG
	dump_smt(smc,smt,"SRF Send") ;
#endif
	smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
	clear_reported(smc) ;
}
static void ess_send_frame(struct s_smc *smc, SMbuf *mb)
{
	if (smc->ess.local_sba_active) {
		DB_ESS("ESS:Send to the local SBA\n",0,0) ;
		if (!smc->ess.sba_reply_pend)
			smc->ess.sba_reply_pend = mb ;
		else {
			DB_ESS("Frame is lost - another frame was pending\n",0,0);
			smt_free_mbuf(smc,mb) ;
		}
	}
	else {
		DB_ESS("ESS:Send to the network\n",0,0) ;
		smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
	}
}
static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest,
				   u_long tid, int local)
/* struct fddi_addr *dest;	dest address */
/* u_long tid;			transaction id */
{
	struct smt_sif_operation *sif ;
	SMbuf			*mb ;
	int			ports ;
	int			i ;

	ports = NUMPHYS ;
#ifndef	CONCENTRATOR
	if (smc->s.sas == SMT_SAS)
		ports = 1 ;
#endif

	if (!(mb = smt_build_frame(smc,SMT_SIF_OPER,SMT_REPLY,
		SIZEOF_SMT_SIF_OPERATION+ports*sizeof(struct smt_p_lem))))
		return ;
	sif = smtod(mb, struct smt_sif_operation *) ;
	smt_fill_timestamp(smc,&sif->ts) ;	/* set time stamp */
	smt_fill_mac_status(smc,&sif->status) ; /* set mac status */
	smt_fill_mac_counter(smc,&sif->mc) ; /* set mac counter field */
	smt_fill_mac_fnc(smc,&sif->fnc) ; /* set frame not copied counter */
	smt_fill_manufacturer(smc,&sif->man) ; /* set manufacturer field */
	smt_fill_user(smc,&sif->user) ;		/* set user field */
	smt_fill_setcount(smc,&sif->setcount) ;	/* set count */
	/*
	 * set link error mon information
	 */
	if (ports == 1) {
		smt_fill_lem(smc,sif->lem,PS) ;
	}
	else {
		for (i = 0 ; i < ports ; i++) {
			smt_fill_lem(smc,&sif->lem[i],i) ;
		}
	}

	sif->smt.smt_dest = *dest ;	/* destination address */
	sif->smt.smt_tid = tid ;	/* transaction ID */
	dump_smt(smc,(struct smt_header *)sif,"SIF Operation Reply") ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}
Beispiel #7
0
static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,
			 u_long tid, int type, int len)





{
	struct smt_ecf	*ecf ;
	SMbuf		*mb ;

	if (!(mb = smt_build_frame(smc,SMT_ECF,type,SMT_ECF_LEN + len)))
		return ;
	ecf = smtod(mb, struct smt_ecf *) ;

	smt_fill_echo(smc,&ecf->ec_echo,tid,len) ;	
	ecf->smt.smt_dest = *dest ;	
	ecf->smt.smt_tid = tid ;	
	smc->mib.priv.fddiPRIVECF_Req_Tx++ ;
	smt_send_frame(smc,mb,fc,0) ;
}
static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,
			 u_long tid, int type, int len)
/* struct fddi_addr *dest;	dest address */
/* int fc;			frame control */
/* u_long tid;			transaction id */
/* int type;			frame type */
/* int len;			frame length */
{
	struct smt_ecf	*ecf ;
	SMbuf		*mb ;

	if (!(mb = smt_build_frame(smc,SMT_ECF,type,SMT_ECF_LEN + len)))
		return ;
	ecf = smtod(mb, struct smt_ecf *) ;

	smt_fill_echo(smc,&ecf->ec_echo,tid,len) ;	/* set ECHO */
	ecf->smt.smt_dest = *dest ;	/* destination address */
	ecf->smt.smt_tid = tid ;	/* transaction ID */
	smc->mib.priv.fddiPRIVECF_Req_Tx++ ;
	smt_send_frame(smc,mb,fc,0) ;
}
Beispiel #9
0
static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest, 
			 int fc, u_long tid, int type, int local)




{
	struct smt_nif	*nif ;
	SMbuf		*mb ;

	if (!(mb = smt_build_frame(smc,SMT_NIF,type,sizeof(struct smt_nif))))
		return ;
	nif = smtod(mb, struct smt_nif *) ;
	smt_fill_una(smc,&nif->una) ;	
	smt_fill_sde(smc,&nif->sde) ;	
	smt_fill_state(smc,&nif->state) ;	
#ifdef	SMT6_10
	smt_fill_fsc(smc,&nif->fsc) ;	
#endif
	nif->smt.smt_dest = *dest ;	
	nif->smt.smt_tid = tid ;	
	dump_smt(smc,(struct smt_header *)nif,"NIF") ;
	smt_send_frame(smc,mb,fc,local) ;
}
static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest, 
			 int fc, u_long tid, int type, int local)
/* struct fddi_addr *dest;	dest address */
/* int fc;			frame control */
/* u_long tid;			transaction id */
/* int type;			frame type */
{
	struct smt_nif	*nif ;
	SMbuf		*mb ;

	if (!(mb = smt_build_frame(smc,SMT_NIF,type,sizeof(struct smt_nif))))
		return ;
	nif = smtod(mb, struct smt_nif *) ;
	smt_fill_una(smc,&nif->una) ;	/* set UNA */
	smt_fill_sde(smc,&nif->sde) ;	/* set station descriptor */
	smt_fill_state(smc,&nif->state) ;	/* set state information */
#ifdef	SMT6_10
	smt_fill_fsc(smc,&nif->fsc) ;	/* set frame status cap. */
#endif
	nif->smt.smt_dest = *dest ;	/* destination address */
	nif->smt.smt_tid = tid ;	/* transaction ID */
	dump_smt(smc,(struct smt_header *)nif,"NIF") ;
	smt_send_frame(smc,mb,fc,local) ;
}
int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
			  int fs)
{
	void			*p ;		
	struct smt_p_0016	*cmd ;		
	SMbuf			*db ;
	u_long			msg_res_type ;	
	u_long			payload, overhead ;
	int			local ;
	int			i ;

	 local = ((fs & L_INDICATOR) != 0) ;

	if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
		DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ;
		return fs;
	}
	msg_res_type = ((struct smt_p_0015 *)p)->res_type ;

	if (!(cmd = (struct smt_p_0016 *) sm_to_para(smc,sm,SMT_P0016))) {
		 DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0);
		 return fs;
	}

	DB_ESSN(2,"fc %x	ft %x\n",sm->smt_class,sm->smt_type) ;
	DB_ESSN(2,"ver %x	tran %lx\n",sm->smt_version,sm->smt_tid) ;
	DB_ESSN(2,"stn_id %s\n",addr_to_string(&sm->smt_source),0) ;

	DB_ESSN(2,"infolen %x	res %x\n",sm->smt_len, msg_res_type) ;
	DB_ESSN(2,"sbacmd %x\n",cmd->sba_cmd,0) ;

	switch (cmd->sba_cmd) {

	case REQUEST_ALLOCATION :
		if (sm->smt_type == SMT_REQUEST) {
			if (!local || smc->mib.fddiESSPayload)
				return fs;
			
			p = (void *) sm_to_para(smc,sm,SMT_P0019)  ;
			for (i = 0; i < 5; i++) {
				if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) {
					return fs;
				}
			}

			smc->ess.alloc_trans_id = sm->smt_tid ;
			DB_ESS("ESS: save Alloc Req Trans ID %lx\n",sm->smt_tid,0);
			p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
			((struct smt_p_320f *)p)->mib_payload =
				smc->mib.a[PATH0].fddiPATHSbaPayload ;
			p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
			((struct smt_p_3210 *)p)->mib_overhead =
				smc->mib.a[PATH0].fddiPATHSbaOverhead ;
			sm->smt_dest = smt_sba_da ;

			if (smc->ess.local_sba_active)
				return fs | I_INDICATOR;

			if (!(db = smt_get_mbuf(smc)))
				return fs;

			db->sm_len = mb->sm_len ;
			db->sm_off = mb->sm_off ;
			memcpy(((char *)(db->sm_data+db->sm_off)),(char *)sm,
				(int)db->sm_len) ;
			dump_smt(smc,
				(struct smt_header *)(db->sm_data+db->sm_off),
				"RAF") ;
			smt_send_frame(smc,db,FC_SMT_INFO,0) ;
			return fs;
		}

		if (smt_check_para(smc,sm,plist_raf_alc_res)) {
			DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
			return fs;
		}

		if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
			!= PRIMARY_RING) ||
			(msg_res_type != SYNC_BW) ||
		(((struct smt_p_reason *)sm_to_para(smc,sm,SMT_P0012))->rdf_reason
			!= SMT_RDF_SUCCESS) ||
			(sm->smt_tid != smc->ess.alloc_trans_id)) {

			DB_ESS("ESS: Allocation Response not accepted\n",0,0) ;
			return fs;
		}

		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
                if (!p) {
                        printk(KERN_ERR "ESS: sm_to_para failed");
                        return fs;
                }       
		payload = ((struct smt_p_320f *)p)->mib_payload ;
		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
                if (!p) {
                        printk(KERN_ERR "ESS: sm_to_para failed");
                        return fs;
                }       
		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;

		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;

		(void)process_bw_alloc(smc,(long)payload,(long)overhead) ;

		return fs;
		

	case CHANGE_ALLOCATION :
		if (sm->smt_type != SMT_REQUEST) {
			DB_ESS("ESS: Do not process Change Responses\n",0,0) ;
			return fs;
		}

		if (smt_check_para(smc,sm,plist_raf_chg_req)) {
			DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
			return fs;
		}

		if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
			!= PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
			DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ;
			return fs;
		}

		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
		payload = ((struct smt_p_320f *)p)->mib_payload ;
		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;

		DB_ESSN(2,"ESS: Change Request from %s\n",
			addr_to_string(&sm->smt_source),0) ;
		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;

		if(!process_bw_alloc(smc,(long)payload,(long)overhead))
			return fs;

		ess_send_response(smc,sm,CHANGE_ALLOCATION) ;

		return fs;
		

	case REPORT_ALLOCATION :
		if (sm->smt_type != SMT_REQUEST) {
			DB_ESS("ESS: Do not process a Report Reply\n",0,0) ;
			return fs;
		}

		DB_ESSN(2,"ESS: Report Request from %s\n",
			addr_to_string(&(sm->smt_source)),0) ;

		if (msg_res_type != SYNC_BW) {
			DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ;
			return fs;
		}

		ess_send_response(smc,sm,REPORT_ALLOCATION) ;

		return fs;
		

	default:
		DB_ESS("ESS: ignoring RAF with bad sba_cmd\n",0,0) ;
		break ;
	}

	return fs;
}
Beispiel #12
0
/*
 * evaluate the RAF frame
 */
int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
			  int fs)
{
	void			*p ;		/* universal pointer */
	struct smt_p_0016	*cmd ;		/* para: command for the ESS */
	SMbuf			*db ;
	u_long			msg_res_type ;	/* recource type */
	u_long			payload, overhead ;
	int			local ;
	int			i ;

	/*
	 * Message Processing Code
	 */
	 local = ((fs & L_INDICATOR) != 0) ;

	/*
	 * get the resource type
	 */
	if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
		DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ;
		return fs;
	}
	msg_res_type = ((struct smt_p_0015 *)p)->res_type ;

	/*
	 * get the pointer to the ESS command
	 */
	if (!(cmd = (struct smt_p_0016 *) sm_to_para(smc,sm,SMT_P0016))) {
		/*
		 * error in frame: para ESS command was not found
		 */
		 DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0);
		 return fs;
	}

	DB_ESSN(2,"fc %x	ft %x\n",sm->smt_class,sm->smt_type) ;
	DB_ESSN(2,"ver %x	tran %lx\n",sm->smt_version,sm->smt_tid) ;
	DB_ESSN(2,"stn_id %s\n",addr_to_string(&sm->smt_source),0) ;

	DB_ESSN(2,"infolen %x	res %x\n",sm->smt_len, msg_res_type) ;
	DB_ESSN(2,"sbacmd %x\n",cmd->sba_cmd,0) ;

	/*
	 * evaluate the ESS command
	 */
	switch (cmd->sba_cmd) {

	/*
	 * Process an ESS Allocation Request
	 */
	case REQUEST_ALLOCATION :
		/*
		 * check for an RAF Request (Allocation Request)
		 */
		if (sm->smt_type == SMT_REQUEST) {
			/*
			 * process the Allocation request only if the frame is
			 * local and no static allocation is used
			 */
			if (!local || smc->mib.fddiESSPayload)
				return fs;

			p = (void *) sm_to_para(smc,sm,SMT_P0019)  ;
			for (i = 0; i < 5; i++) {
				if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) {
					return fs;
				}
			}

			/*
			 * Note: The Application should send a LAN_LOC_FRAME.
			 *	 The ESS do not send the Frame to the network!
			 */
			smc->ess.alloc_trans_id = sm->smt_tid ;
			DB_ESS("ESS: save Alloc Req Trans ID %lx\n",sm->smt_tid,0);
			p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
			((struct smt_p_320f *)p)->mib_payload =
				smc->mib.a[PATH0].fddiPATHSbaPayload ;
			p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
			((struct smt_p_3210 *)p)->mib_overhead =
				smc->mib.a[PATH0].fddiPATHSbaOverhead ;
			sm->smt_dest = smt_sba_da ;

			if (smc->ess.local_sba_active)
				return fs | I_INDICATOR;

			if (!(db = smt_get_mbuf(smc)))
				return fs;

			db->sm_len = mb->sm_len ;
			db->sm_off = mb->sm_off ;
			memcpy(((char *)(db->sm_data+db->sm_off)),(char *)sm,
				(int)db->sm_len) ;
			dump_smt(smc,
				(struct smt_header *)(db->sm_data+db->sm_off),
				"RAF") ;
			smt_send_frame(smc,db,FC_SMT_INFO,0) ;
			return fs;
		}

		/*
		 * The RAF frame is an Allocation Response !
		 * check the parameters
		 */
		if (smt_check_para(smc,sm,plist_raf_alc_res)) {
			DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
			return fs;
		}

		/*
		 * VERIFY THE FRAME IS WELL BUILT:
		 *
		 *	1. path index = primary ring only
		 *	2. resource type = sync bw only
		 *	3. trans action id = alloc_trans_id
		 *	4. reason code = success
		 *
		 * If any are violated, discard the RAF frame
		 */
		if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
			!= PRIMARY_RING) ||
			(msg_res_type != SYNC_BW) ||
		(((struct smt_p_reason *)sm_to_para(smc,sm,SMT_P0012))->rdf_reason
			!= SMT_RDF_SUCCESS) ||
			(sm->smt_tid != smc->ess.alloc_trans_id)) {

			DB_ESS("ESS: Allocation Response not accepted\n",0,0) ;
			return fs;
		}

		/*
		 * Extract message parameters
		 */
		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
                if (!p) {
                        printk(KERN_ERR "ESS: sm_to_para failed");
                        return fs;
                }
		payload = ((struct smt_p_320f *)p)->mib_payload ;
		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
                if (!p) {
                        printk(KERN_ERR "ESS: sm_to_para failed");
                        return fs;
                }
		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;

		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;

		/*
		 * process the bandwidth allocation
		 */
		(void)process_bw_alloc(smc,(long)payload,(long)overhead) ;

		return fs;
		/* end of Process Allocation Request */

	/*
	 * Process an ESS Change Request
	 */
	case CHANGE_ALLOCATION :
		/*
		 * except only replies
		 */
		if (sm->smt_type != SMT_REQUEST) {
			DB_ESS("ESS: Do not process Change Responses\n",0,0) ;
			return fs;
		}

		/*
		 * check the para for the Change Request
		 */
		if (smt_check_para(smc,sm,plist_raf_chg_req)) {
			DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
			return fs;
		}

		/*
		 * Verify the path index and resource
		 * type are correct. If any of
		 * these are false, don't process this
		 * change request frame.
		 */
		if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
			!= PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
			DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ;
			return fs;
		}

		/*
		 * Extract message queue parameters
		 */
		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
		payload = ((struct smt_p_320f *)p)->mib_payload ;
		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;

		DB_ESSN(2,"ESS: Change Request from %s\n",
			addr_to_string(&sm->smt_source),0) ;
		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;

		/*
		 * process the bandwidth allocation
		 */
		if(!process_bw_alloc(smc,(long)payload,(long)overhead))
			return fs;

		/*
		 * send an RAF Change Reply
		 */
		ess_send_response(smc,sm,CHANGE_ALLOCATION) ;

		return fs;
		/* end of Process Change Request */

	/*
	 * Process Report Response
	 */
	case REPORT_ALLOCATION :
		/*
		 * except only requests
		 */
		if (sm->smt_type != SMT_REQUEST) {
			DB_ESS("ESS: Do not process a Report Reply\n",0,0) ;
			return fs;
		}

		DB_ESSN(2,"ESS: Report Request from %s\n",
			addr_to_string(&(sm->smt_source)),0) ;

		/*
		 * verify that the resource type is sync bw only
		 */
		if (msg_res_type != SYNC_BW) {
			DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ;
			return fs;
		}

		/*
		 * send an RAF Change Reply
		 */
		ess_send_response(smc,sm,REPORT_ALLOCATION) ;

		return fs;
		/* end of Process Report Request */

	default:
		/*
		 * error in frame
		 */
		DB_ESS("ESS: ignoring RAF with bad sba_cmd\n",0,0) ;
		break ;
	}

	return fs;
}
Beispiel #13
0
static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
			 int local)



{
	SMbuf	*mb ;
	struct smt_header	*sm ;	
	struct smt_rdf	*rdf ;
	int		len ;
	int		frame_len ;

	sm = smtod(rej,struct smt_header *) ;
	if (sm->smt_type != SMT_REQUEST)
		return ;

	DB_SMT("SMT: sending RDF to %s,reason = 0x%x\n",
		addr_to_string(&sm->smt_source),reason) ;


	
	frame_len = rej->sm_len ;

	if (!(mb=smt_build_frame(smc,SMT_RDF,SMT_REPLY,sizeof(struct smt_rdf))))
		return ;
	rdf = smtod(mb,struct smt_rdf *) ;
	rdf->smt.smt_tid = sm->smt_tid ;		
	rdf->smt.smt_dest = sm->smt_source ;		

	
	rdf->reason.para.p_type = SMT_P_REASON ;
	rdf->reason.para.p_len = sizeof(struct smt_p_reason) - PARA_LEN ;
	rdf->reason.rdf_reason = reason ;

	
	rdf->version.para.p_type = SMT_P_VERSION ;
	rdf->version.para.p_len = sizeof(struct smt_p_version) - PARA_LEN ;
	rdf->version.v_pad = 0 ;
	rdf->version.v_n = 1 ;
	rdf->version.v_index = 1 ;
	rdf->version.v_version[0] = SMT_VID_2 ;
	rdf->version.v_pad2 = 0 ;

	
	if ((unsigned) frame_len <= SMT_MAX_INFO_LEN - sizeof(*rdf) +
		2*sizeof(struct smt_header))
		len = frame_len ;
	else
		len = SMT_MAX_INFO_LEN - sizeof(*rdf) +
			2*sizeof(struct smt_header) ;
	
	len &= ~3 ;
	rdf->refused.para.p_type = SMT_P_REFUSED ;
	
	rdf->refused.para.p_len = len + 4 ;
	rdf->refused.ref_fc = fc ;

	
	smt_swap_para(sm,frame_len,0) ;

	memcpy((char *) &rdf->refused.ref_header,(char *) sm,len) ;

	len -= sizeof(struct smt_header) ;
	mb->sm_len += len ;
	rdf->smt.smt_len += len ;

	dump_smt(smc,(struct smt_header *)rdf,"RDF") ;
	smc->mib.priv.fddiPRIVRDF_Tx++ ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}
Beispiel #14
0
void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)

{
	struct smt_header	*sm ;
	int			local ;

	int			illegal = 0 ;

	switch (m_fc(mb)) {
	case FC_SMT_INFO :
	case FC_SMT_LAN_LOC :
	case FC_SMT_LOC :
	case FC_SMT_NSA :
		break ;
	default :
		smt_free_mbuf(smc,mb) ;
		return ;
	}

	smc->mib.m[MAC0].fddiMACSMTCopied_Ct++ ;
	sm = smtod(mb,struct smt_header *) ;
	local = ((fs & L_INDICATOR) != 0) ;
	hwm_conv_can(smc,(char *)sm,12) ;

	
	if (is_individual(&sm->smt_dest) && !is_my_addr(smc,&sm->smt_dest)) {
		smt_free_mbuf(smc,mb) ;
		return ;
	}
#if	0		
	
	if (is_my_addr(smc,&sm->smt_source) && !local) {
		smt_free_mbuf(smc,mb) ;
		return ;
	}
#endif

	smt_swap_para(sm,(int) mb->sm_len,1) ;
	DB_SMT("SMT : received packet [%s] at 0x%x\n",
		smt_type_name[m_fc(mb) & 0xf],sm) ;
	DB_SMT("SMT : version %d, class %s\n",sm->smt_version,
		smt_class_name[(sm->smt_class>LAST_CLASS)?0 : sm->smt_class]) ;

#ifdef	SBA
	
	if (m_fc(mb) == FC_SMT_NSA && sm->smt_class == SMT_NIF &&
		(sm->smt_type == SMT_ANNOUNCE || sm->smt_type == SMT_REQUEST)) {
			smc->sba.sm = sm ;
			sba(smc,NIF) ;
	}
#endif

	
	if ( (fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) {
		DB_SMT("SMT : ignoring NSA with A-indicator set from %s\n",
			addr_to_string(&sm->smt_source),0) ;
		smt_free_mbuf(smc,mb) ;
		return ;
	}

	
	if (((sm->smt_class == SMT_ECF) && (sm->smt_len > SMT_MAX_ECHO_LEN)) ||
	    ((sm->smt_class != SMT_ECF) && (sm->smt_len > SMT_MAX_INFO_LEN))) {
		smt_free_mbuf(smc,mb) ;
		return ;
	}

	
	switch (sm->smt_class) {
	case SMT_NIF :
	case SMT_SIF_CONFIG :
	case SMT_SIF_OPER :
	case SMT_ECF :
		if (sm->smt_version != SMT_VID)
			illegal = 1;
		break ;
	default :
		if (sm->smt_version != SMT_VID_2)
			illegal = 1;
		break ;
	}
	if (illegal) {
		DB_SMT("SMT : version = %d, dest = %s\n",
			sm->smt_version,addr_to_string(&sm->smt_source)) ;
		smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_VERSION,local) ;
		smt_free_mbuf(smc,mb) ;
		return ;
	}
	if ((sm->smt_len > mb->sm_len - sizeof(struct smt_header)) ||
	    ((sm->smt_len & 3) && (sm->smt_class != SMT_ECF))) {
		DB_SMT("SMT: info length error, len = %d\n",sm->smt_len,0) ;
		smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_LENGTH,local) ;
		smt_free_mbuf(smc,mb) ;
		return ;
	}
	switch (sm->smt_class) {
	case SMT_NIF :
		if (smt_check_para(smc,sm,plist_nif)) {
			DB_SMT("SMT: NIF with para problem, ignoring\n",0,0) ;
			break ;
		} ;
		switch (sm->smt_type) {
		case SMT_ANNOUNCE :
		case SMT_REQUEST :
			if (!(fs & C_INDICATOR) && m_fc(mb) == FC_SMT_NSA
				&& is_broadcast(&sm->smt_dest)) {
				struct smt_p_state	*st ;

				
				if (!is_equal(
					&smc->mib.m[MAC0].fddiMACUpstreamNbr,
					&sm->smt_source)) {
					DB_SMT("SMT : updated my UNA = %s\n",
					addr_to_string(&sm->smt_source),0) ;
					if (!is_equal(&smc->mib.m[MAC0].
					    fddiMACUpstreamNbr,&SMT_Unknown)){
					 
					 smc->mib.m[MAC0].fddiMACOldUpstreamNbr=
					 smc->mib.m[MAC0].fddiMACUpstreamNbr ;
					}

					smc->mib.m[MAC0].fddiMACUpstreamNbr =
						sm->smt_source ;
					smt_srf_event(smc,
						SMT_EVENT_MAC_NEIGHBOR_CHANGE,
						INDEX_MAC,0) ;
					smt_echo_test(smc,0) ;
				}
				smc->sm.smt_tvu = smt_get_time() ;
				st = (struct smt_p_state *)
					sm_to_para(smc,sm,SMT_P_STATE) ;
				if (st) {
					smc->mib.m[MAC0].fddiMACUNDA_Flag =
					(st->st_dupl_addr & SMT_ST_MY_DUPA) ?
					TRUE : FALSE ;
					update_dac(smc,1) ;
				}
			}
			if ((sm->smt_type == SMT_REQUEST) &&
			    is_individual(&sm->smt_source) &&
			    ((!(fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) ||
			     (m_fc(mb) != FC_SMT_NSA))) {
				DB_SMT("SMT : replying to NIF request %s\n",
					addr_to_string(&sm->smt_source),0) ;
				smt_send_nif(smc,&sm->smt_source,
					FC_SMT_INFO,
					sm->smt_tid,
					SMT_REPLY,local) ;
			}
			break ;
		case SMT_REPLY :
			DB_SMT("SMT : received NIF response from %s\n",
				addr_to_string(&sm->smt_source),0) ;
			if (fs & A_INDICATOR) {
				smc->sm.pend[SMT_TID_NIF] = 0 ;
				DB_SMT("SMT : duplicate address\n",0,0) ;
				smc->mib.m[MAC0].fddiMACDupAddressTest =
					DA_FAILED ;
				smc->r.dup_addr_test = DA_FAILED ;
				queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
				smc->mib.m[MAC0].fddiMACDA_Flag = TRUE ;
				update_dac(smc,1) ;
				break ;
			}
			if (sm->smt_tid == smc->sm.pend[SMT_TID_NIF]) {
				smc->sm.pend[SMT_TID_NIF] = 0 ;
				
				if (!is_equal(
					&smc->mib.m[MAC0].fddiMACDownstreamNbr,
					&sm->smt_source)) {
					DB_SMT("SMT : updated my DNA\n",0,0) ;
					if (!is_equal(&smc->mib.m[MAC0].
					 fddiMACDownstreamNbr, &SMT_Unknown)){
					 
				smc->mib.m[MAC0].fddiMACOldDownstreamNbr =
					 smc->mib.m[MAC0].fddiMACDownstreamNbr ;
					}

					smc->mib.m[MAC0].fddiMACDownstreamNbr =
						sm->smt_source ;
					smt_srf_event(smc,
						SMT_EVENT_MAC_NEIGHBOR_CHANGE,
						INDEX_MAC,0) ;
					smt_echo_test(smc,1) ;
				}
				smc->mib.m[MAC0].fddiMACDA_Flag = FALSE ;
				update_dac(smc,1) ;
				smc->sm.smt_tvd = smt_get_time() ;
				smc->mib.m[MAC0].fddiMACDupAddressTest =
					DA_PASSED ;
				if (smc->r.dup_addr_test != DA_PASSED) {
					smc->r.dup_addr_test = DA_PASSED ;
					queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
				}
			}
			else if (sm->smt_tid ==
				smc->sm.pend[SMT_TID_NIF_TEST]) {
				DB_SMT("SMT : NIF test TID ok\n",0,0) ;
			}
			else {
				DB_SMT("SMT : expected TID %lx, got %lx\n",
				smc->sm.pend[SMT_TID_NIF],sm->smt_tid) ;
			}
			break ;
		default :
			illegal = 2 ;
			break ;
		}
		break ;
	case SMT_SIF_CONFIG :	
		if (sm->smt_type != SMT_REQUEST)
			break ;
		DB_SMT("SMT : replying to SIF Config request from %s\n",
			addr_to_string(&sm->smt_source),0) ;
		smt_send_sif_config(smc,&sm->smt_source,sm->smt_tid,local) ;
		break ;
	case SMT_SIF_OPER :	
		if (sm->smt_type != SMT_REQUEST)
			break ;
		DB_SMT("SMT : replying to SIF Operation request from %s\n",
			addr_to_string(&sm->smt_source),0) ;
		smt_send_sif_operation(smc,&sm->smt_source,sm->smt_tid,local) ;
		break ;
	case SMT_ECF :		
		switch (sm->smt_type) {
		case SMT_REPLY :
			smc->mib.priv.fddiPRIVECF_Reply_Rx++ ;
			DB_SMT("SMT: received ECF reply from %s\n",
				addr_to_string(&sm->smt_source),0) ;
			if (sm_to_para(smc,sm,SMT_P_ECHODATA) == NULL) {
				DB_SMT("SMT: ECHODATA missing\n",0,0) ;
				break ;
			}
			if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF]) {
				DB_SMT("SMT : ECF test TID ok\n",0,0) ;
			}
			else if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF_UNA]) {
				DB_SMT("SMT : ECF test UNA ok\n",0,0) ;
			}
			else if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF_DNA]) {
				DB_SMT("SMT : ECF test DNA ok\n",0,0) ;
			}
			else {
				DB_SMT("SMT : expected TID %lx, got %lx\n",
					smc->sm.pend[SMT_TID_ECF],
					sm->smt_tid) ;
			}
			break ;
		case SMT_REQUEST :
			smc->mib.priv.fddiPRIVECF_Req_Rx++ ;
			{
			if (sm->smt_len && !sm_to_para(smc,sm,SMT_P_ECHODATA)) {
			DB_SMT("SMT: ECF with para problem,sending RDF\n",0,0) ;
				smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_LENGTH,
					local) ;
				break ;
			}
			DB_SMT("SMT - sending ECF reply to %s\n",
				addr_to_string(&sm->smt_source),0) ;

			
			sm->smt_dest = sm->smt_source ;
			sm->smt_type = SMT_REPLY ;
			dump_smt(smc,sm,"ECF REPLY") ;
			smc->mib.priv.fddiPRIVECF_Reply_Tx++ ;
			smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
			return ;		
			}
		default :
			illegal = 1 ;
			break ;
		}
		break ;
#ifndef	BOOT
	case SMT_RAF :		
#ifdef	ESS
		DB_ESSN(2,"ESS: RAF frame received\n",0,0) ;
		fs = ess_raf_received_pack(smc,mb,sm,fs) ;
#endif

#ifdef	SBA
		DB_SBAN(2,"SBA: RAF frame received\n",0,0) ;
		sba_raf_received_pack(smc,sm,fs) ;
#endif
		break ;
	case SMT_RDF :		
		smc->mib.priv.fddiPRIVRDF_Rx++ ;
		break ;
	case SMT_ESF :		
		if (sm->smt_type == SMT_REQUEST) {
			DB_SMT("SMT - received ESF, sending RDF\n",0,0) ;
			smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ;
		}
		break ;
	case SMT_PMF_GET :
	case SMT_PMF_SET :
		if (sm->smt_type != SMT_REQUEST)
			break ;
		
		if (sm->smt_class == SMT_PMF_GET)
			smc->mib.priv.fddiPRIVPMF_Get_Rx++ ;
		else
			smc->mib.priv.fddiPRIVPMF_Set_Rx++ ;
		
		if ((sm->smt_class == SMT_PMF_SET) &&
			!is_individual(&sm->smt_dest)) {
			DB_SMT("SMT: ignoring PMF-SET with I/G set\n",0,0) ;
			break ;
		}
		smt_pmf_received_pack(smc,mb, local) ;
		break ;
	case SMT_SRF :
		dump_smt(smc,sm,"SRF received") ;
		break ;
	default :
		if (sm->smt_type != SMT_REQUEST)
			break ;
		
		DB_SMT("SMT : class = %d, send RDF to %s\n",
			sm->smt_class, addr_to_string(&sm->smt_source)) ;

		smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ;
		break ;
#endif
	}
	if (illegal) {
		DB_SMT("SMT: discarding invalid frame, reason = %d\n",
			illegal,0) ;
	}
	smt_free_mbuf(smc,mb) ;
}
static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
			 int local)
/* SMbuf *rej;	mbuf of offending frame */
/* int fc;	FC of denied frame */
/* int reason;	reason code */
{
	SMbuf	*mb ;
	struct smt_header	*sm ;	/* header of offending frame */
	struct smt_rdf	*rdf ;
	int		len ;
	int		frame_len ;

	sm = smtod(rej,struct smt_header *) ;
	if (sm->smt_type != SMT_REQUEST)
		return ;

	DB_SMT("SMT: sending RDF to %s,reason = 0x%x\n",
		addr_to_string(&sm->smt_source),reason) ;


	/*
	 * note: get framelength from MAC length, NOT from SMT header
	 * smt header length is included in sm_len
	 */
	frame_len = rej->sm_len ;

	if (!(mb=smt_build_frame(smc,SMT_RDF,SMT_REPLY,sizeof(struct smt_rdf))))
		return ;
	rdf = smtod(mb,struct smt_rdf *) ;
	rdf->smt.smt_tid = sm->smt_tid ;		/* use TID from sm */
	rdf->smt.smt_dest = sm->smt_source ;		/* set dest = source */

	/* set P12 */
	rdf->reason.para.p_type = SMT_P_REASON ;
	rdf->reason.para.p_len = sizeof(struct smt_p_reason) - PARA_LEN ;
	rdf->reason.rdf_reason = reason ;

	/* set P14 */
	rdf->version.para.p_type = SMT_P_VERSION ;
	rdf->version.para.p_len = sizeof(struct smt_p_version) - PARA_LEN ;
	rdf->version.v_pad = 0 ;
	rdf->version.v_n = 1 ;
	rdf->version.v_index = 1 ;
	rdf->version.v_version[0] = SMT_VID_2 ;
	rdf->version.v_pad2 = 0 ;

	/* set P13 */
	if ((unsigned) frame_len <= SMT_MAX_INFO_LEN - sizeof(*rdf) +
		2*sizeof(struct smt_header))
		len = frame_len ;
	else
		len = SMT_MAX_INFO_LEN - sizeof(*rdf) +
			2*sizeof(struct smt_header) ;
	/* make length multiple of 4 */
	len &= ~3 ;
	rdf->refused.para.p_type = SMT_P_REFUSED ;
	/* length of para is smt_frame + ref_fc */
	rdf->refused.para.p_len = len + 4 ;
	rdf->refused.ref_fc = fc ;

	/* swap it back */
	smt_swap_para(sm,frame_len,0) ;

	memcpy((char *) &rdf->refused.ref_header,(char *) sm,len) ;

	len -= sizeof(struct smt_header) ;
	mb->sm_len += len ;
	rdf->smt.smt_len += len ;

	dump_smt(smc,(struct smt_header *)rdf,"RDF") ;
	smc->mib.priv.fddiPRIVRDF_Tx++ ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}