The branch main has been updated by tuexen:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=99c79cab422705f92f05a2924a29bdf823372ebf

commit 99c79cab422705f92f05a2924a29bdf823372ebf
Author:     Michael Tuexen <tue...@freebsd.org>
AuthorDate: 2023-11-19 14:57:53 +0000
Commit:     Michael Tuexen <tue...@freebsd.org>
CommitDate: 2023-11-19 14:57:53 +0000

    if_tuntap: add LRO support to tap devices
    
    This allows testing the LRO code with packetdrill in local mode.
    
    Reviewed by:            rscheff
    MFC after:              1 week
    Sponsored by:           Netflix, Inc.
    Differential Revision:  https://reviews.freebsd.org/D42548
---
 sys/net/if_tuntap.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c
index 8881bbaec070..5a4231604f5a 100644
--- a/sys/net/if_tuntap.c
+++ b/sys/net/if_tuntap.c
@@ -97,6 +97,7 @@
 #endif
 #include <netinet/udp.h>
 #include <netinet/tcp.h>
+#include <netinet/tcp_lro.h>
 #include <net/bpf.h>
 #include <net/if_tap.h>
 #include <net/if_tun.h>
@@ -144,6 +145,8 @@ struct tuntap_softc {
        struct ether_addr        tun_ether;     /* remote address */
        int                      tun_busy;      /* busy count */
        int                      tun_vhdrlen;   /* virtio-net header length */
+       struct lro_ctrl          tun_lro;       /* for TCP LRO */
+       bool                     tun_lro_ready; /* TCP LRO initialized */
 };
 #define        TUN2IFP(sc)     ((sc)->tun_ifp)
 
@@ -978,7 +981,8 @@ tuncreate(struct cdev *dev)
        IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
        ifp->if_capabilities |= IFCAP_LINKSTATE;
        if ((tp->tun_flags & TUN_L2) != 0)
-               ifp->if_capabilities |= IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6;
+               ifp->if_capabilities |=
+                   IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 | IFCAP_LRO;
        ifp->if_capenable |= IFCAP_LINKSTATE;
 
        if ((tp->tun_flags & TUN_L2) != 0) {
@@ -1175,6 +1179,12 @@ tundtor(void *data)
            (l2tun && (ifp->if_flags & IFF_LINK0) != 0))
                goto out;
 
+       if (l2tun && tp->tun_lro_ready) {
+               TUNDEBUG (ifp, "LRO disabled\n");
+               tcp_lro_free(&tp->tun_lro);
+               tp->tun_lro_ready = false;
+       }
+
        if (ifp->if_flags & IFF_UP) {
                TUN_UNLOCK(tp);
                if_down(ifp);
@@ -1219,6 +1229,14 @@ tuninit(struct ifnet *ifp)
                getmicrotime(&ifp->if_lastchange);
                TUN_UNLOCK(tp);
        } else {
+               if (tcp_lro_init(&tp->tun_lro) == 0) {
+                       TUNDEBUG(ifp, "LRO enabled\n");
+                       tp->tun_lro.ifp = ifp;
+                       tp->tun_lro_ready = true;
+               } else {
+                       TUNDEBUG(ifp, "Could not enable LRO\n");
+                       tp->tun_lro_ready = false;
+               }
                ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
                TUN_UNLOCK(tp);
                /* attempt to start output */
@@ -1765,6 +1783,7 @@ tunwrite_l2(struct tuntap_softc *tp, struct mbuf *m,
        struct epoch_tracker et;
        struct ether_header *eh;
        struct ifnet *ifp;
+       int result;
 
        ifp = TUN2IFP(tp);
 
@@ -1820,7 +1839,15 @@ tunwrite_l2(struct tuntap_softc *tp, struct mbuf *m,
        /* Pass packet up to parent. */
        CURVNET_SET(ifp->if_vnet);
        NET_EPOCH_ENTER(et);
-       (*ifp->if_input)(ifp, m);
+       if (tp->tun_lro_ready && ifp->if_capenable & IFCAP_LRO) {
+               result = tcp_lro_rx(&tp->tun_lro, m, 0);
+               TUNDEBUG(ifp, "tcp_lro_rx() returned %d\n", result);
+       } else
+               result = TCP_LRO_CANNOT;
+       if (result == 0)
+               tcp_lro_flush_all(&tp->tun_lro);
+       else
+               (*ifp->if_input)(ifp, m);
        NET_EPOCH_EXIT(et);
        CURVNET_RESTORE();
        /* ibytes are counted in parent */

Reply via email to