ia64/xen-unstable

view tools/vnet/vnet-module/vif.c @ 6946:e703abaf6e3d

Add behaviour to the remove methods to remove the transaction's path itself. This allows us to write Remove(path) to remove the specified path rather than having to slice the path ourselves.
author emellor@ewan
date Sun Sep 18 14:42:13 2005 +0100 (2005-09-18)
parents 3233e7ecfa9f
children 06d84bf87159
line source
1 /*
2 * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free software Foundation, Inc.,
16 * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
17 *
18 */
20 #include <linux/config.h>
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/string.h>
25 #include <linux/version.h>
27 #include <linux/net.h>
28 #include <linux/in.h>
29 #include <linux/inet.h>
30 #include <linux/netdevice.h>
31 #include <linux/udp.h>
33 #include <net/ip.h>
34 #include <net/protocol.h>
35 #include <net/route.h>
36 #include <linux/skbuff.h>
37 #include <linux/spinlock.h>
39 #include <etherip.h>
40 #include <if_varp.h>
41 #include <vnet_dev.h>
42 #include <vif.h>
43 #include <varp.h>
45 #include "allocate.h"
46 #include "hash_table.h"
47 #include "sys_net.h"
48 #include "sys_string.h"
50 #define MODULE_NAME "VNET"
51 #define DEBUG 1
52 #undef DEBUG
53 #include "debug.h"
55 /** Table of vifs indexed by VifKey. */
56 HashTable *vif_table = NULL;
57 rwlock_t vif_table_lock = RW_LOCK_UNLOCKED;
59 #define vif_read_lock(flags) read_lock_irqsave(&vif_table_lock, (flags))
60 #define vif_read_unlock(flags) read_unlock_irqrestore(&vif_table_lock, (flags))
61 #define vif_write_lock(flags) write_lock_irqsave(&vif_table_lock, (flags))
62 #define vif_write_unlock(flags) write_unlock_irqrestore(&vif_table_lock, (flags))
64 void vif_print(void){
65 HashTable_for_decl(entry);
66 Vif *vif;
67 unsigned long flags;
68 char vnetbuf[VNET_ID_BUF];
70 vif_read_lock(flags);
71 HashTable_for_each(entry, vif_table){
72 vif = entry->value;
73 printk(KERN_INFO "VIF(vnet=%s vmac=" MACFMT ")\n",
74 VnetId_ntoa(&vif->vnet, vnetbuf), MAC6TUPLE(vif->vmac.mac));
75 }
76 vif_read_unlock(flags);
77 }
79 void vif_decref(Vif *vif){
80 if(!vif) return;
81 if(atomic_dec_and_test(&vif->refcount)){
82 kfree(vif);
83 }
84 }
86 void vif_incref(Vif *vif){
87 if(!vif) return;
88 atomic_inc(&vif->refcount);
89 }
91 /** Hash function for keys in the vif table.
92 * Hashes the vnet id and mac.
93 *
94 * @param k key (VifKey)
95 * @return hashcode
96 */
97 Hashcode vif_key_hash_fn(void *k){
98 VifKey *key = k;
99 Hashcode h = 0;
100 h = VnetId_hash(h, &key->vnet);
101 h = Vmac_hash(h, &key->vmac);
102 return h;
103 }
105 /** Test equality for keys in the vif table.
106 * Compares vnet and mac.
107 *
108 * @param k1 key to compare (VifKey)
109 * @param k2 key to compare (VifKey)
110 * @return 1 if equal, 0 otherwise
111 */
112 int vif_key_equal_fn(void *k1, void *k2){
113 VifKey *key1 = k1;
114 VifKey *key2 = k2;
115 return (VnetId_eq(&key1->vnet , &key2->vnet) &&
116 Vmac_eq(&key1->vmac, &key2->vmac));
117 }
119 /** Free an entry in the vif table.
120 *
121 * @param table containing table
122 * @param entry entry to free
123 */
124 static void vif_entry_free_fn(HashTable *table, HTEntry *entry){
125 Vif *vif;
126 if(!entry) return;
127 vif = entry->value;
128 if(vif){
129 vif_decref(vif);
130 }
131 HTEntry_free(entry);
132 }
134 /** Lookup a vif.
135 *
136 * @param vnet vnet id
137 * @param mac MAC address
138 * @return 0 on success, -ENOENT otherwise
139 */
140 int vif_lookup(VnetId *vnet, Vmac *vmac, Vif **vif){
141 int err = 0;
142 VifKey key = { .vnet = *vnet, .vmac = *vmac };
143 HTEntry *entry = NULL;
144 unsigned long flags;
146 vif_read_lock(flags);
147 entry = HashTable_get_entry(vif_table, &key);
148 if(entry){
149 *vif = entry->value;
150 vif_incref(*vif);
151 } else {
152 *vif = NULL;
153 err = -ENOENT;
154 }
155 vif_read_unlock(flags);
156 return err;
157 }
159 /** Create a new vif.
160 *
161 * @param vnet vnet id
162 * @param mac MAC address
163 * @return 0 on success, negative error code otherwise
164 */
165 int vif_add(VnetId *vnet, Vmac *vmac, Vif **val){
166 int err = 0;
167 Vif *vif = NULL;
168 HTEntry *entry;
169 unsigned long flags;
171 dprintf("> vnet=%d\n", vnet);
172 vif = ALLOCATE(Vif);
173 if(!vif){
174 err = -ENOMEM;
175 goto exit;
176 }
177 atomic_set(&vif->refcount, 1);
178 vif->vnet = *vnet;
179 vif->vmac = *vmac;
180 vif_write_lock(flags);
181 entry = HashTable_add(vif_table, vif, vif);
182 vif_write_unlock(flags);
183 if(!entry){
184 err = -ENOMEM;
185 deallocate(vif);
186 vif = NULL;
187 goto exit;
188 }
189 vif_incref(vif);
190 exit:
191 *val = (err ? NULL : vif);
192 dprintf("< err=%d\n", err);
193 return err;
194 }
196 /** Delete an entry.
197 *
198 * @param vnet vnet id
199 * @param mac MAC address
200 * @param coaddr return parameter for care-of address
201 * @return number of entries deleted, or negative error code
202 */
203 int vif_remove(VnetId *vnet, Vmac *vmac){
204 int err = 0;
205 VifKey key = { .vnet = *vnet, .vmac = *vmac };
206 unsigned long flags;
208 vif_write_lock(flags);
209 err = HashTable_remove(vif_table, &key);
210 vif_write_unlock(flags);
211 return err;
212 }
214 void vif_purge(void){
215 HashTable_clear(vif_table);
216 }
218 int vif_create(VnetId *vnet, Vmac *vmac, Vif **vif){
219 int err = 0;
221 dprintf(">\n");
222 if(vif_lookup(vnet, vmac, vif) == 0){
223 vif_decref(*vif);
224 err = -EEXIST;
225 goto exit;
226 }
227 err = vif_add(vnet, vmac, vif);
228 exit:
229 if(err){
230 *vif = NULL;
231 }
232 dprintf("< err=%d\n", err);
233 return err;
234 }
236 /** Initialize the vif table.
237 *
238 * @return 0 on success, error code otherwise
239 */
240 int vif_init(void){
241 int err = 0;
242 dprintf(">\n");
243 vif_table = HashTable_new(0);
244 if(!vif_table){
245 err = -ENOMEM;
246 goto exit;
247 }
248 vif_table->entry_free_fn = vif_entry_free_fn;
249 vif_table->key_hash_fn = vif_key_hash_fn;
250 vif_table->key_equal_fn = vif_key_equal_fn;
252 exit:
253 if(err < 0) wprintf("< err=%d\n", err);
254 dprintf("< err=%d\n", err);
255 return err;
256 }
258 void vif_exit(void){
259 HashTable_free(vif_table);
260 }