/* Insert "ip", of length "len", into "table", and have it point to "ptr" */ int sfrt_flat_insert(void *adr, unsigned char len, INFO ptr, int behavior, table_flat_t* table) { int index; int res; INFO *data; #ifdef SUP_IP6 sfip_t *ip; #else uint32_t ip; #endif tuple_flat_t tuple; TABLE_PTR rt = 0; uint8_t *base; if(!adr ) { return RT_INSERT_FAILURE; } if (len == 0) return RT_INSERT_FAILURE; if(!table || !table->data) { return RT_INSERT_FAILURE; } if( (table->ip_type == IPv4 && len > 32) || (table->ip_type == IPv6 && len > 128) ) { return RT_INSERT_FAILURE; } #ifdef SUP_IP6 ip = adr; #else ip = *(uint32_t*)adr; #endif #ifdef SUP_IP6 if (ip->family == AF_INET) { rt = table->rt; } else if (ip->family == AF_INET6) { rt = table->rt6; } #else rt = table->rt; #endif if (!rt) { return RT_INSERT_FAILURE; } tuple = sfrt_dir_flat_lookup(ip, table->rt); if(tuple.length != len) { if( table->num_ent >= table->max_size) { return RT_POLICY_TABLE_EXCEEDED; } index = table->num_ent; table->num_ent++; } else { index = tuple.index; } /* Insert value into policy table */ base = (uint8_t *)segment_basePtr(); data = (INFO *)(&base[table->data]); data[index] = ptr; /* The actual value that is looked-up is an index * into the data table. */ res = sfrt_dir_flat_insert(ip, len, index, behavior, rt); /* Check if we ran out of memory. If so, need to decrement * table->num_ent */ if(res == MEM_ALLOC_FAILURE) { /* From the control flow above, it's possible table->num_ent was not * incremented. It should be safe to decrement here, because the only * time it will be incremented above is when we are potentially * mallocing one or more new entries (It's not incremented when we * overwrite an existing entry). */ table->num_ent--; } return res; }
/* Insert "ip", of length "len", into "table", and have it point to "ptr" */ int sfrt_flat_insert(sfcidr_t *ip, unsigned char len, INFO ptr, int behavior, table_flat_t* table, updateEntryInfoFunc updateEntry) { int index; int res = RT_SUCCESS; INFO *data; tuple_flat_t tuple; uint32_t* adr; int numAdrDwords; TABLE_PTR rt; uint8_t *base; int64_t bytesAllocated; if(!ip) { return RT_INSERT_FAILURE; } if (len == 0) return RT_INSERT_FAILURE; if(!table || !table->data) { return RT_INSERT_FAILURE; } if(len > 128) { return RT_INSERT_FAILURE; } if (sfaddr_family(&ip->addr) == AF_INET) { if (len < 96) { return RT_INSERT_FAILURE; } len -= 96; adr = sfip_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfip_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } tuple = sfrt_dir_flat_lookup(adr, numAdrDwords, rt); base = (uint8_t *)segment_basePtr(); data = (INFO *)(&base[table->data]); if(tuple.length != len) { if( table->num_ent >= table->max_size) { return RT_POLICY_TABLE_EXCEEDED; } index = table->num_ent; table->num_ent++; /* Insert value into policy table */ data[index] = 0; } else { index = tuple.index; } bytesAllocated = updateEntry(&data[index], ptr, SAVE_TO_CURRENT, base); if (bytesAllocated < 0) { if(tuple.length != len) table->num_ent--; return MEM_ALLOC_FAILURE; } table->allocated += (uint32_t)bytesAllocated; /* The actual value that is looked-up is an index * into the data table. */ res = sfrt_dir_flat_insert(adr, numAdrDwords, len, index, behavior, rt, updateEntry, data); /* Check if we ran out of memory. If so, need to decrement * table->num_ent */ if(res == MEM_ALLOC_FAILURE) { /* From the control flow above, it's possible table->num_ent was not * incremented. It should be safe to decrement here, because the only * time it will be incremented above is when we are potentially * mallocing one or more new entries (It's not incremented when we * overwrite an existing entry). */ table->num_ent--; } return res; }