📄 m2pa.c
字号:
lmi_optmgmt_req *p = (lmi_optmgmt_req *)mp->b_rptr; caddr_t *opt_ptr = p->lmi_opt; size_t *opt_len = mp->b_wptr - opt_ptr; if ( m2->m_state != LMI_UNATTACHED && m2->m_state != LMI_DISABLED && m2->m_state != LMI_ENABLED ) { if ( !(resp = lmi_error_ack(LMI_OUTSTATE, 0, m2->m_state)) ) return -EAGAIN; freemsg(mp); qreply(q, resp); return(0); } if ( !opt_len ) { if ( !(resp = lmi_optmgmt_ack(p->lmi_mgmt_flag, NULL, 0)) ) return -EAGAIN; freemsg(mp); qreply(q, resp); return(0); } if ( !(resp = lmi_optmgmt_ack(T_FAILURE, opt_ptr, opt_len)) ) return -EAGAIN; /* * FIXME: pull out options and fill in response * FIXME: pull out options and fill in response * FIXME: pull out options and fill in response */ freemsg(mp); qreply(q, resp); return(0);}/* * ========================================================================= * * M2PA-Provider --> SL-User PROTOCOL Primitives * * ------------------------------------------------------------------------- * * SL_PDU_REQ * ------------------------------------- * * This is used to send data coming down in a pdu request. We strap options * on the M_DATA blocks and pass it on. * */static int sl_pdu_req(queue_t *q, mblk_t *pdu){ mblk_t *mp; if ( !(mp = m2pa_send_data(pdu->b_cont)) ) return -EAGAIN; freeb(pdu); putnext(q, mp); return(0);}/* * SL_EMERGENCY_REQ * ------------------------------------- * We keep track of whether we are in an emergency situation or not so that * we can modify the alignment and proving procedures when they are invoked. */static int sl_emergency_req(queue_t *q, mblk_t *pdu){ M2PA_PRIV(q)->flags |= M2PA_LOC_EMERGENCY; freemsg(pdu); return(0);}/* * SL_EMERGENCY_CEASES_REQ * ------------------------------------- * We keep track of whether we are in an emergency situation or not so that * we can modify the alignment and proving procedures when they are invoked. */static int sl_emergency_ceases_req(queue_t *q, mblk_t *pdu){ M2PA_PRIV(q)->flags &= ~M2PA_LOC_EMERGENCY; freemsg(pdu); return(0);}/* * SL_START_REQ * ------------------------------------- */static int sl_start_req(queue_t *q, mblk_t *pdu){ mblk_t *mp; m2pa_t *m2 = M2PA_PRIV(q); switch ( m2->state ) { case M2PA_OUT_OF_SERVICE: if ( !(mp = m2pa_send_sio()) ) return -EAGAIN; m2->state = M2PA_NOT_ALIGNED; m2->t2_timer = timeout(m2->t2_timeout, (long)m2, m2->t2_value); putnext(q, mp); break; } /* ignore multiple start primitives */ freemsg(pdu); return(0);}/* * SL_STOP_REQ * ------------------------------------- */static int sl_stop_req(queue_t *q, mblk_t *pdu){ switch ( m2->state ) { case M2PA_AIP: switch ( m2->t_state ) { case TS_WACK_BREQ: return -ERESTART; case TS_IDLE: if ( t_unbnd_req(m2) == -ENOBUFS ) return -EAGAIN; m2->t_state = TS_WACK_UREQ; break; case TS_WCON_CREQ: if ( t_discon_req(m2) == -ENOBUFS ) return -EAGAIN; m2->t_state = TS_WACK_DREQ6; break; case TS_WRES_CIND: if ( t_discon_req(m2) == -ENOBUFS ) return -EAGAIN; m2->t_state = TS_WACK_DREQ7; break; case TS_WACK_CREQ: case TS_WACK_CRES: break; } m2->state = M2PA_OOS; untimeout(m2->t1_timer); m2->t1_timer = 0; break; case M2PA_INS_LOCAL: /* we are always in TS_DATA_XFER state */ if ( t_ordrel_req(m2) == -ENOBUFS ) return -EAGAIN; m2->t_state = TS_WACK_DREQ9; m2->state = M2PA_OOS; break; case M2PA_INS: /* we are always in TS_DATA_XFER state */ if ( t_ordrel_req(m2) == -ENOBUFS ) return -EAGAIN; m2->t_state = TS_WACK_DREQ9; m2->state = M2PA_RETRIEVAL; break; default: case M2PA_IDLE: case M2PA_OOS: case M2PA_RETRIEVAL: /* we are already stopped - ignore */ break; } freemsg(mp); return(0);}/* * SL_RETRIEVE_BSNT_REQ * ------------------------------------- */static int sl_retrieve_bsnt_req(queue_t *q, mblk_t *pdu){ /* * TODO: write this function */ freemsg(mp); return(0);}/* * SL_RETRIEVAL_REQUEST_AND_FSNC_REQ * ------------------------------------- */static int sl_retrieval_request_and_fsnc_req(queue_t *q, mblk_t *pdu){ m2->fsnc = ((sl_retrieval_req_and_fsnc_t *)mp->b_rptr)->sl_fsnc; /* * TODO: perform retrieval */ freemsg(mp); return(0);}/* * SL_RESUME_REQ * ------------------------------------- */static int sl_resume_req(queue_t *q, mblk_t *pdu){ /* * TODO: write this function */ freemsg(mp); return(0);}/* * SL_CLEAR_BUFFERS_REQ * ------------------------------------- */static int sl_clear_buffers_req(queue_t *q, mblk_t *pdu){ /* * TODO: write this function */ freemsg(mp); return(0);}/* * SL_CLEAR_RTB_REQ * ------------------------------------- */static int sl_clear_rtb_req(queue_t *q, mblk_t *pdu){ /* * TODO: write this function */ freemsg(mp); return(0);}/* * SL_LOCAL_PROCESSOR_OUTAGE_REQ * ------------------------------------- */static int sl_local_processor_outage_req(queue_t *q, mblk_t *pdu){ if ( !(m2->flags & M2PA_FLAG_LOCAL_PROC_OUTAGE) ) { if ( m2pa_send_sipo(m2) == -ENOBUFS ) return -EAGAIN; m2->flags |= M2PA_FLAG_LOCAL_PROC_OUTAGE; } freemsg(mp); return(0);}/* * SL_LOCAL_PROCESSOR_RECOVERED_REQ * ------------------------------------- */static int sl_local_processor_recovered_req(queue_t *q, mblk_t *pdu){ if ( m2->flags & M2PA_FLAG_LOCAL_PROC_OUTAGE ) { if ( m2pa_send_not_sipo(m2) == -ENOBUFS ) return -EAGAIN; m2->flags &= ~M2PA_FLAG_LOCAL_PROC_OUTAGE; } freemsg(mp); return(0);}/* * SL_CONGESTION_DISCARD_REQ * ------------------------------------- */static int sl_congestion_discard_req(queue_t *q, mblk_t *pdu){ if ( !(m2->flags & (M2PA_FLAG_L3_CONG_DISC)) ) { if ( !(m2->flags & (M2PA_FLAG_L2_CONG_DISC)) ) if ( m2pa_send_sib(m2) == -ENOBUFS ) return -EAGAIN; m2->flags |= M2PA_FLAG_L3_CONG_DISC; } freemsg(mp); return(0);}/* * SL_CONGESTION_ACCEPT_REQ * ------------------------------------- */static int sl_congestion_accept_req(queue_t *q, mblk_t *pdu){ if ( !(m2->flags & (M2PA_FLAG_L3_CONG_ACPT|S2PA_FLAG_L3_CONG_DISC)) ) { if ( !(m2->flags & (M2PA_FLAG_L2_CONG_ACPT|S2PA_FLAG_L2_CONG_DISC)) ) if ( m2pa_send_sib(m2) == -ENOBUFS ) return -EAGAIN; m2->flags |= M2PA_FLAG_L3_CONG_ACPT; } freemsg(mp); return(0);}/* * SL_NO_CONGESTION_REQ * ------------------------------------- */static int sl_no_congestion_req(queue_t *q, mblk_t *pdu){ if ( m2->flags & (M2PA_FLAG_L3_CONG_ACPT|S2PA_FLAG_L3_CONG_DISC) ) { if ( !(m2->flasg & (M2PA_FLAG_L2_CONG_ACPT|S2PA_FLAG_L2_CONG_DISC)) ) if ( m2pa_send_not_sib(m2) == -ENOBUFS ) return -EAGAIN; m2->flags &= ~M2PA_FLAG_L3_CONG_ACPT; m2->flags &= ~M2PA_FLAG_L3_CONG_DISC; } freemsg(mp); return(0);}/* * SL_POWER_ON_REQ * ------------------------------------- */static int sl_power_on_req(queue_t *q, mblk_t *pdu){ /* * TODO: write this function */ freemsg(mp); return(0);}/* * ========================================================================= * * T-Provider (SCTP) --> M2PA-Provider Primitives (M_CTL, M_PROTO, M_PCPROTO) * * ========================================================================= *//* * T_INFO_ACK * * We might need this if we are using other transports and we send a * T_INFO_REQ to the T-Provider to see what semantics we should use for * encapsulating messages and stuff. If we are only using SCTP, we know what * to expect and will never see this message. */static int t_info_ack(queue_t *q, mblk_t *mp){ struct T_info_ack *p; ptrace(("Unexpected primitive received from T-Provider\n")); (void)q; (void)mp; return(-EPROTO);}/* * T_BIND_ACK * * SCTP will send us this response when we go to bind the stream for * connection or listening. We should acknowledge this fact and move to the * next state in attempting to bring up the SCTP association. */static int t_bind_ack(queue_t *q, mblk_t *tp){ mblk_t *mp; m2pa_t *m2 = M2PA_PRIV(q); if ( m2->t_state == TS_WACK_BREQ ) { if ( !(mp = lmi_ok_ack(LMI_ATTACH_REQ, LMI_DISABLED)) ) return -EAGAIN; m2->t_state = TS_IDLE; m2->m_state = LMI_DISABLED; freemsg(tp); putnext(q, mp); return(0); } return(-EPROTO);}/* * T_OPTMGMT_ACK * * SCTP will send us this repsonse when we use a T_OPTMGMT_REQ to set the * number of inbound and outbound SCTP-streams. Actually, we never really * need this message (T_CONN_REQ and T_CONN_RES work just fine) so we should * not expect this message. This is a T-Provider error. We should M_ERROR * out the stream. */static int t_optmgmt_ack(m2pa_t *m2, mblk_t *mp){ struct T_optmgmt_ack *p; ptrace(("Unexpected primitive received from T-Provider\n")); (void)m2; (void)mp; return(-EPROTO);}/* * T_ADDR_ACK * * SCTP should no send us this message, because we never send a T_ADDR_REQ to * SCTP, so we do not expect the response. This is a T-Provider error. We * should M_ERROR out the queue. */static int t_addr_ack(queue_t *q, mblk_t *tp){ mblk_t *mp; m2pa_t *m2 = M2PA_PRIV(q); struct T_addr_ack *p = (struct T_addr_ack *)tp->b_rptr; const caddr_t ppa_ptr = (caddr_t)(&p->LOCADDR_length); const size_t ppa_len = tp->b_wptr - ppa_ptr; p->LOCADDR_offset -= ppa_ptr - tp->b_rptr; p->REMADDR_offset -= ppa_ptr - tp->b_rptr; if ( !(mp = lmi_info_ack(m2->m_state, ppa_ptr, ppa_len)) ) { p->LOCADDR_offset += ppa_ptr - tp->b_rptr; p->REMADDR_offset += ppa_ptr - tp->b_rptr; return -EAGAIN; } freemsg(tp); putnext(q, mp); return(0);}/* * T_OK_ACK * * SCTP has acknowledged receipt of our last primitive. We can move to the * successful state. */static int t_ok_ack(queue_t *q, mblk_t *tp){ mblk_t *mp; m2pa_t *m2 = M2PA_PRIV(q); struct T_ok_ack *p = (struct T_ok_ack *)tp->b_rptr; switch ( m2->t_state ) { case TS_WACK_UREQ: if ( !(mp = lmi_ok_ack(LMI_DETACH_REQ, LMI_UNATTACHED)) ) return -EAGAIN; m2->t_state = TS_UNBND; m2->m_state = LMI_UNATTACHED; freemsg(tp); putnext(q, mp); return(0); case TS_WACK_CREQ: m2->t_state = TS_WCON_CREQ; /* still waiting for connect */ freemsg(tp); return(0); case TS_WACK_CRES: if ( !(mp = lmi_enable_con()) ) return -EAGAIN; m2->t_state = TS_DATA_XFER; m2->m_state = LMI_ENABLED; freemsg(tp); putnext(q, mp); return(0); case TS_WACK_DREQ6: case TS_WACK_DREQ7: case TS_WACK_DREQ9: case TS_WACK_DREQ10: case TS_WACK_DREQ11: if ( !(mp = lmi_disable_con()) ) return -EAGAIN; m2->t_state = TS_IDLE; m2->m_state = LMI_DISABLED; freemsg(tp); putnext(q, mp); return(0); } return(-EPROTO);}/* * T_ERROR_ACK * * SCTP has refused our last primitive. We can either respond with an error * to the M2PA user or we will have to M_ERROR out the stream. */static int t_error_ack(queue_t *q, mblk_t *tp){ mblk_t *mp; m2pa_t *m2 = M2PA_PRIV(q); struct T_error_ack *p = (struct T_error_ack *)tp->b_rptr; int error = p->TLI_error; int reason = p->UNIX_error; switch ( m2->t_state ) { case TS_WACK_BREQ: /* * FIXME: should translate error and reason */ if ( !(mp = lmi_error_ack(LMI_ATTACH_REQ, error, reason, LMI_UNATTACHED)) ) return -EAGAIN; m2->t_state = TS_UNBND; m2->m_state = LMI_UNATTACHED; freemsg(tp); putnext(q, mp); return(0); case TS_WACK_UREQ: /* * FIXME: should translate error and reason */ if ( !(mp = lmi_error_ack(LMI_DETACH_REQ, error, reason, LMI_DISABLED)) ) return -EAGAIN; m2->t_state = TS_IDLE; m2->m_state = LMI_DISABLED; freemsg(tp); putnext(q, mp); return(0); case TS_WACK_CREQ: /* * FIXME: should translate error and reason */ if ( !(mp = lmi_error_ind(error, reason, LMI_DISABLED)) ) return -EAGAIN; m2->t_state = TS_IDLE; m2->m_state = LMI_DISABLED; freemsg(tp); putnext(q, mp); return(0); case TS_WACK_CRES: /* * FIXME: should translate error and reason */ if ( !(mp = lmi_error_ind(error, reason, LMI_DISABLED)) ) return -EAGAIN; m2->t_state = TS_WRES_CIND; /* m2->m_state = LMI_ENABLE_PENDING; */ /* FIXME: this is not a good place to stay */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -