svn commit: r236034 - user/np/toe_iwarp/sys/netinet
Navdeep Parhar
np at FreeBSD.org
Sat May 26 01:24:39 UTC 2012
Author: np
Date: Sat May 26 01:24:39 2012
New Revision: 236034
URL: http://svn.freebsd.org/changeset/base/236034
Log:
Provide an opportunity to a TOE driver to install its hooks when
expanding a syncache entry into a full socket.
A couple of functions in toecore:
* toe_connect_failed: to be called when an active open using a TOE
device fails.
* toe_4tuple_check: to check whether a 4-tuple is currently in use, and
maybe release it if it's in TIME_WAIT and we have an incoming SYN for
the 4-tuple.
Modified:
user/np/toe_iwarp/sys/netinet/tcp_syncache.c
user/np/toe_iwarp/sys/netinet/toecore.c
user/np/toe_iwarp/sys/netinet/toecore.h
Modified: user/np/toe_iwarp/sys/netinet/tcp_syncache.c
==============================================================================
--- user/np/toe_iwarp/sys/netinet/tcp_syncache.c Sat May 26 00:59:43 2012 (r236033)
+++ user/np/toe_iwarp/sys/netinet/tcp_syncache.c Sat May 26 01:24:39 2012 (r236034)
@@ -858,6 +858,18 @@ syncache_socket(struct syncache *sc, str
if (sc->sc_rxmits > 1)
tp->snd_cwnd = tp->t_maxseg;
+#ifdef TCP_OFFLOAD
+ /*
+ * Allow a TOE driver to install its hooks. Note that we hold the
+ * pcbinfo lock too and that prevents tcp_usr_accept from accepting a
+ * new connection before the TOE driver has done its thing.
+ */
+ if (ADDED_BY_TOE(sc)) {
+ struct toedev *tod = sc->sc_tod;
+
+ tod->tod_offload_socket(tod, sc->sc_todctx, so);
+ }
+#endif
/*
* Copy and activate timers.
*/
Modified: user/np/toe_iwarp/sys/netinet/toecore.c
==============================================================================
--- user/np/toe_iwarp/sys/netinet/toecore.c Sat May 26 00:59:43 2012 (r236033)
+++ user/np/toe_iwarp/sys/netinet/toecore.c Sat May 26 01:24:39 2012 (r236034)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#define TCPSTATES
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/tcp_syncache.h>
#include <netinet/tcp_offload.h>
@@ -154,6 +155,14 @@ toedev_syncache_respond(struct toedev *t
}
static void
+toedev_offload_socket(struct toedev *tod __unused, void *ctx __unused,
+ struct socket *so __unused)
+{
+
+ return;
+}
+
+static void
toedev_ctloutput(struct toedev *tod __unused, struct tcpcb *tp __unused,
int sopt_dir __unused, int sopt_name __unused)
{
@@ -247,6 +256,7 @@ init_toedev(struct toedev *tod)
tod->tod_syncache_added = toedev_syncache_added;
tod->tod_syncache_removed = toedev_syncache_removed;
tod->tod_syncache_respond = toedev_syncache_respond;
+ tod->tod_offload_socket = toedev_offload_socket;
tod->tod_ctloutput = toedev_ctloutput;
}
@@ -324,6 +334,41 @@ toe_syncache_expand(struct in_conninfo *
return (syncache_expand(inc, to, th, lsop, NULL));
}
+/*
+ * General purpose check to see if a 4-tuple is in use by the kernel. If a TCP
+ * header (presumably for an incoming SYN) is also provided, an existing 4-tuple
+ * in TIME_WAIT may be assassinated freeing it up for re-use.
+ *
+ * Note that the TCP header must have been run through tcp_fields_to_host() or
+ * equivalent.
+ */
+int
+toe_4tuple_check(struct in_conninfo *inc, struct tcphdr *th, struct ifnet *ifp)
+{
+ struct inpcb *inp;
+
+ if (inc->inc_flags & INC_ISIPV6)
+ return (ENOSYS); /* XXX: implement */
+
+ inp = in_pcblookup(&V_tcbinfo, inc->inc_faddr, inc->inc_fport,
+ inc->inc_laddr, inc->inc_lport, INPLOOKUP_WLOCKPCB, ifp);
+ if (inp != NULL) {
+ INP_WLOCK_ASSERT(inp);
+
+ if ((inp->inp_flags & INP_TIMEWAIT) && th != NULL) {
+
+ INP_INFO_WLOCK_ASSERT(&V_tcbinfo); /* for twcheck */
+ if (!tcp_twcheck(inp, NULL, th, NULL, 0))
+ return (EADDRINUSE);
+ } else {
+ INP_WUNLOCK(inp);
+ return (EADDRINUSE);
+ }
+ }
+
+ return (0);
+}
+
static void
toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
{
@@ -417,6 +462,41 @@ toe_l2_resolve(struct toedev *tod, struc
return (rc);
}
+void
+toe_connect_failed(struct toedev *tod, struct tcpcb *tp, int err)
+{
+ struct inpcb *inp = tp->t_inpcb;
+
+ INP_WLOCK_ASSERT(inp);
+ KASSERT(tp->t_flags & TF_TOE,
+ ("%s: tp %p not offloaded.", __func__, tp));
+
+ if (!(inp->inp_flags & INP_DROPPED)) {
+ if (err == EAGAIN) {
+
+ /*
+ * Temporary failure during offload, take this PCB back.
+ * Detach from the TOE driver and do the rest of what
+ * TCP's pru_connect would have done if the connection
+ * wasn't offloaded.
+ */
+
+ tod->tod_pcb_detach(tod, tp);
+ KASSERT(!(tp->t_flags & TF_TOE),
+ ("%s: tp %p still offloaded.", __func__, tp));
+ tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
+ (void) tcp_output(tp);
+ } else {
+
+ INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
+ tp = tcp_drop(tp, err);
+ if (tp == NULL)
+ INP_WLOCK(inp); /* re-acquire */
+ }
+ }
+ INP_WLOCK_ASSERT(inp);
+}
+
static int
toecore_load(void)
{
Modified: user/np/toe_iwarp/sys/netinet/toecore.h
==============================================================================
--- user/np/toe_iwarp/sys/netinet/toecore.h Sat May 26 00:59:43 2012 (r236033)
+++ user/np/toe_iwarp/sys/netinet/toecore.h Sat May 26 01:24:39 2012 (r236034)
@@ -80,6 +80,7 @@ struct toedev {
void (*tod_syncache_added)(struct toedev *, void *);
void (*tod_syncache_removed)(struct toedev *, void *);
int (*tod_syncache_respond)(struct toedev *, void *, struct mbuf *);
+ void (*tod_offload_socket)(struct toedev *, void *, struct socket *);
/* TCP socket option */
void (*tod_ctloutput)(struct toedev *, struct tcpcb *, int, int);
@@ -105,8 +106,12 @@ int unregister_toedev(struct toedev *);
int toe_l2_resolve(struct toedev *, struct ifnet *, struct sockaddr *,
uint8_t *, uint16_t *);
+void toe_connect_failed(struct toedev *, struct tcpcb *, int);
+
void toe_syncache_add(struct in_conninfo *, struct tcpopt *, struct tcphdr *,
struct inpcb *, void *, void *);
int toe_syncache_expand(struct in_conninfo *, struct tcpopt *, struct tcphdr *,
struct socket **);
+
+int toe_4tuple_check(struct in_conninfo *, struct tcphdr *, struct ifnet *);
#endif
More information about the svn-src-user
mailing list