Changeset bc216a0 in mainline for uspace/lib/nic/src/nic_addr_db.c
- Timestamp:
- 2012-08-07T22:13:44Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- da68871a
- Parents:
- b17518e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/nic/src/nic_addr_db.c
rb17518e rbc216a0 36 36 */ 37 37 #include "nic_addr_db.h" 38 #include "libarch/common.h" 38 39 #include <assert.h> 39 40 #include <stdlib.h> … … 43 44 #include <adt/hash_table.h> 44 45 #include <macros.h> 45 46 /* The key count hash table field is not used. Use this dummy value. */ 47 #define KEY_CNT 1 48 49 /** 50 * Maximal length of addresses in the DB (in bytes). 51 */ 52 #define NIC_ADDR_MAX_LENGTH 16 46 #include <stdint.h> 47 53 48 54 49 /** … … 56 51 */ 57 52 typedef struct nic_addr_entry { 58 link_t link; 59 uint8_t addr[NIC_ADDR_MAX_LENGTH]; 53 ht_link_t link; 54 uint8_t len; 55 uint8_t addr[1]; 60 56 } nic_addr_entry_t; 61 57 … … 64 60 * Hash table helper functions 65 61 */ 66 67 static bool nic_addr_match(unsigned long *key, size_t key_cnt, 68 const link_t *item) 69 { 70 uint8_t *addr = (uint8_t*)key; 71 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 72 73 return 0 == bcmp(entry->addr, addr, NIC_ADDR_MAX_LENGTH); 74 } 75 76 static size_t nic_addr_key_hash(unsigned long *key) 77 { 78 uint8_t *addr = (uint8_t*)key; 62 typedef struct { 63 size_t len; 64 const uint8_t *addr; 65 } addr_key_t; 66 67 static bool nic_addr_key_equal(void *key_arg, const ht_link_t *item) 68 { 69 addr_key_t *key = (addr_key_t*)key_arg; 70 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 71 72 return 0 == bcmp(entry->addr, key->addr, entry->len); 73 } 74 75 static size_t addr_hash(size_t len, const uint8_t *addr) 76 { 79 77 size_t hash = 0; 80 81 for ( int i = NIC_ADDR_MAX_LENGTH - 1; i >= 0; --i) {82 hash = (hash << 8) ^ (hash >> 24) ^ addr[i];78 79 for (size_t i = 0; i < len; ++i) { 80 hash = (hash << 5) ^ addr[i]; 83 81 } 84 82 … … 86 84 } 87 85 88 static size_t nic_addr_hash(const link_t *item) 89 { 90 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 91 92 unsigned long *key = (unsigned long*)entry->addr; 93 return nic_addr_key_hash(key); 94 } 95 96 static void nic_addr_removed(link_t *item) 86 static size_t nic_addr_key_hash(void *k) 87 { 88 addr_key_t *key = (addr_key_t*)k; 89 return addr_hash(key->len, key->addr); 90 } 91 92 static size_t nic_addr_hash(const ht_link_t *item) 93 { 94 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 95 return addr_hash(entry->len, entry->addr); 96 } 97 98 static void nic_addr_removed(ht_link_t *item) 97 99 { 98 100 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); … … 104 106 .hash = nic_addr_hash, 105 107 .key_hash = nic_addr_key_hash, 106 . match = nic_addr_match,108 .key_equal = nic_addr_key_equal, 107 109 .equal = 0, 108 110 .remove_callback = nic_addr_removed … … 122 124 { 123 125 assert(db); 124 if (addr_len > NIC_ADDR_MAX_LENGTH) { 126 127 if (addr_len > UCHAR_MAX) 125 128 return EINVAL; 126 } 127 128 if (!hash_table_create(&db->set, 0, KEY_CNT, &set_ops)) 129 130 if (!hash_table_create(&db->set, 0, 0, &set_ops)) 129 131 return ENOMEM; 130 132 … … 152 154 { 153 155 assert(db); 154 nic_addr_db_clear(db);155 156 hash_table_destroy(&db->set); 156 157 } … … 171 172 { 172 173 assert(db && addr); 173 /* Ugly type-punning hack. */ 174 unsigned long *key = (unsigned long*)addr; 175 176 if (hash_table_find(&db->set, key)) 174 175 addr_key_t key = { 176 .len = db->addr_len, 177 .addr = addr 178 }; 179 180 if (hash_table_find(&db->set, &key)) 177 181 return EEXIST; 178 182 179 nic_addr_entry_t *entry = malloc(sizeof(nic_addr_entry_t) );183 nic_addr_entry_t *entry = malloc(sizeof(nic_addr_entry_t) + db->addr_len - 1); 180 184 if (entry == NULL) 181 185 return ENOMEM; 182 183 link_initialize(&entry->link); 184 185 bzero(entry->addr, NIC_ADDR_MAX_LENGTH); 186 187 entry->len = (uint8_t) db->addr_len; 186 188 memcpy(entry->addr, addr, db->addr_len); 187 189 … … 202 204 { 203 205 assert(db && addr); 204 unsigned long *key = (unsigned long*)addr; 205 206 link_t *item = hash_table_find(&db->set, key); 207 208 if (item) { 209 hash_table_remove_item(&db->set, item); 206 207 addr_key_t key = { 208 .len = db->addr_len, 209 .addr = addr 210 }; 211 212 if (hash_table_remove(&db->set, &key)) 210 213 return EOK; 211 } else {214 else 212 215 return ENOENT; 213 }214 216 } 215 217 … … 225 227 { 226 228 assert(db && addr); 227 unsigned long *key = (unsigned long*)addr; 228 229 return 0 != hash_table_find(&db->set, key); 229 230 addr_key_t key = { 231 .len = db->addr_len, 232 .addr = addr 233 }; 234 235 return 0 != hash_table_find(&db->set, &key); 230 236 } 231 237 … … 241 247 * Helper function for nic_addr_db_foreach 242 248 */ 243 static bool nic_addr_db_fe_helper( link_t *item, void *arg)249 static bool nic_addr_db_fe_helper(ht_link_t *item, void *arg) 244 250 { 245 251 nic_addr_db_fe_arg_t *hs = (nic_addr_db_fe_arg_t *) arg;
Note:
See TracChangeset
for help on using the changeset viewer.