if stoeplitz is enabled, use it to provide a flowid for tcp packets.
authordlg <dlg@openbsd.org>
Mon, 25 Jan 2021 03:40:46 +0000 (03:40 +0000)
committerdlg <dlg@openbsd.org>
Mon, 25 Jan 2021 03:40:46 +0000 (03:40 +0000)
drivers that implement rss and multiple rings depend on the symmetric
toeplitz code, and use it to generate a key that decides with rx
ring a packet lands on. if the toeplitz code is enabled, this diff
has the pcb and tcp layer use the toeplitz code to generate a flowid
for packets they send, which in turn is used to pick a tx ring.
because the nic and the stack use the same key, the tx and rx sides
end up with the same hash/flowid. at the very least this means that
the same rx and tx queue pair on a particular nic are used for both
sides of the connection. as the stack becomes more parallel, it
will also help keep both sides of the tcp connection processing in
the one place.

sys/netinet/in_pcb.c
sys/netinet/in_pcb.h
sys/netinet/tcp_output.c
sys/netinet6/in6_pcb.c

index 12ed205..99402c9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in_pcb.c,v 1.252 2020/11/07 09:51:40 denis Exp $      */
+/*     $OpenBSD: in_pcb.c,v 1.253 2021/01/25 03:40:46 dlg Exp $        */
 /*     $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $     */
 
 /*
 #include <netinet/ip_esp.h>
 #endif /* IPSEC */
 
+#include "stoeplitz.h"
+#if NSTOEPLITZ > 0
+#include <net/toeplitz.h>
+#endif
+
 const struct in_addr zeroin_addr;
 
 union {
@@ -516,6 +521,10 @@ in_pcbconnect(struct inpcb *inp, struct mbuf *nam)
        inp->inp_faddr = sin->sin_addr;
        inp->inp_fport = sin->sin_port;
        in_pcbrehash(inp);
+#if NSTOEPLITZ > 0
+       inp->inp_flowid = stoeplitz_ip4port(inp->inp_laddr.s_addr,
+           inp->inp_faddr.s_addr, inp->inp_lport, inp->inp_fport);
+#endif
 #ifdef IPSEC
        {
                /* Cause an IPsec SA to be established. */
@@ -549,6 +558,7 @@ in_pcbdisconnect(struct inpcb *inp)
        }
 
        inp->inp_fport = 0;
+       inp->inp_flowid = 0;
        in_pcbrehash(inp);
        if (inp->inp_socket->so_state & SS_NOFDREF)
                in_pcbdetach(inp);
index 4c7ae3f..2f87c82 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in_pcb.h,v 1.120 2020/06/21 05:14:04 dlg Exp $        */
+/*     $OpenBSD: in_pcb.h,v 1.121 2021/01/25 03:40:46 dlg Exp $        */
 /*     $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $     */
 
 /*
@@ -148,6 +148,7 @@ struct inpcb {
        void    *inp_upcall_arg;
        u_int   inp_rtableid;
        int     inp_pipex;              /* pipex indication */
+       uint16_t inp_flowid;
 };
 
 LIST_HEAD(inpcbhead, inpcb);
index 27a8739..f2d1516 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tcp_output.c,v 1.128 2018/11/10 18:40:34 bluhm Exp $  */
+/*     $OpenBSD: tcp_output.c,v 1.129 2021/01/25 03:40:46 dlg Exp $    */
 /*     $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $      */
 
 /*
@@ -69,6 +69,7 @@
  */
 
 #include "pf.h"
+#include "stoeplitz.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1037,6 +1038,10 @@ send:
                                ip->ip_tos |= IPTOS_ECN_ECT0;
 #endif
                }
+#if NSTOEPLITZ > 0
+               m->m_pkthdr.ph_flowid = tp->t_inpcb->inp_flowid;
+               SET(m->m_pkthdr.csum_flags, M_FLOWID);
+#endif
                error = ip_output(m, tp->t_inpcb->inp_options,
                        &tp->t_inpcb->inp_route,
                        (ip_mtudisc ? IP_MTUDISC : 0), NULL, tp->t_inpcb, 0);
index 36057b5..a0b270c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in6_pcb.c,v 1.110 2019/11/29 16:41:01 nayden Exp $    */
+/*     $OpenBSD: in6_pcb.c,v 1.111 2021/01/25 03:40:47 dlg Exp $       */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  */
 
 #include "pf.h"
+#include "stoeplitz.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
 
 #include <netinet6/in6_var.h>
 
+#if NSTOEPLITZ > 0
+#include <net/toeplitz.h>
+#endif
+
 const struct in6_addr zeroin6_addr;
 
 struct inpcbhead *
@@ -297,6 +302,10 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam)
        if (ip6_auto_flowlabel)
                inp->inp_flowinfo |=
                    (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
+#if NSTOEPLITZ > 0
+       inp->inp_flowid = stoeplitz_ip6port(&inp->inp_laddr6,
+           &inp->inp_faddr6, inp->inp_lport, inp->inp_fport);
+#endif
        in_pcbrehash(inp);
        return (0);
 }