Annotation of qemu/roms/ipxe/src/usr/lotest.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2010 Michael Brown <[email protected]>.
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or 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
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: FILE_LICENCE ( GPL2_OR_LATER );
                     20: 
                     21: #include <stdint.h>
                     22: #include <stdlib.h>
                     23: #include <string.h>
                     24: #include <stdio.h>
                     25: #include <errno.h>
                     26: #include <byteswap.h>
                     27: #include <ipxe/iobuf.h>
                     28: #include <ipxe/netdevice.h>
                     29: #include <ipxe/if_ether.h>
                     30: #include <ipxe/keys.h>
                     31: #include <ipxe/console.h>
                     32: #include <usr/ifmgmt.h>
                     33: #include <usr/lotest.h>
                     34: 
                     35: /** @file
                     36:  *
                     37:  * Loopback testing
                     38:  *
                     39:  */
                     40: 
                     41: #define LINK_WAIT_MS 15000
                     42: 
                     43: /**
                     44:  * Process received packet
                     45:  *
                     46:  * @v iobuf            I/O buffer
                     47:  * @v netdev           Network device
                     48:  * @v ll_dest          Link-layer destination address
                     49:  * @v ll_source                Link-layer source address
                     50:  * @ret rc             Return status code
                     51:  */
                     52: static int lotest_rx ( struct io_buffer *iobuf,
                     53:                       struct net_device *netdev __unused,
                     54:                       const void *ll_dest __unused,
                     55:                       const void *ll_source __unused ) {
                     56:        free_iob ( iobuf );
                     57:        return -ENOTSUP;
                     58: }
                     59: 
                     60: /**
                     61:  * Transcribe network-layer address
                     62:  *
                     63:  * @v net_addr         Network-layer address
                     64:  * @ret string         Human-readable transcription of address
                     65:  */
                     66: static const char * lotest_ntoa ( const void *net_addr __unused ) {
                     67:        return "<INVALID>";
                     68: }
                     69: 
                     70: /**
                     71:  * Loopback test network-layer protocol
                     72:  *
                     73:  * Using a dedicated network-layer protocol avoids problems caused by
                     74:  * cards supporting features such as IPv4 checksum offload trying to
                     75:  * interpret the (randomly generated) network-layer content.
                     76:  */
                     77: static struct net_protocol lotest_protocol __net_protocol = {
                     78:        .name = "LOTEST",
                     79:        .rx = lotest_rx,
                     80:        .ntoa = lotest_ntoa,
                     81:        .net_proto = htons ( 0x6950 ), /* Not a genuine protocol number */
                     82:        .net_addr_len = 0,
                     83: };
                     84: 
                     85: /**
                     86:  * Perform loopback test between two network devices
                     87:  *
                     88:  * @v sender           Sending network device
                     89:  * @v receiver         Received network device
                     90:  * @v mtu              Packet size (excluding link-layer headers)
                     91:  * @ret rc             Return status code
                     92:  */
                     93: int loopback_test ( struct net_device *sender, struct net_device *receiver,
                     94:                    size_t mtu ) {
                     95:        uint8_t buf[mtu];
                     96:        struct io_buffer *iobuf;
                     97:        const void *ll_dest;
                     98:        const void *ll_source;
                     99:        uint16_t net_proto;
                    100:        unsigned int i;
                    101:        unsigned int successes;
                    102:        int rc;
                    103: 
                    104:        /* Open network devices */
                    105:        if ( ( rc = ifopen ( sender ) ) != 0 )
                    106:                return rc;
                    107:        if ( ( rc = ifopen ( receiver ) ) != 0 )
                    108:                return rc;
                    109: 
                    110:        /* Wait for link-up */
                    111:        if ( ( rc = iflinkwait ( sender, LINK_WAIT_MS ) ) != 0 )
                    112:                return rc;
                    113:        if ( ( rc = iflinkwait ( receiver, LINK_WAIT_MS ) ) != 0 )
                    114:                return rc;
                    115: 
                    116:        /* Print initial statistics */
                    117:        printf ( "Performing loopback test from %s to %s with %zd byte MTU\n",
                    118:                 sender->name, receiver->name, mtu );
                    119:        ifstat ( sender );
                    120:        ifstat ( receiver );
                    121: 
                    122:        /* Freeze receive queue processing on the receiver, so that we
                    123:         * can extract all received packets.
                    124:         */
                    125:        netdev_rx_freeze ( receiver );
                    126: 
                    127:        /* Perform loopback test */
                    128:        for ( successes = 0 ; ; successes++ ) {
                    129: 
                    130:                /* Print running total */
                    131:                printf ( "\r%d", successes );
                    132: 
                    133:                /* Generate random packet */
                    134:                for ( i = 0 ; i < sizeof ( buf ) ; i++ )
                    135:                        buf[i] = random();
                    136:                iobuf = alloc_iob ( MAX_LL_HEADER_LEN + sizeof ( buf ) );
                    137:                if ( ! iobuf ) {
                    138:                        printf ( "\nFailed to allocate I/O buffer" );
                    139:                        rc = -ENOMEM;
                    140:                        goto done;
                    141:                }
                    142:                iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
                    143:                memcpy ( iob_put ( iobuf, sizeof ( buf ) ),
                    144:                         buf, sizeof ( buf ) );
                    145: 
                    146:                /* Transmit packet */
                    147:                if ( ( rc = net_tx ( iob_disown ( iobuf ), sender,
                    148:                                     &lotest_protocol, receiver->ll_addr,
                    149:                                     sender->ll_addr ) ) != 0 ) {
                    150:                        printf ( "\nFailed to transmit packet: %s",
                    151:                                 strerror ( rc ) );
                    152:                        goto done;
                    153:                }
                    154: 
                    155:                /* Poll until packet arrives */
                    156:                do {
                    157:                        /* Check for cancellation */
                    158:                        if ( iskey() && ( getchar() == CTRL_C ) ) {
                    159:                                rc = -ECANCELED;
                    160:                                goto done;
                    161:                        }
                    162:                        /* Poll network devices */
                    163:                        net_poll();
                    164:                } while ( ( iobuf = netdev_rx_dequeue ( receiver ) ) == NULL );
                    165: 
                    166:                /* Check received packet */
                    167:                if ( ( rc = receiver->ll_protocol->pull ( receiver, iobuf,
                    168:                                                          &ll_dest, &ll_source,
                    169:                                                          &net_proto ) ) != 0 ){
                    170:                        printf ( "\nFailed to strip link-layer header: %s",
                    171:                                 strerror ( rc ) );
                    172:                        goto done;
                    173:                }
                    174:                if ( net_proto == lotest_protocol.net_proto ) {
                    175:                        if ( iob_len ( iobuf ) != sizeof ( buf ) ) {
                    176:                                printf ( "\nLength mismatch: sent %zd, "
                    177:                                         "received %zd",
                    178:                                         sizeof ( buf ), iob_len ( iobuf ) );
                    179:                                DBG ( "\nSent:\n" );
                    180:                                DBG_HDA ( 0, buf, sizeof ( buf ) );
                    181:                                DBG ( "Received:\n" );
                    182:                                DBG_HDA ( 0, iobuf->data, iob_len ( iobuf ) );
                    183:                                rc = -EINVAL;
                    184:                                goto done;
                    185:                        }
                    186:                        if ( memcmp ( iobuf->data, buf, sizeof ( buf ) ) != 0){
                    187:                                printf ( "\nContent mismatch" );
                    188:                                DBG ( "\nSent:\n" );
                    189:                                DBG_HDA ( 0, buf, sizeof ( buf ) );
                    190:                                DBG ( "Received:\n" );
                    191:                                DBG_HDA ( 0, iobuf->data, iob_len ( iobuf ) );
                    192:                                rc = -EINVAL;
                    193:                                goto done;
                    194:                        }
                    195:                } else {
                    196:                        printf ( "\nReceived spurious packet type %04x\n",
                    197:                                 ntohs ( net_proto ) );
                    198:                        /* Continue; this allows for the fact that
                    199:                         * there may have been packets outstanding on
                    200:                         * the wire when we started the test.
                    201:                         */
                    202:                }
                    203: 
                    204:                free_iob ( iob_disown ( iobuf ) );
                    205:        }
                    206: 
                    207:  done:
                    208:        printf ( "\n");
                    209:        free_iob ( iobuf );
                    210:        netdev_rx_unfreeze ( receiver );
                    211: 
                    212:        /* Dump final statistics */
                    213:        ifstat ( sender );
                    214:        ifstat ( receiver );
                    215: 
                    216:        return 0;
                    217: }

unix.superglobalmegacorp.com

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