hash_tbl 改造续..

本文分享了一种使用数组实现Hash表的重构方法,并详细介绍了优化后的结构。通过将频繁使用的hash_foreach操作限制在特定场景中,成功提高了程序的整体性能。

  经过一晚上的倒腾... 终于重构好了hash_tbl, 思路和之前想的一样~ , 从索引头到冲突链都使用数组实现~ 结构如下:

 

 

 

  原来协议层也用的hash_tbl进行管理, 但因为协议是连续自增ID, 不存在动态变化的可能, 所以这块不使用hash_tbl管理了, 直接用静态数组进行映射.

  这样的话, 只有逻辑层发送协议的位置有通过hash_tbl查找具体的net_buff, 不过这块是hash_find, 并无大碍. 因为我们关注的只是hash_foreach的调用, 尽可能的减少它的使用, 才能使程序突破瓶颈.

  重构之后, 重点的压力比较大的hash_foreach只存在于epoll_wait线程与处理线程桥接的管道, keepalive查询, 待释放net_buff队列.

 

  OK, 这样的优化之后, 测试了下, 效果非常不错~

  优化之后的profile:

 

 

  从上图可以看出, foreach已经不再占据消耗时间最多的位置,  下滑到了第8的位置, 整体性能上升了不少, 非常稳定的跑在 16000 count/per sec, 压力测试里每一次完整的调用包含了2次普通协议处理, 2次异步数据库查询, 总体来说, 还算比较满意. :)

int trafficTestGetEthernet(int upIdx, TRAFFIC_TEST_PACKET_CFG *packetCfg) { TPCONFIG_GET_INFO stGetInfo = {0}; UINT8 packetIdx = 0; stGetInfo.pGetObj = tpConfig_objCreate(); if (NULL == stGetInfo.pGetObj) { printf("get_zset =2= \r\n"); return ERR_NO_MEMORY; } strncpy(stGetInfo.szZsetName, TPZSET_ETHERNET_TRAFFIC_TEST_IDX, TPCONFIG_BUFF_LEN_63); stGetInfo.type = TPCONFIG_GETTYPE_ZSET; if (PFM_ERR_C_OK != tpConfig_get(&stGetInfo)) { tpConfig_objFree(stGetInfo.pGetObj); return ERR_NOT_FOUND; } TPCONFIG_ITER_KEY(&stGetInfo.iterName) { char* pKey = tpConfig_getKeyName(&stGetInfo.iterName); printf("get_zset key[%s]\r\n", pKey); TPCONFIG_ITER_FV(&stGetInfo.iterName); { if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(&stGetInfo.iterName, &packetCfg->rawPacket, pKey, CFG_TRAFFIC_TEST_F_RAW_PACKET)) { continue; } if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(&stGetInfo.iterName, &packetCfg->srcMac, pKey, CFG_TRAFFIC_TEST_F_SRC_MAC)) { continue; } if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(&stGetInfo.iterName, &packetCfg->dstMac, pKey, CFG_TRAFFIC_TEST_F_DST_MAC)) { continue; } if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(&stGetInfo.iterName, &packetCfg->srcIp, pKey, CFG_TRAFFIC_TEST_F_SRC_IP)) { continue; } if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(&stGetInfo.iterName, &packetCfg->dstIp, pKey, CFG_TRAFFIC_TEST_F_DST_IP)) { continue; } if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(&stGetInfo.iterName, &packetCfg->lenType, pKey, CFG_TRAFFIC_TEST_F_LENTYPE)) { continue; } if (PFM_ERR_C_OK == tpConfig_IterGetNumU8(&stGetInfo.iterName, &packetCfg->vlan, pKey, CFG_TRAFFIC_TEST_F_VLAN)) { continue; } } } tpConfig_objFree(stGetInfo.pGetObj); return ERR_NO_ERROR; } 该代码存在问题,宏定义如下#define TPZSET_ETHERNET_TRAFFIC_TEST_IDX "TPZSET_ETHERNET_TRAFFIC_TEST:%d" #define ETHERNET_M_TRAFFIC_TEST_TBL_ALL "ETHERNET_M_TRAFFIC_TEST:*" #define ETHERNET_M_TRAFFIC_TEST_TBL_IDX "ETHERNET_M_TRAFFIC_TEST:%d_%d" 传入一个端口和一个报文结构体,我想要Get到该端口不同packetid的报文,该如何去拿
10-30
static INT32 _dalFptRuleCntUpdateHnd() { int ret = ERR_NO_ERROR; unit_list ul = {}; FPT_ID fptId = 0; RULE_ID ruleId = 0; void *handler = NULL; char *curKey = NULL; char tpclRuleStr[HI_TPCL_RULE_ID_LEN + 1] = {}; HI_TPCL_COUNTER_T tpclCnt = {}; dal_ado_t *setAdoi = NULL; dal_ado_t *getAdoi = NULL; HI_TPCL_APP_E appId = 0; UINT8 setFlag = 0; // GT_U32 timeFlag = 0; setAdoi = dalAdoiCreate(DMP_DEV_NAME_SWITCHMAC, DAL_MOD_FPT, DAL_CFG_TYPE_ENTRY | DAL_CFG_TYPE_NOPUB); APPL_ENSURE_DONE(ret, setAdoi, ERR_NO_MEMORY); PFM_IF_FAIL_DONE_RET(ret, dalAdoiEntryTableAppend(setAdoi, DAL_FPT_K_CNT_TBL), ERR_BAD_PARAM); PFM_IF_FAIL_DONE_RET(ret, dalAdoiEntryOperAppend(setAdoi, DAL_FPT_K_CNT_TBL, DAL_OPER_REPLACE), ERR_BAD_PARAM); PFM_IF_FAIL_DONE_RET(ret, dalAdoiUnitListAppend(setAdoi, ul), ERR_BAD_PARAM); /* 获取到所有Rule的dal计数条目 logging为False的规则不会被创建dal计数条目 */ getAdoi = dalAsdoiCreate(DMP_DEV_NAME_SWITCHMAC, DAL_MOD_FPT, DAL_CFG_TYPE_ENTRY); APPL_ENSURE_DONE(ret, getAdoi, ERR_BAD_PARAM); PFM_IF_FAIL_DONE_RET(ret, dalAdoiEntryTableAppend(getAdoi, DAL_FPT_K_CNT_TBL), ERR_BAD_PARAM); PFM_IF_FAIL_DONE_RET(ret, dalAdoiEntryOperAppend(getAdoi, DAL_FPT_K_CNT_TBL, DAL_OPER_GET_ALL), ERR_BAD_PARAM); if (PFM_ERR_C_OK != dalGet(getAdoi)) { goto done; } DAL_ADOI_ENTRY_ITER_ALL(getAdoi, handler) { if (NULL == handler) { continue; } DAL_ADOI_ENTRY_LOOP(handler) { if (NULL == (curKey = DAL_ADOI_ENTRY_KEY(handler))) { continue; } /* 获取tpcl命中计数 */ APPL_ENSURE_DONE(ret, 2 == sscanf(curKey, DAL_FPT_K_CNT_TBL_FMT, &fptId, &ruleId), ERR_BAD_PARAM); snprintf(tpclRuleStr, HI_TPCL_RULE_ID_LEN, DAL_FPT_TPCL_RULE_ID_FMT, fptId, ruleId); APPL_IF_ERR_DONE(ret, _fptId2AppId(fptId, &appId)); /* logging为1时 hash缓存和TpclRuleCnt应该为同生命周期 logging为0时 规则存在hash缓存而hiTpclRuleCntRead读取失效 */ if (ERR_NO_ERROR != hiTpclRuleCntRead(appId, tpclRuleStr, &tpclCnt)) { DE("Read cnt fail: %s", tpclRuleStr); continue; } /* 首次 */ if (0 == g_ruleHistory.fptId) { g_ruleHistory.fptId = fptId; g_ruleHistory.ruleId = ruleId; } if (0 == g_outRuleHistory.fptId) { g_outRuleHistory.fptId = fptId; g_outRuleHistory.ruleId = ruleId; } if (fptId == g_ruleHistory.fptId || fptId == g_outRuleHistory.fptId) { if ( 0 == portStatus ) { if ( g_ruleHistory.lastCount && !tpclCnt.pkt ) { APPL_IF_ERR_DONE(ret, _dalFptRuleCntHistoryAdd(fptId, ruleId, g_ruleHistory.lastCount)); DN("round %d end , count %d has been send to adoi", ROUND, g_ruleHistory.lastCount); g_ruleHistory.lastCount = 0; ROUND ++; } if (tpclCnt.pkt) { g_ruleHistory.lastCount = tpclCnt.pkt; } } else if ( 2 == portStatus ) { if (g_outRuleHistory.lastCount == tpclCnt.pkt && 0 != tpclCnt.pkt) { g_outRuleHistory.delaydCount ++; } if (g_outRuleHistory.delaydCount >= 4) { APPL_IF_ERR_DONE(ret, _dalFptRuleCntHistoryAdd(fptId, ruleId, tpclCnt.pkt)); APPL_IF_ERR_DONE(ret, hiTpclRuleCntClr(appId, tpclRuleStr)); g_outRuleHistory.lastCount = 0; g_outRuleHistory.delaydCount = 0; DN("Outbound upload: %llu packets", tpclCnt.pkt ); ROUND++; } g_outRuleHistory.lastCount = tpclCnt.pkt; // 只需记录最新值 } } else { DE("fptId:%d != g_ruleHistory.fptId:%d",fptId,g_ruleHistory.fptId); } /* dal写入增量加入后的新值 */ PFM_IF_FAIL_DONE_RET(ret, dalAdoiAddEntryKey(setAdoi, DAL_FPT_K_CNT_TBL, curKey, fptId), ERR_BAD_PARAM); PFM_IF_FAIL_DONE_RET(ret, dalAdoiAddEntryUI64(setAdoi, DAL_FPT_K_CNT_TBL, DAL_FPT_F_CNT_NUM, tpclCnt.pkt), ERR_BAD_PARAM); setFlag = 1; } } if (setFlag) { PFM_IF_FAIL_DONE_RET(ret, dalSet(setAdoi), ERR_BAD_PARAM); } done: if (getAdoi) { dalAdoiDestroy(getAdoi); } if (setAdoi) { dalAdoiDestroy(setAdoi); } return ret; } 好的,在这个函数里,g_ruleHistory需预先设定,这意味着我的fptId与ruleId必须唯一。这对多条规则并不使用,因此,能否以上述构建结构体的函数为思路,为每个规则单独构建一个结构体
11-05
///*!Copyright(c) 2022-2025 Shenzhen TP-Link Technologies Co.,Ltd. // *All rights reserved. // * // *\file srvcFpt.c // * // *\author caoyi1 <caoyi1@tp-link.net> // *\version 1.0.0 // *\date 02/06/2025 // * // *\history \args 1.0.0 02/06/2025, caoyi1, Create file. // */ // ///**************************************************************************************************/ ///* INCLUDE_FILES */ ///**************************************************************************************************/ /*system header*/ #include "linux/ip.h" /*common header*/ #include "fepTypes.h" #include "fepDefs.h" /* platform header */ #include "pal/msgq.h" #include "pal/thread.h" /* public application header */ #include "common/applError.h" #include "fpt/errFpt.h" /*service header*/ #include "timer/timer.h" #include "userPort/user_port.h" #define DBG_ON 1 #include "tpDbg/tpdebug.h" /* application private header */ #include "data/dataFpt.h" #include "srvcFpt.h" #include "adFpt.h" #include "midware/tpNotify.h" #include "midware/tpRpc.h" #include "gr/gr_thread.h" #include "midware/fepPacket.h" #include <net/if.h> #include <time.h> /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ /* name */ #define FPT_MOD_NAME "fpt" #define FPT_DMP_MODIFY_RULE_NODE_NAME FPT_MOD_NAME"_dmp_modify_node" #define FPT_CNT_CHECK_TIMER_NAME ("fpt_cnt_check_tm") #define maxHandleLen 128 /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* EXTERN_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_PROTOTYPES */ /**************************************************************************************************/ static UINT32 round_counter = 0; static TIMER_ID fptCountCheckTimer; // 计数定时器 static struct timespec last_pkt_time = {}; //最后收包时间戳 static struct timespec current_time = {}; //当前时间戳 static int round = 0; static FPT_ID globalFptId = 0; static RULE_ID globalRuleId = 0; static int isHashTableInitialized = 0; //哈希表是否创建 typedef struct ruleDataMap { UINT8 srcIp[4], dstIp[4]; UINT8 proto; UINT16 sProt, dProt; }ruleMap; typedef struct HANDLE_DATA_STORE { FPT_ID fptId; RULE_ID ruleId; int round; PKT_HANDLE fptHandle; ruleMap rule; struct timespec last_pkt_time; }handleConfig; /**************************************************************************************************/ /* VARIABLES */ /**************************************************************************************************/ //static TIMER_ID fptTimer; // //PKT_HANDLE *handleNetLink = NULL; /**************************************************************************************************/ /* LOCAL_FUNCTIONS */ /**************************************************************************************************/ /* 生成规则唯一键 */ static char* _makeRuleKey(FPT_ID fptId, RULE_ID ruleId) { static char key[32]; snprintf(key, sizeof(key), "srvcFpt_%u_rule_%u", fptId, ruleId); return key; } /* 查找或创建规则状态 */ static histStore* _getHandleCfgData(FPT_ID fptId, RULE_ID ruleId) { char* key = _makeRuleKey(fptId, ruleId); ENTRY e = { .key = key, .data = NULL }; histStore* newHist = calloc(1, sizeof(histStore)); /* 哈希查找 */ ENTRY* ep = hsearch(e, FIND); if (ep) { return (histStore*)ep->data; } /* 不存在则创建 */ if (!newHist) { return NULL; } e.data = newHist; ep = hsearch(e, ENTER); // 插入哈希表 if (!ep) { free(newHist); return NULL; } return newHist; } STATUS _srvcFptTimeStateUpdateCb(FEP_PACKET_SEND_T rcvMsg, int round) { int ret = ERR_NO_ERROR; tpState_Obj *pSetObj = NULL; pSetObj = tpState_objCreate(); char keyStr[TPSTATE_KEY_MAX_LEN] = { 0 }; char tblStr[TPSTATE_KEY_MAX_LEN] = { 0 }; // INT64 score = 0; snprintf(tblStr, sizeof(tblStr), FPT_STATE_TIME_TBL); snprintf(keyStr, sizeof(keyStr), FPT_STATE_TIME_KEY, globalFptId, globalRuleId, round); PFM_IF_FAIL_DONE_RET(ret, tpState_objAddKey(pSetObj, keyStr), ERR_BAD_PARAM); PFM_IF_FAIL_DONE_RET(ret, tpState_objAddFieldNumU64(pSetObj, FPT_STATE_TIME_SEC, rcvMsg.extraArg->commonArg.time_sec), ERR_BAD_PARAM); PFM_IF_FAIL_DONE_RET(ret, tpState_objAddFieldNumU64(pSetObj, FPT_STATE_TIME_NSEC, rcvMsg.extraArg->commonArg.time_nanosec), ERR_BAD_PARAM); PFM_IF_FAIL_DONE_RET(ret, tpState_onlySet(pSetObj, tblStr, TPSTATE_OPER_MOD_OR_ADD),ERR_BAD_PARAM); printf("time data has been add to stateDB \r\n"); done: if (pSetObj) { tpState_objFree(pSetObj); } return ret; } void _srvcCountTimeoutCheckHnd() { clock_gettime(CLOCK_MONOTONIC, &current_time); double time_diff = (current_time.tv_sec - last_pkt_time.tv_sec) + (current_time.tv_nsec - last_pkt_time.tv_nsec) * 1e-9; // 5秒内无新包则重置计数器 if (time_diff > 5.0 && round_counter > 0) { round_counter = 0; printf("Timeout: Reset rule_counter to 0\n"); } } static void _srvcConfigObj2IpRule(FPT_ID fptId, RULE_ID ruleId, tpConfig_Iter *iter, FPT_IP_RULE *ipRule) { char tblKey[TPOBJ_KEY_MAX_LEN] = {}; char *tmpStr = NULL; UINT8 tmpU8 = 0; UINT32 tmpU32 = 0; APPL_ENSURE_RET_VOID(iter); APPL_ENSURE_RET_VOID(ipRule); snprintf(tblKey, TPOBJ_KEY_MAX_LEN, IP_FPT_RULE_IDX, fptId, ruleId); ipRule->ruleId = ruleId; TPCONFIG_ITER_FV(iter) { if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(iter, &tmpStr, tblKey, IP_FPT_RULE_SIP)) { ipRule->ipRule.ipValid.sIpEnable = 1; fptIpStr2IpArray(tmpStr, ipRule->ipRule.sourceAddress.ipAddr); continue; } if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(iter, &tmpStr, tblKey, IP_FPT_RULE_SIP_MASK)) { ipRule->ipRule.ipValid.sIpEnable = 1; fptIpStr2IpArray(tmpStr, ipRule->ipRule.sourceAddressMask.ipAddr); continue; } if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(iter, &tmpStr, tblKey, IP_FPT_RULE_DIP)) { ipRule->ipRule.ipValid.dIpEnable = 1; fptIpStr2IpArray(tmpStr, ipRule->ipRule.destAddress.ipAddr); continue; } if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(iter, &tmpStr, tblKey, IP_FPT_RULE_DIP_MASK)) { ipRule->ipRule.ipValid.dIpEnable = 1; fptIpStr2IpArray(tmpStr, ipRule->ipRule.destAddressMask.ipAddr); continue; } if (PFM_ERR_C_OK == tpConfig_IterGetNumU8(iter, &tmpU8, tblKey, IP_FPT_RULE_LOGGING)) { ipRule->logging = tmpU8; continue; } if (PFM_ERR_C_OK == tpConfig_IterGetNumU8(iter, &tmpU8, tblKey, IP_FPT_RULE_IP_PROTO)) { ipRule->ipRule.ipValid.ipProtoValid = 1; ipRule->ipRule.ipProto = tmpU8; continue; } if (PFM_ERR_C_OK == tpConfig_IterGetNumU32(iter, &tmpU32, tblKey, IP_FPT_RULE_SPORT)) { ipRule->ipRule.ipValid.l4SourcePortValid = 1; ipRule->ipRule.fptL4Struct.sport = tmpU32; continue; } if (PFM_ERR_C_OK == tpConfig_IterGetNumU32(iter, &tmpU32, tblKey, IP_FPT_RULE_SPORT_MASK)) { ipRule->ipRule.ipValid.l4SourcePortValid = 1; ipRule->ipRule.fptL4Struct.spMask = tmpU32; continue; } if (PFM_ERR_C_OK == tpConfig_IterGetNumU32(iter, &tmpU32, tblKey, IP_FPT_RULE_DPORT)) { ipRule->ipRule.ipValid.l4DestPortValid = 1; ipRule->ipRule.fptL4Struct.dport = tmpU32; continue; } if (PFM_ERR_C_OK == tpConfig_IterGetNumU32(iter, &tmpU32, tblKey, IP_FPT_RULE_DPORT_MASK)) { ipRule->ipRule.ipValid.l4DestPortValid = 1; ipRule->ipRule.fptL4Struct.dpMask = tmpU32; continue; } } } /**************************************************************************************************/ /* PUBLIC_FUNCTIONS */ /**************************************************************************************************/ STATUS fptFepPacketInit() { FEP_PACKET_INIT_T fepPKtParam = {}; fepPKtParam.channelCfgPath = FEP_PACKET_CHANNEL_CFG_PATH; fepPKtParam.maxBuffSize = 2048; fepPKtParam.maxSocketNum = 10; PFM_IF_FAIL_RET_VAL(fepPacketInit(&fepPKtParam), ERR_INIT); if (!isHashTableInitialized) { if ( 0 == hcreate(maxHentries) ) { DE("srvc hcreate failed"); return ERR_NO_MEMORY; } else { isHashTableInitialized = !isHashTableInitialized; } } return ERR_NO_ERROR; } void fptFepPacketCb(char *buff, UINT32 len, FEP_PACKET_EXTRA_T *extraArg) { FPT_ID fptId = 0; RULE_ID ruleId = 0; struct iphdr *ipHeader = (struct iphdr*)(buff + sizeof(struct ethhdr)); UINT8 proto = ipHeader->protocol; UINT32 srcIp = ipHeader->saddr; UINT32 dstIp = ipHeader->daddr; APPL_ENSURE_RET_VOID(ret, 2 == sscanf(fptHandle, "fptHandle:fpt%d_rule%d", &fptId, &ruleId), ERR_BAD_PARAM); clock_gettime(CLOCK_MONOTONIC, &last_pkt_time); round_counter++; FEP_PACKET_SEND_T rcvMsg = {}; rcvMsg.len = len; rcvMsg.buffer = buff; rcvMsg.extraArg = extraArg; if (1 == rule_counter) { round ++ ; _srvcFptTimeStateUpdateCb(globalFptId, globalRuleId, rcvMsg, round); DW("first arrive timeStamp has been saved \r\n"); } return ; } STATUS fptFepPacketCreateAfPkt(FPT_ID fptId, RULE_ID ruleId, FPT_IP_RULE *ipRule) { FEP_PACKET_CREATE_T param = { 0 }; FEP_PACKET_FILTER_T filter = { 0 }; FEP_PACKET_RULE_DATA_T ethTypeRule = { 0 }; FEP_PACKET_RULE_DATA_T procRule = { 0 }; FEP_PACKET_RULE_DATA_T srcIpRule = { 0 }; FEP_PACKET_RULE_DATA_T dstIpRule = { 0 }; FEP_PACKET_RULE_DATA_T actionRule = { 0 }; char fptHandle; snprintf(fptHandle, 128, "fptHandle:fpt%d_rule%d", fptId, ruleId); PKT_HANDLE fptHandle = NULL; handleConfig* handleCfg = NULL; handleCfg = _getHandleCfgData(fptId, ruleId); handleCfg->fptId = fptId; handleCfg->ruleId = ruleId; handleCfg->rule.srcIp = ipRule->ipRule.sourceAddress; handleCfg->rule.dstIp = ipRule->ipRule.destAddress; handleCfg->rule.proto = ipRule->ipRule.ipProto; UINT8 ethTpye[2] = {0x08, 0x00}; UINT8 ipProtocol[] = {ipRule->ipRule.ipProto}; UINT8 srcIp[] = {ipRule->ipRule.sourceAddress[0], ipRule->ipRule.sourceAddress[1], ipRule->ipRule.sourceAddress[2], ipRule->ipRule.sourceAddress[3]}; UINT8 dstIp[] = {ipRule->ipRule.destAddress[0], ipRule->ipRule.destAddress[1], ipRule->ipRule.destAddress[2], ipRule->ipRule.destAddress[3]}; param.handleName = "fptHandleDmpModify"; param.fillter = &filter; param.dmpName = NULL; filter.ruleListType = RX_LIST_PRIORITY_5; filter.priority = -1; /* 越大优先级越低,注册在dmp默认送CPU节点前,防止影响其他模块 */ filter.modName = FPT_MOD_NAME; filter.ruleNodeName = FPT_DMP_MODIFY_RULE_NODE_NAME; filter.own = FEP_RX_NOT_OWNED; filter.nodeNum = 5; // filter.nodeNum = 3; /* 以太网类型 */ ethTypeRule.value = ethTpye; ethTypeRule.len = sizeof(ethTpye); filter.node[0].nodeType = PACKET_FILTER_MATCH; filter.node[0].filterType = FEP_PACKET_MATCH_NETWORK; filter.node[0].filterRule = FEP_PACKET_MATCH; filter.node[0].pos = FEP_PACKET_NODE_POS_TAIL; filter.node[0].rule = &ethTypeRule; /* 三层协议 */ procRule.value = ipProtocol; procRule.len = sizeof(ipProtocol); filter.node[1].nodeType = PACKET_FILTER_MATCH; filter.node[1].filterType = FEP_PACKET_MATCH_TRANSPORT; filter.node[1].filterRule = FEP_PACKET_MATCH; filter.node[1].pos = FEP_PACKET_NODE_POS_TAIL; filter.node[1].rule = &procRule; /* 源ip */ srcIpRule.value = srcIp; srcIpRule.len = sizeof(srcIp); filter.node[2].nodeType = PACKET_FILTER_MATCH; filter.node[2].filterType = FEP_PACKET_MATCH_NETWORK_SRC_IPV4; filter.node[2].filterRule = FEP_PACKET_MATCH; filter.node[2].pos = FEP_PACKET_NODE_POS_TAIL; filter.node[2].rule = &srcIpRule; /* 目的ip */ dstIpRule.value = dstIp; dstIpRule.len = sizeof(dstIp); filter.node[3].nodeType = PACKET_FILTER_MATCH; filter.node[3].filterType = FEP_PACKET_MATCH_NETWORK_DST_IPV4; filter.node[3].filterRule = FEP_PACKET_MATCH; filter.node[3].pos = FEP_PACKET_NODE_POS_TAIL; filter.node[3].rule = &dstIpRule; /* action */ filter.node[4].nodeType = PACKET_FILTER_ACTION; filter.node[4].filterType = FEP_PACKET_ACTION_SEND_TO_PROC; filter.node[4].pos = FEP_PACKET_NODE_POS_TAIL; filter.node[4].rule = &actionRule; fptHandle = fepPacketCreate(&param); APPL_ENSURE_RET_VAL(NULL != fptHandle, ERR_INIT); handleCfg->fptHandle = fptHandle; PFM_IF_FAIL_RET(fepPacketRecvAdd(fptHandle, fptFepPacketCb)); return ERR_NO_ERROR; } STATUS fptFepPacketDestroy(FPT_ID fptId, RULE_ID ruleId) { handleConfig* handleCfg = NULL; PKT_HANDLE fptHandle = NULL; handleCfg = _getHandleCfgData(fptId, ruleId); fptHandle = handleCfg->fptHandle; fepPacketDestroy(fptHandle); return ERR_NO_ERROR; } STATUS srvcFptRuleDispatch(tpConfig_Iter *iter) { char* keyName = NULL; FPT_ID fptId = 0; RULE_ID ruleId = 0; FPT_TYPE_MODE fptType = FPT_TYPE_IP; FPT_RULE_UNION fptRule = {}; /* 删除rule */ if (TPCONFIG_IS_DELETE(iter)) { TPCONFIG_ITER_KEY(iter) { keyName = tpConfig_getKeyName(iter); APPL_ENSURE_RET(2 == sscanf(keyName, FPT_RULE_IDX, &fptId, &ruleId)); APPL_IF_ERR_RET(fptFepPacketDestroy(fptId, ruleId)); } return ERR_NO_ERROR; } /* 添加rule */ TPCONFIG_ITER_KEY(iter) { keyName = tpConfig_getKeyName(iter); APPL_ENSURE_RET(2 == sscanf(keyName, FPT_RULE_IDX, &fptId, &ruleId)); memset(&fptRule, 0, sizeof(FPT_RULE_UNION)); APPL_IF_ERR_RET(fptId2Type(fptId, &fptType)); switch (fptType) { case FPT_TYPE_IP: _srvcConfigObj2IpRule(fptId, ruleId, iter, &fptRule.ipRule); APPL_IF_ERR_RET(fptFepPacketCreateAfPkt(fptId, ruleId, (void *)&fptRule.ipRule)); break; default: return ERR_FPT_FPT_TYPE_INVALID; // DBG_INFO_ERROR("bad type."); } } return ERR_NO_ERROR; } //STATUS srvcFptPktUpdate() //{ // TPDATA_OBJ *obj = tpDataObjCreate(TPDATA_OBJ_DEF_INIT); // if (ERR_NO_ERROR == dataFptAllActionGet(obj)) // { // PFM_IF_FAIL_RET(fepPacketRecvAdd(fptHandle, fptFepPacketCb)); // 开启收包 // } // else // { // PFM_IF_FAIL_RET(fepPacketRecvRemove(fptHandle)); // 关闭收包 // } // // return ERR_NO_ERROR; //} //STATUS fptFepPacketDeInit() //{ // APPL_IF_ERR_RET(fepPacketRecvRemove(fptHandle)); // 关闭收包 // APPL_IF_ERR_RET(fptFepPacketRuleUnReg()); // fepPacketDeInit(); // return ERR_NO_ERROR; //} // // //STATUS srvcPppoeFepPacketDeinit() //{ // APPL_IF_ERR_RET(fptFepPacketDeInit()); // return ERR_NO_ERROR; //} // // //STATUS srvcFptFepPacketInit() //{ //// APPL_IF_ERR_RET(fptFepPacketInit()); // fepPacket初始化 // APPL_IF_ERR_RET(fptFepPacketCreateAfPkt()); // 创建收发包规则 // return ERR_NO_ERROR; //} // //STATUS fptFepPacketRuleUnReg() //{ // fepPacketDestroy(fptHandle); // 删除收发包规则 // return ERR_NO_ERROR; //} STATUS srvcFptFepPacketInit() { tpConfig_Obj* pSubObj = tpConfig_objCreate(); APPL_ENSURE_RET_VAL(pSubObj, ERR_NO_MEMORY); /* fepPacket初始化 */ APPL_IF_ERR_RET(fptFepPacketInit()); /* 创建收发包规则 */ // (fptFepPacketCreateAfPkt()); /* 开启收包 */ // PFM_IF_FAIL_RET(fepPacketRecvAdd(fptHandle, fptFepPacketCb)); /* 订阅消息发布者 */ PFM_IF_FAIL_RET(tpConfig_dispatchSubReg(pSubObj, FPT_MODULE_NAME));// 订阅 FPT 模块的配置变更 /* 结束普通消息订阅 */ PFM_IF_FAIL_RET(tpConfig_dispatchSubEnd(pSubObj, TPCONFIG_CHANNEL_DATA_TYPE)); /* 注册Key回调 */ PFM_IF_FAIL_RET(tpConfig_dispatchFunReg(IP_FPT_RULE_ALL, (char *)srvcFptRuleDispatch)); /* 检查收包是否恒定的计时器 */ struct timespec CheckTm = {}; CheckTm.tv_sec = 1; CheckTm.tv_nsec = 0; /* 1s 更新一次 */ /* 定时刷新命中计数 */ fptCountCheckTimer = add_timer(FPT_CNT_CHECK_TIMER_NAME, &CheckTm, _srvcCountTimeoutCheckHnd, NULL, 0, EXECUTE_FOREVER); APPL_ENSURE_RET_VAL(TIMER_ID_IS_VALID(fptCountCheckTimer), ERR_INIT); return ERR_NO_ERROR; } 在以上内容中,如何在fptFepPacketCb函数内根据 UINT8 proto = ipHeader->protocol; UINT32 srcIp = ipHeader->saddr; UINT32 dstIp = ipHeader->daddr;反向得到哈希键,给我完整的实现过程,尽可能简便,不用考虑哈希冲突,只考虑实现
11-07
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值