Annotation of cf/hv_nio.c, revision 1.1.1.4

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.