==== //depot/projects/toehead/sys/netinet/tcp_syncache.c#1 - /home/kmacy/devel/p4/HEAD/sys/netinet/tcp_syncache.c ==== @@ -78,6 +78,7 @@ #include #include #include +#include #ifdef INET6 #include #endif @@ -136,7 +137,8 @@ #define SCF_SIGNATURE 0x20 /* send MD5 digests */ #define SCF_SACK 0x80 /* send SACK option */ #ifndef DISABLE_TCP_OFFLOAD - void *sc_pspare[2]; /* toepcb / toe_usrreqs */ + struct toe_usrreqs *sc_tu; /* TOE operations */ + void *sc_toepcb; /* TOE protocol block */ #endif #ifdef MAC struct label *sc_label; /* MAC label reference */ @@ -198,6 +200,10 @@ SYSCTL_NODE(_net_inet_tcp, OID_AUTO, syncache, CTLFLAG_RW, 0, "TCP SYN cache"); +static int tcp_syncache_drop_all(SYSCTL_HANDLER_ARGS); +SYSCTL_PROC(_net_inet_tcp_syncache, OID_AUTO, drop_all, CTLTYPE_INT | CTLFLAG_RW, + 0, 0, tcp_syncache_drop_all, "IU", "drop all elements in the syncache"); + SYSCTL_INT(_net_inet_tcp_syncache, OID_AUTO, bucketlimit, CTLFLAG_RDTUN, &tcp_syncache.bucket_limit, 0, "Per-bucket hash limit for syncache"); @@ -356,6 +362,10 @@ TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash); sch->sch_length--; +#ifndef DISABLE_TCP_OFFLOAD + if (sc->sc_tu) + sc->sc_tu->tu_syncache_event(SC_DROP, sc->sc_toepcb); +#endif syncache_free(sc); tcp_syncache.cache_count--; } @@ -406,7 +416,6 @@ sch->sch_nextc = sc->sc_rxttime; continue; } - if (sc->sc_rxmits > tcp_syncache.rexmt_limit) { if ((s = tcp_log_addrs(&sc->sc_inc, NULL, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: Retransmits exhausted, " @@ -873,7 +882,7 @@ * Segment validation: * ACK must match our initial sequence number + 1 (the SYN|ACK). */ - if (th->th_ack != sc->sc_iss + 1) { + if (th->th_ack != sc->sc_iss + 1 && sc->sc_toepcb == NULL) { 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); @@ -884,29 +893,13 @@ * 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) { + if (th->th_seq != sc->sc_irs + 1 && sc->sc_toepcb == NULL) { 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); goto failed; } -#if 0 - /* - * If timestamps were present in the SYN and we accepted - * them in our SYN|ACK we require them to be present from - * now on. And vice versa. - * - * Unfortunately, during testing of 7.0 some users found - * network devices that violate this constraint, so it must - * be disabled. - */ - if ((sc->sc_flags & SCF_TIMESTAMP) && !(to->to_flags & TOF_TS)) { - if ((s = tcp_log_addrs(inc, th, NULL, NULL))) - log(LOG_DEBUG, "%s; %s: Timestamp missing, " - "segment rejected\n", s, __func__); - goto failed; - } -#endif + if (!(sc->sc_flags & SCF_TIMESTAMP) && (to->to_flags & TOF_TS)) { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Timestamp not expected, " @@ -917,7 +910,8 @@ * If timestamps were negotiated the reflected timestamp * must be equal to what we actually sent in the SYN|ACK. */ - if ((to->to_flags & TOF_TS) && to->to_tsecr != sc->sc_ts) { + if ((to->to_flags & TOF_TS) && to->to_tsecr != sc->sc_ts && + sc->sc_toepcb == NULL) { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: TSECR %u != TS %u, " "segment rejected\n", @@ -957,9 +951,10 @@ * consume all available buffer space if it were ACKed. By not ACKing * the data, we avoid this DoS scenario. */ -void -syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, - struct inpcb *inp, struct socket **lsop, struct mbuf *m) +static void +_syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, + struct inpcb *inp, struct socket **lsop, struct mbuf *m, + struct toe_usrreqs *tu, void *toepcb) { struct tcpcb *tp; struct socket *so; @@ -1037,6 +1032,11 @@ sc = syncache_lookup(inc, &sch); /* returns locked entry */ SCH_LOCK_ASSERT(sch); if (sc != NULL) { +#ifndef DISABLE_TCP_OFFLOAD + if (sc->sc_tu) + sc->sc_tu->tu_syncache_event(SC_ENTRY_PRESENT, + sc->sc_toepcb); +#endif tcpstat.tcps_sc_dupsyn++; if (ipopts) { /* @@ -1071,7 +1071,7 @@ s, __func__); free(s, M_TCPLOG); } - if (syncache_respond(sc) == 0) { + if ((sc->sc_toepcb == NULL) && syncache_respond(sc) == 0) { sc->sc_rxmits = 0; syncache_timeout(sc, sch, 1); tcpstat.tcps_sndacks++; @@ -1104,7 +1104,7 @@ } } } - + /* * Fill in the syncache values. */ @@ -1120,7 +1120,10 @@ sc->sc_ip_tos = ip_tos; sc->sc_ip_ttl = ip_ttl; } - +#ifndef DISABLE_TCP_OFFLOAD + sc->sc_tu = tu; + sc->sc_toepcb = toepcb; +#endif sc->sc_irs = th->th_seq; sc->sc_iss = arc4random(); sc->sc_flags = 0; @@ -1212,7 +1215,7 @@ /* * Do a standard 3-way handshake. */ - if (syncache_respond(sc) == 0) { + if (sc->sc_toepcb || syncache_respond(sc) == 0) { if (tcp_syncookies && tcp_syncookiesonly && sc != &scs) syncache_free(sc); else if (sc != &scs) @@ -1230,8 +1233,11 @@ if (sc == &scs) mac_syncache_destroy(&maclabel); #endif - *lsop = NULL; - m_freem(m); + if (m) { + + *lsop = NULL; + m_freem(m); + } return; } @@ -1390,6 +1396,21 @@ return (error); } +void +syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, + struct inpcb *inp, struct socket **lsop, struct mbuf *m) +{ + _syncache_add(inc, to, th, inp, lsop, m, NULL, NULL); +} + +void +syncache_offload_add(struct in_conninfo *inc, struct tcpopt *to, + struct tcphdr *th, struct inpcb *inp, struct socket **lsop, + struct toe_usrreqs *tu, void *toepcb) +{ + _syncache_add(inc, to, th, inp, lsop, NULL, tu, toepcb); +} + /* * The purpose of SYN cookies is to avoid keeping track of all SYN's we * receive and to be able to handle SYN floods from bogus source addresses @@ -1716,3 +1737,29 @@ return error; } +static int +tcp_syncache_drop_all(SYSCTL_HANDLER_ARGS) +{ + struct syncache_head *sch = tcp_syncache.hashbase; + struct syncache *sc, *nsc; + int error, v; + + v = 0; + error = sysctl_handle_int(oidp, &v, 0, req); + if (error) + return (error); + if (v == 0) + return (0); + + printf("dropping syncache entries\n"); + SCH_LOCK(sch); + TAILQ_FOREACH_SAFE(sc, &sch->sch_bucket, sc_hash, nsc) { + printf("dropping %p\n", sc); + + syncache_drop(sc, sch); + } + SCH_UNLOCK(sch); + + return (0); +} + ==== //depot/projects/toehead/sys/netinet/tcp_syncache.h#1 - /home/kmacy/devel/p4/HEAD/sys/netinet/tcp_syncache.h ==== @@ -40,6 +40,9 @@ struct tcphdr *, struct socket **, struct mbuf *); void syncache_add(struct in_conninfo *, struct tcpopt *, struct tcphdr *, struct inpcb *, struct socket **, struct mbuf *); +void syncache_offload_add(struct in_conninfo *, struct tcpopt *, + struct tcphdr *, struct inpcb *, struct socket **, + struct toe_usrreqs *tu, void *toepcb); void syncache_chkrst(struct in_conninfo *, struct tcphdr *); void syncache_badack(struct in_conninfo *); int syncache_pcbcount(void);