iPXE
Data Structures | Functions | Variables
fcns.c File Reference

Fibre Channel name server lookups. More...

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/interface.h>
#include <ipxe/iobuf.h>
#include <ipxe/process.h>
#include <ipxe/xfer.h>
#include <ipxe/fc.h>
#include <ipxe/fcns.h>

Go to the source code of this file.

Data Structures

struct  fc_ns_query
 A Fibre Channel name server query. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static void fc_ns_query_free (struct refcnt *refcnt)
 Free name server query.
static void fc_ns_query_close (struct fc_ns_query *query, int rc)
 Close name server query.
static int fc_ns_query_deliver (struct fc_ns_query *query, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Receive name server query response.
static void fc_ns_query_step (struct fc_ns_query *query)
 Name server query process.
int fc_ns_query (struct fc_peer *peer, struct fc_port *port, int(*done)(struct fc_peer *peer, struct fc_port *port, struct fc_port_id *peer_port_id))
 Issue Fibre Channel name server query.

Variables

static struct interface_operation fc_ns_query_xchg_op []
 Name server exchange interface operations.
static struct interface_descriptor fc_ns_query_xchg_desc
 Name server exchange interface descriptor.
static struct process_descriptor fc_ns_query_process_desc
 Name server process descriptor.

Detailed Description

Fibre Channel name server lookups.

Definition in file fcns.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static void fc_ns_query_free ( struct refcnt refcnt) [static]

Free name server query.

Parameters:
refcntReference count

Definition at line 74 of file fcns.c.

References container_of, fc_peer_put(), fc_port_put(), free, fc_ns_query::peer, and fc_ns_query::port.

Referenced by fc_ns_query().

                                                       {
        struct fc_ns_query *query =
                container_of ( refcnt, struct fc_ns_query, refcnt );

        fc_peer_put ( query->peer );
        fc_port_put ( query->port );
        free ( query );
}
static void fc_ns_query_close ( struct fc_ns_query query,
int  rc 
) [static]

Close name server query.

Parameters:
queryName server query
rcReason for close

Definition at line 89 of file fcns.c.

References intf_shutdown(), fc_ns_query::process, process_del(), and fc_ns_query::xchg.

Referenced by fc_ns_query_deliver(), and fc_ns_query_step().

                                                                    {

        /* Stop process */
        process_del ( &query->process );

        /* Shut down interfaces */
        intf_shutdown ( &query->xchg, rc );
}
static int fc_ns_query_deliver ( struct fc_ns_query query,
struct io_buffer iobuf,
struct xfer_metadata *meta  __unused 
) [static]

Receive name server query response.

Parameters:
queryName server query
iobufI/O buffer
metaData transfer metadata
Return values:
rcReturn status code

Definition at line 106 of file fcns.c.

References fc_ct_header::code, fc_ns_reject_response::ct, fc_ns_response::ct, io_buffer::data, DBGC, done, fc_ns_query::done, EINVAL, ENOTSUP, fc_ct_header::explanation, FC_GS_ACCEPT, FC_GS_REJECT, fc_id_ntoa(), fc_ns_query_close(), fc_ntoa(), free_iob(), fc_ns_response::gid_pn, iob_len(), fc_port::name, ntohs, fc_ns_query::peer, fc_ns_query::port, fc_ns_port_id::port_id, fc_ns_gid_pn_response::port_id, fc_peer::port_wwn, rc, fc_ct_header::reason, and fc_ns_response::reject.

                                                                       {
        union fc_ns_response *resp = iobuf->data;
        struct fc_port_id *peer_port_id;
        int rc;

        /* Sanity check */
        if ( iob_len ( iobuf ) < sizeof ( resp->ct ) ) {
                DBGC ( query, "FCNS %p received underlength response (%zd "
                       "bytes)\n", query, iob_len ( iobuf ) );
                rc = -EINVAL;
                goto done;
        }

        /* Handle response */
        switch ( ntohs ( resp->ct.code ) ) {
        case FC_GS_ACCEPT:
                if ( iob_len ( iobuf ) < sizeof ( resp->gid_pn ) ) {
                        DBGC ( query, "FCNS %p received underlength accept "
                               "response (%zd bytes)\n",
                               query, iob_len ( iobuf ) );
                        rc = -EINVAL;
                        goto done;
                }
                peer_port_id = &resp->gid_pn.port_id.port_id;
                DBGC ( query, "FCNS %p resolved %s to %s via %s\n",
                       query, fc_ntoa ( &query->peer->port_wwn ),
                       fc_id_ntoa ( peer_port_id ), query->port->name );
                if ( ( rc = query->done ( query->peer, query->port,
                                          peer_port_id ) ) != 0 )
                        goto done;
                break;
        case FC_GS_REJECT:
                DBGC ( query, "FCNS %p rejected (reason %02x explanation "
                       "%02x)\n", query, resp->reject.ct.reason,
                       resp->reject.ct.explanation );
                break;
        default:
                DBGC ( query, "FCNS %p received invalid response code %04x\n",
                       query, ntohs ( resp->ct.code ) );
                rc = -ENOTSUP;
                goto done;
        }

        rc = 0;
 done:
        free_iob ( iobuf );
        fc_ns_query_close ( query, rc );
        return rc;
}
static void fc_ns_query_step ( struct fc_ns_query query) [static]

Name server query process.

Parameters:
queryName server query

Definition at line 163 of file fcns.c.

References fc_ct_header::code, fc_ns_gid_pn_request::ct, DBGC, FC_CT_REVISION, FC_DS_SUBTYPE_NAME, fc_gs_port_id, FC_GS_TYPE_DS, FC_NS_GET, FC_NS_PORT_ID, FC_NS_PORT_NAME, fc_ns_query_close(), FC_TYPE_CT, fc_xchg_originate(), xfer_metadata::flags, htons, memcpy(), memset(), fc_ns_query::peer, fc_ns_query::port, fc_ns_gid_pn_request::port_wwn, fc_peer::port_wwn, rc, fc_ct_header::revision, strerror(), fc_ct_header::subtype, fc_ct_header::type, fc_ns_query::xchg, xfer_deliver_raw_meta(), and XFER_FL_OVER.

                                                           {
        struct xfer_metadata meta;
        struct fc_ns_gid_pn_request gid_pn;
        int xchg_id;
        int rc;

        /* Create exchange */
        if ( ( xchg_id = fc_xchg_originate ( &query->xchg, query->port,
                                             &fc_gs_port_id,
                                             FC_TYPE_CT ) ) < 0 ) {
                rc = xchg_id;
                DBGC ( query, "FCNS %p could not create exchange: %s\n",
                       query, strerror ( rc ) );
                fc_ns_query_close ( query, rc );
                return;
        }

        /* Construct query request */
        memset ( &gid_pn, 0, sizeof ( gid_pn ) );
        gid_pn.ct.revision = FC_CT_REVISION;
        gid_pn.ct.type = FC_GS_TYPE_DS;
        gid_pn.ct.subtype = FC_DS_SUBTYPE_NAME;
        gid_pn.ct.code = htons ( FC_NS_GET ( FC_NS_PORT_NAME, FC_NS_PORT_ID ));
        memcpy ( &gid_pn.port_wwn, &query->peer->port_wwn,
                 sizeof ( gid_pn.port_wwn ) );
        memset ( &meta, 0, sizeof ( meta ) );
        meta.flags = XFER_FL_OVER;

        /* Send query */
        if ( ( rc = xfer_deliver_raw_meta ( &query->xchg, &gid_pn,
                                            sizeof ( gid_pn ), &meta ) ) != 0){
                DBGC ( query, "FCNS %p could not deliver query: %s\n",
                       query, strerror ( rc ) );
                fc_ns_query_close ( query, rc );
                return;
        }
}
int fc_ns_query ( struct fc_peer peer,
struct fc_port port,
int(*)(struct fc_peer *peer, struct fc_port *port, struct fc_port_id *peer_port_id)  done 
)

Issue Fibre Channel name server query.

Parameters:
peerFibre Channel peer
portFibre Channel port
Return values:
rcReturn status code

Definition at line 222 of file fcns.c.

References DBGC, done, fc_ns_query::done, ENOMEM, fc_ns_query_free(), fc_ntoa(), fc_peer_get(), fc_port_get(), intf_init(), fc_port::name, fc_ns_query::peer, fc_ns_query::port, fc_peer::port_wwn, fc_ns_query::process, process_init(), ref_init, ref_put, fc_ns_query::refcnt, fc_ns_query::xchg, and zalloc().

                                                                       {
        struct fc_ns_query *query;

        /* Allocate and initialise structure */
        query = zalloc ( sizeof ( *query ) );
        if ( ! query )
                return -ENOMEM;
        ref_init ( &query->refcnt, fc_ns_query_free );
        intf_init ( &query->xchg, &fc_ns_query_xchg_desc, &query->refcnt );
        process_init ( &query->process, &fc_ns_query_process_desc,
                       &query->refcnt );
        query->peer = fc_peer_get ( peer );
        query->port = fc_port_get ( port );
        query->done = done;

        DBGC ( query, "FCNS %p querying %s via %s\n",
               query, fc_ntoa ( &query->peer->port_wwn ), port->name );

        /* Mortalise self and return */
        ref_put ( &query->refcnt );
        return 0;
}

Variable Documentation

Initial value:

Name server exchange interface operations.

Definition at line 202 of file fcns.c.

Initial value:

Name server exchange interface descriptor.

Definition at line 208 of file fcns.c.

Initial value:

Name server process descriptor.

Definition at line 212 of file fcns.c.