void IPREASM_blk_del_all ( IP_DGRAM_PTR dgram /* [IN] the IP datagram */ ) { /* Body */ uint32_t i, j; IPREASM_INDIDX_PTR indir; /* free the direct blocks */ for (i = 0; i < IPREASM_NB_DIRECT; i++) { if (!dgram->DIRECT[i]) continue; RTCS_part_free(dgram->DIRECT[i]); } /* Endfor */ /* free the indirect blocks */ for (i = 0; i < IPREASM_NB_IND; i++) { indir = dgram->INDIR[i]; if (!indir) continue; for (j = 0; j < IPREASM_IND_SIZE; j++) { if (!indir->DIRECT[j]) continue; RTCS_part_free(indir->DIRECT[j]); } /* Endfor */ RTCS_part_free(indir); } /* Endfor */ } /* Endbody */
static void RTCSPCB_free_internal ( PCB_PTR inpcb /* [IN] packet to free */ ) { RTCSPCB_PTR rtcs_pcb = (RTCSPCB_PTR)inpcb->PRIVATE; /* Can't free this PCB until all duplicates are freed */ if (RTCS_sem_trywait(&rtcs_pcb->DUPCOUNT) == RTCS_OK) { PCBLOG(("\nPCB: Free_internal: delaying %p", rtcs_pcb)); return; } /* If this PCB is a duplicate, decrement the original's refcount */ if (rtcs_pcb->DUPPTR) { PCBLOG(("\nPCB: Free_internal: about to free %p", rtcs_pcb->DUPPTR)); RTCSPCB_free(rtcs_pcb->DUPPTR); rtcs_pcb->DUPPTR = NULL; } /* If this PCB has been forked, don't forget the link layer's PCB */ if (rtcs_pcb->PCB_ORIG) { PCB_free(rtcs_pcb->PCB_ORIG); rtcs_pcb->PCB_ORIG = NULL; } /* handle the FREE_FRAG_FIELD */ if (rtcs_pcb->FREE_FRAG_BITFIELD) { uint32_t i; for (i = 0; i < RTCSPCB_FRAG_MAX; i++) { if (rtcs_pcb->FREE_FRAG_BITFIELD & (1 << i)) { _mem_free(rtcs_pcb->PCBPTR->FRAG[i].FRAGMENT); } } rtcs_pcb->FREE_FRAG_BITFIELD = 0; } if (rtcs_pcb->PCB_FREE) { inpcb->FREE = rtcs_pcb->PCB_FREE; inpcb->PRIVATE = rtcs_pcb->PCB_PRIVATE; inpcb->FRAG[0] = rtcs_pcb->PCB_BUFFER; PCBLOG(("\nPCB: Free_internal: PCB is %p", inpcb)); PCB_free(inpcb); } if (rtcs_pcb->UDP_REQUEST) { RTCS_cmd_complete(rtcs_pcb->UDP_REQUEST, RTCS_OK); rtcs_pcb->UDP_REQUEST = NULL; } RTCS_part_free(rtcs_pcb); }
uint_32 IP_route_add_virtual ( _ip_address address, /* Destination address */ _ip_address netmask, /* Mask for the address parameter */ _ip_address source, /* Source address for interface */ _ip_address source_net, /* Allowed source network */ _ip_address source_mask, /* Allowes source network mask */ IP_IF_PTR destif, /* Interface for outgoing packets */ pointer data /* Route information */ ) { /* Body */ #if RTCSCFG_ENABLE_VIRTUAL_ROUTES IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP); IP_ROUTE_VIRTUAL_PTR route; struct ip_route_insert insdata; IP_ROUTE_FN_PTR fn; route = RTCS_part_alloc(IP_cfg_ptr->VIRTUAL_PARTID); if (!route) { return RTCSERR_IP_VIRTUAL_ALLOC; } /* Endif */ route->ADDRESS = source; route->IS_DIRECT = NULL; route->DESTIF = destif; route->FLAGS = RTF_STATIC | RTF_UP; route->SOURCE_NET = source_net; route->SOURCE_MASK = source_mask; route->DATA = data; insdata.error = RTCSERR_IP_VIRTUAL_ALLOC; insdata.route = route; insdata.index = 2; insdata.sort = NULL; IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, address & netmask, netmask, IP_cfg_ptr->RADIX_PARTID, IP_route_insert, &insdata); if (insdata.error) { RTCS_part_free(route); } else if (!~netmask) { fn = IP_cfg_ptr->ROUTE_FN; while (fn) { fn->INIT_RT((IP_ROUTE_INDIRECT_PTR)route, 0); fn = fn->NEXT; } /* Endwhile */ } /* Endif */ return insdata.error; #else return RTCSERR_IP_VIRTUAL_ALLOC; #endif } /* Endbody */
static void IP_route_delete ( pointer _PTR_ node, /* ptr to address of the IPRADIX_NODE DATA ptr */ pointer data /* ptr to data that can ID node to be deleted */ ) { /* Body */ IP_ROUTE_PRV_PTR route = *node; IP_ROUTE_DIRECT_PTR tmp_ptr, search_ptr; struct ip_route_delete _PTR_ remdata = data; uint_32 i = remdata->index; IP_ROUTE_FN_PTR fn; if (route && route->ROUTETYPE[i]) { /* Make sure the node is valid */ /* ** Search the circular list for the correct node. ** tmp_ptr will always point to the node BEFORE search_ptr */ tmp_ptr = route->ROUTETYPE[i]; search_ptr = tmp_ptr->NEXT; do { if (remdata->test(search_ptr, remdata->data)) { tmp_ptr->NEXT = search_ptr->NEXT; /* De-thread the node */ if (route->ROUTETYPE[i] == search_ptr) { /* Update head if needed */ route->ROUTETYPE[i] = search_ptr->NEXT; } /* Endif */ if (route->ROUTETYPE[i] == search_ptr) { /* There is 1 node */ route->ROUTETYPE[i] = NULL; if (route->ROUTETYPE[0] == NULL && route->ROUTETYPE[1] == NULL && route->ROUTETYPE[2] == NULL) { *node = NULL; /* Free data ptr if needed */ } /* Endif */ } /* Endif */ for (fn = remdata->fn; fn; fn = fn->NEXT) { fn->REM_RT((IP_ROUTE_INDIRECT_PTR)search_ptr); } /* Endfor */ RTCS_part_free(search_ptr); break; } /* Endif */ /* Move on to the next node */ tmp_ptr = search_ptr; search_ptr = search_ptr->NEXT; } while (search_ptr != route->ROUTETYPE[i]->NEXT); } /* Endif */ } /* Endbody */
void SOCK_Free_sock_struct ( SOCKET_STRUCT_PTR socket_ptr ) { /* Body */ SOCKET_CONFIG_STRUCT_PTR socket_cfg_ptr = RTCS_getcfg(SOCKET); #if RTCSCFG_SOCKET_OWNERSHIP //FSL AB SOCKET_OWNER_STRUCT_PTR owner_ptr; SOCKET_OWNER_STRUCT_PTR free_ptr; #endif socket_ptr->VALID = 0; #if RTCSCFG_SOCKET_OWNERSHIP owner_ptr = socket_ptr->OWNERS.NEXT; while (owner_ptr != NULL) { free_ptr = owner_ptr; owner_ptr = owner_ptr->NEXT; _mem_free(free_ptr); } /* Endwhile */ #endif RTCS_mutex_lock(&socket_cfg_ptr->SOCK_MUTEX); /* ** Fix up the head/next pointer of our predecessor. */ if ( socket_ptr->PREV == NULL ) { socket_cfg_ptr->SOCKET_HEAD = socket_ptr->NEXT; } else { (socket_ptr->PREV)->NEXT = socket_ptr->NEXT; } /* Endif */ /* ** Fix up the tail/prev pointer of our successor. */ if ( socket_ptr->NEXT == NULL ) { socket_cfg_ptr->SOCKET_TAIL = socket_ptr->PREV; } else { (socket_ptr->NEXT)->PREV = socket_ptr->PREV; } /* Endif */ /* ** Release the socket structure memory. */ RTCS_part_free(socket_ptr); socket_cfg_ptr->CURRENT_SOCKETS--; RTCS_mutex_unlock(&socket_cfg_ptr->SOCK_MUTEX); } /* Endbody */
void IPREASM_del_dgram ( IP_DGRAM_PTR dgram /* [IN] the IP datagram */ ) { /* Body */ /* Cancel the expire timer and free all memory */ TCPIP_Event_cancel(&dgram->TIMER); RTCS_DLIST_DEL(IPREASM_head, dgram); IPREASM_blk_del_all(dgram); RTCS_part_free(dgram); } /* Endbody */
uint_32 IGMP_member_delete ( MC_MEMBER_PTR _PTR_ pmember ) { /* Body */ MC_MEMBER_PTR group; group = *pmember; *pmember = group->NEXT; RTCS_part_free(group); return RTCS_OK; } /* Endbody */
static void IP_route_delete_indirect_all ( pointer _PTR_ node, /* ptr to address of the IPRADIX_NODE DATA ptr */ pointer data /* ptr to the gateway address to be removed */ ) { /* Body */ IP_ROUTE_PTR route = *node; IP_ROUTE_INDIRECT_PTR tmp_ptr, search_ptr; IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP); IP_ROUTE_FN_PTR fn; if (route && route->INDIRECT) { /* Make sure the node is valid */ search_ptr = route->INDIRECT->NEXT; /* search with next element */ tmp_ptr = search_ptr->NEXT; /* if we have only one elment while loop will not execute */ while (search_ptr != route->INDIRECT) { for (fn = IP_cfg_ptr->ROUTE_FN; fn; fn = fn->NEXT) { fn->REM_RT(search_ptr); } /* Endfor */ RTCS_part_free(search_ptr); search_ptr = tmp_ptr; tmp_ptr = search_ptr->NEXT; } /* Endwhile */ /* Free the first element */ for (fn = IP_cfg_ptr->ROUTE_FN; fn; fn = fn->NEXT) { fn->REM_RT(search_ptr); } /* Endfor */ RTCS_part_free(search_ptr); if (route->DIRECT == NULL && route->VIRTUAL == NULL) { *node = NULL; /* Free data ptr if needed */ } else { route->INDIRECT = NULL; } /* Endif */ } /* Endif */ } /* Endbody */
uint_32 IP_route_add_direct ( _ip_address address, /* Address or network address of destif */ _ip_address netmask, /* Mask for the address parameter */ IP_IF_PTR netif, /* Interface for incomming packets */ IP_IF_PTR destif /* Interface for outgoing packets */ ) { /* Body */ IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP); IP_ROUTE_DIRECT_PTR route; IP_ROUTE_FN_PTR fn; struct ip_route_insert insertdata; route = RTCS_part_alloc(IP_cfg_ptr->ROUTE_PARTID); if (!route) { return RTCSERR_IP_ROUTE_ALLOC; } /* Endif */ route->ADDRESS = address; route->NETIF = netif; route->DESTIF = destif; route->FLAGS = RTF_STATIC | RTF_UP; insertdata.error = RTCSERR_IP_ROUTE_ALLOC; insertdata.route = route; insertdata.index = 0; insertdata.sort = NULL; IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, address & netmask, netmask, IP_cfg_ptr->RADIX_PARTID, IP_route_insert, &insertdata); if (insertdata.error) { RTCS_part_free(route); } else if (!~netmask) { ROUTE_new_bindif(route); /* If the route is a leaf (has a full IP) */ } else if (route->DESTIF != IP_cfg_ptr->IF_LOCALHOST) { fn = IP_cfg_ptr->ROUTE_FN; /* If the route is a network connection */ while (fn) { fn->INIT_RT((IP_ROUTE_INDIRECT_PTR)((void _PTR_)route), 0); fn = fn->NEXT; } /* Endwhile */ } /* Endif */ return insertdata.error; } /* Endbody */
uint_32 IP_route_add_indirect ( _ip_address address, /* Gateway address */ _ip_address netmask, /* Network mask */ _ip_address network, /* Network address */ uint_32 flag, /* [IN] RTF_* */ uint_16 metric /* [IN] the route metric [0,65535] */ ) { /* Body */ IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP); IP_ROUTE_INDIRECT_PTR route; struct ip_route_insert insertdata; IP_ROUTE_FN_PTR fn; route = RTCS_part_alloc(IP_cfg_ptr->GATE_PARTID); if (!route) { return RTCSERR_IP_GATE_ALLOC; } /* Endif */ route->GATEWAY = address; route->FLAGS = flag | RTF_UP; route->IS_DIRECT = NULL; route->METRIC = metric; insertdata.error = RTCSERR_IP_GATE_ALLOC; insertdata.route = route; insertdata.index = 1; insertdata.sort = IP_route_add_indirect_sort; IPRADIX_insert(&IP_cfg_ptr->ROUTE_ROOT.NODE, network & netmask, netmask, IP_cfg_ptr->RADIX_PARTID, IP_route_insert, &insertdata); if (insertdata.error) { RTCS_part_free(route); } else { fn = IP_cfg_ptr->ROUTE_FN; while (fn) { fn->INIT_RT(route, metric); fn = fn->NEXT; } /* Endwhile */ } /* Endif */ return insertdata.error; } /* Endbody */
static void IP_route_add_indirect_sort ( pointer head, pointer new_node ) { /* Body */ IP_ROUTE_INDIRECT_PTR _PTR_ head_ptr = head; IP_ROUTE_INDIRECT_PTR node = new_node, search = *head_ptr, last; IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP); IP_ROUTE_FN_PTR fn; search = *head_ptr; /* ** Check if there is non static route here. Remove it if there is because ** static routes take precedence over dynamic routes. This function is only ** called if there is already a node, and if this node is a dynamic node ** there will only be one. We can simply replace it with the new node. */ if (!(search->FLAGS & RTF_STATIC)) { for (fn = IP_cfg_ptr->ROUTE_FN; fn; fn = fn->NEXT) { fn->REM_RT(search); } /* Endfor */ RTCS_part_free(search); *head_ptr = node; return; } /* Endif */ /* Find the place to insert the new node */ last = NULL; while (search->METRIC < node->METRIC) { last = search; search = search->NEXT; if (search == *head_ptr) { break; } /* Endif */ } /* Endwhile */ /* ** At this point we found the place to insert. We need to special case ** insertion into the front of the list, but the other cases are easy. */ if (!last) { /* ** The new node has to be the first in the list. We need a pointer to the ** last element in the list to complete the insertion. The following ** insertion works for any number of nodes. */ last = search->NEXT; while (last->NEXT != search) { last = last->NEXT; } /* Endwhile */ /* Update the head_ptr to point to the new node */ *head_ptr = node; } /* Endif */ /* Link in the new node */ node->NEXT = search; last->NEXT = node; return; } /* Endbody */