| /* |
| * Copyright (c) 2009 Mindspeed Technologies, Inc. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License |
| * as published by the Free Software Foundation; either version 2 |
| * of the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| * |
| */ |
| #include "fe.h" |
| #include "module_ipv4.h" |
| #include "module_ipsec.h" |
| |
| |
| /* This function returns total arp entries configured in a given hash index */ |
| static int IPV4_Get_Hash_CTEntries(int ct_hash_index) |
| { |
| |
| int tot_ct_entries = 0; |
| PCtEntry pCtEntry; |
| struct slist_entry *entry; |
| |
| slist_for_each(pCtEntry, entry, &ct_cache[ct_hash_index], list) |
| { |
| if (IS_IPV4(pCtEntry) && (pCtEntry->status & CONNTRACK_ORIG) == CONNTRACK_ORIG) |
| tot_ct_entries++; |
| } |
| |
| return tot_ct_entries; |
| } |
| |
| /* This function fills the snapshot of ipv4 CT entries in a given hash index */ |
| static int IPv4_CT_Get_Hash_Snapshot(int ct_hash_index, int ct_total_entries, PCtExCommand pSnapshot) |
| { |
| |
| int tot_ct_entries=0; |
| PCtEntry pCtEntry; |
| PCtEntry pReplyEntry = NULL; |
| struct slist_entry *entry; |
| |
| slist_for_each(pCtEntry, entry, &ct_cache[ct_hash_index], list) |
| { |
| if (IS_IPV4(pCtEntry) &&(pCtEntry->status & CONNTRACK_ORIG) == CONNTRACK_ORIG) |
| { |
| |
| pReplyEntry = CT_TWIN(pCtEntry); |
| |
| pSnapshot->Daddr = pCtEntry->Daddr_v4; |
| pSnapshot->Saddr = pCtEntry->Saddr_v4; |
| pSnapshot->Sport = pCtEntry->Sport; |
| pSnapshot->Dport = pCtEntry->Dport; |
| |
| pSnapshot->DaddrReply = pCtEntry->twin_Daddr; |
| pSnapshot->SaddrReply = pCtEntry->twin_Saddr; |
| pSnapshot->SportReply = pCtEntry->twin_Sport; |
| pSnapshot->DportReply = pCtEntry->twin_Dport; |
| pSnapshot->protocol = GET_PROTOCOL(pCtEntry); |
| pSnapshot->fwmark = IP_get_fwmark(pCtEntry, pReplyEntry); |
| pSnapshot->SA_nr = 0; |
| pSnapshot->SAReply_nr = 0; |
| pSnapshot->format = 0; |
| |
| if ((pCtEntry->status & CONNTRACK_SEC) == CONNTRACK_SEC) |
| { |
| int i; |
| pSnapshot->format |= CT_SECURE; |
| for (i= 0; i < SA_MAX_OP; i++) |
| { |
| if (pCtEntry->hSAEntry[i]) |
| { |
| pSnapshot->SA_nr++; |
| pSnapshot->SA_handle[i] = pCtEntry->hSAEntry[i]; |
| } |
| } |
| |
| for (i= 0; i < SA_MAX_OP; i++) |
| { |
| if (pReplyEntry->hSAEntry[i]) |
| { |
| pSnapshot->SAReply_nr++; |
| pSnapshot->SAReply_handle[i] = pReplyEntry->hSAEntry[i]; |
| } |
| |
| } |
| |
| } |
| |
| |
| pSnapshot++; |
| tot_ct_entries++; |
| |
| if (--ct_total_entries <= 0) |
| break; |
| } |
| } |
| |
| return tot_ct_entries; |
| |
| } |
| |
| |
| /* This function creates the snapshot memory and returns the |
| next ipv4 CT entry from the snapshop of the ipv4 conntrack entries of a |
| single hash to the caller */ |
| |
| int IPv4_Get_Next_Hash_CTEntry(PCtExCommand pCtCmd, int reset_action) |
| { |
| int ct_hash_entries; |
| static PCtExCommand pCtSnapshot = NULL; |
| static int ct_hash_index = 0,ct_snapshot_entries =0, ct_snapshot_index = 0, ct_snapshot_buf_entries = 0; |
| PCtExCommand pCt; |
| |
| if(reset_action) |
| { |
| ct_hash_index = 0; |
| ct_snapshot_entries =0; |
| ct_snapshot_index = 0; |
| if(pCtSnapshot) |
| { |
| Heap_Free(pCtSnapshot); |
| pCtSnapshot = NULL; |
| } |
| ct_snapshot_buf_entries = 0; |
| } |
| |
| if (ct_snapshot_index == 0) |
| { |
| |
| while( ct_hash_index < NUM_CT_ENTRIES) |
| { |
| |
| ct_hash_entries = IPV4_Get_Hash_CTEntries(ct_hash_index); |
| if(ct_hash_entries == 0) |
| { |
| ct_hash_index++; |
| continue; |
| } |
| if (ct_hash_entries > ct_snapshot_buf_entries) |
| { |
| if(pCtSnapshot) |
| Heap_Free(pCtSnapshot); |
| |
| pCtSnapshot = Heap_Alloc(ct_hash_entries * sizeof(CtExCommand)); |
| |
| if (!pCtSnapshot) |
| { |
| ct_hash_index = 0; |
| ct_snapshot_buf_entries = 0; |
| return ERR_NOT_ENOUGH_MEMORY; |
| } |
| ct_snapshot_buf_entries = ct_hash_entries; |
| } |
| |
| ct_snapshot_entries = IPv4_CT_Get_Hash_Snapshot(ct_hash_index ,ct_hash_entries, pCtSnapshot); |
| |
| break; |
| } |
| |
| if (ct_hash_index >= NUM_CT_ENTRIES) |
| { |
| ct_hash_index = 0; |
| if(pCtSnapshot) |
| { |
| Heap_Free(pCtSnapshot); |
| pCtSnapshot = NULL; |
| } |
| |
| ct_snapshot_buf_entries = 0; |
| return ERR_CT_ENTRY_NOT_FOUND; |
| } |
| |
| } |
| |
| pCt = &pCtSnapshot[ct_snapshot_index++]; |
| SFL_memcpy(pCtCmd, pCt, sizeof(CtExCommand)); |
| if (ct_snapshot_index == ct_snapshot_entries) |
| { |
| ct_snapshot_index = 0; |
| ct_hash_index ++; |
| } |
| |
| return NO_ERR; |
| |
| } |
| |
| |
| |
| /* This function returns total routes configured in a given hash index */ |
| static int IPV4_Get_Hash_Routes(int rt_hash_index) |
| { |
| int tot_routes = 0; |
| struct slist_entry *entry; |
| |
| slist_for_each_entry(entry, &rt_cache[rt_hash_index]) |
| { |
| tot_routes++; |
| } |
| |
| return tot_routes; |
| } |
| |
| /* This function fills the snapshot of route entries in a given hash index */ |
| static int IPV4_RT_Get_Hash_Snapshot(int rt_hash_index,int rt_total_entries, PRtCommand pSnapshot) |
| { |
| |
| int tot_routes=0; |
| PRouteEntry pRtEntry; |
| struct slist_entry *entry; |
| POnifDesc onif_desc; |
| |
| slist_for_each(pRtEntry, entry, &rt_cache[rt_hash_index], list) |
| { |
| COPY_MACADDR(pSnapshot->macAddr, pRtEntry->dstmac); |
| |
| onif_desc = get_onif_by_index(pRtEntry->itf->index); |
| if (onif_desc) |
| strcpy((char *)pSnapshot->outputDevice, (char *)onif_desc->name); |
| else |
| pSnapshot->outputDevice[0] = '\0'; |
| |
| pSnapshot->mtu = pRtEntry->mtu; |
| pSnapshot->id = pRtEntry->id; |
| |
| pSnapshot++; |
| tot_routes++; |
| |
| if (--rt_total_entries <= 0) |
| break; |
| } |
| |
| return tot_routes; |
| } |
| |
| |
| |
| /* This function creates the snapshot memory and returns the |
| next route entry from the snapshop of the route entries of a |
| single hash to the caller */ |
| |
| int IPV4_Get_Next_Hash_RtEntry(PRtCommand pRtCmd, int reset_action) |
| { |
| int rt_hash_entries; |
| PRtCommand pRt; |
| static PRtCommand pRtSnapshot = NULL; |
| static int rt_hash_index = 0, rt_snapshot_entries =0, rt_snapshot_index=0, rt_snapshot_buf_entries = 0; |
| |
| if(reset_action) |
| { |
| rt_hash_index = 0; |
| rt_snapshot_entries =0; |
| rt_snapshot_index=0; |
| if(pRtSnapshot) |
| { |
| Heap_Free(pRtSnapshot); |
| pRtSnapshot = NULL; |
| } |
| rt_snapshot_buf_entries = 0; |
| } |
| |
| if (rt_snapshot_index == 0) |
| { |
| while( rt_hash_index < NUM_ROUTE_ENTRIES) |
| { |
| |
| rt_hash_entries = IPV4_Get_Hash_Routes(rt_hash_index); |
| if(rt_hash_entries == 0) |
| { |
| rt_hash_index++; |
| continue; |
| } |
| |
| if(rt_hash_entries > rt_snapshot_buf_entries) |
| { |
| if(pRtSnapshot) |
| Heap_Free(pRtSnapshot); |
| pRtSnapshot = Heap_Alloc(rt_hash_entries * sizeof(RtCommand)); |
| |
| if (!pRtSnapshot) |
| { |
| rt_hash_index = 0; |
| rt_snapshot_buf_entries = 0; |
| return ERR_NOT_ENOUGH_MEMORY; |
| } |
| rt_snapshot_buf_entries = rt_hash_entries; |
| } |
| |
| rt_snapshot_entries = IPV4_RT_Get_Hash_Snapshot(rt_hash_index ,rt_hash_entries, pRtSnapshot); |
| |
| break; |
| } |
| |
| if (rt_hash_index >= NUM_ROUTE_ENTRIES) |
| { |
| rt_hash_index = 0; |
| if(pRtSnapshot) |
| { |
| Heap_Free(pRtSnapshot); |
| pRtSnapshot = NULL; |
| } |
| rt_snapshot_buf_entries = 0; |
| return ERR_RT_ENTRY_NOT_FOUND; |
| } |
| |
| } |
| |
| pRt = &pRtSnapshot[rt_snapshot_index++]; |
| SFL_memcpy(pRtCmd, pRt, sizeof(RtCommand)); |
| if (rt_snapshot_index == rt_snapshot_entries) |
| { |
| rt_snapshot_index = 0; |
| rt_hash_index ++; |
| } |
| |
| |
| return NO_ERR; |
| |
| } |