📄 fa_mn_addr.c
字号:
/* $Id: fa_mn_addr.c,v 1.6 2000/07/26 17:06:58 jm Exp $ * Foreign Agent - MN home address hash tables * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2000, Dynamics group * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. *//* MN home address hash tables are used to select a suitable upper tunnel type * in the lower FAs so that the non-unique addresses can be routed correctly * (i.e. do not use the same tunnel with two equal MN home addresses) */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <stddef.h>#include <assert.h>#include <string.h>#include <time.h>#include "debug.h"#include "hashtable.h"#include "fa_mn_addr.h"#define DEBUG_FLAG 'F'/* dynamically generated hashtable of FAs that are below this FA */struct mn_addr_data { struct node node; struct in_addr addr;};/* MN home address hashes for IPIP/keyed GRE selection */static struct hashtable *mn_addr_IPIP = NULL;static struct hashtable **mn_addr_GRE = NULL;static int mn_addr_GRE_count = 0;#define INIT_GRE_HASHES 8static intaddr_hash(void *key, const int hashsize){ unsigned char *c = key; return *c ^ *(c + 1) ^ *(c + 2) ^ *(c + 3);}static intaddr_cmp(void *key, struct node *cmprd){ struct mn_addr_data *data = (struct mn_addr_data *) cmprd; if (memcmp(key, &data->addr, 4) == 0) return 1; return 0;}/** * mn_addr_init: * * Initialize the MN home address hash tables * * Returns: 0 on success or -1 on failure. */intmn_addr_init(void){ int i; mn_addr_IPIP = hashtable_init(256); if (mn_addr_IPIP == NULL) return -1; mn_addr_GRE = (struct hashtable **) malloc(INIT_GRE_HASHES * sizeof(struct hashtable *)); if (mn_addr_GRE == NULL) { free(mn_addr_IPIP); mn_addr_IPIP = NULL; return -1; } mn_addr_GRE_count = INIT_GRE_HASHES; for (i = 0; i < INIT_GRE_HASHES; i++) mn_addr_GRE[i] = NULL; return 0;}/* Help function for mn_addr_free() - remove an entry from a hash table */static intremove_addr(struct node *node, void *data){ hashtable_remove(node); return 1;}/** * mn_addr_free: * * Free the memory used by MN home address hash tables */voidmn_addr_free(void){ int i; if (mn_addr_IPIP != NULL) { hashtable_iterator(mn_addr_IPIP, remove_addr, NULL); hashtable_destroy(mn_addr_IPIP); } for (i = 0; i < mn_addr_GRE_count; i++) { if (mn_addr_GRE[i] != NULL) { hashtable_iterator(mn_addr_GRE[i], remove_addr, NULL); hashtable_destroy(mn_addr_GRE[i]); } }}/** * mn_addr_add: * @addr: Address of MN * * Get a appropriate upper tunnel type for a new MN home address and add the * address to the hash table. * * Returns: * MN_ADDR_TUNNEL_ERROR (-2): failure (out of memory), * MN_ADDR_TUNNEL_IPIP (-1): use IPIP tunnel (no key) * >= 0: use GRE with the return value as the key */intmn_addr_add(struct in_addr *addr){ struct mn_addr_data *entry; int i, j; entry = (struct mn_addr_data *) malloc(sizeof(struct mn_addr_data)); if (entry == NULL) return MN_ADDR_TUNNEL_ERROR; memset(entry, 0, sizeof(struct mn_addr_data)); list_init_node(&entry->node); entry->addr.s_addr = addr->s_addr; if (hashtable_fetch(mn_addr_IPIP, addr_hash, addr, addr_cmp) == NULL) { hashtable_add(mn_addr_IPIP, addr_hash, addr, &entry->node); return MN_ADDR_TUNNEL_IPIP; } for (i = 0; i < mn_addr_GRE_count; i++) { if (mn_addr_GRE[i] == NULL) { mn_addr_GRE[i] = hashtable_init(256); if (mn_addr_GRE[i] == NULL) { free(entry); return MN_ADDR_TUNNEL_ERROR; } break; } if (hashtable_fetch(mn_addr_GRE[i], addr_hash, addr, addr_cmp) == NULL) break; } if (i >= mn_addr_GRE_count) { void *tmp; /* no place found in the reserved hash tables - allocate more * space for tables */ tmp = realloc(mn_addr_GRE, 2 * mn_addr_GRE_count * sizeof(struct hashtable *)); if (tmp == NULL) { free(entry); return MN_ADDR_TUNNEL_ERROR; } mn_addr_GRE = (struct hashtable **) tmp; for (j = mn_addr_GRE_count; j < 2 * mn_addr_GRE_count; j++) mn_addr_GRE[j] = NULL; i = mn_addr_GRE_count; mn_addr_GRE_count *= 2; mn_addr_GRE[i] = hashtable_init(256); if (mn_addr_GRE[i] == NULL) { free(entry); return MN_ADDR_TUNNEL_ERROR; } } hashtable_add(mn_addr_GRE[i], addr_hash, addr, &entry->node); return i;}/** * mn_addr_remove: * @addr: * @type: -1 IPIP (no key) * >= 0 GRE (type = key) * * Remove the given MN home address from the hash tables. * * Returns: 0 on success or -1 on failure. */intmn_addr_remove(struct in_addr *addr, int type){ struct node *node; if (type < -1) return -1; if (type == -1) { if (mn_addr_IPIP == NULL) return -1; node = hashtable_fetch(mn_addr_IPIP, addr_hash, addr, addr_cmp); } else { if (type >= mn_addr_GRE_count || (mn_addr_GRE[type] == NULL)) return -1; node = hashtable_fetch(mn_addr_GRE[type], addr_hash, addr, addr_cmp); } if (node != NULL) { hashtable_remove(node); return 0; } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -