Can DPDK selectively init NIC ports - c

I'm using an dual-port NIC, Mellanox ConnectX-5, and the DPDK version is dpdk-stable-19.11.3. After configuration, the call of rte_eth_dev_count_avail() returns 2. But only one port of my ConnectX-5 NIC is connected to the other machine. All I can find is to init all available ports like this.
RTE_ETH_FOREACH_DEV(portid)
if (port_init(portid, mbuf_pool) != 0)
rte_exit(EXIT_FAILURE, "Cannot init port %u\n", portid);
Can dpdk selectively init ports? Or is there any way to make rte_eth_dev_count_avail() returning 1?

Another quick way to assign a particular port out all available ports to DPDK application by using DPDK tool dpdk-devbind.py and EAL port initialization will pick port which is assigned to UIO/VFIO kernel driver. Below are devbind script steps to identify port current status and how to bind required port to DPDK.
[root#linux usertools]# ./dpdk-devbind.py --status
Network devices using kernel driver
===================================
0000:00:03.0 '82540EM Gigabit Ethernet Controller 100e' if= drv=e1000 unused=vfio-pci
0000:00:04.0 '82540EM Gigabit Ethernet Controller 100e' if= drv=e1000 unused=vfio-pci
[root#linux usertools]# ./dpdk-devbind.py --bind=vfio-pci 00:04.0
[root#linux usertools]# ./dpdk-devbind.py --status
Network devices using DPDK-compatible driver
============================================
0000:00:04.0 '82540EM Gigabit Ethernet Controller 100e' drv=vfio-pci unused=e1000
Network devices using kernel driver
===================================
0000:00:03.0 '82540EM Gigabit Ethernet Controller 100e' if= drv=e1000 unused=vfio-pci
[EDIT-1] based on the updated question from author, the request is identify from the available DPDK ports which is connected? as mentioned above answer one needs to use rte_eth_link_get

Yes one can selectively init ports by passing the right PCIe Bus:Device:Function address as a whitelist. Hence only desired ports will pop up in the application.
How to do it:
create a dummy application to take in all DPDK port.
Initialize and start the dpdk ports. Check for link-state and create port-mask (global variable) which filters in application logic.
Invoke rte_eth_dev_stop & rte_eth_dev_close for link down ports.
Invoke rte_eal_cleanup.
Use the port-mask, as an argument for execv to invoke your desired DPDK application.
this way you can run your application with valid ports to it.
But relying on rte_eth_link_get is tricky because
if the other end is connected to dpdk-pktgen, first your DPDK application has to init the NIC locally.
if connected to linux box, the nic has to be bought up first with ifconfig [other nic] up
at times one needs to check link.link_speed if its valid.
certain PMD needs write to PCIe mapped register, hence has to dev_configure and port_init to get a reliable reading for link status.
Hence safest and recommended way to use is identify the NIC PCIe B:D:F in Linux driver and then whitelist the ports by using option -w for the desired port under igb_uio/virtio-pci. This can be done by bind all NIC back in linux by
lshw -c network -businfo will list NIC and PCIe Bus:Device:Function with kerel device name and driver.
use ethtool [eth device name] | grep Link to identify the link is connected.
for reference, you can use https://github.com/vipinpv85/DPDK-APP_SAMPLES/blob/master/auto-baseaddr-selector.c as template for dummy applciation.

Related

How to receive data from tun interface to dpdk binded NIC?

I want to have any Traffic generator(say iperf,D-ITG or even ping) to send data to a tun interface. This tun interface should automatically forward to NIC which is binded to DPDK. I want to run l3fwd example which picks up data from the interface.
I used the option --vdev=net_tun0 in commandline which creates tun interface. I thought tun/tap PMD will automatically poll the packets at tun/tap interface and redirect to/from NIC. But, that's not happening. I am not able to receive any packets.
I require dpdk and traffic generator to run on the same PC. DPDK should pick the traffic at the userspace.
Since the question is not that clear (whether it is DPDK RX-TX or Kernel RX-TX), here are the answers for DPDK application point of view
DPDK TUN PMD allows creating Kernel TUN interface with ip layer
onwards (there is no MAC Layer). just like all PMD devices, you have
to poll with rte_eth_rx_burst and use rte_eth_tx_burst inside
DPDK Application.
Similarly, if you plan to use TAP PMD, dpdk will create Kernel TAP
the interface which has to be polled with rte_eth_rx_burst and
rte_eth_tx_burst inside DPDK application.
Once you use vdev=net_tap0 this creates Kernel tap interface dtap0. So to grab packets received to Kernel interface you have call rte_eth_rx_burst to send a specific packet to Kernel TAP interface you need to use rte_eth_tx_burst.
as per your requirement which is to direct any traffic generator to kernel to TAP interface, then send to physical NIC bound with DPDK, this what you have to do
make use a simple application like examples/skeleton or testpmd or examples/l2fwd with no mac update`
ensure you pass the vdev=net_tap0,iface=<your desired name for interface> to the DPDK application.
Using ip or ifconfig bring up the interface with ip address and the state as up (Promisc mode is optional).
ensure your destination address route is through tap interface by cross-checking route -n.
now kick start your traffic generator with dest-ip and interface as required.
Note: In my deployment case, I ended up setting static ARP too.
This will send the packet to kernel TAP interface, which is then intercepted by DPDK application via rx_burst calls. Using port to port forward behaviour this is then forwarded to DPDK Physical NIC. In reverse direction, the packet received from physical nic is bought into the application by rx_burst and then tx_burst to TAP PMD. this will then inject to the kernel TAP interface.

Force connection on specific USB port/symlink

I am planning to use Dump1090 and I want to have 2 RTLSDR dongles on the same computer, always plugged into the same USB port. I am planning to assign a symlink "adsb" to the port for the RTL dongle that has an ADS-B antenna connected to it. Is there a way to force the connection on this specific USB port?
By default, the code takes the first device available.
Thank you
https://github.com/antirez/dump1090/blob/master/dump1090.c

BLE Bridge Mode in Linux example

I want to use Bluetooth(4.0) on my board to transmit it's Name so any Mobile Application can see it's name and Mobile application initiates the pairing and connection with my Bluetooth.
I have seen some examples of Bluetooth(4.0) scanning nearby devices; For example:- It does scan for Bluetooth Mouser/Keyboard, but in this case Bluetooth(4.0) is in mode where it chooses the device it want to connect while I want it reverse so Any mobile application can see my Bluetooth and gets connect with it and does communication.
How can I put my Bluetooth(4.0) in such mode in Linux? Is there any C library using which I can put Bluetooth(4.0) is the mode where it goes in Bridge mode instead of scanning nearby devices?
You can set the name of your device like this:
hciconfig name "foo"
and check your name with:
hciconfig name
You also have to enable Low Energy advertising for your device to be found by others:
hciconfig leadv
You can configure your device to accept incoming connections like this (lm for link mode):
hciconfig lm MASTER,ACCEPT
This way the kernel will accept a connection, even if there are no listening sockets.
Considering you want to do actual communication, you would need to write a program, accepting the connection and sending/receiving data. Just putting your device in a mode where other devices can connect to it isn't really worth anything (because you can't communicate).
The basic principle is to open up an L2CAP socket, with the Channel ID of 4 (for Low Energy), then do standard bind/listen/accept. I suggest you look at the source code of Bluez and the examples.

How to implement Serial Port Profile Link Command used in ConnectBlue Bluetooth Module?

I am trying to implement Bluetooth using "connect-blue-oem-spa-331" module using UART protocol and using MSP430 as base controller. I'm using Embedded C as a language of programming.
Everything just works fine until I reach to Serial Port Link Command "AT*ADCP". Every time I get response as ERROR. I have tried with both options by keeping ECHO ENABLED and ECHO DISABLED.
p_cmd = "AT*ADCP=XXXXXXXXXXXX,0,0,0\r";
this is my command. 'X' represents the Bluetooth confirm device address which I confirm when I execute DEVICE_INQUIRY command.
The module through which I am executing all these commands is always MASTER and will initiate pairing and communication process. As a safety I have kept it non-discoverable.
How can I implement the Serial Port Profile Link command without getting error when I confirm the bluetooth device using DEVICE_INQUIRY command.
I have been working with blue tooth for last 4 months. I had faced above issue in early days. And after running through documentation available for product I solved the issue. I thought to reply this question which I've asked.
I was using Connect Blue OEM-SPA-331i classic Bluetooth module in my project, and was using Serial Port Profile to implement Bluetooth commands.
When I inquire devices I get the list of Bluetooth Devices available and discoverable in the vicinity(mine was CLASS-I Device); and lists them as (48 bit MAC Address,Class of Device) i.e. ( 001234ab987f,786545) of the discovered Bluetooth Module.
When I'm trying to establish Serial Port Profile Link, it was required that I must write address of peer device to be connected over Serial Port Profile in Serial Port Adapter. The order of the commands should be
Inquire discoverable devices
Write the desired peer device address to Serial Port Adapter, remember it in power cycles.
Establish Profile Link.
This way I resolved my issue of link not getting established.

How to debug a "openvswitch" like kernel modules program in a virtual machine environment?

I am working on a project like "openvswitch" --- a linux kernel modules that interfaces with
various network interface cards.
You can bind some network interfaces (like eth0, eth1) to the module, and then packet received from the interfaces will be handled by the kernel module (it may modified the packet header and send the packet from another binding interface).
In a virtual machine environment, I can easily do the development work (kernel space programming often crash the machine) but I can hardly do the testing work. It is difficulty to
send a specific packet to the vm's specific interface. Is there any easy way for this?
Use a traffic generation tool like Scapy on your hypervisor to send traffic to the virtual NICs that are attached to your VM. With qemu/libvirt these interfaces normally come up as "vnet0", "vnet1", etc.
Do not use bridges, but send traffic directly to the vnic. Linux bridges are good at forwarding IP traffic but will not let every ethernet frame go through unmodified.

Resources