"Fossies" - the Fresh Open Source Software Archive

Member "open-iscsi-2.1.0/usr/transport.c" (14 Nov 2019, 6353 Bytes) of package /linux/misc/open-iscsi-2.1.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "transport.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.0.876_vs_2.0.877.

    1 /*
    2  * iSCSI transport
    3  *
    4  * Copyright (C) 2006 Mike Christie
    5  * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published
    9  * by the Free Software Foundation; either version 2 of the License, or
   10  * (at your option) any later version.
   11  *
   12  * This program is distributed in the hope that it will be useful, but
   13  * WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15  * General Public License for more details.
   16  */
   17 #include <stdlib.h>
   18 #include <string.h>
   19 #include <stdio.h>
   20 #include <unistd.h>
   21 #include <errno.h>
   22 #include <libkmod.h>
   23 #include <net/if.h>
   24 #include <sys/ioctl.h>
   25 #include <sys/socket.h>
   26 #include <sys/types.h>
   27 #include <sys/wait.h>
   28 
   29 #include "sysdeps.h"
   30 #include "iscsi_err.h"
   31 #include "initiator.h"
   32 #include "transport.h"
   33 #include "log.h"
   34 #include "iscsi_util.h"
   35 #include "iscsi_sysfs.h"
   36 #include "uip_mgmt_ipc.h"
   37 #include "cxgbi.h"
   38 #include "be2iscsi.h"
   39 #include "iser.h"
   40 
   41 struct iscsi_transport_template iscsi_tcp = {
   42     .name       = "tcp",
   43     .ep_connect = iscsi_io_tcp_connect,
   44     .ep_poll    = iscsi_io_tcp_poll,
   45     .ep_disconnect  = iscsi_io_tcp_disconnect,
   46 };
   47 
   48 struct iscsi_transport_template iscsi_iser = {
   49     .name       = "iser",
   50     .rdma       = 1,
   51     .ep_connect = ktransport_ep_connect,
   52     .ep_poll    = ktransport_ep_poll,
   53     .ep_disconnect  = ktransport_ep_disconnect,
   54     .create_conn    = iser_create_conn,
   55 };
   56 
   57 struct iscsi_transport_template cxgb3i = {
   58     .name       = "cxgb3i",
   59     .set_host_ip    = SET_HOST_IP_OPT,
   60         .bind_ep_required = 1,
   61     .ep_connect = ktransport_ep_connect,
   62     .ep_poll    = ktransport_ep_poll,
   63     .ep_disconnect  = ktransport_ep_disconnect,
   64     .create_conn    = cxgbi_create_conn,
   65 };
   66 
   67 struct iscsi_transport_template cxgb4i = {
   68     .name       = "cxgb4i",
   69     .set_host_ip    = SET_HOST_IP_NOT_REQ,
   70         .bind_ep_required = 1,
   71     .ep_connect = ktransport_ep_connect,
   72     .ep_poll    = ktransport_ep_poll,
   73     .ep_disconnect  = ktransport_ep_disconnect,
   74     .create_conn    = cxgbi_create_conn,
   75 };
   76 
   77 struct iscsi_transport_template bnx2i = {
   78     .name       = "bnx2i",
   79     .set_host_ip    = SET_HOST_IP_REQ,
   80     .use_boot_info  = 1,
   81         .bind_ep_required = 1,
   82     .ep_connect = ktransport_ep_connect,
   83     .ep_poll    = ktransport_ep_poll,
   84     .ep_disconnect  = ktransport_ep_disconnect,
   85     .set_net_config = uip_broadcast_params,
   86     .exec_ping  = uip_broadcast_ping_req,
   87 };
   88 
   89 struct iscsi_transport_template be2iscsi = {
   90     .name       = "be2iscsi",
   91         .bind_ep_required = 1,
   92     .sync_vlan_settings = 1,
   93     .create_conn    = be2iscsi_create_conn,
   94     .ep_connect = ktransport_ep_connect,
   95     .ep_poll    = ktransport_ep_poll,
   96     .ep_disconnect  = ktransport_ep_disconnect,
   97 };
   98 
   99 struct iscsi_transport_template qla4xxx = {
  100     .name       = "qla4xxx",
  101     .set_host_ip    = SET_HOST_IP_NOT_REQ,
  102         .bind_ep_required = 1,
  103     .ep_connect = ktransport_ep_connect,
  104     .ep_poll    = ktransport_ep_poll,
  105     .ep_disconnect  = ktransport_ep_disconnect,
  106 };
  107 
  108 struct iscsi_transport_template ocs = {
  109     .name       = "ocs",
  110         .bind_ep_required = 1,
  111     .ep_connect = ktransport_ep_connect,
  112     .ep_poll    = ktransport_ep_poll,
  113     .ep_disconnect  = ktransport_ep_disconnect,
  114 };
  115 
  116 struct iscsi_transport_template qedi = {
  117     .name       = "qedi",
  118     .set_host_ip    = SET_HOST_IP_REQ,
  119     .use_boot_info  = 1,
  120     .bind_ep_required = 1,
  121     .no_netdev = 1,
  122     .ep_connect = ktransport_ep_connect,
  123     .ep_poll    = ktransport_ep_poll,
  124     .ep_disconnect  = ktransport_ep_disconnect,
  125     .set_net_config = uip_broadcast_params,
  126     .exec_ping  = uip_broadcast_ping_req,
  127 };
  128 
  129 static struct iscsi_transport_template *iscsi_transport_templates[] = {
  130     &iscsi_tcp,
  131     &iscsi_iser,
  132     &cxgb3i,
  133     &cxgb4i,
  134     &bnx2i,
  135     &qla4xxx,
  136     &be2iscsi,
  137     &ocs,
  138     &qedi,
  139     NULL
  140 };
  141 
  142 int transport_probe_for_offload(void)
  143 {
  144     struct if_nameindex *ifni;
  145     char transport_name[ISCSI_TRANSPORT_NAME_MAXLEN];
  146     int i, sockfd;
  147     struct ifreq if_hwaddr;
  148 
  149     ifni = if_nameindex();
  150     if (!ifni) {
  151         log_error("Could not search for transport modules: %s",
  152               strerror(errno));
  153         return ISCSI_ERR_TRANS_NOT_FOUND;
  154     }
  155 
  156     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  157     if (sockfd < 0) {
  158         log_error("Could not open socket for ioctl: %s",
  159               strerror(errno));
  160         goto free_ifni;
  161     }
  162 
  163     for (i = 0; ifni[i].if_index && ifni[i].if_name; i++) {
  164         struct if_nameindex *n = &ifni[i];
  165 
  166         log_debug(6, "kmod probe found %s", n->if_name);
  167 
  168         strlcpy(if_hwaddr.ifr_name, n->if_name, IFNAMSIZ);
  169         if (ioctl(sockfd, SIOCGIFHWADDR, &if_hwaddr) < 0)
  170             continue;
  171 
  172         /* check for ARPHRD_ETHER (ethernet) */
  173         if (if_hwaddr.ifr_hwaddr.sa_family != 1)
  174             continue;
  175 
  176         if (net_get_transport_name_from_netdev(n->if_name,
  177                                transport_name))
  178             continue;
  179 
  180         transport_load_kmod(transport_name);
  181     }
  182     close(sockfd);
  183 
  184 free_ifni:
  185     if_freenameindex(ifni);
  186     return 0;
  187 }
  188 
  189 /*
  190  * Most distros still do not have wide libkmod use, so
  191  * use modprobe for now
  192  */
  193 int transport_load_kmod(char *transport_name)
  194 {
  195     struct kmod_ctx *ctx;
  196     struct kmod_module *mod;
  197     int rc;
  198 
  199     ctx = kmod_new(NULL, NULL);
  200     if (!ctx) {
  201         log_error("Could not load transport module %s. Out of "
  202               "memory.", transport_name);
  203         return ISCSI_ERR_NOMEM;
  204     }
  205 
  206     kmod_load_resources(ctx);
  207 
  208     /*
  209      * dumb dumb dumb - named iscsi_tcp and ib_iser differently from
  210      * transport name
  211      */
  212     if (!strcmp(transport_name, "tcp"))
  213         rc = kmod_module_new_from_name(ctx, "iscsi_tcp", &mod);
  214     else if (!strcmp(transport_name, "iser"))
  215         rc = kmod_module_new_from_name(ctx, "ib_iser", &mod);
  216     else
  217         rc = kmod_module_new_from_name(ctx, transport_name, &mod);
  218     if (rc) {
  219         log_error("Failed to load module %s.", transport_name);
  220         rc = ISCSI_ERR_TRANS_NOT_FOUND;
  221         goto unref_mod;
  222     }
  223 
  224     rc = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST,
  225                          NULL, NULL, NULL, NULL);
  226     if (rc) {
  227         log_error("Could not insert module %s. Kmod error %d",
  228               transport_name, rc);
  229         rc = ISCSI_ERR_TRANS_NOT_FOUND;
  230     }
  231     kmod_module_unref(mod);
  232 
  233 unref_mod:
  234     kmod_unref(ctx);
  235     return rc;
  236 }
  237 
  238 int set_transport_template(struct iscsi_transport *t)
  239 {
  240     struct iscsi_transport_template *tmpl;
  241     int j;
  242 
  243     for (j = 0; iscsi_transport_templates[j] != NULL; j++) {
  244         tmpl = iscsi_transport_templates[j];
  245 
  246         if (!strcmp(tmpl->name, t->name)) {
  247             t->template = tmpl;
  248             log_debug(3, "Matched transport %s", t->name);
  249             return 0;
  250         }
  251     }
  252 
  253     log_error("Could not find template for %s. An updated iscsiadm "
  254           "is probably needed.", t->name);
  255     return ENOSYS;
  256 }