From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1195C56202 for ; Thu, 26 Nov 2020 13:04:05 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 53B2621D46 for ; Thu, 26 Nov 2020 13:04:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=daynix-com.20150623.gappssmtp.com header.i=@daynix-com.20150623.gappssmtp.com header.b="qOXcS2ny" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 53B2621D46 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=daynix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60808 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kiGwM-0001RC-QU for qemu-devel@archiver.kernel.org; Thu, 26 Nov 2020 08:04:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36814) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kiGtN-00087X-ST for qemu-devel@nongnu.org; Thu, 26 Nov 2020 08:00:59 -0500 Received: from mail-oi1-x242.google.com ([2607:f8b0:4864:20::242]:46328) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kiGtK-0002hz-5e for qemu-devel@nongnu.org; Thu, 26 Nov 2020 08:00:57 -0500 Received: by mail-oi1-x242.google.com with SMTP id w15so2151324oie.13 for ; Thu, 26 Nov 2020 05:00:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=xPgYGqzABaRj7hEC92+KjugrLXHEaS3J84vF0EZVNoA=; b=qOXcS2nyXSdxwAw0xayAGk6TCLuWdraFBu7vwuKFvjdxhKNU74WFZ5dH3Ei2YpfpeX BEW84+EBTOBE71mEcqNC5EeZKT5eVgK00IrnjoJDRNcB1PlLx1G9LsvQCiYHwa0PGskh c3ApuwXtDCiH4Cs6o+c2st5C9PwyFVS8UZD2tPX45VDvh7dfTRHryGmpUHnpZSafn7eB QnlhuzAa3ZUu7YVuJeFJVt8K729aRK+Bt2muklCl1fKP5XBJnHPGs9cHMnBmesDpRKfQ QbjyIZT4F0PGRZ3w7y3y1yGPse8NZnnDUIsOA21l9CbzdsQrjQ3pvrg4FKVh8Us1s9We zO2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=xPgYGqzABaRj7hEC92+KjugrLXHEaS3J84vF0EZVNoA=; b=mOfMjZDNsASq58Uw3A2S2yQ/nA7ErDhzVsnIfsmZRrP8nOMmq9RnlslX8qON3aLs3w NivJ7iOYVAaEybTAihynjiMH3BEUAft9tCNl54Uy7KqwjfExTyEB/rz9ItJb2Gl2seP/ L0WxuFsKpYbQD+w/VzVAPXXFxHOf9okCoK08v3gV3+z3QFUausao0VNKDCUGZigJb/0F /Z3DGXtI81MKvaByBERe1V7VWGtkmKTEj4EXXnKxog2OyQFULOFSJTqRQRmR6x2WE8YW QQTqalAa6a9bRFKAvmpPSp6VulM6l6jKuDkikDsKQbC/65KfAHcwqEUz9PiaOmu9nfxM mYuQ== X-Gm-Message-State: AOAM532zgHaqOy8s3r3EjfM5jayeribNS0BSFNj42ehxHfuR3P/hZ6Hf fV2yJSRWc+EgS1dtfRtehCpbz7bh+u+AxXDp57ddhQ== X-Google-Smtp-Source: ABdhPJxZotSo23ofOR3dhxypSLxwQGmjNPWMXOZXT7ztgd+AvW/KvxqbrNqY6/MMP7S4JGzyYkXm2+yReVvnSQqADQE= X-Received: by 2002:aca:c4c4:: with SMTP id u187mr1998043oif.54.1606395652164; Thu, 26 Nov 2020 05:00:52 -0800 (PST) MIME-Version: 1.0 References: <20201119111305.485202-1-andrew@daynix.com> <20201119111305.485202-6-andrew@daynix.com> <41b81b86-225f-8d5a-3acc-0cae799c11d3@redhat.com> In-Reply-To: <41b81b86-225f-8d5a-3acc-0cae799c11d3@redhat.com> From: Yuri Benditovich Date: Thu, 26 Nov 2020 15:00:40 +0200 Message-ID: Subject: Re: [RFC PATCH v2 5/5] docs: Added eBPF documentation. To: Jason Wang Content-Type: multipart/alternative; boundary="0000000000003761c805b5022280" Received-SPF: none client-ip=2607:f8b0:4864:20::242; envelope-from=yuri.benditovich@daynix.com; helo=mail-oi1-x242.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Yan Vugenfirer , Andrew Melnychenko , qemu-devel@nongnu.org, "Michael S . Tsirkin" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" --0000000000003761c805b5022280 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, Nov 24, 2020 at 10:55 AM Jason Wang wrote: > > On 2020/11/19 =E4=B8=8B=E5=8D=887:13, Andrew Melnychenko wrote: > > From: Andrew > > > > Also, added maintainers information. > > > > Signed-off-by: Yuri Benditovich > > Signed-off-by: Andrew Melnychenko > > --- > > MAINTAINERS | 7 +++ > > docs/ebpf_rss.rst | 133 +++++++++++++++++++++++++++++++++++++++++++++= + > > 2 files changed, 140 insertions(+) > > create mode 100644 docs/ebpf_rss.rst > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 2c22bbca5a..d93c85b867 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -3111,6 +3111,13 @@ S: Maintained > > F: hw/semihosting/ > > F: include/hw/semihosting/ > > > > +EBPF: > > +M: Jason Wang > > +R: Andrew Melnychenko > > +R: Yuri Benditovich > > +S: Maintained > > +F: ebpf/* > > + > > Build and test automation > > ------------------------- > > Build and test automation > > diff --git a/docs/ebpf_rss.rst b/docs/ebpf_rss.rst > > new file mode 100644 > > index 0000000000..f832defdf4 > > --- /dev/null > > +++ b/docs/ebpf_rss.rst > > @@ -0,0 +1,133 @@ > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > > +eBPF RSS virtio-net support > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > > + > > +RSS(Receive Side Scaling) is used to distribute network packets to > guest virtqueues > > +by calculating packet hash. Usually every queue is processed then by a > specific guest CPU core. > > + > > +For now there are 2 RSS implementations in qemu: > > +- 'in-qemu' RSS (functions if qemu receives network packets, i.e. > vhost=3Doff) > > +- eBPF RSS (can function with also with vhost=3Don) > > + > > +eBPF support (CONFIG_EBPF) is enabled by 'configure' script. > > +To enable eBPF RSS support use './configure --enable-bpf'. > > + > > +If steering BPF is not set for kernel's TUN module, the TUN uses > automatic selection > > +of rx virtqueue based on lookup table built according to calculated > symmetric hash > > +of transmitted packets. > > +If steering BPF is set for TUN the BPF code calculates the hash of > packet header and > > +returns the virtqueue number to place the packet to. > > + > > +Simplified decision formula: > > + > > +.. code:: C > > + > > + queue_index =3D indirection_table[hash( data>)%] > > + > > + > > +Not for all packets, the hash can/should be calculated. > > + > > +Note: currently, eBPF RSS does not support hash reporting. > > + > > +eBPF RSS turned on by different combinations of vhost-net, vitrio-net > and tap configurations: > > + > > +- eBPF is used: > > + > > + tap,vhost=3Doff & virtio-net-pci,rss=3Don,hash=3Doff > > + > > +- eBPF is used: > > + > > + tap,vhost=3Don & virtio-net-pci,rss=3Don,hash=3Doff > > + > > +- 'in-qemu' RSS is used: > > + > > + tap,vhost=3Doff & virtio-net-pci,rss=3Don,hash=3Don > > + > > +- eBPF is used, hash population feature is not reported to the guest: > > + > > + tap,vhost=3Don & virtio-net-pci,rss=3Don,hash=3Don > > + > > +If CONFIG_EBPF is not set then only 'in-qemu' RSS is supported. > > +Also 'in-qemu' RSS, as a fallback, is used if the eBPF program failed > to load or set to TUN. > > + > > +RSS eBPF program > > +---------------- > > + > > +RSS program located in ebpf/tun_rss_steering.h as an array of 'struct > bpf_insn'. > > +So the program is part of the qemu binary. > > +Initially, the eBPF program was compiled by clang and source code > located at ebpf/rss.bpf.c. > > +Prerequisites to recompile the eBPF program (regenerate > ebpf/tun_rss_steering.h): > > + > > + llvm, clang, kernel source tree, python3 + (pip3 pyelftools) > > + Adjust 'linuxhdrs' in Makefile.ebpf to reflect the location of > the kernel source tree > > + > > + $ cd ebpf > > + $ make -f Makefile.ebpf > > + > > +Note the python script for convertation from eBPF ELF object to '.h' > file - Ebpf_to_C.py: > > + > > + $ python EbpfElf_to_C.py rss.bpf.o tun_rss_steering > > + > > +The first argument of the script is ELF object, second - section name > where the eBPF program located. > > +The script would generate
.h file with eBPF instructions > and 'relocate array'. > > +'relocate array' is an array of 'struct fixup_mapfd_t' with the name o= f > the eBPF map and instruction offset where the file descriptor of the map > should be placed. > > + > > +Current eBPF RSS implementation uses 'bounded loops' with 'backward > jump instructions' which present in the last kernels. > > +Overall eBPF RSS works on kernels 5.8+. > > > This reminds me that we probably need to probe this ability via > configure script. > > I'm not sure. One can boot with an older kernel, build qemu and run it with a newer kernel, correct? > Thanks > > > > + > > +eBPF RSS implementation > > +----------------------- > > + > > +eBPF RSS loading functionality located in ebpf/ebpf_rss.c and > ebpf/ebpf_rss.h. > > + > > +The `struct EBPFRSSContext` structure that holds 4 file descriptors: > > + > > +- ctx - pointer of the libbpf context. > > +- program_fd - file descriptor of the eBPF RSS program. > > +- map_configuration - file descriptor of the 'configuration' map. This > map contains one element of 'struct EBPFRSSConfig'. This configuration > determines eBPF program behavior. > > +- map_toeplitz_key - file descriptor of the 'Toeplitz key' map. One > element of the 40byte key prepared for the hashing algorithm. > > +- map_indirections_table - 128 elements of queue indexes. > > + > > +`struct EBPFRSSConfig` fields: > > + > > +- redirect - "boolean" value, should the hash be calculated, on false > - `default_queue` would be used as the final decision. > > +- populate_hash - for now, not used. eBPF RSS doesn't support hash > reporting. > > +- hash_types - binary mask of different hash types. See > `VIRTIO_NET_RSS_HASH_TYPE_*` defines. If for packet hash should not be > calculated - `default_queue` would be used. > > +- indirections_len - length of the indirections table, maximum 128. > > +- default_queue - the queue index that used for packet that shouldn't > be hashed. For some packets, the hash can't be calculated(g.e ARP). > > + > > +Functions: > > + > > +- `ebpf_rss_init()` - sets ctx to NULL, which indicates that > EBPFRSSContext is not loaded. > > +- `ebpf_rss_load()` - creates 3 maps and loads eBPF program from > tun_rss_steering.h. Returns 'true' on success. After that, program_fd can > be used to set steering for TAP. > > +- `ebpf_rss_set_all()` - sets values for eBPF maps. > `indirections_table` length is in EBPFRSSConfig. `toeplitz_key` is > VIRTIO_NET_RSS_MAX_KEY_SIZE aka 40 bytes array. > > +- `ebpf_rss_unload()` - close all file descriptors and set ctx to NULL= . > > + > > +Simplified eBPF RSS workflow: > > + > > +.. code:: C > > + > > + struct EBPFRSSConfig config; > > + config.redirect =3D 1; > > + config.hash_types =3D VIRTIO_NET_RSS_HASH_TYPE_UDPv4 | > VIRTIO_NET_RSS_HASH_TYPE_TCPv4; > > + config.indirections_len =3D VIRTIO_NET_RSS_MAX_TABLE_LEN; > > + config.default_queue =3D 0; > > + > > + uint16_t table[VIRTIO_NET_RSS_MAX_TABLE_LEN] =3D {...}; > > + uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE] =3D {...}; > > + > > + struct EBPFRSSContext ctx; > > + ebpf_rss_init(&ctx); > > + ebpf_rss_load(&ctx); > > + ebpf_rss_set_all(&ctx, &config, table, key); > > + if (net_client->info->set_steering_ebpf !=3D NULL) { > > + net_client->info->set_steering_ebpf(net_client, > ctx->program_fd); > > + } > > + ... > > + ebpf_unload(&ctx); > > + > > + > > +NetClientState SetSteeringEBPF() > > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > + > > +For now, `set_steering_ebpf()` method supported by Linux TAP > NetClientState. The method requires an eBPF program file descriptor as an > argument. > > --0000000000003761c805b5022280 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Tue, Nov 24, 2020 at 10:55 AM Jaso= n Wang <jasowang@redhat.com&g= t; wrote:

On 2020/11/19 =E4=B8=8B=E5=8D=887:13, Andrew Melnychenko wrote:
> From: Andrew <andrew@daynix.com>
>
> Also, added maintainers information.
>
> Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
> Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
> ---
>=C2=A0 =C2=A0MAINTAINERS=C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A07 +++<= br> >=C2=A0 =C2=A0docs/ebpf_rss.rst | 133 ++++++++++++++++++++++++++++++++++= ++++++++++++
>=C2=A0 =C2=A02 files changed, 140 insertions(+)
>=C2=A0 =C2=A0create mode 100644 docs/ebpf_rss.rst
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 2c22bbca5a..d93c85b867 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3111,6 +3111,13 @@ S: Maintained
>=C2=A0 =C2=A0F: hw/semihosting/
>=C2=A0 =C2=A0F: include/hw/semihosting/
>=C2=A0 =C2=A0
> +EBPF:
> +M: Jason Wang <jasowang@redhat.com>
> +R: Andrew Melnychenko <andrew@daynix.com>
> +R: Yuri Benditovich <yuri.benditovich@daynix.com>
> +S: Maintained
> +F: ebpf/*
> +
>=C2=A0 =C2=A0Build and test automation
>=C2=A0 =C2=A0-------------------------
>=C2=A0 =C2=A0Build and test automation
> diff --git a/docs/ebpf_rss.rst b/docs/ebpf_rss.rst
> new file mode 100644
> index 0000000000..f832defdf4
> --- /dev/null
> +++ b/docs/ebpf_rss.rst
> @@ -0,0 +1,133 @@
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D
> +eBPF RSS virtio-net support
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D
> +
> +RSS(Receive Side Scaling) is used to distribute network packets to gu= est virtqueues
> +by calculating packet hash. Usually every queue is processed then by = a specific guest CPU core.
> +
> +For now there are 2 RSS implementations in qemu:
> +- 'in-qemu' RSS (functions if qemu receives network packets, = i.e. vhost=3Doff)
> +- eBPF RSS (can function with also with vhost=3Don)
> +
> +eBPF support (CONFIG_EBPF) is enabled by 'configure' script.<= br> > +To enable eBPF RSS support use './configure --enable-bpf'. > +
> +If steering BPF is not set for kernel's TUN module, the TUN uses = automatic selection
> +of rx virtqueue based on lookup table built according to calculated s= ymmetric hash
> +of transmitted packets.
> +If steering BPF is set for TUN the BPF code calculates the hash of pa= cket header and
> +returns the virtqueue number to place the packet to.
> +
> +Simplified decision formula:
> +
> +.. code:: C
> +
> +=C2=A0 =C2=A0 queue_index =3D indirection_table[hash(<packet data&= gt;)%<indirection_table size>]
> +
> +
> +Not for all packets, the hash can/should be calculated.
> +
> +Note: currently, eBPF RSS does not support hash reporting.
> +
> +eBPF RSS turned on by different combinations of vhost-net, vitrio-net= and tap configurations:
> +
> +- eBPF is used:
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 tap,vhost=3Doff & virtio-net-pci,rss= =3Don,hash=3Doff
> +
> +- eBPF is used:
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 tap,vhost=3Don & virtio-net-pci,rss= =3Don,hash=3Doff
> +
> +- 'in-qemu' RSS is used:
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 tap,vhost=3Doff & virtio-net-pci,rss= =3Don,hash=3Don
> +
> +- eBPF is used, hash population feature is not reported to the guest:=
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 tap,vhost=3Don & virtio-net-pci,rss= =3Don,hash=3Don
> +
> +If CONFIG_EBPF is not set then only 'in-qemu' RSS is supporte= d.
> +Also 'in-qemu' RSS, as a fallback, is used if the eBPF progra= m failed to load or set to TUN.
> +
> +RSS eBPF program
> +----------------
> +
> +RSS program located in ebpf/tun_rss_steering.h as an array of 'st= ruct bpf_insn'.
> +So the program is part of the qemu binary.
> +Initially, the eBPF program was compiled by clang and source code loc= ated at ebpf/rss.bpf.c.
> +Prerequisites to recompile the eBPF program (regenerate ebpf/tun_rss_= steering.h):
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 llvm, clang, kernel source tree, python3 = + (pip3 pyelftools)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Adjust 'linuxhdrs' in Makefile.eb= pf to reflect the location of the kernel source tree
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ cd ebpf
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ make -f Makefile.ebpf
> +
> +Note the python script for convertation from eBPF ELF object to '= .h' file - Ebpf_to_C.py:
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ python EbpfElf_to_C.py rss.bpf.o tun_rs= s_steering
> +
> +The first argument of the script is ELF object, second - section name= where the eBPF program located.
> +The script would generate <section name>.h file with eBPF instr= uctions and 'relocate array'.
> +'relocate array' is an array of 'struct fixup_mapfd_t'= ; with the name of the eBPF map and instruction offset where the file descr= iptor of the map should be placed.
> +
> +Current eBPF RSS implementation uses 'bounded loops' with = 9;backward jump instructions' which present in the last kernels.
> +Overall eBPF RSS works on kernels 5.8+.


This reminds me that we probably need to probe this ability via
configure script.


I'm not sure. One can boot with an= older kernel, build qemu and run it with a newer kernel, correct?
=C2=A0
=C2=A0
Thanks


> +
> +eBPF RSS implementation
> +-----------------------
> +
> +eBPF RSS loading functionality located in ebpf/ebpf_rss.c and ebpf/eb= pf_rss.h.
> +
> +The `struct EBPFRSSContext` structure that holds 4 file descriptors:<= br> > +
> +- ctx - pointer of the libbpf context.
> +- program_fd - file descriptor of the eBPF RSS program.
> +- map_configuration - file descriptor of the 'configuration' = map. This map contains one element of 'struct EBPFRSSConfig'. This = configuration determines eBPF program behavior.
> +- map_toeplitz_key - file descriptor of the 'Toeplitz key' ma= p. One element of the 40byte key prepared for the hashing algorithm.
> +- map_indirections_table - 128 elements of queue indexes.
> +
> +`struct EBPFRSSConfig` fields:
> +
> +- redirect - "boolean" value, should the hash be calculated= , on false=C2=A0 - `default_queue` would be used as the final decision.
> +- populate_hash - for now, not used. eBPF RSS doesn't support has= h reporting.
> +- hash_types - binary mask of different hash types. See `VIRTIO_NET_R= SS_HASH_TYPE_*` defines. If for packet hash should not be calculated - `def= ault_queue` would be used.
> +- indirections_len - length of the indirections table, maximum 128. > +- default_queue - the queue index that used for packet that shouldn&#= 39;t be hashed. For some packets, the hash can't be calculated(g.e ARP)= .
> +
> +Functions:
> +
> +- `ebpf_rss_init()` - sets ctx to NULL, which indicates that EBPFRSSC= ontext is not loaded.
> +- `ebpf_rss_load()` - creates 3 maps and loads eBPF program from tun_= rss_steering.h. Returns 'true' on success. After that, program_fd c= an be used to set steering for TAP.
> +- `ebpf_rss_set_all()` - sets values for eBPF maps. `indirections_tab= le` length is in EBPFRSSConfig. `toeplitz_key` is VIRTIO_NET_RSS_MAX_KEY_SI= ZE aka 40 bytes array.
> +- `ebpf_rss_unload()` - close all file descriptors and set ctx to NUL= L.
> +
> +Simplified eBPF RSS workflow:
> +
> +.. code:: C
> +
> +=C2=A0 =C2=A0 struct EBPFRSSConfig config;
> +=C2=A0 =C2=A0 config.redirect =3D 1;
> +=C2=A0 =C2=A0 config.hash_types =3D VIRTIO_NET_RSS_HASH_TYPE_UDPv4 | = VIRTIO_NET_RSS_HASH_TYPE_TCPv4;
> +=C2=A0 =C2=A0 config.indirections_len =3D VIRTIO_NET_RSS_MAX_TABLE_LE= N;
> +=C2=A0 =C2=A0 config.default_queue =3D 0;
> +
> +=C2=A0 =C2=A0 uint16_t table[VIRTIO_NET_RSS_MAX_TABLE_LEN] =3D {...};=
> +=C2=A0 =C2=A0 uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE] =3D {...};
> +
> +=C2=A0 =C2=A0 struct EBPFRSSContext ctx;
> +=C2=A0 =C2=A0 ebpf_rss_init(&ctx);
> +=C2=A0 =C2=A0 ebpf_rss_load(&ctx);
> +=C2=A0 =C2=A0 ebpf_rss_set_all(&ctx, &config, table, key); > +=C2=A0 =C2=A0 if (net_client->info->set_steering_ebpf !=3D NULL= ) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 net_client->info->set_steering_ebpf= (net_client, ctx->program_fd);
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 ...
> +=C2=A0 =C2=A0 ebpf_unload(&ctx);
> +
> +
> +NetClientState SetSteeringEBPF()
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +For now, `set_steering_ebpf()` method supported by Linux TAP NetClien= tState. The method requires an eBPF program file descriptor as an argument.=

--0000000000003761c805b5022280--