Annotation of qemu/roms/ipxe/src/net/eth_slow.c, revision 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 <stdlib.h>
        !            22: #include <string.h>
        !            23: #include <byteswap.h>
        !            24: #include <errno.h>
        !            25: #include <ipxe/iobuf.h>
        !            26: #include <ipxe/netdevice.h>
        !            27: #include <ipxe/if_ether.h>
        !            28: #include <ipxe/ethernet.h>
        !            29: #include <ipxe/eth_slow.h>
        !            30: 
        !            31: /** @file
        !            32:  *
        !            33:  * Ethernet slow protocols
        !            34:  *
        !            35:  * We implement a very simple passive LACP entity, that pretends that
        !            36:  * each port is the only port on an individual system.  We avoid the
        !            37:  * need for timeout logic (and retaining local state about our
        !            38:  * partner) by requesting the same timeout period (1s or 30s) as our
        !            39:  * partner requests, and then simply responding to every packet the
        !            40:  * partner sends us.
        !            41:  */
        !            42: 
        !            43: struct net_protocol eth_slow_protocol __net_protocol;
        !            44: 
        !            45: /** Slow protocols multicast address */
        !            46: static const uint8_t eth_slow_address[ETH_ALEN] =
        !            47:        { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x02 };
        !            48: 
        !            49: /**
        !            50:  * Name LACP TLV type
        !            51:  *
        !            52:  * @v type             LACP TLV type
        !            53:  * @ret name           Name of LACP TLV type
        !            54:  */
        !            55: static inline __attribute__ (( always_inline )) const char *
        !            56: eth_slow_lacp_tlv_name ( uint8_t type ) {
        !            57:        switch ( type ) {
        !            58:        case ETH_SLOW_TLV_TERMINATOR:           return "terminator";
        !            59:        case ETH_SLOW_TLV_LACP_ACTOR:           return "actor";
        !            60:        case ETH_SLOW_TLV_LACP_PARTNER:         return "partner";
        !            61:        case ETH_SLOW_TLV_LACP_COLLECTOR:       return "collector";
        !            62:        default:                                return "<invalid>";
        !            63:        }
        !            64: }
        !            65: 
        !            66: /**
        !            67:  * Name marker TLV type
        !            68:  *
        !            69:  * @v type             Marker TLV type
        !            70:  * @ret name           Name of marker TLV type
        !            71:  */
        !            72: static inline __attribute__ (( always_inline )) const char *
        !            73: eth_slow_marker_tlv_name ( uint8_t type ) {
        !            74:        switch ( type ) {
        !            75:        case ETH_SLOW_TLV_TERMINATOR:           return "terminator";
        !            76:        case ETH_SLOW_TLV_MARKER_REQUEST:       return "request";
        !            77:        case ETH_SLOW_TLV_MARKER_RESPONSE:      return "response";
        !            78:        default:                                return "<invalid>";
        !            79:        }
        !            80: }
        !            81: 
        !            82: /**
        !            83:  * Name LACP state
        !            84:  *
        !            85:  * @v state            LACP state
        !            86:  * @ret name           LACP state name
        !            87:  */
        !            88: static const char * eth_slow_lacp_state_name ( uint8_t state ) {
        !            89:        static char state_chars[] = "AFGSRTLX";
        !            90:        unsigned int i;
        !            91: 
        !            92:        for ( i = 0 ; i < 8 ; i++ ) {
        !            93:                state_chars[i] |= 0x20;
        !            94:                if ( state & ( 1 << i ) )
        !            95:                        state_chars[i] &= ~0x20;
        !            96:        }
        !            97:        return state_chars;
        !            98: }
        !            99: 
        !           100: /**
        !           101:  * Dump LACP packet
        !           102:  *
        !           103:  * @v iobuf            I/O buffer
        !           104:  * @v netdev           Network device
        !           105:  * @v label            "RX" or "TX"
        !           106:  */
        !           107: static void eth_slow_lacp_dump ( struct io_buffer *iobuf,
        !           108:                                 struct net_device *netdev,
        !           109:                                 const char *label ) {
        !           110:        union eth_slow_packet *eth_slow = iobuf->data;
        !           111:        struct eth_slow_lacp *lacp = &eth_slow->lacp;
        !           112: 
        !           113:        DBGC ( netdev,
        !           114:               "SLOW %s %s LACP actor (%04x,%s,%04x,%02x,%04x) [%s]\n",
        !           115:               netdev->name, label, ntohs ( lacp->actor.system_priority ),
        !           116:               eth_ntoa ( lacp->actor.system ),
        !           117:               ntohs ( lacp->actor.key ),
        !           118:               ntohs ( lacp->actor.port_priority ),
        !           119:               ntohs ( lacp->actor.port ),
        !           120:               eth_slow_lacp_state_name ( lacp->actor.state ) );
        !           121:        DBGC ( netdev,
        !           122:               "SLOW %s %s LACP partner (%04x,%s,%04x,%02x,%04x) [%s]\n",
        !           123:               netdev->name, label, ntohs ( lacp->partner.system_priority ),
        !           124:               eth_ntoa ( lacp->partner.system ),
        !           125:               ntohs ( lacp->partner.key ),
        !           126:               ntohs ( lacp->partner.port_priority ),
        !           127:               ntohs ( lacp->partner.port ),
        !           128:               eth_slow_lacp_state_name ( lacp->partner.state ) );
        !           129:        DBGC ( netdev, "SLOW %s %s LACP collector %04x (%d us)\n",
        !           130:               netdev->name, label, ntohs ( lacp->collector.max_delay ),
        !           131:               ( ntohs ( lacp->collector.max_delay ) * 10 ) );
        !           132:        DBGC2_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
        !           133: }
        !           134: 
        !           135: /**
        !           136:  * Process incoming LACP packet
        !           137:  *
        !           138:  * @v iobuf            I/O buffer
        !           139:  * @v netdev           Network device
        !           140:  * @ret rc             Return status code
        !           141:  */
        !           142: static int eth_slow_lacp_rx ( struct io_buffer *iobuf,
        !           143:                              struct net_device *netdev ) {
        !           144:        union eth_slow_packet *eth_slow = iobuf->data;
        !           145:        struct eth_slow_lacp *lacp = &eth_slow->lacp;
        !           146: 
        !           147:        eth_slow_lacp_dump ( iobuf, netdev, "RX" );
        !           148: 
        !           149:        /* Build response */
        !           150:        memset ( lacp->reserved, 0, sizeof ( lacp->reserved ) );
        !           151:        memset ( &lacp->terminator, 0, sizeof ( lacp->terminator ) );
        !           152:        memset ( &lacp->collector, 0, sizeof ( lacp->collector ) );
        !           153:        lacp->collector.tlv.type = ETH_SLOW_TLV_LACP_COLLECTOR;
        !           154:        lacp->collector.tlv.length = ETH_SLOW_TLV_LACP_COLLECTOR_LEN;
        !           155:        memcpy ( &lacp->partner, &lacp->actor, sizeof ( lacp->partner ) );
        !           156:        lacp->partner.tlv.type = ETH_SLOW_TLV_LACP_PARTNER;
        !           157:        lacp->partner.tlv.length = ETH_SLOW_TLV_LACP_PARTNER_LEN;
        !           158:        memset ( &lacp->partner.reserved, 0,
        !           159:                 sizeof ( lacp->partner.reserved ) );
        !           160:        memset ( &lacp->actor, 0, sizeof ( lacp->actor ) );
        !           161:        lacp->actor.tlv.type = ETH_SLOW_TLV_LACP_ACTOR;
        !           162:        lacp->actor.tlv.length = ETH_SLOW_TLV_LACP_ACTOR_LEN;
        !           163:        lacp->actor.system_priority = htons ( LACP_SYSTEM_PRIORITY_MAX );
        !           164:        memcpy ( lacp->actor.system, netdev->ll_addr,
        !           165:                 sizeof ( lacp->actor.system ) );
        !           166:        lacp->actor.key = htons ( 1 );
        !           167:        lacp->actor.port_priority = htons ( LACP_PORT_PRIORITY_MAX );
        !           168:        lacp->actor.port = htons ( 1 );
        !           169:        lacp->actor.state = ( LACP_STATE_IN_SYNC |
        !           170:                              LACP_STATE_COLLECTING |
        !           171:                              LACP_STATE_DISTRIBUTING |
        !           172:                              ( lacp->partner.state & LACP_STATE_FAST ) );
        !           173:        lacp->header.version = ETH_SLOW_LACP_VERSION;
        !           174: 
        !           175:        /* Send response */
        !           176:        eth_slow_lacp_dump ( iobuf, netdev, "TX" );
        !           177:        return net_tx ( iobuf, netdev, &eth_slow_protocol, eth_slow_address,
        !           178:                        netdev->ll_addr );
        !           179: }
        !           180: 
        !           181: /**
        !           182:  * Dump marker packet
        !           183:  *
        !           184:  * @v iobuf            I/O buffer
        !           185:  * @v netdev           Network device
        !           186:  * @v label            "RX" or "TX"
        !           187:  */
        !           188: static void eth_slow_marker_dump ( struct io_buffer *iobuf,
        !           189:                                   struct net_device *netdev,
        !           190:                                   const char *label ) {
        !           191:        union eth_slow_packet *eth_slow = iobuf->data;
        !           192:        struct eth_slow_marker *marker = &eth_slow->marker;
        !           193: 
        !           194:        DBGC ( netdev, "SLOW %s %s marker %s port %04x system %s xact %08x\n",
        !           195:               netdev->name, label,
        !           196:               eth_slow_marker_tlv_name ( marker->marker.tlv.type ),
        !           197:               ntohs ( marker->marker.port ),
        !           198:               eth_ntoa ( marker->marker.system ),
        !           199:               ntohl ( marker->marker.xact ) );
        !           200:        DBGC2_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
        !           201: }
        !           202: 
        !           203: /**
        !           204:  * Process incoming marker packet
        !           205:  *
        !           206:  * @v iobuf            I/O buffer
        !           207:  * @v netdev           Network device
        !           208:  * @ret rc             Return status code
        !           209:  */
        !           210: static int eth_slow_marker_rx ( struct io_buffer *iobuf,
        !           211:                                struct net_device *netdev ) {
        !           212:        union eth_slow_packet *eth_slow = iobuf->data;
        !           213:        struct eth_slow_marker *marker = &eth_slow->marker;
        !           214: 
        !           215:        eth_slow_marker_dump ( iobuf, netdev, "RX" );
        !           216: 
        !           217:        if ( marker->marker.tlv.type == ETH_SLOW_TLV_MARKER_REQUEST ) {
        !           218:                /* Send marker response */
        !           219:                marker->marker.tlv.type = ETH_SLOW_TLV_MARKER_RESPONSE;
        !           220:                eth_slow_marker_dump ( iobuf, netdev, "TX" );
        !           221:                return net_tx ( iobuf, netdev, &eth_slow_protocol,
        !           222:                                eth_slow_address, netdev->ll_addr );
        !           223:        } else {
        !           224:                /* Discard all other marker packets */
        !           225:                free_iob ( iobuf );
        !           226:                return -EINVAL;
        !           227:        }
        !           228: }
        !           229: 
        !           230: /**
        !           231:  * Process incoming slow packet
        !           232:  *
        !           233:  * @v iobuf            I/O buffer
        !           234:  * @v netdev           Network device
        !           235:  * @v ll_dest          Link-layer destination address
        !           236:  * @v ll_source                Link-layer source address
        !           237:  * @ret rc             Return status code
        !           238:  */
        !           239: static int eth_slow_rx ( struct io_buffer *iobuf,
        !           240:                         struct net_device *netdev,
        !           241:                         const void *ll_dest __unused,
        !           242:                         const void *ll_source __unused ) {
        !           243:        union eth_slow_packet *eth_slow = iobuf->data;
        !           244: 
        !           245:        /* Sanity checks */
        !           246:        if ( iob_len ( iobuf ) < sizeof ( *eth_slow ) ) {
        !           247:                free_iob ( iobuf );
        !           248:                return -EINVAL;
        !           249:        }
        !           250: 
        !           251:        /* Handle according to subtype */
        !           252:        switch ( eth_slow->header.subtype ) {
        !           253:        case ETH_SLOW_SUBTYPE_LACP:
        !           254:                return eth_slow_lacp_rx ( iobuf, netdev );
        !           255:        case ETH_SLOW_SUBTYPE_MARKER:
        !           256:                return eth_slow_marker_rx ( iobuf, netdev );
        !           257:        default:
        !           258:                DBGC ( netdev, "SLOW %s RX unknown subtype %02x\n",
        !           259:                       netdev->name, eth_slow->header.subtype );
        !           260:                free_iob ( iobuf );
        !           261:                return -EINVAL;
        !           262:        }
        !           263: }
        !           264: 
        !           265: /** Slow protocol */
        !           266: struct net_protocol eth_slow_protocol __net_protocol = {
        !           267:        .name = "Slow",
        !           268:        .net_proto = htons ( ETH_P_SLOW ),
        !           269:        .rx = eth_slow_rx,
        !           270: };

unix.superglobalmegacorp.com

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