How to use ebpf over dpdk without maps - dpdk

I need to run an ebpf security app over dpdk but don't have maps to do it.
Without dpdk the ebpf app parses every incoming packet 5tuple and other params and compares them with an ebpf map containing ACLs. Packets matching the ACLs are dropped. The map is being dynamically updated with ACLs by a user space app.
However in the dpdk implementation of ebpf there are no maps.
Is there an alternative way to feed the ebpf app with a list of ACL rules and update them dynamically ?

There are no BPF maps in the DPDK implementation of eBPF and no other way to persist state between two runs of the BPF VM. So your best bet is indeed to encode that information into the program itself.

[EDIT-1] for the question Is there an alternative way to feed the ebpf app with a list of ACL rules and update them dynamically ?
[Answer] yes there is, please refer to option-1 below for running eBPF code in dpdk thread context to get access to tables, acl and other huge page cotnext.
There are 2 instances of EBPF in DPDK
running eBPF code in DPDK thread context
Running eBPF with AF_XDP to inject the packet to DPDK process
eBPF in DPDK thread context: is intended to allow user to create sandbox logic that run in DPDK threads or callback achieving goals like dynamic debug, debug counters, special rules etc.
eBPF in AF_XDP: is not part of DPDK logic, but part of kernel packet processing via XDP. Packets that are marked to be sent to DPDK can use AF_XDP sockets via BPF map to sent to DPDK application. The advantage with this approach the NIC interface need not bind with UIO drivers like uio_pci_generic, vfio-pci or igb_uio
Since it is not clear from the question I need to run an ebpf security app over dpdk, please find answers for both
Method-1 (eBPF context on DPDK threads): In this approach, you will rewrite and adopt the XDP ebpf to accept MBUF strcut data (or mtod of MBUF) to access ethernet + payload. EBPF 5 tuple maps need to be converted to lookup either with DPDK API or custom API to compare against packet 5 Tuple. To mimic the same behaviour as eBPF Maps updated via user application, you will need to make use DPDK multiple process (secondary application) to update 5 tuple table entries.
Method-2 (eBPF context in Kernel XDP hooks): using the existing eBPF security app built the binary. Using DPDK AF_XDP load the eBPF binary to the interface. Update the 5 tuple lookup table by BPF API (Python or C or GO) wrapper appropriately (as you are done previously).
Note:
If you are using method-1, To achieve native performance my recommendation is to rewrite the eBPF code DPDK API (since you want to use DPDK). One can leverage HW offloads, multiple queues, PTYPES, RTE_FLOW and there is no overhead to run the sandbox eBPF in the DPDK thread context.
If you are using method-2 Since the action for 5 tuple match is drop I have to assume in case of a match you would be injecting back to kernel. hence DPDK thread is not required. Unless you have specific packets to be processed by DPDK userspace.
The shared userspace can be created with rte_malloc which can be accessed by multiple DPDK process.

Related

enable Dpdk application talk to Linux process

I have DPDK-20.11.3 installed.
Given that a Dpdk application is a process from the Linux point of view, I would assume that there should be ways (possibly with constraints) of communication between the Dpdk application and Linux native application (capable of using Linux sockets interface).
What are the possible options, that I could explore? Pipes, shared memory? I don't have any tcp/ip stack ported on dpdk, so I likely can't use sockets at all?
I'd appreciate links and documents that could shed some light on this. Thanks!
You can use KNI interface. Here is the Sample app for the same.
https://doc.dpdk.org/guides-20.11/sample_app_ug/kernel_nic_interface.html
As clarified over comments the real intention is to send and receive full or partial packets into the Kernel network subsystem. The easiest way is to make use of DPDK PCAP PMD or TAP PMD.
How to use:
Tap:
ensure the DPDK application is running in a Linux environment.
making use of DPDK testpmd, l2fwd or skeleton update DPDK EAL by --vdev=net_tap0.
Starting DPDK application will result in tap interface dtap0
bring the interface up by sudo ip link set dtap0 up
One can assign an IP address or use a raw promiscuous device.
pinging both kernel thread and DPDK TAP PMD thread, up to 4Gbps of packet throughput can be achieved for small packets.
PCAP:
Create veth interface pair in Linux using ip link add dev v1 type veth peer name v2
use v1 in linux network subsystem
use v2 in dpdk application by --vdev=net_pcap0,iface=v2
Note:
my recommendation is to use the TAP interface since it is a dedicated PMD handling probe and removed with the DPDK application. Assigning IP address from Linux also allows it to be part of a local termination, firewall and netfilter processing. All kernel network knobs for ipv4formward, TCP, udp and sctp can be exercised too.
I do not recommend the use of KNI PMD, since it is deprecated and will be removed, additional thread in the kernel to handle the buffer management and Netlink, external dependency to be built (not done for most distros package distribution).
environment

How to add veth interfaces in dpdk

I need to create a veth device for the slowpath for control packets.
What I tried till now:
I have created veth interfaces using below command
sudo ip link add veth1-2 type veth peer name veth2-1
when I use command sudo dpdk-devbind.py --bind=igb_uio veth1-2 to add veth into dpdk.
It gives me an error that "Unknown device: veth2-1
Is there any way we can add veth interfaces in dpdk ?
If you want a "dpdk-solution", then what you'll want to look at is KNI: https://doc.dpdk.org/guides/prog_guide/kernel_nic_interface.html
From their docs:
The DPDK Kernel NIC Interface (KNI) allows userspace applications access to the Linux* control plane.
The benefits of using the DPDK KNI are:
Faster than existing Linux TUN/TAP interfaces (by eliminating system
calls and copy_to_user()/copy_from_user() operations.
Allows management of DPDK ports using standard Linux net tools such as
ethtool, ifconfig and tcpdump.
Allows an interface with the kernel network stack.
If your fine using a non-dpdk solution, then a TUN/TAP device is a typical way to interface with the networking stack. Your application would receive packets on the dpdk-controlled nic, and if it is a control packet you would simply forward it on to the TUN/TAP device (or KNI if using DPDK's version of TUN/TAP). Similarly for the other direction, if the TUN/TAP/KNI device receives a packet from the networking stack, you would simply send it out the DPDK physical nic.

Multiple Simultaneous gRPC connections to different servers via different interfaces (eth0, wlan0, ppp0)

We have started using gRPC C++ for our embedded system project (ARM Processor Cortex-A7) as a client. We have successfully created a sample application which communicates with the server using protobuf.
We have a new requirement now. We have to open multiple connections to the different endpoints (or server) via different interfaces (like ethernet, wifi and cellular [using ppp]).
I tried to google but couldn't find any solutions to it. I have tried gRPC forum but hasn't received a proper reply to my question.
I have wondering if gRPC has provision to bind to a particular interface or IP. Linux POSIX socket provides SO_BINDTODEVICE option but I am not sure if gRPC has any application layer method or function to achieve it (can't find it in the documentation).
Or Can we achieve it via some other hack (may be by modifying the routing table?).

Is it possible to write a web server using Intel DPDK?

I am a newbie to Intel DPDK.
I am planning to write an http web server.
Can it be implemented using the following logic using DPDK ?
Get the packets and send it to Worker Logical Cores.
A Worker Logical Core build 'http reuqest' sent by the client, using
the incoming packets.
Process the 'http reuest' in the Worker Logical Core and produce an
'http response'.
Create packets for the 'http response' and dispatch them to output
software rings.
I am not sure whether the above is feasible or not.
Is it possible to write a web server using Intel DPDK?
It is lot of work since you'll need a TCP/IP stack on top of the DPDK. Even once you'll have ported a TCP/IP stack on top of DPDK (or reusing a port from an OS), you won't have the performance because it is easy to write C code that runs, but writting a TCP/IP stack that sustains good performances, it is a very difficult development.
You can try http://www.6wind.com/6windgate-performance/tcp-termination/ : they do not provide a HTTP server, but they provide a L7 like TCP socket support to build the fastest HTTP servers.
Yes, its possible to build a Web Server using DPDK. You could either use a KNI interface provided by DPDK. All packets received on a KNI interfaces are still routed through the kernel network stack -- however, and heres the catch, this is still faster than directly receiving packets from the kernel (requires multiple copies). With DPDK you could still ping cores to RX and different lcores to TX. You could then instruct your OS not to use these lcores for anything else. So you really have dedicated lcores for packet TX and RX. Ensure that Tx and RX lcores lie on different CPU sockets.
More information at:
http://dpdk.org/doc/guides/sample_app_ug/kernel_nic_interface.html

What's the best RPC package to write a C++ client/server for a peer-to-peer system?

I have a program that performs compute-heavy local processing. The compute packages have 16MiB input buffers and generate between 10KB and 16MiB of output. This all happens in a multi-threaded environment.
I have a number of users who are compute-bound. I'm interested in adding support for peer-to-peer multiprocessing. That is, clients would be run on multiple computers in the organization. The master would find available clients, send them 16MiB buffers, and then get the results.
The master will have a list of available clients. It will then send a message to each client that it is free. The clients will start a thread for each core that they have. Each thread will ask the master for a work buffer, will compute the results, and will then send the results to the master. The master will incorporate the results from each client into the final output.
A typical run involves crunching between 100 and 50,000 16MiB buffers. The output is typically in the 100MB to 10GB range. There are no data dependencies between the buffers.
I'm looking for the best way to arrange the communications between the client and the server. My plan is to use some kind of RPC. I do not want to embed a web server in either the client or the server. Instead, my plan is to simply receive connections on a TCP socket and have some kind of basic RPC.
Here are the options I'm considering:
I can role my own client/server system and use protocol buffers to put the whole thing together.
I could use one of the existing RPC systems for potocol buffers.
I could embed a web server and use XMLRPC.
The implementation language is C++. The program compiles for Linux, MacOS, and with mingw for Windows.
Thanks.
We found that 0MQ met our criteria.