source: trunk/packages/xen-common/xen-common/tools/vnet/vnet-module/vnet_eval.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 9.1 KB
Line 
1/*
2 * Copyright (C) 2004, 2005 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 */
19
20#ifdef __KERNEL__
21
22#include <linux/config.h>
23#include <linux/module.h>
24#include <linux/types.h>
25#include <linux/kernel.h>
26#include <linux/version.h>
27#include <linux/errno.h>
28
29#else
30
31#include "sys_kernel.h"
32#include "spinlock.h"
33
34#include <sys/types.h>
35#include <sys/socket.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38
39#endif
40
41#include "vnet.h"
42#include "varp.h"
43#include "vif.h"
44#include "vnet_forward.h"
45#include "sa.h"
46
47#include "iostream.h"
48
49#ifdef __KERNEL__
50#include "kernel_stream.h"
51#else
52#include "file_stream.h"
53#endif
54
55#include "sxpr_util.h"
56#include "vnet_eval.h"
57
58#define MODULE_NAME "VNET"
59#define DEBUG 1
60#undef DEBUG
61#include "debug.h"
62
63/** Create a vnet.
64 * It is an error if a vnet with the same id exists.
65 *
66 * @param vnet vnet id
67 * @param device vnet device name
68 * @param security security level
69 * @return 0 on success, error code otherwise
70 */
71static int ctrl_vnet_add(VnetId *vnet, char *device, int security){
72    int err = 0;
73    Vnet *vnetinfo = NULL;
74
75    if(strlen(device) >= IFNAMSIZ){
76        err = -EINVAL;
77        goto exit;
78    }
79    if(Vnet_lookup(vnet, NULL) == 0){
80        err = -EEXIST;
81        goto exit;
82    }
83    err = Vnet_alloc(&vnetinfo);
84    if(err) goto exit;
85    vnetinfo->vnet = *vnet;
86    vnetinfo->security = security;
87    strcpy(vnetinfo->device, device);
88    err = Vnet_create(vnetinfo);
89  exit:
90    if(vnetinfo) Vnet_decref(vnetinfo);
91    return err;
92}
93
94/** Create an entry for a vif with the given vnet and vmac.
95 *
96 * @param vnet vnet id
97 * @param vmac mac address
98 * @return 0 on success, error code otherwise
99 */
100static int ctrl_vif_add(VnetId *vnet, Vmac *vmac){
101    int err = 0;
102    Vif *vif = NULL;
103
104    err = Vnet_lookup(vnet, NULL);
105    if(err) goto exit;
106    err = vif_create(vnet, vmac, 0, &vif);
107  exit:
108    if(vif) vif_decref(vif);
109    return err;
110}
111
112/** Delete a vif.
113 *
114 * @param vnet vnet id
115 * @param vmac mac address
116 * @return 0 on success, error code otherwise
117 */
118static int ctrl_vif_del(VnetId *vnet, Vmac *vmac){
119    int err = 0;
120    Vif *vif = NULL;
121
122    err = Vnet_lookup(vnet, NULL);
123    if(err) goto exit;
124    err = vif_lookup(vnet, vmac, &vif);
125    if(err) goto exit;
126    vif_remove(vnet, vmac);
127  exit:
128    if(vif) vif_decref(vif);
129    return err;
130}
131
132/** (varp.print)
133 */
134static int eval_varp_print(Sxpr exp, IOStream *out, void *data){
135    int err = 0;
136    vnet_print(out);
137    vif_print(out);
138    varp_print(out);
139    return err;
140}
141
142static int eval_varp_list(Sxpr exp, IOStream *out, void *data){
143    int err = 0;
144    varp_print(out);
145    return err;
146}
147
148/** (varp.mcaddr (addr <addr>))
149 */
150static int eval_varp_mcaddr(Sxpr exp, IOStream *out, void *data){
151    int err =0;
152    Sxpr oaddr = intern("addr");
153    uint32_t addr;
154
155    err = child_addr(exp, oaddr, &addr);
156    if(err < 0) goto exit;
157    varp_set_mcast_addr(addr);
158  exit:
159    return err;
160}
161
162/** (varp.flush)
163 */
164static int eval_varp_flush(Sxpr exp, IOStream *out, void *data){
165    int err = 0;
166    varp_flush();
167    return err;
168}
169
170/** (vnet.add (id <id>)
171 *            [(vnetif <name>)]
172 *            [(security { none | auth | conf } )]
173 *  )
174 */
175int eval_vnet_add(Sxpr exp, IOStream *out, void *data){
176    int err = 0;
177    Sxpr oid = intern("id");
178    Sxpr osecurity = intern("security");
179    Sxpr ovnetif = intern("vnetif");
180    Sxpr csecurity;
181    VnetId vnet = {};
182    char *device = NULL;
183    char dev[IFNAMSIZ] = {};
184    char *security = NULL;
185    int sec;
186
187    err = child_vnet(exp, oid, &vnet);
188    if(err) goto exit;
189    child_string(exp, ovnetif, &device);
190    if(!device){
191        snprintf(dev, IFNAMSIZ-1, "vnif%04x", ntohs(vnet.u.vnet16[VNETID_SIZE16 - 1]));
192        device = dev;
193    }
194    csecurity = sxpr_child_value(exp, osecurity, intern("none"));
195    err = stringof(csecurity, &security);
196    if(err) goto exit;
197    if(strcmp(security, "none")==0){
198        sec = 0;
199    } else if(strcmp(security, "auth")==0){
200        sec = SA_AUTH;
201    } else if(strcmp(security, "conf")==0){
202        sec = SA_CONF;
203    } else {
204        err = -EINVAL;
205        goto exit;
206    }
207    err = ctrl_vnet_add(&vnet, device, sec);
208 exit:
209    return err;
210}
211
212/** Delete a vnet.
213 *
214 * (vnet.del (id <id>))
215 *
216 * @param vnet vnet id
217 * @return 0 on success, error code otherwise
218 */
219static int eval_vnet_del(Sxpr exp, IOStream *out, void *data){
220    int err = 0;
221    Sxpr oid = intern("id");
222    VnetId vnet = {};
223
224    err = child_vnet(exp, oid, &vnet);
225    if(err) goto exit;
226    err = Vnet_del(&vnet);
227  exit:
228    return err;
229}
230
231static int eval_vnet_list(Sxpr exp, IOStream *out, void *data){
232    int err = 0;
233    vnet_print(out);
234    return err;
235}
236
237/** (vif.add (vnet <vnet>) (vmac <macaddr>))
238 */
239static int eval_vif_add(Sxpr exp, IOStream *out, void *data){
240    int err = 0;
241    Sxpr ovnet = intern("vnet");
242    Sxpr ovmac = intern("vmac");
243    VnetId vnet = {};
244    Vmac vmac = {};
245
246    err = child_vnet(exp, ovnet, &vnet);
247    if(err) goto exit;
248    err = child_mac(exp, ovmac, vmac.mac);
249    if(err) goto exit;
250    err = ctrl_vif_add(&vnet, &vmac);
251  exit:
252    return err;
253}
254
255/** (vif.del (vnet <vnet>) (vmac <macaddr>))
256 */
257static int eval_vif_del(Sxpr exp, IOStream *out, void *data){
258    int err = 0;
259    Sxpr ovnet = intern("vnet");
260    Sxpr ovmac = intern("vmac");
261    VnetId vnet = {};
262    Vmac vmac = {};
263
264    err = child_vnet(exp, ovnet, &vnet);
265    if(err) goto exit;
266    err = child_mac(exp, ovmac, vmac.mac);
267    if(err) goto exit;
268    err = ctrl_vif_del(&vnet, &vmac);
269  exit:
270    return err;
271}
272
273static int eval_vif_list(Sxpr exp, IOStream *out, void *data){
274    int err = 0;
275    vif_print(out);
276    return err;
277}
278
279/** Eval a vnet add request.
280 *
281 * (peer.add (addr <addr>) [(port <port>)])
282 *
283 * @param exp request
284 * @param out output stream
285 * @param data data
286 * @return 0 on success, error code otherwise
287 */
288int eval_peer_add(Sxpr exp, IOStream *out, void *data){
289    int err = 0;
290    Sxpr oaddr = intern("addr");
291    Sxpr oport = intern("port");
292    VarpAddr addr = { .family = AF_INET };
293    int port;
294
295    err = child_addr(exp, oaddr, &addr.u.ip4.s_addr);
296    if(err < 0) goto exit;
297    err = child_int(exp, oport, &port);
298    if(err < 0){
299        err = 0;
300        port = varp_port;
301    }
302    if(err) goto exit;
303    err = vnet_peer_add(&addr, port);
304  exit:
305    return err;
306}
307
308/** Eval a peer delete request.
309 *
310 * (peer.del (addr <addr>))
311 *
312 * @param vnetd vnetd
313 * @param exp request
314 * @param out output stream
315 * @param data data
316 * @return 0 on success, error code otherwise
317 */
318static int eval_peer_del(Sxpr exp, IOStream *out, void *data){
319    int err = 0;
320    Sxpr oaddr = intern("addr");
321    VarpAddr addr = { .family = AF_INET };
322
323    err = child_addr(exp, oaddr, &addr.u.ip4.s_addr);
324    if(err < 0) goto exit;
325    err = vnet_peer_del(&addr);
326  exit:
327    return err;
328}
329
330/** Eval a peer list request.
331 *
332 * (peer.list)
333 *
334 * @param exp request
335 * @param out output stream
336 * @param data data
337 * @return 0 on success, error code otherwise
338 */
339static int eval_peer_list(Sxpr exp, IOStream *out, void *data){
340    int err = 0;
341    vnet_peer_print(out);
342    return err;
343}
344
345int vnet_eval_defs(SxprEval *defs, Sxpr exp, IOStream *io, void *data){
346    int err = 0;
347    SxprEval *def;
348
349    iprintf("> "); objprint(iostdout, exp, 0); IOStream_print(iostdout, "\n");
350    err = -ENOSYS;
351    for(def = defs; !NONEP(def->name); def++){
352        if(sxpr_elementp(exp, def->name)){
353            err = def->fn(exp, io, data);
354            break;
355        }
356    }
357    iprintf("< err=%d\n", err);
358    return err;
359}
360
361int vnet_eval(Sxpr exp, IOStream *io, void *data){
362    SxprEval defs[] = {
363        { .name = intern("peer.add"),     .fn = eval_peer_add     },
364        { .name = intern("peer.del"),     .fn = eval_peer_del     },
365        { .name = intern("peer.list"),    .fn = eval_peer_list    },
366        { .name = intern("varp.flush"),   .fn = eval_varp_flush   },
367        { .name = intern("varp.list"),    .fn = eval_varp_list    },
368        { .name = intern("varp.mcaddr"),  .fn = eval_varp_mcaddr  },
369        { .name = intern("varp.print"),   .fn = eval_varp_print   },
370        { .name = intern("vif.add"),      .fn = eval_vif_add      },
371        { .name = intern("vif.del"),      .fn = eval_vif_del      },
372        { .name = intern("vif.list"),     .fn = eval_vif_list     },
373        { .name = intern("vnet.add"),     .fn = eval_vnet_add     },
374        { .name = intern("vnet.del"),     .fn = eval_vnet_del     },
375        { .name = intern("vnet.list"),    .fn = eval_vnet_list    },
376        { .name = ONONE, .fn = NULL } };
377    return vnet_eval_defs(defs, exp, io, data);
378}
Note: See TracBrowser for help on using the repository browser.