|
|
1.1 root 1: /* 1.1.1.2 root 2: * Cisco router simulation platform. 1.1 root 3: * Copyright (c) 2006 Christophe Fillot ([email protected]) 4: * 5: * Hypervisor NIO 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 <sys/mman.h> 15: #include <signal.h> 16: #include <fcntl.h> 17: #include <errno.h> 18: #include <assert.h> 19: #include <stdarg.h> 20: #include <sys/ioctl.h> 21: #include <sys/types.h> 22: #include <sys/socket.h> 23: #include <arpa/inet.h> 24: #include <pthread.h> 25: 26: #include "utils.h" 27: #include "net.h" 28: #include "atm.h" 29: #include "frame_relay.h" 30: #include "crc.h" 31: #include "net_io.h" 32: #include "net_io_bridge.h" 33: #include "net_io_filter.h" 34: #ifdef GEN_ETH 35: #include "gen_eth.h" 36: #endif 37: #include "registry.h" 38: #include "hypervisor.h" 39: 40: /* 41: * Create a UDP NIO 42: * 43: * Parameters: <nio_name> <local_port> <remote_host> <remote_port> 44: */ 45: static int cmd_create_udp(hypervisor_conn_t *conn,int argc,char *argv[]) 46: { 47: netio_desc_t *nio; 48: 49: nio = netio_desc_create_udp(argv[0],atoi(argv[1]),argv[2],atoi(argv[3])); 50: 51: if (!nio) { 52: hypervisor_send_reply(conn,HSC_ERR_CREATE,1, 53: "unable to create UDP NIO"); 54: return(-1); 55: } 56: 57: netio_release(argv[0]); 58: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); 59: return(0); 60: } 61: 62: /* 1.1.1.4 ! root 63: * Create a Auto UDP NIO ! 64: * ! 65: * Parameters: <nio_name> <local_addr> <local_port_start> <local_port_end> ! 66: */ ! 67: static int cmd_create_udp_auto(hypervisor_conn_t *conn,int argc,char *argv[]) ! 68: { ! 69: netio_desc_t *nio; ! 70: int local_port; ! 71: ! 72: nio = netio_desc_create_udp_auto(argv[0],argv[1],atoi(argv[2]),atoi(argv[3])); ! 73: ! 74: if (!nio) { ! 75: hypervisor_send_reply(conn,HSC_ERR_CREATE,1, ! 76: "unable to create UDP Auto NIO"); ! 77: return(-1); ! 78: } ! 79: ! 80: local_port = netio_udp_auto_get_local_port(nio); ! 81: ! 82: netio_release(argv[0]); ! 83: hypervisor_send_reply(conn,HSC_INFO_OK,1,"%d",local_port); ! 84: return(0); ! 85: } ! 86: ! 87: /* ! 88: * Connect an UDP Auto NIO to a remote host/port. ! 89: * ! 90: * Parameters: <nio_name> <remote_host> <remote_port> ! 91: */ ! 92: static int cmd_connect_udp_auto(hypervisor_conn_t *conn,int argc,char *argv[]) ! 93: { ! 94: netio_desc_t *nio; ! 95: int res; ! 96: ! 97: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) ! 98: return(-1); ! 99: ! 100: res = netio_udp_auto_connect(nio,argv[1],atoi(argv[2])); ! 101: netio_release(argv[0]); ! 102: ! 103: if (res == 0) { ! 104: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' connected",argv[0]); ! 105: return(0); ! 106: } else { ! 107: hypervisor_send_reply(conn,HSC_ERR_CREATE,1,"unable to connect NIO"); ! 108: return(-1); ! 109: } ! 110: } ! 111: ! 112: ! 113: /* ! 114: * Create a Multicast NIO ! 115: * ! 116: * Parameters: <nio_name> <mcast_group> <mcast_port> ! 117: */ ! 118: static int cmd_create_mcast(hypervisor_conn_t *conn,int argc,char *argv[]) ! 119: { ! 120: netio_desc_t *nio; ! 121: ! 122: nio = netio_desc_create_mcast(argv[0],argv[1],atoi(argv[2])); ! 123: ! 124: if (!nio) { ! 125: hypervisor_send_reply(conn,HSC_ERR_CREATE,1, ! 126: "unable to create Multicast NIO"); ! 127: return(-1); ! 128: } ! 129: ! 130: netio_release(argv[0]); ! 131: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); ! 132: return(0); ! 133: } ! 134: ! 135: /* Set TTL for a Multicast NIO */ ! 136: static int cmd_set_mcast_ttl(hypervisor_conn_t *conn,int argc,char *argv[]) ! 137: { ! 138: netio_desc_t *nio; ! 139: ! 140: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) ! 141: return(-1); ! 142: ! 143: netio_mcast_set_ttl(nio,atoi(argv[1])); ! 144: ! 145: netio_release(argv[0]); ! 146: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' TTL changed",argv[0]); ! 147: return(0); ! 148: } ! 149: ! 150: /* 1.1 root 151: * Create a UNIX NIO 152: * 153: * Parameters: <nio_name> <local_file> <remote_file> 154: */ 155: static int cmd_create_unix(hypervisor_conn_t *conn,int argc,char *argv[]) 156: { 157: netio_desc_t *nio; 158: 159: nio = netio_desc_create_unix(argv[0],argv[1],argv[2]); 160: 161: if (!nio) { 162: hypervisor_send_reply(conn,HSC_ERR_CREATE,1,"unable to create UNIX NIO"); 163: return(-1); 164: } 165: 166: netio_release(argv[0]); 167: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); 168: return(0); 169: } 170: 171: /* 172: * Create a VDE NIO 173: * 174: * Parameters: <nio_name> <control_file> <local_file> 175: */ 176: static int cmd_create_vde(hypervisor_conn_t *conn,int argc,char *argv[]) 177: { 178: netio_desc_t *nio; 179: 180: nio = netio_desc_create_vde(argv[0],argv[1],argv[2]); 181: 182: if (!nio) { 183: hypervisor_send_reply(conn,HSC_ERR_CREATE,1,"unable to create VDE NIO"); 184: return(-1); 185: } 186: 187: netio_release(argv[0]); 188: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); 189: return(0); 190: } 191: 192: /* 193: * Create a TAP NIO 194: * 195: * Parameters: <nio_name> <tap_device> 196: */ 197: static int cmd_create_tap(hypervisor_conn_t *conn,int argc,char *argv[]) 198: { 199: netio_desc_t *nio; 200: 201: nio = netio_desc_create_tap(argv[0],argv[1]); 202: 203: if (!nio) { 204: hypervisor_send_reply(conn,HSC_ERR_CREATE,1,"unable to create TAP NIO"); 205: return(-1); 206: } 207: 208: netio_release(argv[0]); 209: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); 210: return(0); 211: } 212: 213: /* 214: * Create a generic ethernet PCAP NIO 215: * 216: * Parameters: <nio_name> <eth_device> 217: */ 218: #ifdef GEN_ETH 219: static int cmd_create_gen_eth(hypervisor_conn_t *conn,int argc,char *argv[]) 220: { 221: netio_desc_t *nio; 222: 223: nio = netio_desc_create_geneth(argv[0],argv[1]); 224: 225: if (!nio) { 226: hypervisor_send_reply(conn,HSC_ERR_CREATE,1, 227: "unable to create generic ethernet NIO"); 228: return(-1); 229: } 230: 231: netio_release(argv[0]); 232: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); 233: return(0); 234: } 235: #endif 236: 237: /* 238: * Create a linux raw ethernet NIO 239: * 240: * Parameters: <nio_name> <eth_device> 241: */ 242: #ifdef LINUX_ETH 243: static int cmd_create_linux_eth(hypervisor_conn_t *conn,int argc,char *argv[]) 244: { 245: netio_desc_t *nio; 246: 247: nio = netio_desc_create_lnxeth(argv[0],argv[1]); 248: 249: if (!nio) { 250: hypervisor_send_reply(conn,HSC_ERR_CREATE,1, 251: "unable to create Linux raw ethernet NIO"); 252: return(-1); 253: } 254: 255: netio_release(argv[0]); 256: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); 257: return(0); 258: } 259: #endif 260: 261: /* 262: * Create a Null NIO 263: * 264: * Parameters: <nio_name> 265: */ 266: static int cmd_create_null(hypervisor_conn_t *conn,int argc,char *argv[]) 267: { 268: netio_desc_t *nio; 269: 270: nio = netio_desc_create_null(argv[0]); 271: 272: if (!nio) { 273: hypervisor_send_reply(conn,HSC_ERR_CREATE,1, 274: "unable to create Null NIO"); 275: return(-1); 276: } 277: 278: netio_release(argv[0]); 279: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); 280: return(0); 281: } 282: 283: /* 284: * Create a FIFO NIO 285: * 286: * Parameters: <nio_name> 287: */ 288: static int cmd_create_fifo(hypervisor_conn_t *conn,int argc,char *argv[]) 289: { 290: netio_desc_t *nio; 291: 292: nio = netio_desc_create_fifo(argv[0]); 293: 294: if (!nio) { 295: hypervisor_send_reply(conn,HSC_ERR_CREATE,1, 296: "unable to create FIFO NIO"); 297: return(-1); 298: } 299: 300: netio_release(argv[0]); 301: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' created",argv[0]); 302: return(0); 303: } 304: 305: /* 306: * Establish a cross-connect between 2 FIFO NIO 307: * 308: * Parameters: <nio_A_name> <nio_B_name> 309: */ 310: static int cmd_crossconnect_fifo(hypervisor_conn_t *conn,int argc,char *argv[]) 311: { 312: netio_desc_t *a,*b; 313: 314: if (!(a = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) 315: return(-1); 316: 317: if (!(b = hypervisor_find_object(conn,argv[1],OBJ_TYPE_NIO))) { 318: netio_release(argv[0]); 319: return(-1); 320: } 321: 322: netio_fifo_crossconnect(a,b); 323: 324: netio_release(argv[0]); 325: netio_release(argv[1]); 326: 327: hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); 328: return(0); 329: } 330: 331: /* Delete a NIO */ 332: static int cmd_delete(hypervisor_conn_t *conn,int argc,char *argv[]) 333: { 334: int res; 335: 336: res = netio_delete(argv[0]); 337: 338: if (res == 1) { 339: hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' deleted",argv[0]); 340: } else { 341: hypervisor_send_reply(conn,HSC_ERR_DELETE,1, 342: "unable to delete NIO '%s'",argv[0]); 343: } 344: 345: return(res); 346: } 347: 348: /* 349: * Enable/Disable debugging for an NIO 350: * 351: * Parameters: <nio_name> <debug_level> 352: */ 353: static int cmd_set_debug(hypervisor_conn_t *conn,int argc,char *argv[]) 354: { 355: netio_desc_t *nio; 356: 357: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) 358: return(-1); 359: 360: nio->debug = atoi(argv[1]); 361: 362: netio_release(argv[0]); 363: hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); 364: return(0); 365: } 366: 367: /* Bind a packet filter */ 368: static int cmd_bind_filter(hypervisor_conn_t *conn,int argc,char *argv[]) 369: { 370: netio_desc_t *nio; 371: int res; 372: 373: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) 374: return(-1); 375: 376: res = netio_filter_bind(nio,atoi(argv[1]),argv[2]); 377: netio_release(argv[0]); 378: 379: if (!res) { 380: hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); 381: } else { 382: hypervisor_send_reply(conn,HSC_ERR_UNK_OBJ,1, 383: "Unknown filter %s",argv[2]); 384: } 385: return(0); 386: } 387: 388: /* Unbind a packet filter */ 389: static int cmd_unbind_filter(hypervisor_conn_t *conn,int argc,char *argv[]) 390: { 391: netio_desc_t *nio; 392: int res; 393: 394: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) 395: return(-1); 396: 397: res = netio_filter_unbind(nio,atoi(argv[1])); 398: netio_release(argv[0]); 399: 400: if (!res) { 401: hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); 402: } else { 403: hypervisor_send_reply(conn,HSC_ERR_UNK_OBJ,1, 404: "No filter previously defined"); 405: } 406: return(0); 407: } 408: 409: 410: /* Setup a packet filter for a given NIO */ 411: static int cmd_setup_filter(hypervisor_conn_t *conn,int argc,char *argv[]) 412: { 413: netio_desc_t *nio; 414: 415: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) 416: return(-1); 417: 418: netio_filter_setup(nio,atoi(argv[1]),argc-2,&argv[2]); 419: netio_release(argv[0]); 420: 421: hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); 422: return(0); 423: } 424: 1.1.1.4 ! root 425: /* Get statistics of a NIO */ ! 426: static int cmd_get_stats(hypervisor_conn_t *conn,int argc,char *argv[]) ! 427: { ! 428: netio_desc_t *nio; ! 429: m_uint64_t spi,spo,sbi,sbo; ! 430: ! 431: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) ! 432: return(-1); ! 433: ! 434: spi = nio->stats_pkts_in; ! 435: spo = nio->stats_pkts_out; ! 436: sbi = nio->stats_bytes_in; ! 437: sbo = nio->stats_bytes_out; ! 438: ! 439: netio_release(argv[0]); ! 440: ! 441: hypervisor_send_reply(conn,HSC_INFO_OK,1,"%llu %llu %llu %llu", ! 442: spi,spo,sbi,sbo); ! 443: return(0); ! 444: } ! 445: ! 446: /* Reset statistics of a NIO */ ! 447: static int cmd_reset_stats(hypervisor_conn_t *conn,int argc,char *argv[]) ! 448: { ! 449: netio_desc_t *nio; ! 450: ! 451: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) ! 452: return(-1); ! 453: ! 454: netio_reset_stats(nio); ! 455: netio_release(argv[0]); ! 456: ! 457: hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); ! 458: return(0); ! 459: } ! 460: ! 461: /* Set bandwidth constraint */ ! 462: static int cmd_set_bandwidth(hypervisor_conn_t *conn,int argc,char *argv[]) ! 463: { ! 464: netio_desc_t *nio; ! 465: ! 466: if (!(nio = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO))) ! 467: return(-1); ! 468: ! 469: netio_set_bandwidth(nio,atoi(argv[1])); ! 470: netio_release(argv[0]); ! 471: ! 472: hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); ! 473: return(0); ! 474: } ! 475: 1.1 root 476: /* Show info about a NIO object */ 477: static void cmd_show_nio_list(registry_entry_t *entry,void *opt,int *err) 478: { 479: hypervisor_conn_t *conn = opt; 480: hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%s",entry->name); 481: } 482: 483: /* NIO List */ 484: static int cmd_nio_list(hypervisor_conn_t *conn,int argc,char *argv[]) 485: { 486: int err = 0; 487: registry_foreach_type(OBJ_TYPE_NIO,cmd_show_nio_list,conn,&err); 488: hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); 489: return(0); 490: } 491: 492: /* NIO commands */ 493: static hypervisor_cmd_t nio_cmd_array[] = { 494: { "create_udp", 4, 4, cmd_create_udp, NULL }, 1.1.1.4 ! root 495: { "create_udp_auto", 4, 4, cmd_create_udp_auto, NULL }, ! 496: { "connect_udp_auto", 3, 3, cmd_connect_udp_auto, NULL }, ! 497: { "create_mcast", 3, 3, cmd_create_mcast, NULL }, ! 498: { "set_mcast_ttl", 2, 2, cmd_set_mcast_ttl, NULL }, 1.1 root 499: { "create_unix", 3, 3, cmd_create_unix, NULL }, 500: { "create_vde", 3, 3, cmd_create_vde, NULL }, 501: { "create_tap", 2, 2, cmd_create_tap, NULL }, 502: #ifdef GEN_ETH 503: { "create_gen_eth", 2, 2, cmd_create_gen_eth, NULL }, 504: #endif 505: #ifdef LINUX_ETH 506: { "create_linux_eth", 2, 2, cmd_create_linux_eth, NULL }, 507: #endif 508: { "create_null", 1, 1, cmd_create_null, NULL }, 509: { "create_fifo", 1, 1, cmd_create_fifo, NULL }, 510: { "crossconnect_fifo", 2, 2, cmd_crossconnect_fifo, NULL }, 511: { "delete", 1, 1, cmd_delete, NULL }, 512: { "set_debug", 2, 2, cmd_set_debug, NULL }, 513: { "bind_filter", 3, 3, cmd_bind_filter, NULL }, 514: { "unbind_filter", 2, 2, cmd_unbind_filter, NULL }, 515: { "setup_filter", 2, 10, cmd_setup_filter, NULL }, 1.1.1.4 ! root 516: { "get_stats", 1, 1, cmd_get_stats }, ! 517: { "reset_stats", 1, 1, cmd_reset_stats }, ! 518: { "set_bandwidth", 2, 2, cmd_set_bandwidth }, 1.1 root 519: { "list", 0, 0, cmd_nio_list, NULL }, 520: { NULL, -1, -1, NULL, NULL }, 521: }; 522: 523: /* Hypervisor NIO initialization */ 524: int hypervisor_nio_init(void) 525: { 526: hypervisor_module_t *module; 527: 1.1.1.3 root 528: module = hypervisor_register_module("nio",NULL); 1.1 root 529: assert(module != NULL); 530: 531: hypervisor_register_cmd_array(module,nio_cmd_array); 532: return(0); 533: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.