aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/tcp_offload.c (renamed from sys/netinet/tcp_ofld.c)100
-rw-r--r--sys/netinet/tcp_offload.h328
-rw-r--r--sys/netinet/tcp_ofld.h203
-rw-r--r--sys/netinet/tcp_syncache.c36
4 files changed, 386 insertions, 281 deletions
diff --git a/sys/netinet/tcp_ofld.c b/sys/netinet/tcp_offload.c
index e6d9c0a05a0b..b7eb1593b57f 100644
--- a/sys/netinet/tcp_ofld.c
+++ b/sys/netinet/tcp_offload.c
@@ -47,82 +47,54 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_pcb.h>
#include <netinet/tcp.h>
#include <netinet/tcp_var.h>
-#include <netinet/tcp_ofld.h>
+#include <netinet/tcp_offload.h>
#include <netinet/toedev.h>
+
int
-ofld_connect(struct socket *so, struct sockaddr *nam)
+tcp_offload_connect(struct socket *so, struct sockaddr *nam)
{
struct ifnet *ifp;
struct toedev *tdev;
struct rtentry *rt;
int error;
- rt = rtalloc1(nam, 1, 0);
- if (rt)
+ /*
+ * Look up the route used for the connection to
+ * determine if it uses an interface capable of
+ * offloading the connection.
+ */
+ rt = rtalloc1(nam, 1 /*report*/, 0 /*ignflags*/);
+ if (rt)
RT_UNLOCK(rt);
- else
+ else
return (EHOSTUNREACH);
ifp = rt->rt_ifp;
+ if ((ifp->if_capenable & IFCAP_TOE) == 0) {
+ printf("no toe capability on %p\n", ifp);
+
+ error = EINVAL;
+ goto fail;
+ }
+
tdev = TOEDEV(ifp);
- if (tdev == NULL)
- return (EINVAL);
-
- if (tdev->tod_can_offload(tdev, so) == 0)
- return (EINVAL);
-
- if ((error = tdev->tod_connect(tdev, so, rt, nam)))
- return (error);
-
- return (0);
-}
-
-int
-ofld_send(struct tcpcb *tp)
-{
-
- return (tp->t_tu->tu_send(tp));
-}
-
-int
-ofld_rcvd(struct tcpcb *tp)
-{
-
- return (tp->t_tu->tu_rcvd(tp));
-}
-
-int
-ofld_disconnect(struct tcpcb *tp)
-{
-
- return (tp->t_tu->tu_disconnect(tp));
-}
-
-int
-ofld_abort(struct tcpcb *tp)
-{
-
- return (tp->t_tu->tu_abort(tp));
-}
-
-void
-ofld_detach(struct tcpcb *tp)
-{
-
- tp->t_tu->tu_detach(tp);
-}
-
-void
-ofld_listen_open(struct tcpcb *tp)
-{
-
- EVENTHANDLER_INVOKE(ofld_listen, OFLD_LISTEN_OPEN, tp);
-}
-
-void
-ofld_listen_close(struct tcpcb *tp)
-{
-
- EVENTHANDLER_INVOKE(ofld_listen, OFLD_LISTEN_CLOSE, tp);
+ if (tdev == NULL) {
+ printf("tdev not set\n");
+
+ error = EPERM;
+ goto fail;
+ }
+
+ if (tdev->tod_can_offload(tdev, so) == 0) {
+ printf("not offloadable\n");
+
+ error = EPERM;
+ goto fail;
+ }
+
+ return (tdev->tod_connect(tdev, so, rt, nam));
+fail:
+ RTFREE(rt);
+ return (error);
}
diff --git a/sys/netinet/tcp_offload.h b/sys/netinet/tcp_offload.h
new file mode 100644
index 000000000000..33d73ee553af
--- /dev/null
+++ b/sys/netinet/tcp_offload.h
@@ -0,0 +1,328 @@
+/*-
+ * Copyright (c) 2007, Chelsio Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Neither the name of the Chelsio Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET_TCP_OFFLOAD_H_
+#define _NETINET_TCP_OFFLOAD_H_
+
+#ifndef _KERNEL
+#error "no user-serviceable parts inside"
+#endif
+
+/*
+ * A driver publishes that it provides offload services
+ * by setting IFCAP_TOE in the ifnet. The offload connect
+ * will bypass any further work if the interface that a
+ * connection would use does not support TCP offload.
+ *
+ * The TOE API assumes that the tcp offload engine can offload the
+ * the entire connection from set up to teardown, with some provision
+ * being made to allowing the software stack to handle time wait. If
+ * the device does not meet these criteria, it is the driver's responsibility
+ * to overload the functions that it needs to in tcp_usrreqs and make
+ * its own calls to tcp_output if it needs to do so.
+ *
+ * There is currently no provision for the device advertising the congestion
+ * control algorithms it supports as there is currently no API for querying
+ * an operating system for the protocols that it has loaded. This is a desirable
+ * future extension.
+ *
+ *
+ *
+ * It is assumed that individuals deploying TOE will want connections
+ * to be offloaded without software changes so all connections on an
+ * interface providing TOE are offloaded unless the the SO_NO_OFFLOAD
+ * flag is set on the socket.
+ *
+ *
+ * The toe_usrreqs structure constitutes the TOE driver's
+ * interface to the TCP stack for functionality that doesn't
+ * interact directly with userspace. If one wants to provide
+ * (optional) functionality to do zero-copy to/from
+ * userspace one still needs to override soreceive/sosend
+ * with functions that fault in and pin the user buffers.
+ *
+ * + tu_send
+ * - tells the driver that new data may have been added to the
+ * socket's send buffer - the driver should not fail if the
+ * buffer is in fact unchanged
+ * - the driver is responsible for providing credits (bytes in the send window)
+ * back to the socket by calling sbdrop() as segments are acknowledged.
+ * - The driver expects the inpcb lock to be held - the driver is expected
+ * not to drop the lock. Hence the driver is not allowed to acquire the
+ * pcbinfo lock during this call.
+ *
+ * + tu_rcvd
+ * - returns credits to the driver and triggers window updates
+ * to the peer (a credit as used here is a byte in the peer's receive window)
+ * - the driver is expected to determine how many bytes have been
+ * consumed and credit that back to the card so that it can grow
+ * the window again by maintaining its own state between invocations.
+ * - In principle this could be used to shrink the window as well as
+ * grow the window, although it is not used for that now.
+ * - this function needs to correctly handle being called any number of
+ * times without any bytes being consumed from the receive buffer.
+ * - The driver expects the inpcb lock to be held - the driver is expected
+ * not to drop the lock. Hence the driver is not allowed to acquire the
+ * pcbinfo lock during this call.
+ *
+ * + tu_disconnect
+ * - tells the driver to send FIN to peer
+ * - driver is expected to send the remaining data and then do a clean half close
+ * - disconnect implies at least half-close so only send, reset, and detach
+ * are legal
+ * - the driver is expected to handle transition through the shutdown
+ * state machine and allow the stack to support SO_LINGER.
+ * - The driver expects the inpcb lock to be held - the driver is expected
+ * not to drop the lock. Hence the driver is not allowed to acquire the
+ * pcbinfo lock during this call.
+ *
+ * + tu_reset
+ * - closes the connection and sends a RST to peer
+ * - driver is expectd to trigger an RST and detach the toepcb
+ * - no further calls are legal after reset
+ * - The driver expects the inpcb lock to be held - the driver is expected
+ * not to drop the lock. Hence the driver is not allowed to acquire the
+ * pcbinfo lock during this call.
+ *
+ * The following fields in the tcpcb are expected to be referenced by the driver:
+ * + iss
+ * + rcv_nxt
+ * + rcv_wnd
+ * + snd_isn
+ * + snd_max
+ * + snd_nxt
+ * + snd_una
+ * + t_flags
+ * + t_inpcb
+ * + t_maxseg
+ * + t_toe
+ *
+ * The following fields in the inpcb are expected to be referenced by the driver:
+ * + inp_lport
+ * + inp_fport
+ * + inp_laddr
+ * + inp_fport
+ * + inp_socket
+ * + inp_ip_tos
+ *
+ * The following fields in the socket are expected to be referenced by the
+ * driver:
+ * + so_comp
+ * + so_error
+ * + so_linger
+ * + so_options
+ * + so_rcv
+ * + so_snd
+ * + so_state
+ * + so_timeo
+ *
+ * These functions all return 0 on success and can return the following errors
+ * as appropriate:
+ * + EPERM:
+ * + ENOBUFS: memory allocation failed
+ * + EMSGSIZE: MTU changed during the call
+ * + EHOSTDOWN:
+ * + EHOSTUNREACH:
+ * + ENETDOWN:
+ * * ENETUNREACH: the peer is no longer reachable
+ *
+ * + tu_detach
+ * - tells driver that the socket is going away so disconnect
+ * the toepcb and free appropriate resources
+ * - allows the driver to cleanly handle the case of connection state
+ * outliving the socket
+ * - no further calls are legal after detach
+ * - the driver is expected to provide its own synchronization between
+ * detach and receiving new data.
+ *
+ * + tu_syncache_event
+ * - even if it is not actually needed, the driver is expected to
+ * call syncache_add for the initial SYN and then syncache_expand
+ * for the SYN,ACK
+ * - tells driver that a connection either has not been added or has
+ * been dropped from the syncache
+ * - the driver is expected to maintain state that lives outside the
+ * software stack so the syncache needs to be able to notify the
+ * toe driver that the software stack is not going to create a connection
+ * for a received SYN
+ * - The driver is responsible for any synchronization required between
+ * the syncache dropping an entry and the driver processing the SYN,ACK.
+ *
+ */
+struct toe_usrreqs {
+ int (*tu_send)(struct tcpcb *tp);
+ int (*tu_rcvd)(struct tcpcb *tp);
+ int (*tu_disconnect)(struct tcpcb *tp);
+ int (*tu_reset)(struct tcpcb *tp);
+ void (*tu_detach)(struct tcpcb *tp);
+ void (*tu_syncache_event)(int event, void *toep);
+};
+
+#define TOE_SC_ENTRY_PRESENT 1 /* 4-tuple already present */
+#define TOE_SC_DROP 2 /* connection was timed out */
+
+/*
+ * Because listen is a one-to-many relationship (a socket can be listening
+ * on all interfaces on a machine some of which may be using different TCP
+ * offload devices), listen uses a publish/subscribe mechanism. The TCP
+ * offload driver registers a listen notification function with the stack.
+ * When a listen socket is created all TCP offload devices are notified
+ * so that they can do the appropriate set up to offload connections on the
+ * port to which the socket is bound. When the listen socket is closed,
+ * the offload devices are notified so that they will stop listening on that
+ * port and free any associated resources as well as sending RSTs on any
+ * connections in the SYN_RCVD state.
+ *
+ */
+
+typedef void (*tcp_offload_listen_start_fn)(void *, struct tcpcb *);
+typedef void (*tcp_offload_listen_stop_fn)(void *, struct tcpcb *);
+
+EVENTHANDLER_DECLARE(tcp_offload_listen_start, tcp_offload_listen_start_fn);
+EVENTHANDLER_DECLARE(tcp_offload_listen_stop, tcp_offload_listen_stop_fn);
+
+/*
+ * Check if the socket can be offloaded by the following steps:
+ * - determine the egress interface
+ * - check the interface for TOE capability and TOE is enabled
+ * - check if the device has resources to offload the connection
+ */
+int tcp_offload_connect(struct socket *so, struct sockaddr *nam);
+
+/*
+ * The tcp_gen_* routines are wrappers around the toe_usrreqs calls,
+ * in the non-offloaded case they translate to tcp_output.
+ *
+ * Listen is a special case because it is a 1 to many relationship
+ * and there can be more than one offload driver in the system.
+ */
+
+/*
+ * Connection is offloaded
+ */
+#define tp_offload(tp) ((tp)->t_flags & TF_TOE)
+/*
+ * The socket has not been marked as "do not offload"
+ */
+#define SO_OFFLOADABLE(so) ((so->so_options & SO_NO_OFFLOAD) == 0)
+
+static __inline int
+tcp_gen_connect(struct socket *so, struct sockaddr *nam)
+{
+ struct tcpcb *tp = sototcpcb(so);
+ int error;
+
+ /*
+ * If offload has been disabled for this socket or the
+ * connection cannot be offloaded just call tcp_output
+ * to start the TCP state machine.
+ */
+#ifndef TCP_OFFLOAD_DISABLE
+ if (!SO_OFFLOADABLE(so) || (error = tcp_offload_connect(so, nam)) != 0)
+#endif
+ error = tcp_output(tp);
+ return (error);
+}
+
+static __inline int
+tcp_gen_send(struct tcpcb *tp)
+{
+
+#ifndef TCP_OFFLOAD_DISABLE
+ if (tp_offload(tp))
+ return (tp->t_tu->tu_send(tp));
+#endif
+ return (tcp_output(tp));
+}
+
+static __inline int
+tcp_gen_rcvd(struct tcpcb *tp)
+{
+
+#ifndef TCP_OFFLOAD_DISABLE
+ if (tp_offload(tp))
+ return (tp->t_tu->tu_rcvd(tp));
+#endif
+ return (tcp_output(tp));
+}
+
+static __inline int
+tcp_gen_disconnect(struct tcpcb *tp)
+{
+
+#ifndef TCP_OFFLOAD_DISABLE
+ if (tp_offload(tp))
+ return (tp->t_tu->tu_disconnect(tp));
+#endif
+ return (tcp_output(tp));
+}
+
+static __inline int
+tcp_gen_reset(struct tcpcb *tp)
+{
+
+#ifndef TCP_OFFLOAD_DISABLE
+ if (tp_offload(tp))
+ return (tp->t_tu->tu_reset(tp));
+#endif
+ return (tcp_output(tp));
+}
+
+static __inline void
+tcp_gen_detach(struct tcpcb *tp)
+{
+
+#ifndef TCP_OFFLOAD_DISABLE
+ if (tp_offload(tp))
+ tp->t_tu->tu_detach(tp);
+#endif
+}
+
+static __inline void
+tcp_gen_listen_open(struct tcpcb *tp)
+{
+
+#ifndef TCP_OFFLOAD_DISABLE
+ if (SO_OFFLOADABLE(tp->t_inpcb->inp_socket))
+ EVENTHANDLER_INVOKE(tcp_offload_listen_start, tp);
+#endif
+}
+
+static __inline void
+tcp_gen_listen_close(struct tcpcb *tp)
+{
+
+#ifndef TCP_OFFLOAD_DISABLE
+ EVENTHANDLER_INVOKE(tcp_offload_listen_stop, tp);
+#endif
+}
+
+#undef tp_offload
+#undef SO_OFFLOADABLE
+#endif /* _NETINET_TCP_OFFLOAD_H_ */
diff --git a/sys/netinet/tcp_ofld.h b/sys/netinet/tcp_ofld.h
deleted file mode 100644
index 047f763a038d..000000000000
--- a/sys/netinet/tcp_ofld.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/*-
- * Copyright (c) 2007, Chelsio Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Neither the name of the Chelsio Corporation nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _NETINET_TCP_OFLD_H_
-#define _NETINET_TCP_OFLD_H_
-
-#ifndef _KERNEL
-#error "no user-serviceable parts inside"
-#endif
-
-#define SC_ENTRY_PRESENT 1
-#define SC_DROP 2
-
-#define tp_offload(tp) ((tp)->t_flags & TF_TOE)
-#define SO_OFFLOADABLE(so) ((so->so_options & SO_NO_OFFLOAD) == 0)
-
-int ofld_connect(struct socket *so, struct sockaddr *nam);
-int ofld_can_offload(struct tcpcb *tp, struct sockaddr *nam);
-
-int ofld_abort(struct tcpcb *tp);
-int ofld_disconnect(struct tcpcb *tp);
-int ofld_send(struct tcpcb *tp);
-int ofld_rcvd(struct tcpcb *tp);
-void ofld_detach(struct tcpcb *tp);
-void ofld_listen_close(struct tcpcb *tp);
-void ofld_listen_open(struct tcpcb *tp);
-
-#ifndef DISABLE_TCP_OFFLOAD
-static __inline int
-tcp_gen_connect(struct socket *so, struct sockaddr *nam)
-{
- struct tcpcb *tp = sototcpcb(so);
- int error;
-
- if (!SO_OFFLOADABLE(so) || (error = ofld_connect(so, nam)) != 0)
- error = tcp_output(tp);
- return (error);
-}
-
-static __inline int
-tcp_gen_disconnect(struct tcpcb *tp)
-{
- int error;
-
- if (tp_offload(tp))
- error = ofld_disconnect(tp);
- else
- error = tcp_output(tp);
- return (error);
-}
-
-static __inline int
-tcp_gen_abort(struct tcpcb *tp)
-{
- int error;
-
- if (tp_offload(tp))
- error = ofld_abort(tp);
- else
- error = tcp_output(tp);
- return (error);
-}
-
-static __inline int
-tcp_gen_send(struct tcpcb *tp)
-{
- int error;
-
- if (tp_offload(tp))
- error = ofld_send(tp);
- else
- error = tcp_output(tp);
- return (error);
-}
-
-static __inline int
-tcp_gen_rcvd(struct tcpcb *tp)
-{
- int error;
-
- if (tp_offload(tp))
- error = ofld_rcvd(tp);
- else
- error = tcp_output(tp);
- return (error);
-}
-
-static __inline void
-tcp_gen_listen_open(struct tcpcb *tp)
-{
-
- if (SO_OFFLOADABLE(tp->t_inpcb->inp_socket))
- ofld_listen_open(tp);
-}
-
-static __inline void
-tcp_gen_listen_close(struct tcpcb *tp)
-{
- ofld_listen_close(tp);
-}
-
-static __inline void
-tcp_gen_detach(struct tcpcb *tp)
-{
- if (tp_offload(tp))
- ofld_detach(tp);
-}
-
-#else
-
-static __inline int
-tcp_gen_connect(struct socket *so, struct sockaddr *nam)
-{
-
- return (tcp_output(tp));
-}
-
-static __inline int
-tcp_gen_disconnect(struct tcpcb *tp)
-{
-
- return (tcp_output(tp));
-}
-
-static __inline int
-tcp_gen_abort(struct tcpcb *tp)
-{
-
- return (tcp_output(tp));
-}
-
-static __inline int
-tcp_gen_send(struct tcpcb *tp)
-{
-
- return (tcp_output(tp));
-}
-
-static __inline int
-tcp_gen_rcvd(struct tcpcb *tp)
-{
-
- return (tcp_output(tp));
-}
-
-static __inline void
-tcp_gen_listen_open(struct tcpcb *tp)
-{
-}
-
-static __inline void
-tcp_gen_listen_close(struct tcpcb *tp)
-{
-}
-
-static __inline void
-tcp_gen_detach(struct tcpcb *tp)
-{
-}
-
-#endif
-
-struct toe_usrreqs {
- int (*tu_send)(struct tcpcb *tp);
- int (*tu_rcvd)(struct tcpcb *tp);
- int (*tu_disconnect)(struct tcpcb *tp);
- int (*tu_abort)(struct tcpcb *tp);
- void (*tu_detach)(struct tcpcb *tp);
- void (*tu_syncache_event)(int event, void *toep);
-};
-
-#define OFLD_LISTEN_OPEN 1
-#define OFLD_LISTEN_CLOSE 2
-typedef void (*ofld_listen_fn)(void *, int, struct tcpcb *);
-EVENTHANDLER_DECLARE(ofld_listen, ofld_listen_fn);
-
-#endif
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 1aaf6981227b..68b5ac8aad12 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/tcp_syncache.h>
-#include <netinet/tcp_ofld.h>
+#include <netinet/tcp_offload.h>
#ifdef INET6
#include <netinet6/tcp6_var.h>
#endif
@@ -136,7 +136,7 @@ struct syncache {
#define SCF_UNREACH 0x10 /* icmp unreachable received */
#define SCF_SIGNATURE 0x20 /* send MD5 digests */
#define SCF_SACK 0x80 /* send SACK option */
-#ifndef DISABLE_TCP_OFFLOAD
+#ifndef TCP_OFFLOAD_DISABLE
struct toe_usrreqs *sc_tu; /* TOE operations */
void *sc_toepcb; /* TOE protocol block */
#endif
@@ -145,6 +145,13 @@ struct syncache {
#endif
};
+#ifdef TCP_OFFLOAD_DISABLE
+#define TOEPCB_ISSET(sc) (0)
+#else
+#define TOEPCB_ISSET(sc) ((sc)->sc_toepcb != NULL)
+#endif
+
+
struct syncache_head {
struct mtx sch_mtx;
TAILQ_HEAD(sch_head, syncache) sch_bucket;
@@ -358,9 +365,9 @@ syncache_drop(struct syncache *sc, struct syncache_head *sch)
TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash);
sch->sch_length--;
-#ifndef DISABLE_TCP_OFFLOAD
+#ifndef TCP_OFFLOAD_DISABLE
if (sc->sc_tu)
- sc->sc_tu->tu_syncache_event(SC_DROP, sc->sc_toepcb);
+ sc->sc_tu->tu_syncache_event(TOE_SC_DROP, sc->sc_toepcb);
#endif
syncache_free(sc);
tcp_syncache.cache_count--;
@@ -729,7 +736,8 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
struct in_addr laddr;
struct sockaddr_in sin;
- inp->inp_options = ip_srcroute(m);
+ inp->inp_options = (m) ? ip_srcroute(m) : NULL;
+
if (inp->inp_options == NULL) {
inp->inp_options = sc->sc_ipopts;
sc->sc_ipopts = NULL;
@@ -878,7 +886,7 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
* Segment validation:
* ACK must match our initial sequence number + 1 (the SYN|ACK).
*/
- if (th->th_ack != sc->sc_iss + 1 && sc->sc_toepcb == NULL) {
+ if (th->th_ack != sc->sc_iss + 1 && !TOEPCB_ISSET(sc)) {
if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
log(LOG_DEBUG, "%s; %s: ACK %u != ISS+1 %u, segment "
"rejected\n", s, __func__, th->th_ack, sc->sc_iss);
@@ -889,7 +897,7 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
* number + 1 (the SYN) because we didn't ACK any data that
* may have come with the SYN.
*/
- if (th->th_seq != sc->sc_irs + 1 && sc->sc_toepcb == NULL) {
+ if (th->th_seq != sc->sc_irs + 1 && !TOEPCB_ISSET(sc)) {
if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
log(LOG_DEBUG, "%s; %s: SEQ %u != IRS+1 %u, segment "
"rejected\n", s, __func__, th->th_seq, sc->sc_irs);
@@ -907,7 +915,7 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
* must be equal to what we actually sent in the SYN|ACK.
*/
if ((to->to_flags & TOF_TS) && to->to_tsecr != sc->sc_ts &&
- sc->sc_toepcb == NULL) {
+ !TOEPCB_ISSET(sc)) {
if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
log(LOG_DEBUG, "%s; %s: TSECR %u != TS %u, "
"segment rejected\n",
@@ -1011,7 +1019,7 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
#ifdef INET6
if (!inc->inc_isipv6)
#endif
- ipopts = ip_srcroute(m);
+ ipopts = (m) ? ip_srcroute(m) : NULL;
/*
* See if we already have an entry for this connection.
@@ -1028,9 +1036,9 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
sc = syncache_lookup(inc, &sch); /* returns locked entry */
SCH_LOCK_ASSERT(sch);
if (sc != NULL) {
-#ifndef DISABLE_TCP_OFFLOAD
+#ifndef TCP_OFFLOAD_DISABLE
if (sc->sc_tu)
- sc->sc_tu->tu_syncache_event(SC_ENTRY_PRESENT,
+ sc->sc_tu->tu_syncache_event(TOE_SC_ENTRY_PRESENT,
sc->sc_toepcb);
#endif
tcpstat.tcps_sc_dupsyn++;
@@ -1067,7 +1075,7 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
s, __func__);
free(s, M_TCPLOG);
}
- if ((sc->sc_toepcb == NULL) && syncache_respond(sc) == 0) {
+ if (!TOEPCB_ISSET(sc) && syncache_respond(sc) == 0) {
sc->sc_rxmits = 0;
syncache_timeout(sc, sch, 1);
tcpstat.tcps_sndacks++;
@@ -1116,7 +1124,7 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
sc->sc_ip_tos = ip_tos;
sc->sc_ip_ttl = ip_ttl;
}
-#ifndef DISABLE_TCP_OFFLOAD
+#ifndef TCP_OFFLOAD_DISABLE
sc->sc_tu = tu;
sc->sc_toepcb = toepcb;
#endif
@@ -1211,7 +1219,7 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
/*
* Do a standard 3-way handshake.
*/
- if (sc->sc_toepcb || syncache_respond(sc) == 0) {
+ if (TOEPCB_ISSET(sc) || syncache_respond(sc) == 0) {
if (tcp_syncookies && tcp_syncookiesonly && sc != &scs)
syncache_free(sc);
else if (sc != &scs)