📄 ldppdu.c
字号:
/********************************************************************/
/* Product Name: MPLS PACK 1.0 */
/* Module Name: LDP */
/* File Name: Ldppdu.c */
/* Author Name: Jing Xiaoyuan, Li Jianping */
/* Creat Date: 12/20/99 */
/* Version : 1.0 */
/* Function : 解码PDU包,并处理执行发现功能的Hello消息 */
/* modifier : hu.yonghong 2002-6-19 */
/* wengqing 2003.1.16 if the session is to de deleted,delete lspcb whitch appended after session */
/* wengqing 2003.2.10 if hello decode error,directly return */
/* szh mod 2003-9-11 ProcessHello()szh add protect */
/* szh add protect 2003-10-11 ProcessHello() */
/* szh mod 2003-10-20 减少LDP向A041发送的消息改成函数调用 */
/* szh mod 2003-11-12 add session_error检测变量,看是否存在通过helloindex找
不到session的情况
/* 2003-12-10 lixia mod for debug mpls*/
/********************************************************************/
#include "ldpvars.h"
extern void sessTimeout(mplsLdpSession_t * session);
extern void ProcSessTcpTimer(mplsLdpSession_t * session);
ulong session_error=0,sesserror_index=0;
long checkStatuscode(long encodedSize)
{
long statuscode = SUCCESS;
switch ( encodedSize )
{
case MPLS_MSGTYPEERROR:
statuscode = UNKNOWNMSGTYP;
break;
case MPLS_TLVTYPEERROR:
statuscode = UNKNOWNTLV;
break;
case MPLS_FECELEM_ERROR:
statuscode = UNKNOWNFEC;
break;
case MPLS_TLV_LENGTH_ERROR:
statuscode = BADTLVLEN;
break;
case MPLS_TLV_VAL_ERROR:
statuscode = MALFORMTLVVAL;
break;
case MPLS_MSG_LENGTH_ERROR:
statuscode = BADMSGLEN;
break;
default:
break;
}
return statuscode;
}
void checkRetCode(long encodedSize, mplsLdpSession_t * session, mplsLdpMsg_t msgHead)
{
long statuscode = SUCCESS;
statuscode = checkStatuscode( encodedSize);
if ( statuscode == SUCCESS )
return;
else
{
switch(statuscode)
{
case UNKNOWNMSGTYP:
case UNKNOWNTLV:
case UNKNOWNFEC:
sndnotifymsgproc(session,statuscode,msgHead.msgId,
msgHead.flags.flags.msgType);
break;
case BADMSGLEN:
case BADTLVLEN:
case MALFORMTLVVAL:
DelTmid(session);
sndnotifymsgproc(session,statuscode,msgHead.msgId,
msgHead.flags.flags.msgType);
if(statuscode == MALFORMTLVVAL)
processldpstats(SESSATTEMPED, session);
SendTcpRel(session);
break;
default :
break;
}
}
return;
}
mplsLdpInterface_t *LDP_ADDR_SEARCH_IF(unsigned long Address)
{
int ii,jj = -1;
for (ii = 0; ii < allInterface.num; ii++)
{
if (allInterface.interface[ii].ifIpAddress == Address)
{
jj = ii;
break;
}
}
if(jj == -1)
return NULL;
/* 检测本地接收端口是否支持MPLS */
if (allInterface.interface[jj].adminStatus != 1) // 此端口不支持MPLS
{
#ifdef MPLS_ERR_PRINT
DEBUG_OUT(DEBUG_OWNER_MPLS, DEBUG_LEVEL_MPLS_LSP,"!!!!Recv Interface not support MPLS!!! Error!!! \n");
printf("!!!!Recv Interface not support MPLS!!! Error!!! \n");
#endif
return NULL;
}
return &(allInterface.interface[jj]);
}
mplsLdpEntity_t *LDP_IF_SEARCH_ENTITY(mplsLdpInterface_t *ldpInterface)
{
int ii,jj = -1;
for (ii = 0; ii < allEntity.num; ii++)
{
if((ldpInterface->ifIndex == allEntity.entity[ii].ifArray)&&
(ldpInterface->entityLdpId.lsrAddress == allEntity.entity[ii].ldpId.lsrAddress)&&
(ldpInterface->entityLdpId.labelSpace == allEntity.entity[ii].ldpId.labelSpace))
{
jj = ii;
break;
}
}
if(jj == -1)
return NULL;
return &(allEntity.entity[jj]);
}
mplsLdpInterface_t *LDP_ENTITY_SEARCH_IF(mplsLdpEntity_t *pEntity)
{
int ii,jj = -1;
for (ii = 0; ii < allInterface.num; ii++)
{
if((allInterface.interface[ii].ifIndex == pEntity->ifArray)&&
(allInterface.interface[ii].entityLdpId.lsrAddress == pEntity->ldpId.lsrAddress)&&
(allInterface.interface[ii].entityLdpId.labelSpace == pEntity->ldpId.labelSpace))
{
jj = ii;
break;
}
}
if(jj == -1)
return NULL;
return &allInterface.interface[jj];
}
mplsLdpEntity_t *ldp_search_entity_index(unsigned long index)
{
int ii,jj = -1;
for (ii = 0; ii < allEntity.num; ii++)
{
if(allEntity.entity[ii].index == index)
{
jj = ii;
break;
}
}
if(jj == -1)
return NULL;
return &(allEntity.entity[jj]);
}
/* 处理接收到的Hello包 */
/* modify by hyh 2002-6-18 17:01 */
short ProcessHello(mplsLdpHelloMsg_t *helloRecMsg,
unsigned long localAddr,
unsigned long peerAddr,
mplsLdpId_t peerLdpId)
{
ldpMibHelloIndexReq_t helIndex;
mplsLdpHello_t *hello = NULL;
mplsLdpHello_t hellotmp;
ldpMibSessionIndexReq_t sesIndex_s;
mplsLdpSession_t *session1 = MPLS_NULL;
mplsLdpSession_t *session2 = MPLS_NULL;
mplsLdpSession_t sessiontmp;
ldpMibPeerIndexReq_t peerIndex;
mplsLdpPeer_t *peer = MPLS_NULL;
mplsLdpPeer_t peertmp;
unsigned long helloIndex;
long tmid;
tmidHel_t aa;
long ifIndex;
unsigned char helloIndexExist;
unsigned long size;
mplsLdpId_t entityLdpId;
unsigned long peerTransAddr;
mplsLdpEntity_t *ldpEntity = NULL;
mplsLdpInterface_t *ldpInterface = NULL;
unsigned short ii;
int rtcode;
/* 由address检索interface表 */
ldpInterface = LDP_ADDR_SEARCH_IF(localAddr);
if (ldpInterface == NULL)
{
#ifdef MPLS_ERR_PRINT
printf("!!!!Recv Interface not in Interface Table Error \n");
DEBUG_OUT(DEBUG_OWNER_MPLS, DEBUG_LEVEL_MPLS_SESSION,"!!!!Recv Interface not in Interface Table Error \n");
#endif
return LDP_FALSE;
}
ifIndex = ldpInterface->ifIndex;;
/* 由interface检索entity表 */
ldpEntity = LDP_IF_SEARCH_ENTITY(ldpInterface);
if(ldpEntity == NULL)
return LDP_FALSE;
entityLdpId = ldpEntity->ldpId;
if(peerLdpId.lsrAddress == entityLdpId.lsrAddress)
return;
if (helloRecMsg->trAdrTlvExists == 1)
peerTransAddr = helloRecMsg->trAdr.address;
else
peerTransAddr = peerAddr;
/* 1. 首先检索HELLO表,是否已经存在对应的表项 */
helIndex.unionIndex.entityLdpId = entityLdpId;
helIndex.unionIndex.ifIndex = ifIndex;
helIndex.unionIndex.peerLdpId = peerLdpId;
helIndex.indexFlag = 2;
hello = (mplsLdpHello_t *)MibHello(&helIndex, LDP_SEARCH);
if (hello == MPLS_NULL)
{
/* 1.3 协商本entity的发送holdtime */
hellotmp.helloHoldTime = ldpEntity->helloHoldTimer*LDP_MIN_TIME_INTERVAL;
if(ldpEntity->helloHoldTimer > helloRecMsg->chp.holdTime)
{
ldpEntity->helloSendTimer = helloRecMsg->chp.holdTime*LDP_MIN_TIME_INTERVAL/3;
hellotmp.helloHoldTime = helloRecMsg->chp.holdTime*LDP_MIN_TIME_INTERVAL;
if(ldpEntity->helloSendTimer == 0)
{
ldpEntity->helloSendTimer = \
DEFAULT_DIRECT_LDP_HELLO_INTERVAL*LDP_MIN_TIME_INTERVAL/3;
hellotmp.helloHoldTime = DEFAULT_DIRECT_LDP_HELLO_INTERVAL*LDP_MIN_TIME_INTERVAL;
}
}
/* 1.1 创建新的hello邻接*/
hellotmp.entityLdpId = entityLdpId;
hellotmp.peerLdpId = peerLdpId;
/* 1.2 暂时不根据peerLdpId中的对等方的IP地址来判断是否TARGET_HELLO,而是默认为DIRECT_HELLO */
hellotmp.helloType = DIRECT_HELLO;
if (helloRecMsg->csnTlvExists == 1) /* hyh 02-8-6 */
hellotmp.cfgNum = helloRecMsg->csn.seqNumber;
else
hellotmp.cfgNum = 0;
hellotmp.sessionIndex = 0;
hellotmp.ifIndex = ifIndex;
hellotmp.nexthopAddr = peerAddr;
hellotmp.helloPeerAddr = peerTransAddr;
hellotmp.EntityIndex = ldpEntity->index;
hello = (mplsLdpHello_t *)MibHello(&hellotmp, LDP_SET);
if (hello == MPLS_NULL)
return LDP_FALSE;
/* 设置hello邻接维持定时器 */
MPLS_SET_TIMER(hello->helloHoldTime,
(void *)DelHello,
hello,
ldptime_q,
hello->adj_timerid);
// helloIndex = hello->index;
}
else
{
/* 2. 可以找到相应的HELLO表项,刷新计时器的值 */
/*如果hello的地址不对,不处理*/
if((hello->nexthopAddr != peerAddr)&&(hello->ifIndex != 0))
return LDP_FALSE;
/* 重置hello邻接维持定时器 */
if(hello->adj_timerid > 0)
{
MPLS_CLEAR_TIMER(hello->adj_timerid,ldptime_q,rtcode);
hello->adj_timerid = 0;
}
MPLS_SET_TIMER(hello->helloHoldTime,
(void *)DelHello,
hello,
ldptime_q,
hello->adj_timerid);
}
/* 3. 处理可选TLV:csnTlvExists */
if (helloRecMsg->csnTlvExists == 1)
if((helloRecMsg->csn.seqNumber > hello->cfgNum)&&(hello->sessionIndex > 0)) //配置有变化
{
hello->cfgNum = helloRecMsg->csn.seqNumber;
/* 查询HELLO中的SESSION,去掉RETRY回退 */
sesIndex_s.sessionIndex = hello->sessionIndex;
sesIndex_s.indexFlag = 1;
session1 = (mplsLdpSession_t *)MibSession(&sesIndex_s, LDP_SEARCH);
if (session1 != MPLS_NULL)
{
if ((session1->role==ACTIVE)&&(session1->tmidCon>0)&&(session1->state==NONEXISTENT))
{
session1->tcpConRetry = 0;
if(session1->tmidCon > 0)
{
MPLS_CLEAR_TIMER(session1->tmidCon,ldptime_q,rtcode);
session1->tmidCon = 0;
}
SessionFSM(session1,LDPSESINIT,NULL);
}
}
}
/* 4. 查询是否有相应的会话*/
sesIndex_s.unionIndex.entityLdpId = entityLdpId;
sesIndex_s.unionIndex.peerLdpId = peerLdpId;
sesIndex_s.indexFlag = 2;
session2 = (mplsLdpSession_t *)MibSession(&sesIndex_s, LDP_SEARCH);
/* szh add protect 2003-10-11 */
if(session2 != MPLS_NULL)
{
if((session2->state == INITIALIZED || session2->state == OPENREC ||
session2->state == OPENSENT || session2->state == OPERATIONAL)&&
( session2->life_timerid == 0)) /* abnormal state */
{
/* 置session维持定时器 */
MPLS_SET_TIMER(session2->keepAliveHoldTime,
(void *)sessTimeout,
session2,
ldptime_q,
session2->life_timerid);
printf(" session input abnormal state %d!!!!!!",session2->state);
}
else
{
if(session2->state == TCP_CONNECT_AWAITED &&
session2->tmidCon == 0) /* abnormal state */
{
MPLS_SET_TIMER(TCPREQ_TIME,(void *)ProcSessTcpTimer,
session2,ldptime_q,session2->tmidCon);
printf(" tcp setup input abnormal state %d!!!!!!",session2->state);
}
}
}
/* szh add protect end 2003-10-11 */
if((session2 != MPLS_NULL)&&(session2->state != TCP_RELEASE_AWAITED))
{
/* 找到session,此时session有可能是这个hello的邻接,也有可能是新的hello邻接
*/
/*如果session的地址不对,直接删掉hello返回*/
if(((session2->nexthopaddr != peerAddr)||(session2->localIpaddr != localAddr))
&&(session2->ifIndex != 0))
{
if(hello->adj_timerid > 0)
{
MPLS_CLEAR_TIMER(hello->adj_timerid,ldptime_q,rtcode);
hello->adj_timerid = 0;
}
DelHello(hello);
return LDP_FALSE;
}
helloIndexExist = 0;
for (ii=0;ii<SESSION_OWNED_HELLO;ii++)
if (session2->helloArray[ii] == hello->index)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -