/* * 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; }
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; }
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) ; }