In order for the TCP Handshake to support ECN++, and further ECN-related
improvements, the ECN bits need to be exposed to the TCP SYNcache. This change is a minimal modification to the function headers, without any functional change intended. Submitted by: Richard Scheffenegger Reviewed by: rgrimes@, rrs@, tuexen@ Differential Revision: https://reviews.freebsd.org/D22436
This commit is contained in:
parent
669a285ffb
commit
fa49a96419
@ -988,7 +988,7 @@ t4opt_to_tcpopt(const struct tcp_options *t4opt, struct tcpopt *to)
|
||||
|
||||
static void
|
||||
pass_accept_req_to_protohdrs(struct adapter *sc, const struct mbuf *m,
|
||||
struct in_conninfo *inc, struct tcphdr *th)
|
||||
struct in_conninfo *inc, struct tcphdr *th, uint8_t *iptos)
|
||||
{
|
||||
const struct cpl_pass_accept_req *cpl = mtod(m, const void *);
|
||||
const struct ether_header *eh;
|
||||
@ -1005,6 +1005,21 @@ pass_accept_req_to_protohdrs(struct adapter *sc, const struct mbuf *m,
|
||||
tcp = (const void *)(l3hdr + G_IP_HDR_LEN(hlen));
|
||||
}
|
||||
|
||||
/* extract TOS (DiffServ + ECN) byte for AccECN */
|
||||
if (iptos) {
|
||||
if (((struct ip *)l3hdr)->ip_v == IPVERSION) {
|
||||
const struct ip *ip = (const void *)l3hdr;
|
||||
*iptos = ip->ip_tos;
|
||||
}
|
||||
#ifdef INET6
|
||||
else
|
||||
if (((struct ip *)l3hdr)->ip_v == (IPV6_VERSION >> 4)) {
|
||||
const struct ip6_hdr *ip6 = (const void *)l3hdr;
|
||||
*iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
|
||||
}
|
||||
#endif /* INET */
|
||||
}
|
||||
|
||||
if (inc) {
|
||||
bzero(inc, sizeof(*inc));
|
||||
inc->inc_fport = tcp->th_sport;
|
||||
@ -1150,6 +1165,7 @@ do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss,
|
||||
unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
|
||||
#endif
|
||||
struct offload_settings settings;
|
||||
uint8_t iptos;
|
||||
|
||||
KASSERT(opcode == CPL_PASS_ACCEPT_REQ,
|
||||
("%s: unexpected opcode 0x%x", __func__, opcode));
|
||||
@ -1208,7 +1224,7 @@ do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss,
|
||||
if (lctx->vnet != ifp->if_vnet)
|
||||
REJECT_PASS_ACCEPT_REQ(true);
|
||||
|
||||
pass_accept_req_to_protohdrs(sc, m, &inc, &th);
|
||||
pass_accept_req_to_protohdrs(sc, m, &inc, &th, &iptos);
|
||||
if (inc.inc_flags & INC_ISIPV6) {
|
||||
|
||||
/* Don't offload if the ifcap isn't enabled */
|
||||
@ -1284,7 +1300,7 @@ do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss,
|
||||
* syncache_add. Note that syncache_add releases the pcb lock.
|
||||
*/
|
||||
t4opt_to_tcpopt(&cpl->tcpopt, &to);
|
||||
toe_syncache_add(&inc, &to, &th, inp, tod, synqe);
|
||||
toe_syncache_add(&inc, &to, &th, inp, tod, synqe, iptos);
|
||||
|
||||
if (atomic_load_int(&synqe->ok_to_respond) > 0) {
|
||||
uint64_t opt0;
|
||||
@ -1350,9 +1366,10 @@ synqe_to_protohdrs(struct adapter *sc, struct synq_entry *synqe,
|
||||
struct tcphdr *th, struct tcpopt *to)
|
||||
{
|
||||
uint16_t tcp_opt = be16toh(cpl->tcp_opt);
|
||||
uint8_t iptos;
|
||||
|
||||
/* start off with the original SYN */
|
||||
pass_accept_req_to_protohdrs(sc, synqe->syn, inc, th);
|
||||
pass_accept_req_to_protohdrs(sc, synqe->syn, inc, th, &iptos);
|
||||
|
||||
/* modify parts to make it look like the ACK to our SYN|ACK */
|
||||
th->th_flags = TH_ACK;
|
||||
|
@ -1282,7 +1282,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
|
||||
#endif
|
||||
TCP_PROBE3(debug__input, tp, th, m);
|
||||
tcp_dooptions(&to, optp, optlen, TO_SYN);
|
||||
if (syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL))
|
||||
if (syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL, iptos))
|
||||
goto tfo_socket_result;
|
||||
|
||||
/*
|
||||
|
@ -1369,7 +1369,7 @@ syncache_tfo_expand(struct syncache *sc, struct socket **lsop, struct mbuf *m,
|
||||
int
|
||||
syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
||||
struct inpcb *inp, struct socket **lsop, struct mbuf *m, void *tod,
|
||||
void *todctx)
|
||||
void *todctx, uint8_t iptos)
|
||||
{
|
||||
struct tcpcb *tp;
|
||||
struct socket *so;
|
||||
|
@ -45,7 +45,7 @@ int syncache_expand(struct in_conninfo *, struct tcpopt *,
|
||||
struct tcphdr *, struct socket **, struct mbuf *);
|
||||
int syncache_add(struct in_conninfo *, struct tcpopt *,
|
||||
struct tcphdr *, struct inpcb *, struct socket **, struct mbuf *,
|
||||
void *, void *);
|
||||
void *, void *, uint8_t);
|
||||
void syncache_chkrst(struct in_conninfo *, struct tcphdr *, struct mbuf *);
|
||||
void syncache_badack(struct in_conninfo *);
|
||||
int syncache_pcblist(struct sysctl_req *);
|
||||
|
@ -346,13 +346,13 @@ unregister_toedev(struct toedev *tod)
|
||||
|
||||
void
|
||||
toe_syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
||||
struct inpcb *inp, void *tod, void *todctx)
|
||||
struct inpcb *inp, void *tod, void *todctx, uint8_t iptos)
|
||||
{
|
||||
struct socket *lso = inp->inp_socket;
|
||||
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
||||
syncache_add(inc, to, th, inp, &lso, NULL, tod, todctx);
|
||||
syncache_add(inc, to, th, inp, &lso, NULL, tod, todctx, iptos);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -135,7 +135,7 @@ int toe_l2_resolve(struct toedev *, struct ifnet *, struct sockaddr *,
|
||||
void toe_connect_failed(struct toedev *, struct inpcb *, int);
|
||||
|
||||
void toe_syncache_add(struct in_conninfo *, struct tcpopt *, struct tcphdr *,
|
||||
struct inpcb *, void *, void *);
|
||||
struct inpcb *, void *, void *, uint8_t);
|
||||
int toe_syncache_expand(struct in_conninfo *, struct tcpopt *, struct tcphdr *,
|
||||
struct socket **);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user