can dpdk KNI module support to receive GRO packets? - dpdk

As described above, I passed a GRO tcp packet to the rte_kni_tx_burst function, which will eventually be converted to an skb and passed to the kernel(netif_rx_ni), but it doesn't seem to work. can KNI module support to receive GRO packets?
https://github.com/DPDK/dpdk/blob/v19.11/kernel/linux/kni/kni_net.c#L414

Related

How to send packet another server using dpdk?

My question is how to send packet another Physical Server from my Computer using dpdk.
I already watched example code rxtx_callbacks and i want to use this code.
but there is no place to enter a specific ip and port to another server.
how i can send packets to places on a server using dpdk with specified ip and port?
and how i can receive packets using dpdk?
Is l3fwd correct or is this another concept?
help me
DPDK is an open-source library that allows one to bypass Kernel and ETH-IP-TCP stack to send packets from userspace directly on NIC or other custom hardware. There are multiple examples and projects like pktgen and TREX which uses to generate user-defined packets (desired MAC address, VLAN, IP and TCP-UDP) payload.
For the queries
how i can send packets to places on a server using dpdk with specified ip and port?
[Answer] make use of DPDK PKTGEN as an easy way to generate. Other examples are pcap based burst replay and trex.
But the easiest way to generate and send traffic is using scapy with DPDK sample application skeleton. Following are the steps required to achieve the same.
Install DPDK to desired platform (preferably Linux)
build the DPDK example skeleton found in path [dpdk root folder]/examples/skeleton
bind a physical NIC (if traffic needs to be send out of server) with userspace drivers like igb_uio, uio_pci_generic or vfio-pci
start the application with options '-l 1 --vdev=net_tap0,iface=scapyEth'. this will create TAP interface with name scapyEth.
using scapy now create your custom packet with desired MAC, VLAN, IP and Port numbers.
and how i can receive packets using dpdk?
[Answer] on receiver side run DPDK application like testpmd, l2fwd, or skeleton if packets needs to received by Userspace DPDK application or any Linux sockets can receive the UDP packets.
Note: easiest way to check whether packets are received is to run tcpudmp. example tcpdump -eni eth1 -Q in (where eth1 is physical interface on Reciever Server.
Note: Since the request how i can send packets to places on a server is not clear
Using DPDK one can send packets through a physical interface using dedicated NIC, FPGA and wireless devices
DPDK can send packets among applications using memif interface
DPDK can send packets between VM using virtio and vhost
DPDK can send and receive packets to kernel, where Kernel routing stack and ARP table determine which kernel interface will forward the packets.

Getting the destination IP of incoming UDP packet in C++

I found the function: GetTcpTable in C++. In the header: iphlpapi.h. That gives me the destination IP of TCP packet and I was wondering if there's a function from the same header that would give me the destination IP of UDP packet... I tried the function: GetUdpTable but it gives only the local IP and port. I will be more than happy if that function has also code example in C++ of course. Thank you anyway!
EDIT:
I using pcap.h now and i still don't know how to catch UDP packets and take from them the ip. There is a code that i can use?
GetTcpTable() does not give you the destination IP of TCP packets. It merely gives you a list of currently listening TCP ports and active TCP connections.
GetUdpTable() can give you the list of currently listening UDP ports, where UDP packets can be sent to. There are no connections in UDP.
But, if you want to know the actual destination IP for each UDP packet received, and without having to use a low-level capture library like WinPCap, then you can use the WSARecvMsg() function to receive your UDP packets, rather than using the recvfrom() or even recv() function.
WSARecvMsg() can report metadata about each packet, most notably the IP_PKTINFO (IPv4) and IPV6_PKTINFO (IPv6) control blocks, which specify the destination IP of the packet and the index of the network interface that received the packet.
You need to use WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER) to obtain a pointer to the WSARecvMsg() function (see Why is the WSARecvMsg function implemented as a function pointer and can this pointer be reused? for the reason why), and use setsockopt() to enable the IP_PKTINFO/IPV6_PKTINFO socket option, before you start calling WSARecvMsg() to receive packets.
See Function to retrieve the header destination address from a packet in windows XP for an example.

C++ (BSD Sockets) - Modify incoming packets before forwarding:

I'm using a Linux (Debian based) system on which IP forwarding is enabled (/proc/sys/net/ipv4/ip_forward is set to 1). I can read the incoming packets using a C++ raw sockets program, but I want to modify their content before they are forwarded (using BSD sockets only). This link mentions that I can use an "iptables REDIRECT rule" to send the incoming packets to a port my program is listening on, but I didn't find any information on how exactly this should be done. Mainly, I want to know:
How I should forward the packets after modifying them. Do I have to send them manually from the program to their destination address after they are received and modified?
What I should do in case the program isn't listening on a particular port (e.g. a program concerned with only the IP headers of the packets).
In case it matters receiving and forwarding are done on the same wireless interface. I have to forward packets to, and receive packets from devices on the same WLAN.

Single socket sends and receives over both wlan and eth interface

Using C++ I create a single UDP socket, supplying both an IPv4 address and port. I run this on Ubuntu and have both a wlan0 and eth0 interface up and running. Apparently something decides that both interfaces should be used, I appreciate that. Sending and receiving using a different interface does create a kind of a pickle (NAT traversal???) for me though. Using Wireshark I can see packages coming in, but my application does not register them.
To clarify:
I have a tracker which will supply me with a peer. The tracker will also contact that peer to send me a message. In order to overcome NAT traversal issues, I will send a puncture message.
The problem now is that the puncture messages is sent over wlan (I am testing locally with two machines), whereas the messages from the peer are coming in over eth.
So, I think the simplest solution would be to simply use one interface. (Or both one socket)
EDIT:
I will try what is mentioned here on specifying a single interface.
#Barmar, pointed out that UDP sockets may change interface when sendto is called with a destination address that would benefit from it.
I am still fuzzy on the reason for my problem though. Can someone explain why this is an issue in the first place?
EDIT2:
The above mentioned solution of forcing one interface for the socket bind did not work. Apparently the sendto method will choose to ignore this and still go for the other interface if it feels that that will work better.
Does anyone know how to make sure that socket sticks to the interface it was assigned to?
If you need to ensure that UDP replies come from the same address that the request was sent to, the solution is to use multiple sockets. You open one socket for each IP of the server (this may be more than one socket per interface, because of interface aliases), and bind the socket to that IP. Then you use select() or poll() to wait for requests on all sockets at once. When a request comes in on a particular socket, you send the reply out through that same socket, and its source IP will match the original packet's destination.

How to find the destination address of a UDP packet using boost::asio?

I'm developing a peer-to-peer communications network for use over a LAN in an industrial environment. Some messages are are just asynchronous, and don't require a response. Others are request-response. The request messages (and the async messages) are sent to a multicast group, and the replies to requests are sent unicast. Each endpoint, therefore, receives UDP packets that are sent to the multicast group, and also receives messages that are just sent to it using plain unicast.
So far it's working fine, but there doesn't seem to be any way in boost::asio to find out the destination address of a received UDP packet (using socket.async_receive_from) - whether it was sent to the multicast group or the actual interface. I can use the contents of the message to infer whether it was sent multicast or unicast, but it would be nice to be able to also check the destination address.
We are currently using Windows 7, but will be transitioning to Linux in the future.
Is there a way to find the destination address of a UDP packet received using boost::asio?
Unfortunately this is not possible with boost::asio, and usually is not "the way to do" it, as you try to access Transport Layer information at the Application Layer.
So you basically have two options:
a) Write non-portable system code with for example IP_PKTINFO or SO_BINDTODEVICE on Linux. Example Code can be found on the boost asio mailing list here
b) use two distinct sockets, one for the multicast and one for the unicast. You therefore need to specify a listen_address other than "0.0.0.0" on each socket.
udp::endpoint(address_v4::from_string("239.192.152.143"), 6771)
This Question on SO might also be helpful: Using a specific network interface for a socket in windows