tcp_offload.c revision 182591
1/*-
2 * Copyright (c) 2007, Chelsio Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 *    this list of conditions and the following disclaimer.
10 *
11 * 2. Neither the name of the Chelsio Corporation nor the names of its
12 *    contributors may be used to endorse or promote products derived from
13 *    this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/netinet/tcp_offload.c 182591 2008-09-01 05:30:22Z kmacy $");
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/types.h>
34#include <sys/malloc.h>
35#include <sys/kernel.h>
36#include <sys/sysctl.h>
37#include <sys/mbuf.h>
38#include <sys/socket.h>
39#include <sys/socketvar.h>
40#include <sys/vimage.h>
41
42#include <net/if.h>
43#include <net/if_types.h>
44#include <net/if_var.h>
45
46#include <netinet/in.h>
47#include <netinet/in_systm.h>
48#include <netinet/in_pcb.h>
49#include <netinet/tcp.h>
50#include <netinet/tcp_var.h>
51#include <netinet/tcp_offload.h>
52#include <netinet/toedev.h>
53
54uint32_t toedev_registration_count;
55
56int
57tcp_offload_connect(struct socket *so, struct sockaddr *nam)
58{
59	struct ifnet *ifp;
60	struct toedev *tdev;
61	struct rtentry *rt;
62	int error;
63
64	if (toedev_registration_count == 0)
65		return (EINVAL);
66
67	/*
68	 * Look up the route used for the connection to
69	 * determine if it uses an interface capable of
70	 * offloading the connection.
71	 */
72	rt = rtalloc1(nam, 0 /*report*/, 0 /*ignflags*/);
73	if (rt)
74		RT_UNLOCK(rt);
75	else
76		return (EHOSTUNREACH);
77
78	ifp = rt->rt_ifp;
79	if ((ifp->if_capenable & IFCAP_TOE) == 0) {
80		error = EINVAL;
81		goto fail;
82	}
83
84	tdev = TOEDEV(ifp);
85	if (tdev == NULL) {
86		error = EPERM;
87		goto fail;
88	}
89
90	if (tdev->tod_can_offload(tdev, so) == 0) {
91		error = EPERM;
92		goto fail;
93	}
94
95	return (tdev->tod_connect(tdev, so, rt, nam));
96fail:
97	RTFREE(rt);
98	return (error);
99}
100
101
102/*
103 * This file contains code as a short-term staging area before it is moved in
104 * to sys/netinet/tcp_offload.c
105 */
106
107void
108tcp_offload_twstart(struct tcpcb *tp)
109{
110
111	INP_INFO_WLOCK(&V_tcbinfo);
112	INP_WLOCK(tp->t_inpcb);
113	tcp_twstart(tp);
114	INP_INFO_WUNLOCK(&V_tcbinfo);
115}
116
117struct tcpcb *
118tcp_offload_close(struct tcpcb *tp)
119{
120
121	INP_INFO_WLOCK(&V_tcbinfo);
122	INP_WLOCK(tp->t_inpcb);
123	tp = tcp_close(tp);
124	INP_INFO_WUNLOCK(&V_tcbinfo);
125	if (tp)
126		INP_WUNLOCK(tp->t_inpcb);
127
128	return (tp);
129}
130
131struct tcpcb *
132tcp_offload_drop(struct tcpcb *tp, int error)
133{
134
135	INP_INFO_WLOCK(&V_tcbinfo);
136	INP_WLOCK(tp->t_inpcb);
137	tp = tcp_drop(tp, error);
138	INP_INFO_WUNLOCK(&V_tcbinfo);
139	if (tp)
140		INP_WUNLOCK(tp->t_inpcb);
141
142	return (tp);
143}
144
145