📄 mpsend.c
字号:
/* mpsend.c - MP Send related functions *//* Copyright 1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01n,23jan03,ijm fix for SPR#85876, netStackDataPoolShow displays increasing count for HEADER mblocks and negative count for DATA mblocks, removed redundant packet frees in mp_send_ppp_packet, free packet if ENOBUFS in mp_fragment_ppp_packet_and_send, changed logMsg to printf01m,06aug02,jr fixed build warnings 01l,05may02,vk modifications to use m_prepend() to attach MP header and fragment data01k,28apr02,vk modification as part of ARM fixes01j,23feb02,ak removing the state lock and release in mp_send_ppp_packet()01i,04jan02,vk Modifications to avoid copying the input to a local buffer before fragmentation01h,11dec01,ak Made incrementing buffer pointer conditional in mp_fragment_ppp_packet_and_send01g,08oct01,ak Maximum fragment length supported on a link is PPP MAC header length subtracted from the MTU supported from the link01f,19sep01,ak Modification to fragment the packet based on MRU contribution of individual links01e,19sep01,ak Removed the check incoming packet size > remote MRRU in mp_send_ppp_packet()01d,19sep01,ak Setting the MBLK header after netTupleGet in mp_fragment_ppp_packet_and_send()01c,19sep01,ak Support for rotating the links for non-fragmented packets01b,30may01,ijm fixed memory leak problem in mp_fragment_ppp_packet_and_send()01a,20feb01,as created from routerware source base*//*DESCRIPTIONThis module implements the MP send related functions and is partof the MP_FRAMING_LAYER functionality.The PPP packet to be sent is fragmented and encapsulated with the MP headersbased on the SHORT sequence or the LONG sequence header format. The fragmentlength is decided based on the bandwidth of the individual links of the bundle,through which the fragments are sent.The constructed fragments are finally sent to the MP_INTERFACE_LAYER componentof the MEMBER stack, through the queue if it is enabled. If the queue is notenabled, the fragments are sent using the pfwSend function.INCLUDE FILES : mpFramingLayerP.h*//* defines */#define SIZE_OF_PPP_CONTROL_AND_ADDRESS_FIELDS 2#define HALF_SIZE_OF_PPP_PROTOCOL_FIELD 1#define BUNDLE_CLOSED 0/* includes */#include "stdio.h"#include "private/ppp/mpFramingLayerP.h"#include "logLib.h"/* externs */IMPORT STATUS mp_send_ppp_packet (PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, M_BLK_ID pMblkId, PFW_PACKET_TYPE packet_type);IMPORT STATUS mpSendQueueAdd (PFW_OBJ *pfwObj, FUNCPTR jobHandlerFunc, void *data, int);/* locals and forwards */LOCAL void mp_compress_ppp_header ( M_BLK_ID pMblkId );LOCAL STATUS mp_fragment_ppp_packet_and_send ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, M_BLK_ID packet, PFW_PACKET_TYPE packet_type );LOCAL STATUS mp_encapsulate_ppp_fragment_and_send ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, enum FRAGMENT_FLAG fragment_flag, M_BLK_ID packet, USHORT link_number, USHORT ppp_fragment_length, PFW_PACKET_TYPE packet_type );LOCAL STATUS encapsulate_ppp_fragment ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, enum FRAGMENT_FLAG fragment_flag, M_BLK_ID packet, M_BLK_ID pppp_encapsulated_mp_packet, USHORT ppp_fragment_length/* UINT packet_offset */ );LOCAL STATUS mp_populate_ppp_fragment_header_with_short_sequence_number ( MP_PACKET_WITH_SHORT_SEQUENCE_NUMBER *sptr_mp_packet, USHORT short_sequence_number, enum FRAGMENT_FLAG fragment_flag );LOCAL void install_short_sequence_number_into_header ( SHORT_SEQUENCE_NUMBER_MP_HEADER *sptr_short_sequence_number_mp_header, USHORT short_sequence_number );LOCAL void convert_short_sequence_number_header_into_network_order ( SHORT_SEQUENCE_NUMBER_MP_HEADER *sptr_short_sequence_number_mp_header );STATUS mp_populate_ppp_fragment_header_with_long_sequence_number ( MP_PACKET_WITH_LONG_SEQUENCE_NUMBER *sptr_mp_packet, ULONG long_sequence_number, enum FRAGMENT_FLAG fragment_flag );LOCAL void install_long_sequence_number_into_header ( LONG_SEQUENCE_NUMBER_MP_HEADER *sptr_long_sequence_number_mp_header, ULONG long_sequence_number );LOCAL void convert_long_sequence_number_header_into_network_order ( LONG_SEQUENCE_NUMBER_MP_HEADER *sptr_long_sequence_number_mp_header );void _mpSend ( void *data );/******************************************************************************** mp_send_ppp_packet - fragments the PPP packet and sends the fragments ** This function fragments the given PPP packet and encapsulates the fragments * with MP procedure and sends them.** RETURNS OK/ERROR*/STATUS mp_send_ppp_packet ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, /* plugin object state */ M_BLK_ID pMblkId, /* packet to send */ PFW_PACKET_TYPE packet_type /* packet type */ ) { USHORT pppPacketLength = 0; M_BLK_ID mblkPacket = NULL; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if ((mblkPacket = pMblkId) == NULL) {#ifdef PPP_DEBUG printf ("Null packet for MP Send \n");#endif /* PPP_DEBUG */ return ERROR; } if ((mblkPacket->mBlkHdr.mFlags & M_PKTHDR) && (mblkPacket->mBlkHdr.mNext != NULL)) { pppPacketLength = mblkPacket->mBlkPktHdr.len; } else { pppPacketLength = mblkPacket->mBlkHdr.mLen; } if (pStackData->bundle.sending_end.no_of_links == 0 || pStackData->bundle_state == MP_BUNDLE_CLOSED_STATE) {#ifdef PPP_DEBUG printf ("mp_send_ppp_packet: No Link present or bundle is in closed state \n");#endif /* PPP_DEBUG */ netMblkClChainFree (mblkPacket); return ERROR; } mp_compress_ppp_header (mblkPacket); if (mp_fragment_ppp_packet_and_send (pMpFramingLayerState, mblkPacket, packet_type) == OK) { return OK; } return ERROR; }/******************************************************************************** mp_compress_ppp_header - * compresses the Protocol Field in PPP encapsulated packet** This function compresses the protocol field in the given PPP encapsulated * packet* * RETURNS N/A*/LOCAL void mp_compress_ppp_header ( M_BLK_ID packet /* packet to compress */ ) { PPP_PACKET *pppPacket = NULL; pppPacket = mtod (packet, PPP_PACKET *);#if (_BYTE_ORDER == _BIG_ENDIAN) /* big endian support */ if ((pppPacket->header.protocol_type & 0xff00) == 0x0000)#else if ((pppPacket->header.protocol_type & 0x00ff) == 0x0000)#endif { packet->mBlkHdr.mData = packet->mBlkHdr.mData + HALF_SIZE_OF_PPP_PROTOCOL_FIELD; if (packet->mBlkHdr.mNext != NULL) { packet->mBlkPktHdr.len = packet->mBlkPktHdr.len - HALF_SIZE_OF_PPP_PROTOCOL_FIELD; packet->mBlkHdr.mLen = packet->mBlkHdr.mLen - HALF_SIZE_OF_PPP_PROTOCOL_FIELD; } else packet->mBlkHdr.mLen = packet->mBlkHdr.mLen - HALF_SIZE_OF_PPP_PROTOCOL_FIELD; } }/******************************************************************************** mp_fragment_ppp_packet_and_send - fragment the Protocol Field Compressied * PPP packet. Also encapsulates the fragments and send them.** This function fragments the given PFC applied PPP packet, encapsulates the * fragments with MP procedure and sends them. It does not fragment a packet if * its size is smaller than a value configured in the profile of the * MP_FRAMING_LAYER component. While fragmenting, it balances the load across * the links in the bundle with the bandwidth share information available on the * sending end of the bundle class.** RETURNS OK/ERROR*/LOCAL STATUS mp_fragment_ppp_packet_and_send ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, M_BLK_ID packet, PFW_PACKET_TYPE packet_type ) { USHORT link_number = 0; UINT pppPacketLength = 0; UINT sentPacketLength = 0; UINT fragment_length = 0; enum FRAGMENT_FLAG fragment_flag; PFW_OBJ *pfwObj = NULL; int remainingLen = 0; BOOL bFirstFragment = 0; UINT majorFragmentLength = 0; UINT packet_offset = 0; M_BLK_ID fragMblk; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if (packet == NULL) return ERROR; if ((packet->mBlkHdr.mFlags & M_PKTHDR) && (packet->mBlkHdr.mNext != NULL)) { pppPacketLength = packet->mBlkPktHdr.len; } else { pppPacketLength = packet->mBlkHdr.mLen; } pfwObj = pMpFramingLayerState->pluginObj->pfwObj; /* do not fragment the packet, only encapsulate with MP procedure and send */ if (pppPacketLength < pStackData->bundle.sending_end.small_packet_length) { if (pStackData->bundle.sending_end.linkForNonFragmentedPacket >= pStackData->bundle.sending_end.no_of_links) pStackData->bundle.sending_end.linkForNonFragmentedPacket = 0; link_number = pStackData->bundle.sending_end.linkForNonFragmentedPacket++; fragment_length = pppPacketLength; fragment_flag = ONLY_FRAGMENT;#ifdef PPP_DEBUG printf ("MP Tx: Packet sent through the single link %d in the bundle\n", (int) link_number);#endif /* PPP_DEBUG */ fragMblk = netMblkChainDup(pStackData->netPoolId,packet, 0,M_COPYALL,M_DONTWAIT); if (fragMblk == NULL) {#ifdef PPP_DEBUG printf ("ENOBUFS while getting mBlk for single MP fragment\n");#endif /* PPP_DEBUG */ netMblkClChainFree (packet); return ERROR; } if (mp_encapsulate_ppp_fragment_and_send (pMpFramingLayerState, fragment_flag, fragMblk, link_number, fragment_length, packet_type) == OK) { netMblkClChainFree (packet); return OK; } else { netMblkClChainFree (packet); return ERROR; } } else /* fragment the packet, encapsulate with MP procedure and send */ { remainingLen = pppPacketLength; bFirstFragment = TRUE; while (remainingLen > 0) { sentPacketLength = 0; if (remainingLen <= (pStackData->bundle.sending_end.aggregateMru - (PPP_WITH_MAC_HEADER_LENGTH * pStackData->bundle.sending_end.no_of_links))) majorFragmentLength = remainingLen; else majorFragmentLength = (pStackData->bundle.sending_end.aggregateMru - (PPP_WITH_MAC_HEADER_LENGTH * pStackData->bundle.sending_end.no_of_links)); for (link_number = 0x0000; link_number < pStackData->bundle.sending_end.no_of_links; ++link_number) {#if defined (INCLUDE_FLOATING_POINT) fragment_length = pStackData->bundle.sending_end.mru_share[link_number] * majorFragmentLength;#else fragment_length = (majorFragmentLength * pStackData->bundle.sending_end.mru_share[link_number]) / 100;#endif /* If the link is not the last link */ if (link_number != (pStackData->bundle.sending_end.no_of_links - 1)) { sentPacketLength = sentPacketLength + fragment_length; } /* the last link */ else { /* In the last link send the remaining whole packet */ fragment_length = majorFragmentLength - sentPacketLength; }#ifdef PPP_DEBUG printf ("MP: Fragmenting packet of length 0x%x for link 0x%x\n", (int) fragment_length,(int)link_number);#endif /* PPP_DEBUG */ /* Assign the fragment flag information */ if (bFirstFragment) { bFirstFragment = FALSE; if ((remainingLen - fragment_length) <= 0) { fragment_flag = ONLY_FRAGMENT; } else { fragment_flag = FIRST_FRAGMENT; } } else if ((remainingLen - fragment_length) <= 0) { fragment_flag = LAST_FRAGMENT; } else { fragment_flag = NOT_END_FRAGMENT; } if (fragment_length == 0x0000) { continue; } fragMblk = netMblkChainDup(pStackData->netPoolId,packet, packet_offset,fragment_length,M_DONTWAIT); if (fragMblk == NULL) {#ifdef PPP_DEBUG printf ("No pool memory for offset %d, fragment length %d\n", packet_offset, fragment_length);#endif /* PPP_DEBUG */ netMblkClChainFree (packet); return ERROR; } if (mp_encapsulate_ppp_fragment_and_send (pMpFramingLayerState, fragment_flag, fragMblk, link_number, fragment_length, packet_type) == ERROR) {#ifdef PPP_DEBUG printf ("Error while encapsulating the PPP packet for MP\n");#endif /* PPP_DEBUG */ return ERROR; } packet_offset += fragment_length; remainingLen -= fragment_length; } /* end of for */ } /* end of while */ netMblkClChainFree (packet); } /* end of else */ return OK; }/******************************************************************************** mp_encapsulate_ppp_fragment_and_send - * Encapsulates a PPP fragment with MP procedure and sends it** This function allocates memory to store the PPP fragment with MP and PPP * encapsulation. It encapsulates the PPP fragment with MP procedure and sends it.* * RETURNS OK/ERROR*/LOCAL STATUS mp_encapsulate_ppp_fragment_and_send ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, enum FRAGMENT_FLAG fragment_flag, M_BLK_ID packet, USHORT link_number, USHORT ppp_fragment_length, PFW_PACKET_TYPE packet_type ) { USHORT mp_packet_length = 0; USHORT ppp_encapsulated_mp_packet_length = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -