/* ========================================================================== Description: Look up the MAC address in the IGMP table. Return NULL if not found. Return: pEntry - pointer to the MAC entry; NULL is not found ========================================================================== */ PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup( IN PMULTICAST_FILTER_TABLE pMulticastFilterTable, IN PUCHAR pAddr, IN PNET_DEV dev) { ULONG HashIdx, Now; PMULTICAST_FILTER_TABLE_ENTRY pEntry = NULL, pPrev = NULL; if (pMulticastFilterTable == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__)); return NULL; } RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock); HashIdx = MULTICAST_ADDR_HASH_INDEX(pAddr); pEntry = pPrev = pMulticastFilterTable->Hash[HashIdx]; while (pEntry && pEntry->Valid) { if ((pEntry->net_dev == dev) && MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) { NdisGetSystemUpTime(&Now); pEntry->lastTime = Now; break; } else { NdisGetSystemUpTime(&Now); if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC) && RTMP_TIME_AFTER(Now, pEntry->lastTime+IGMPMAC_TB_ENTRY_AGEOUT_TIME)) { /* Remove the aged entry */ if (pEntry == pMulticastFilterTable->Hash[HashIdx]) { pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext; pPrev = pMulticastFilterTable->Hash[HashIdx]; DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList); NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY)); pMulticastFilterTable->Size --; pEntry = pPrev; DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size)); } else { pPrev->pNext = pEntry->pNext; DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList); NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY)); pMulticastFilterTable->Size --; pEntry = pPrev->pNext; DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size)); } } else { pPrev = pEntry; pEntry = pEntry->pNext; } } } RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock); return pEntry; }
/* ========================================================================== Description: Add and new entry into MAC table ========================================================================== */ BOOLEAN MulticastFilterTableInsertEntry( IN PRTMP_ADAPTER pAd, IN PUCHAR pGrpId, IN PUCHAR pMemberAddr, IN PNET_DEV dev, IN MulticastFilterEntryType type) { UCHAR HashIdx; int i; MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL, *pCurrEntry, *pPrevEntry; PMEMBER_ENTRY pMemberEntry; PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable; if (pMulticastFilterTable == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__)); return FALSE; } /* if FULL, return */ if (pMulticastFilterTable->Size >= MAX_LEN_OF_MULTICAST_FILTER_TABLE) { DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table full. max-entries = %d\n", __FUNCTION__, MAX_LEN_OF_MULTICAST_FILTER_TABLE)); return FALSE; } /* check the rule is in table already or not. */ if ((pEntry = MulticastFilterTableLookup(pMulticastFilterTable, pGrpId, dev))) { /* doesn't indicate member mac address. */ if(pMemberAddr == NULL) { return FALSE; } pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead; while (pMemberEntry) { if (MAC_ADDR_EQUAL(pMemberAddr, pMemberEntry->Addr)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: already in Members list.\n", __FUNCTION__)); return FALSE; } pMemberEntry = pMemberEntry->pNext; } } RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock); do { ULONG Now; /* the multicast entry already exist but doesn't include the member yet. */ if (pEntry != NULL && pMemberAddr != NULL) { InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr); break; } /* allocate one MAC entry */ for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++) { /* pick up the first available vacancy */ pEntry = &pMulticastFilterTable->Content[i]; NdisGetSystemUpTime(&Now); if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC) && ((Now - pEntry->lastTime) > IGMPMAC_TB_ENTRY_AGEOUT_TIME)) { PMULTICAST_FILTER_TABLE_ENTRY pHashEntry; HashIdx = MULTICAST_ADDR_HASH_INDEX(pEntry->Addr); pHashEntry = pMulticastFilterTable->Hash[HashIdx]; if ((pEntry->net_dev == pHashEntry->net_dev) && MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr)) { pMulticastFilterTable->Hash[HashIdx] = pHashEntry->pNext; pMulticastFilterTable->Size --; DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size)); } else { while (pHashEntry->pNext) { pPrevEntry = pHashEntry; pHashEntry = pHashEntry->pNext; if ((pEntry->net_dev == pHashEntry->net_dev) && MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr)) { pPrevEntry->pNext = pHashEntry->pNext; pMulticastFilterTable->Size --; DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size)); break; } } } pEntry->Valid = FALSE; DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList); } if (pEntry->Valid == FALSE) { NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY)); pEntry->Valid = TRUE; COPY_MAC_ADDR(pEntry->Addr, pGrpId); pEntry->net_dev = dev; NdisGetSystemUpTime(&Now); pEntry->lastTime = Now; pEntry->type = type; initList(&pEntry->MemberList); if (pMemberAddr != NULL) InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr); pMulticastFilterTable->Size ++; DBGPRINT(RT_DEBUG_TRACE, ("MulticastFilterTableInsertEntry -IF(%s) allocate entry #%d, Total= %d\n", RTMP_OS_NETDEV_GET_DEVNAME(dev), i, pMulticastFilterTable->Size)); break; } } /* add this MAC entry into HASH table */ if (pEntry) { HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId); if (pMulticastFilterTable->Hash[HashIdx] == NULL) { pMulticastFilterTable->Hash[HashIdx] = pEntry; } else { pCurrEntry = pMulticastFilterTable->Hash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pEntry; } } }while(FALSE); RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock); return TRUE; }
/* ========================================================================== Description: Delete a specified client from MAC table ========================================================================== */ BOOLEAN MulticastFilterTableDeleteEntry( IN PRTMP_ADAPTER pAd, IN PUCHAR pGrpId, IN PUCHAR pMemberAddr, IN PNET_DEV dev) { USHORT HashIdx; MULTICAST_FILTER_TABLE_ENTRY *pEntry, *pPrevEntry; PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable; if (pMulticastFilterTable == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__)); return FALSE; } RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock); do { HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId); pPrevEntry = pEntry = pMulticastFilterTable->Hash[HashIdx]; while (pEntry && pEntry->Valid) { if ((pEntry->net_dev == dev) && MAC_ADDR_EQUAL(pEntry->Addr, pGrpId)) break; else { pPrevEntry = pEntry; pEntry = pEntry->pNext; } } /* check the rule is in table already or not. */ if (pEntry && (pMemberAddr != NULL)) { /*USHORT Aid = MCAST_WCID; */ /*SST Sst = SST_ASSOC; */ /*UCHAR PsMode = PWR_ACTIVE, Rate; */ /*if(APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate)) */ DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr); if (IgmpMemberCnt(&pEntry->MemberList) > 0) break; } if (pEntry) { if (pEntry == pMulticastFilterTable->Hash[HashIdx]) { pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext; DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList); NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY)); pMulticastFilterTable->Size --; DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size)); } else { pPrevEntry->pNext = pEntry->pNext; DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList); NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY)); pMulticastFilterTable->Size --; DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size)); } } else { DBGPRINT(RT_DEBUG_ERROR, ("%s: the Group doesn't exist.\n", __FUNCTION__)); } } while(FALSE); RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock); return TRUE; }
/* ========================================================================== Description: Delete a specified client from MAC table ========================================================================== */ BOOLEAN MulticastFilterTableDeleteEntry( IN PRTMP_ADAPTER pAd, IN PUCHAR pGrpId, IN PUCHAR pMemberAddr, IN PNET_DEV dev) { USHORT HashIdx; MULTICAST_FILTER_TABLE_ENTRY *pEntry, *pPrevEntry; PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable; if (pMulticastFilterTable == NULL) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__)); return FALSE; } RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock); do { HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId); pPrevEntry = pEntry = pMulticastFilterTable->Hash[HashIdx]; while (pEntry && pEntry->Valid) { if ((pEntry->net_dev == dev) && MAC_ADDR_EQUAL(pEntry->Addr, pGrpId)) break; else { pPrevEntry = pEntry; pEntry = pEntry->pNext; } } /* check the rule is in table already or not. */ if (pEntry && (pMemberAddr != NULL)) { DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr); if (IgmpMemberCnt(&pEntry->MemberList) > 0) break; } if (pEntry) { if (pEntry == pMulticastFilterTable->Hash[HashIdx]) { pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext; DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList); NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY)); pMulticastFilterTable->Size --; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size)); } else { pPrevEntry->pNext = pEntry->pNext; DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList); NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY)); pMulticastFilterTable->Size --; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size)); } } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: the Group doesn't exist.\n", __FUNCTION__)); } } while(FALSE); RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock); return TRUE; }