1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)
4 *
5 * Hypervisor NIO bridge routines.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <signal.h>
15 #include <fcntl.h>
16 #include <errno.h>
17 #include <assert.h>
18 #include <stdarg.h>
19 #include <sys/ioctl.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <arpa/inet.h>
23 #include <pthread.h>
24
25 #include "utils.h"
26 #include "net.h"
27 #include "crc.h"
28 #include "net_io.h"
29 #include "net_io_bridge.h"
30 #include "registry.h"
31 #include "hypervisor.h"
32
33 /* Create a new NIO bridge */
cmd_create(hypervisor_conn_t * conn,int argc,char * argv[])34 static int cmd_create(hypervisor_conn_t *conn,int argc,char *argv[])
35 {
36 netio_bridge_t *t;
37
38 if (!(t = netio_bridge_create(argv[0]))) {
39 hypervisor_send_reply(conn,HSC_ERR_CREATE,1,
40 "unable to create NIO bridge '%s'",
41 argv[0]);
42 return(-1);
43 }
44
45 netio_bridge_release(argv[0]);
46 hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO bridge '%s' created",argv[0]);
47 return(0);
48 }
49
50 /* Rename a NIO bridge */
cmd_rename(hypervisor_conn_t * conn,int argc,char * argv[])51 static int cmd_rename(hypervisor_conn_t *conn,int argc,char *argv[])
52 {
53 netio_bridge_t *t;
54 char *newname;
55
56 if (!(t = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO_BRIDGE)))
57 return(-1);
58
59 if (registry_exists(argv[1],OBJ_TYPE_NIO_BRIDGE)) {
60 netio_bridge_release(argv[0]);
61 hypervisor_send_reply(conn,HSC_ERR_RENAME,1,
62 "unable to rename NIO bridge '%s', '%s' already exists",
63 argv[0],argv[1]);
64 return(-1);
65 }
66
67 if(!(newname = strdup(argv[1]))) {
68 netio_bridge_release(argv[0]);
69 hypervisor_send_reply(conn,HSC_ERR_RENAME,1,
70 "unable to rename NIO bridge '%s', out of memory",
71 argv[0]);
72 return(-1);
73 }
74
75 if (registry_rename(argv[0],newname,OBJ_TYPE_NIO_BRIDGE)) {
76 free(newname);
77 netio_bridge_release(argv[0]);
78 hypervisor_send_reply(conn,HSC_ERR_RENAME,1,
79 "unable to rename NIO bridge '%s'",
80 argv[0]);
81 return(-1);
82 }
83
84 free(t->name);
85 t->name = newname;
86
87 netio_bridge_release(argv[1]);
88 hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO bridge '%s' renamed to '%s'",argv[0],argv[1]);
89 return(0);
90 }
91
92 /* Delete an NIO bridge */
cmd_delete(hypervisor_conn_t * conn,int argc,char * argv[])93 static int cmd_delete(hypervisor_conn_t *conn,int argc,char *argv[])
94 {
95 int res;
96
97 res = netio_bridge_delete(argv[0]);
98
99 if (res == 1) {
100 hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO bridge '%s' deleted",
101 argv[0]);
102 } else {
103 hypervisor_send_reply(conn,HSC_ERR_DELETE,1,
104 "unable to delete NIO bridge '%s'",argv[0]);
105 }
106
107 return(res);
108 }
109
110 /*
111 * Add a NIO to a bridge
112 *
113 * Parameters: <bridge_name> <nio_name>
114 */
cmd_add_nio(hypervisor_conn_t * conn,int argc,char * argv[])115 static int cmd_add_nio(hypervisor_conn_t *conn,int argc,char *argv[])
116 {
117 netio_bridge_t *t;
118
119 if (!(t = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO_BRIDGE)))
120 return(-1);
121
122 if (netio_bridge_add_netio(t,argv[1]) == -1) {
123 netio_bridge_release(argv[0]);
124 hypervisor_send_reply(conn,HSC_ERR_BINDING,1,
125 "unable to bind NIO '%s' to bridge '%s'",
126 argv[1],argv[0]);
127 return(-1);
128 }
129
130 netio_bridge_release(argv[0]);
131 hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' bound.",argv[1]);
132 return(0);
133 }
134
135 /*
136 * Remove a NIO from a bridge
137 *
138 * Parameters: <bridge_name> <nio_name>
139 */
cmd_remove_nio(hypervisor_conn_t * conn,int argc,char * argv[])140 static int cmd_remove_nio(hypervisor_conn_t *conn,int argc,char *argv[])
141 {
142 netio_bridge_t *t;
143
144 if (!(t = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO_BRIDGE)))
145 return(-1);
146
147 if (netio_bridge_remove_netio(t,argv[1]) == -1) {
148 netio_bridge_release(argv[0]);
149 hypervisor_send_reply(conn,HSC_ERR_BINDING,1,
150 "unable to bind NIO '%s' to bridge '%s'",
151 argv[1],argv[0]);
152 return(-1);
153 }
154
155 netio_bridge_release(argv[0]);
156 hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' unbound.",argv[1]);
157 return(0);
158 }
159
160 /* Show info about a NIO bridge object */
cmd_show_list(registry_entry_t * entry,void * opt,int * err)161 static void cmd_show_list(registry_entry_t *entry,void *opt,int *err)
162 {
163 hypervisor_conn_t *conn = opt;
164 hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%s",entry->name);
165 }
166
167 /* Bridge switch List */
cmd_list(hypervisor_conn_t * conn,int argc,char * argv[])168 static int cmd_list(hypervisor_conn_t *conn,int argc,char *argv[])
169 {
170 int err = 0;
171 registry_foreach_type(OBJ_TYPE_NIO_BRIDGE,cmd_show_list,conn,&err);
172 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
173 return(0);
174 }
175
176 /* NIO bridge commands */
177 static hypervisor_cmd_t nio_bridge_cmd_array[] = {
178 { "create", 1, 1, cmd_create, NULL },
179 { "rename", 2, 2, cmd_rename, NULL },
180 { "delete", 1, 1, cmd_delete, NULL },
181 { "add_nio", 2, 2, cmd_add_nio, NULL },
182 { "remove_nio", 2, 2, cmd_remove_nio, NULL },
183 { "list", 0, 0, cmd_list, NULL },
184 { NULL, -1, -1, NULL, NULL },
185 };
186
187 /* Hypervisor NIO bridge initialization */
hypervisor_nio_bridge_init(void)188 int hypervisor_nio_bridge_init(void)
189 {
190 hypervisor_module_t *module;
191
192 module = hypervisor_register_module("nio_bridge",NULL);
193 assert(module != NULL);
194
195 hypervisor_register_cmd_array(module,nio_bridge_cmd_array);
196 return(0);
197 }
198