tcp_offload.c revision 180674
1194676Sthompsa/*- 2194676Sthompsa * Copyright (c) 2007, Chelsio Inc. 3194676Sthompsa * All rights reserved. 4195957Salfred * 5194676Sthompsa * Redistribution and use in source and binary forms, with or without 6194676Sthompsa * modification, are permitted provided that the following conditions are met: 7194676Sthompsa * 8194676Sthompsa * 1. Redistributions of source code must retain the above copyright notice, 9194676Sthompsa * this list of conditions and the following disclaimer. 10194676Sthompsa * 11194676Sthompsa * 2. Neither the name of the Chelsio Corporation nor the names of its 12194676Sthompsa * contributors may be used to endorse or promote products derived from 13194676Sthompsa * this software without specific prior written permission. 14194676Sthompsa * 15194676Sthompsa * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16194676Sthompsa * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17194676Sthompsa * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18194676Sthompsa * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19194676Sthompsa * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20194676Sthompsa * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21194676Sthompsa * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22194676Sthompsa * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23194676Sthompsa * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24194676Sthompsa * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25194676Sthompsa * POSSIBILITY OF SUCH DAMAGE. 26194676Sthompsa */ 27194676Sthompsa 28194676Sthompsa#include <sys/cdefs.h> 29194676Sthompsa__FBSDID("$FreeBSD: head/sys/netinet/tcp_offload.c 180674 2008-07-21 21:22:56Z kmacy $"); 30194676Sthompsa 31194676Sthompsa#include <sys/param.h> 32194676Sthompsa#include <sys/systm.h> 33194676Sthompsa#include <sys/types.h> 34194676Sthompsa#include <sys/malloc.h> 35195957Salfred#include <sys/kernel.h> 36195957Salfred#include <sys/sysctl.h> 37195957Salfred#include <sys/mbuf.h> 38199055Sthompsa#include <sys/socket.h> 39194676Sthompsa#include <sys/socketvar.h> 40194676Sthompsa 41194676Sthompsa#include <net/if.h> 42194676Sthompsa#include <net/if_types.h> 43194676Sthompsa#include <net/if_var.h> 44194676Sthompsa 45194676Sthompsa#include <netinet/in.h> 46194676Sthompsa#include <netinet/in_systm.h> 47194676Sthompsa#include <netinet/in_pcb.h> 48194676Sthompsa#include <netinet/tcp.h> 49195957Salfred#include <netinet/tcp_var.h> 50195957Salfred#include <netinet/tcp_offload.h> 51195957Salfred#include <netinet/toedev.h> 52195957Salfred 53195957Salfredint 54195957Salfredtcp_offload_connect(struct socket *so, struct sockaddr *nam) 55195957Salfred{ 56195957Salfred struct ifnet *ifp; 57195957Salfred struct toedev *tdev; 58195957Salfred struct rtentry *rt; 59195957Salfred int error; 60195957Salfred 61194676Sthompsa /* 62194676Sthompsa * Look up the route used for the connection to 63194676Sthompsa * determine if it uses an interface capable of 64195957Salfred * offloading the connection. 65194676Sthompsa */ 66195957Salfred rt = rtalloc1(nam, 1 /*report*/, 0 /*ignflags*/); 67194676Sthompsa if (rt) 68194676Sthompsa RT_UNLOCK(rt); 69194676Sthompsa else 70194676Sthompsa return (EHOSTUNREACH); 71194676Sthompsa 72195957Salfred ifp = rt->rt_ifp; 73194676Sthompsa if ((ifp->if_capenable & IFCAP_TOE) == 0) { 74194676Sthompsa error = EINVAL; 75195957Salfred goto fail; 76194676Sthompsa } 77194676Sthompsa 78194676Sthompsa tdev = TOEDEV(ifp); 79194676Sthompsa if (tdev == NULL) { 80194676Sthompsa error = EPERM; 81194676Sthompsa goto fail; 82194676Sthompsa } 83194676Sthompsa 84194676Sthompsa if (tdev->tod_can_offload(tdev, so) == 0) { 85194676Sthompsa error = EPERM; 86194676Sthompsa goto fail; 87194676Sthompsa } 88194676Sthompsa 89194676Sthompsa return (tdev->tod_connect(tdev, so, rt, nam)); 90195957Salfredfail: 91195957Salfred RTFREE(rt); 92194676Sthompsa return (error); 93195957Salfred} 94195957Salfred 95194676Sthompsa 96195957Salfred/* 97194676Sthompsa * This file contains code as a short-term staging area before it is moved in 98194676Sthompsa * to sys/netinet/tcp_offload.c 99194676Sthompsa */ 100195957Salfred 101195957Salfredvoid 102194676Sthompsatcp_offload_twstart(struct tcpcb *tp) 103194676Sthompsa{ 104194676Sthompsa 105195957Salfred INP_INFO_WLOCK(&tcbinfo); 106195957Salfred INP_WLOCK(tp->t_inpcb); 107195957Salfred tcp_twstart(tp); 108195957Salfred INP_INFO_WUNLOCK(&tcbinfo); 109195957Salfred} 110194676Sthompsa 111195957Salfredstruct tcpcb * 112194676Sthompsatcp_offload_close(struct tcpcb *tp) 113194676Sthompsa{ 114194676Sthompsa 115194676Sthompsa INP_INFO_WLOCK(&tcbinfo); 116194676Sthompsa INP_WLOCK(tp->t_inpcb); 117194676Sthompsa tp = tcp_close(tp); 118194676Sthompsa INP_INFO_WUNLOCK(&tcbinfo); 119194676Sthompsa if (tp) 120194676Sthompsa INP_WUNLOCK(tp->t_inpcb); 121194676Sthompsa 122195957Salfred return (tp); 123195957Salfred} 124194676Sthompsa 125194676Sthompsastruct tcpcb * 126194676Sthompsatcp_offload_drop(struct tcpcb *tp, int error) 127194676Sthompsa{ 128195957Salfred 129194676Sthompsa INP_INFO_WLOCK(&tcbinfo); 130195957Salfred INP_WLOCK(tp->t_inpcb); 131194676Sthompsa tp = tcp_drop(tp, error); 132195957Salfred INP_INFO_WUNLOCK(&tcbinfo); 133195957Salfred if (tp) 134195957Salfred INP_WUNLOCK(tp->t_inpcb); 135195957Salfred 136195957Salfred return (tp); 137195957Salfred} 138194676Sthompsa 139194676Sthompsa