The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/cxgbe/tom/t4_connect.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2012 Chelsio Communications, Inc.
    5  * All rights reserved.
    6  * Written by: Navdeep Parhar <np@FreeBSD.org>
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include "opt_inet.h"
   34 #include "opt_inet6.h"
   35 
   36 #ifdef TCP_OFFLOAD
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/kernel.h>
   40 #include <sys/ktr.h>
   41 #include <sys/module.h>
   42 #include <sys/protosw.h>
   43 #include <sys/domain.h>
   44 #include <sys/socket.h>
   45 #include <sys/socketvar.h>
   46 #include <sys/sysctl.h>
   47 #include <net/ethernet.h>
   48 #include <net/if.h>
   49 #include <net/if_types.h>
   50 #include <net/if_vlan_var.h>
   51 #include <net/route.h>
   52 #include <net/route/nhop.h>
   53 #include <netinet/in.h>
   54 #include <netinet/in_pcb.h>
   55 #include <netinet/ip.h>
   56 #define TCPSTATES
   57 #include <netinet/tcp_fsm.h>
   58 #include <netinet/tcp_var.h>
   59 #include <netinet/toecore.h>
   60 #include <netinet/cc/cc.h>
   61 
   62 #include "common/common.h"
   63 #include "common/t4_msg.h"
   64 #include "common/t4_regs.h"
   65 #include "common/t4_regs_values.h"
   66 #include "t4_clip.h"
   67 #include "tom/t4_tom_l2t.h"
   68 #include "tom/t4_tom.h"
   69 
   70 /*
   71  * Active open succeeded.
   72  */
   73 static int
   74 do_act_establish(struct sge_iq *iq, const struct rss_header *rss,
   75     struct mbuf *m)
   76 {
   77         struct adapter *sc = iq->adapter;
   78         const struct cpl_act_establish *cpl = (const void *)(rss + 1);
   79         u_int tid = GET_TID(cpl);
   80         u_int atid = G_TID_TID(ntohl(cpl->tos_atid));
   81         struct toepcb *toep = lookup_atid(sc, atid);
   82         struct inpcb *inp = toep->inp;
   83 
   84         KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
   85         KASSERT(toep->tid == atid, ("%s: toep tid/atid mismatch", __func__));
   86 
   87         CTR3(KTR_CXGBE, "%s: atid %u, tid %u", __func__, atid, tid);
   88         free_atid(sc, atid);
   89 
   90         CURVNET_SET(toep->vnet);
   91         INP_WLOCK(inp);
   92         toep->tid = tid;
   93         insert_tid(sc, tid, toep, inp->inp_vflag & INP_IPV6 ? 2 : 1);
   94         if (inp->inp_flags & INP_DROPPED) {
   95 
   96                 /* socket closed by the kernel before hw told us it connected */
   97 
   98                 send_flowc_wr(toep, NULL);
   99                 send_reset(sc, toep, be32toh(cpl->snd_isn));
  100                 goto done;
  101         }
  102 
  103         make_established(toep, be32toh(cpl->snd_isn) - 1,
  104             be32toh(cpl->rcv_isn) - 1, cpl->tcp_opt);
  105         inp->inp_flowtype = M_HASHTYPE_OPAQUE;
  106         inp->inp_flowid = tid;
  107 
  108 done:
  109         INP_WUNLOCK(inp);
  110         CURVNET_RESTORE();
  111         return (0);
  112 }
  113 
  114 void
  115 act_open_failure_cleanup(struct adapter *sc, u_int atid, u_int status)
  116 {
  117         struct toepcb *toep = lookup_atid(sc, atid);
  118         struct inpcb *inp = toep->inp;
  119         struct toedev *tod = &toep->td->tod;
  120         struct epoch_tracker et;
  121 
  122         free_atid(sc, atid);
  123         toep->tid = -1;
  124 
  125         CURVNET_SET(toep->vnet);
  126         if (status != EAGAIN)
  127                 NET_EPOCH_ENTER(et);
  128         INP_WLOCK(inp);
  129         toe_connect_failed(tod, inp, status);
  130         final_cpl_received(toep);       /* unlocks inp */
  131         if (status != EAGAIN)
  132                 NET_EPOCH_EXIT(et);
  133         CURVNET_RESTORE();
  134 }
  135 
  136 /*
  137  * Active open failed.
  138  */
  139 static int
  140 do_act_open_rpl(struct sge_iq *iq, const struct rss_header *rss,
  141     struct mbuf *m)
  142 {
  143         struct adapter *sc = iq->adapter;
  144         const struct cpl_act_open_rpl *cpl = (const void *)(rss + 1);
  145         u_int atid = G_TID_TID(G_AOPEN_ATID(be32toh(cpl->atid_status)));
  146         u_int status = G_AOPEN_STATUS(be32toh(cpl->atid_status));
  147         struct toepcb *toep = lookup_atid(sc, atid);
  148         int rc;
  149 
  150         KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
  151         KASSERT(toep->tid == atid, ("%s: toep tid/atid mismatch", __func__));
  152 
  153         CTR3(KTR_CXGBE, "%s: atid %u, status %u ", __func__, atid, status);
  154 
  155         /* Ignore negative advice */
  156         if (negative_advice(status))
  157                 return (0);
  158 
  159         if (status && act_open_has_tid(status))
  160                 release_tid(sc, GET_TID(cpl), toep->ctrlq);
  161 
  162         rc = act_open_rpl_status_to_errno(status);
  163         act_open_failure_cleanup(sc, atid, rc);
  164 
  165         return (0);
  166 }
  167 
  168 void
  169 t4_init_connect_cpl_handlers(void)
  170 {
  171 
  172         t4_register_cpl_handler(CPL_ACT_ESTABLISH, do_act_establish);
  173         t4_register_shared_cpl_handler(CPL_ACT_OPEN_RPL, do_act_open_rpl,
  174             CPL_COOKIE_TOM);
  175 }
  176 
  177 void
  178 t4_uninit_connect_cpl_handlers(void)
  179 {
  180 
  181         t4_register_cpl_handler(CPL_ACT_ESTABLISH, NULL);
  182         t4_register_shared_cpl_handler(CPL_ACT_OPEN_RPL, NULL, CPL_COOKIE_TOM);
  183 }
  184 
  185 #ifdef KTR
  186 #define DONT_OFFLOAD_ACTIVE_OPEN(x)     do { \
  187         reason = __LINE__; \
  188         rc = (x); \
  189         goto failed; \
  190 } while (0)
  191 #else
  192 #define DONT_OFFLOAD_ACTIVE_OPEN(x)     do { \
  193         rc = (x); \
  194         goto failed; \
  195 } while (0)
  196 #endif
  197 
  198 static inline int
  199 act_open_cpl_size(struct adapter *sc, int isipv6)
  200 {
  201         int idx;
  202         static const int sz_table[3][2] = {
  203                 {
  204                         sizeof (struct cpl_act_open_req),
  205                         sizeof (struct cpl_act_open_req6)
  206                 },
  207                 {
  208                         sizeof (struct cpl_t5_act_open_req),
  209                         sizeof (struct cpl_t5_act_open_req6)
  210                 },
  211                 {
  212                         sizeof (struct cpl_t6_act_open_req),
  213                         sizeof (struct cpl_t6_act_open_req6)
  214                 },
  215         };
  216 
  217         MPASS(chip_id(sc) >= CHELSIO_T4);
  218         idx = min(chip_id(sc) - CHELSIO_T4, 2);
  219 
  220         return (sz_table[idx][!!isipv6]);
  221 }
  222 
  223 /*
  224  * active open (soconnect).
  225  *
  226  * State of affairs on entry:
  227  * soisconnecting (so_state |= SS_ISCONNECTING)
  228  * tcbinfo not locked (This has changed - used to be WLOCKed)
  229  * inp WLOCKed
  230  * tp->t_state = TCPS_SYN_SENT
  231  * rtalloc1, RT_UNLOCK on rt.
  232  */
  233 int
  234 t4_connect(struct toedev *tod, struct socket *so, struct nhop_object *nh,
  235     struct sockaddr *nam)
  236 {
  237         struct adapter *sc = tod->tod_softc;
  238         struct toepcb *toep = NULL;
  239         struct wrqe *wr = NULL;
  240         struct ifnet *rt_ifp = nh->nh_ifp;
  241         struct vi_info *vi;
  242         int qid_atid, rc, isipv6;
  243         struct inpcb *inp = sotoinpcb(so);
  244         struct tcpcb *tp = intotcpcb(inp);
  245 #ifdef KTR
  246         int reason;
  247 #endif
  248         struct offload_settings settings;
  249         struct epoch_tracker et;
  250         uint16_t vid = 0xfff, pcp = 0;
  251 
  252         INP_WLOCK_ASSERT(inp);
  253         KASSERT(nam->sa_family == AF_INET || nam->sa_family == AF_INET6,
  254             ("%s: dest addr %p has family %u", __func__, nam, nam->sa_family));
  255 
  256         if (rt_ifp->if_type == IFT_ETHER)
  257                 vi = rt_ifp->if_softc;
  258         else if (rt_ifp->if_type == IFT_L2VLAN) {
  259                 struct ifnet *ifp = VLAN_TRUNKDEV(rt_ifp);
  260 
  261                 vi = ifp->if_softc;
  262                 VLAN_TAG(rt_ifp, &vid);
  263                 VLAN_PCP(rt_ifp, &pcp);
  264         } else if (rt_ifp->if_type == IFT_IEEE8023ADLAG)
  265                 DONT_OFFLOAD_ACTIVE_OPEN(ENOSYS); /* XXX: implement lagg+TOE */
  266         else
  267                 DONT_OFFLOAD_ACTIVE_OPEN(ENOTSUP);
  268         if (sc->flags & KERN_TLS_ON)
  269                 DONT_OFFLOAD_ACTIVE_OPEN(ENOTSUP);
  270 
  271         rw_rlock(&sc->policy_lock);
  272         settings = *lookup_offload_policy(sc, OPEN_TYPE_ACTIVE, NULL,
  273             EVL_MAKETAG(vid, pcp, 0), inp);
  274         rw_runlock(&sc->policy_lock);
  275         if (!settings.offload)
  276                 DONT_OFFLOAD_ACTIVE_OPEN(EPERM);
  277 
  278         toep = alloc_toepcb(vi, M_NOWAIT);
  279         if (toep == NULL)
  280                 DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM);
  281 
  282         toep->tid = alloc_atid(sc, toep);
  283         if (toep->tid < 0)
  284                 DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM);
  285 
  286         toep->l2te = t4_l2t_get(vi->pi, rt_ifp,
  287             nh->nh_flags & NHF_GATEWAY ? &nh->gw_sa : nam);
  288         if (toep->l2te == NULL)
  289                 DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM);
  290 
  291         toep->vnet = so->so_vnet;
  292         init_conn_params(vi, &settings, &inp->inp_inc, so, NULL,
  293             toep->l2te->idx, &toep->params);
  294         init_toepcb(vi, toep);
  295 
  296         isipv6 = nam->sa_family == AF_INET6;
  297         wr = alloc_wrqe(act_open_cpl_size(sc, isipv6), toep->ctrlq);
  298         if (wr == NULL)
  299                 DONT_OFFLOAD_ACTIVE_OPEN(ENOMEM);
  300 
  301         qid_atid = V_TID_QID(toep->ofld_rxq->iq.abs_id) | V_TID_TID(toep->tid) |
  302             V_TID_COOKIE(CPL_COOKIE_TOM);
  303 
  304         if (isipv6) {
  305                 struct cpl_act_open_req6 *cpl = wrtod(wr);
  306                 struct cpl_t5_act_open_req6 *cpl5 = (void *)cpl;
  307                 struct cpl_t6_act_open_req6 *cpl6 = (void *)cpl;
  308 
  309                 if ((inp->inp_vflag & INP_IPV6) == 0)
  310                         DONT_OFFLOAD_ACTIVE_OPEN(ENOTSUP);
  311 
  312                 toep->ce = t4_get_clip_entry(sc, &inp->in6p_laddr, true);
  313                 if (toep->ce == NULL)
  314                         DONT_OFFLOAD_ACTIVE_OPEN(ENOENT);
  315 
  316                 switch (chip_id(sc)) {
  317                 case CHELSIO_T4:
  318                         INIT_TP_WR(cpl, 0);
  319                         cpl->params = select_ntuple(vi, toep->l2te);
  320                         break;
  321                 case CHELSIO_T5:
  322                         INIT_TP_WR(cpl5, 0);
  323                         cpl5->iss = htobe32(tp->iss);
  324                         cpl5->params = select_ntuple(vi, toep->l2te);
  325                         break;
  326                 case CHELSIO_T6:
  327                 default:
  328                         INIT_TP_WR(cpl6, 0);
  329                         cpl6->iss = htobe32(tp->iss);
  330                         cpl6->params = select_ntuple(vi, toep->l2te);
  331                         break;
  332                 }
  333                 OPCODE_TID(cpl) = htobe32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
  334                     qid_atid));
  335                 cpl->local_port = inp->inp_lport;
  336                 cpl->local_ip_hi = *(uint64_t *)&inp->in6p_laddr.s6_addr[0];
  337                 cpl->local_ip_lo = *(uint64_t *)&inp->in6p_laddr.s6_addr[8];
  338                 cpl->peer_port = inp->inp_fport;
  339                 cpl->peer_ip_hi = *(uint64_t *)&inp->in6p_faddr.s6_addr[0];
  340                 cpl->peer_ip_lo = *(uint64_t *)&inp->in6p_faddr.s6_addr[8];
  341                 cpl->opt0 = calc_options0(vi, &toep->params);
  342                 cpl->opt2 = calc_options2(vi, &toep->params);
  343 
  344                 CTR6(KTR_CXGBE,
  345                     "%s: atid %u, toep %p, inp %p, opt0 %#016lx, opt2 %#08x",
  346                     __func__, toep->tid, toep, inp, be64toh(cpl->opt0),
  347                     be32toh(cpl->opt2));
  348         } else {
  349                 struct cpl_act_open_req *cpl = wrtod(wr);
  350                 struct cpl_t5_act_open_req *cpl5 = (void *)cpl;
  351                 struct cpl_t6_act_open_req *cpl6 = (void *)cpl;
  352 
  353                 switch (chip_id(sc)) {
  354                 case CHELSIO_T4:
  355                         INIT_TP_WR(cpl, 0);
  356                         cpl->params = select_ntuple(vi, toep->l2te);
  357                         break;
  358                 case CHELSIO_T5:
  359                         INIT_TP_WR(cpl5, 0);
  360                         cpl5->iss = htobe32(tp->iss);
  361                         cpl5->params = select_ntuple(vi, toep->l2te);
  362                         break;
  363                 case CHELSIO_T6:
  364                 default:
  365                         INIT_TP_WR(cpl6, 0);
  366                         cpl6->iss = htobe32(tp->iss);
  367                         cpl6->params = select_ntuple(vi, toep->l2te);
  368                         break;
  369                 }
  370                 OPCODE_TID(cpl) = htobe32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
  371                     qid_atid));
  372                 inp_4tuple_get(inp, &cpl->local_ip, &cpl->local_port,
  373                     &cpl->peer_ip, &cpl->peer_port);
  374                 cpl->opt0 = calc_options0(vi, &toep->params);
  375                 cpl->opt2 = calc_options2(vi, &toep->params);
  376 
  377                 CTR6(KTR_CXGBE,
  378                     "%s: atid %u, toep %p, inp %p, opt0 %#016lx, opt2 %#08x",
  379                     __func__, toep->tid, toep, inp, be64toh(cpl->opt0),
  380                     be32toh(cpl->opt2));
  381         }
  382 
  383         offload_socket(so, toep);
  384         NET_EPOCH_ENTER(et);
  385         rc = t4_l2t_send(sc, wr, toep->l2te);
  386         NET_EPOCH_EXIT(et);
  387         if (rc == 0) {
  388                 toep->flags |= TPF_CPL_PENDING;
  389                 return (0);
  390         }
  391 
  392         undo_offload_socket(so);
  393 #if defined(KTR)
  394         reason = __LINE__;
  395 #endif
  396 failed:
  397         CTR3(KTR_CXGBE, "%s: not offloading (%d), rc %d", __func__, reason, rc);
  398 
  399         if (wr)
  400                 free_wrqe(wr);
  401 
  402         if (toep) {
  403                 if (toep->tid >= 0)
  404                         free_atid(sc, toep->tid);
  405                 if (toep->l2te)
  406                         t4_l2t_release(toep->l2te);
  407                 if (toep->ce)
  408                         t4_release_clip_entry(sc, toep->ce);
  409                 free_toepcb(toep);
  410         }
  411 
  412         return (rc);
  413 }
  414 #endif

Cache object: 8c04fad56bf2545a9782eadffb5955f4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.