DPDK IP reassemble API returns NULL - dpdk
I am new to DPDK, currently testing IP reassemble API and I am having difficulties. Below is the C++ code which I wrote to test the IP reassemble. I took the reference from the examples list provided from dpdk itself. dpdk version which I am using is 20.08 in debian machine. dpdk user guide mentions the API works on src add, dst add and packet ID, even though all three data are proper still the API returns NULL. Any kind of help will be much appreciated. Thanks in advance.
Search the Fragment Table for entry with packet’s <IPv4 Source Address, IPv4 Destination Address, Packet ID>.
If the entry is found, then check if that entry already timed-out. If yes, then free all previously received fragments, and remove information about them from the entry.
If no entry with such key is found, then try to create a new one by one of two ways:
Use as empty entry.
Delete a timed-out entry, free mbufs associated with it mbufs and store a new entry with specified key in it.
Update the entry with new fragment information and check if a packet can be reassembled (the packet’s entry contains all fragments).
If yes, then, reassemble the packet, mark table’s entry as empty and return the reassembled mbuf to the caller.
If no, then return a NULL to the caller.
CONFIG_RTE_LIBRTE_IP_FRAG=y
CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG=y
CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG=100
CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=n
#define DEF_FLOW_NUM 0x1000
#define DEF_FLOW_TTL MS_PER_S
#define IP_FRAG_TBL_BUCKET_ENTRIES 128
static uint32_t max_flow_num = DEF_FLOW_NUM;
static uint32_t max_flow_ttl = DEF_FLOW_TTL;
struct lcore_queue_conf {
struct rte_ip_frag_tbl *frag_tbl;
struct rte_mempool *pool;
struct rte_ip_frag_death_row death_row;
}__rte_cache_aligned;
static struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];
static inline int setup_queue_tbl(struct lcore_queue_conf *qconf)
{
uint64_t frag_cycles = (rte_get_tsc_hz() + MS_PER_S - 1) / MS_PER_S * max_flow_ttl;
qconf->frag_tbl = rte_ip_frag_table_create(max_flow_num, IP_FRAG_TBL_BUCKET_ENTRIES, max_flow_num, frag_cycles, rte_socket_id());
if((qconf->frag_tbl) == NULL){
RTE_LOG(ERR, IP_RSMBL, "Table Failed.");
return -1;
}
qconf->pool=rte_pktmbuf_pool_create("BUFFER", POOL_SIZE*2, POOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
if(qconf->pool== NULL){
RTE_LOG(ERR, IP_RSMBL, "Mem Pool Failed.");
return -1;
}
return 0;
}
static inline void reassemble(struct rte_mbuf *reassemblepkt, struct lcore_queue_conf *qconf, uint64_t cur_tsc)
{
struct rte_mbuf *mo;
struct rte_ether_hdr *eth_hdr;
struct rte_ipv4_hdr *ip_hdr;
eth_hdr = rte_pktmbuf_mtod(reassemblepkt, struct rte_ether_hdr *);
ip_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1);
if (rte_ipv4_frag_pkt_is_fragmented(ip_hdr)){
reassemblepkt->l2_len = sizeof(*eth_hdr);
reassemblepkt->l3_len = sizeof(*ip_hdr);
int ip_len;
ip_len = rte_be_to_cpu_16(ip_hdr->total_length);
mo = rte_ipv4_frag_reassemble_packet(qconf->frag_tbl, &qconf->death_row, reassemblepkt, cur_tsc, ip_hdr);
if (mo == NULL){
cout << "Total Length: " << ip_len << ", l3 length: " << reassemblepkt->l3_len << " ,Packet ID: " << ip_hdr->packet_id << " , src add:" << ip_hdr->src_addr << " , dst add:" << ip_hdr->dst_addr << endl;
RTE_LOG(ERR, IP_RSMBL, "Reassemble Failed.\n");
}
if ((mo != reassemblepkt) && (mo != NULL)){
cout << "Reassemble is success." << endl;
reassemblepkt = mo;
}
}
}
static int
lcore_main(struct lcore_queue_conf *qconf)
{
int rx, rec;
struct rte_mbuf *bufs[BUFFER_LENGTH];
uint64_t cur_tsc;
int i;
RTE_ETH_FOREACH_DEV(port){
cout << "RX Thread: Socket ID: " << rte_socket_id() << endl;
cout << "RX Thread: lcore count: " << dec << rte_lcore_count() << endl;
cout << "RX Thread: lcore ID: " << rte_lcore_id() << endl;
cout << "RX Thread Started." << endl;
cout << "=====================================================" << endl;
}
while(!quit_signal) {
cur_tsc = rte_rdtsc();
RTE_ETH_FOREACH_DEV(port){
rx=rte_eth_rx_burst(port, 0, bufs, BUFFER_LENGTH);
if(unlikely(rx == 0 ))
continue;
if(rx){
for(i=0; i<rx; i++)
reassemble(bufs[i], qconf, cur_tsc);
rte_ip_frag_free_death_row(&qconf->death_row, PREFETCH_OFFSET);
rec = rte_ring_enqueue_burst(Myring, (void **)bufs, rx, NULL);
}
}
}
return 0;
}
int main(int argc, char *argv[])
{
int ret;
uint16_t portcheck;
DPDKPORT p1;
struct lcore_queue_conf *qconf;
/* catch ctrl-c so we can print on exit */
signal(SIGINT, int_handler);
/* EAL setup */
ret=rte_eal_init(argc, argv);
cout << "=====================================================" << endl;
if(ret < 0)
cout << "EAL initialising failed." << strerror(-ret) << endl;
else
cout << "EAL initialisation success." << endl;
qconf = &lcore_queue_conf[rte_get_master_lcore()];
if(setup_queue_tbl(qconf) != 0)
rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno));
.
.
.
.
RTE_ETH_FOREACH_DEV(portcheck){
if(p1.eth_init(portcheck, qconf->pool) != 0)
rte_exit(EXIT_FAILURE, "Ethernet port initialisation failed.");
}
/* Master core call */
lcore_main(qconf);
return 0;
}
The Output as follows.
EAL: Detected 12 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: Invalid NUMA socket, default to 0
EAL: Invalid NUMA socket, default to 0
EAL: using IOMMU type 1 (Type 1)
EAL: Probe PCI driver: net_ixgbe (8086:15d1) device: 0000:01:00.0 (socket 0)
EAL: Invalid NUMA socket, default to 0
EAL: No legacy callbacks, legacy socket not created
=====================================================
EAL initialisation success.
USER1: rte_ip_frag_table_create: allocated of 201326720 bytes at socket 0
PORT 0: Ethernet configuration success.
TX queue configuration success.
RX queue configuration success.
PORT 0: NIC started successfully.
PORT 0: Enabled promiscuous mode.
MAC Addr b4:96:91:3f:21:b6
=====================================================
RX Thread: Socket ID: 0
RX Thread: lcore count: 12
RX Thread: lcore ID: 0
RX Thread Started.
=====================================================
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831203304 , dst add:11304
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 40960 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 40960 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 40960 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 40960 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 40960 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 40960 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 32, l3 length: 20 ,Packet ID: 40960 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 2048, l3 length: 20 ,Packet ID: 1030 , src add:2831191337 , dst add:10280
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 42752 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 42752 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 42752 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 42752 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 42752 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 44, l3 length: 20 ,Packet ID: 42752 , src add:992520384 , dst add:4294967295
IP_RSMBL: Reassemble Failed.
Total Length: 32, l3 length: 20 ,Packet ID: 42752 , src add:992520384 , dst add:4294967295
I added printf inside the ip_reassemble example program and same thing is observed. unable to figure it out why is it happening. When I open the input pcap in Wireshark, Wireshark is able to reassemble properly. Please anyone suggest me a pcap or a way to check if IP reassemble is working fine.
/* process this fragment. */
mo = rte_ipv4_frag_reassemble_packet(tbl, dr, m, tms, ip_hdr);
if (mo == NULL) {
/* no packet to send out. */
printf("IP reassemble failed\n");
return;
}
/* we have our packet reassembled. */
if (mo != m) {
printf("IP reassemble success\n");
m = mo;
eth_hdr = rte_pktmbuf_mtod(m,
struct rte_ether_hdr *);
ip_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1);
}
root#user:/home/user/dpdk/examples/ip_reassembly# ./build/ip_reassembly -l 1 -- -p 1 -q 2
EAL: Detected 12 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: Invalid NUMA socket, default to 0
EAL: Invalid NUMA socket, default to 0
EAL: using IOMMU type 1 (Type 1)
EAL: Probe PCI driver: net_ixgbe (8086:15d1) device: 0000:01:00.0 (socket 0)
EAL: Invalid NUMA socket, default to 0
EAL: No legacy callbacks, legacy socket not created
0x7ffdd2cbd50e
IP_RSMBL: Creating LPM table on socket 0
IP_RSMBL: Creating LPM6 table on socket 0
USER1: rte_ip_frag_table_create: allocated of 25165952 bytes at socket 0
Initializing port 0 ... Port 0 modified RSS hash function based on hardware support,requested:0xa38c configured:0x8104
Address:B4:96:91:3F:21:B6
txq=1,0,0
IP_RSMBL: Socket 0: adding route 100.10.0.0/16 (port 0)
IP_RSMBL: Socket 0: adding route 100.20.0.0/16 (port 1)
IP_RSMBL: Socket 0: adding route 100.30.0.0/16 (port 2)
IP_RSMBL: Socket 0: adding route 100.40.0.0/16 (port 3)
IP_RSMBL: Socket 0: adding route 100.50.0.0/16 (port 4)
IP_RSMBL: Socket 0: adding route 100.60.0.0/16 (port 5)
IP_RSMBL: Socket 0: adding route 100.70.0.0/16 (port 6)
IP_RSMBL: Socket 0: adding route 100.80.0.0/16 (port 7)
IP_RSMBL: Socket 0: adding route 0101:0101:0101:0101:0101:0101:0101:0101/48 (port 0)
IP_RSMBL: Socket 0: adding route 0201:0101:0101:0101:0101:0101:0101:0101/48 (port 1)
IP_RSMBL: Socket 0: adding route 0301:0101:0101:0101:0101:0101:0101:0101/48 (port 2)
IP_RSMBL: Socket 0: adding route 0401:0101:0101:0101:0101:0101:0101:0101/48 (port 3)
IP_RSMBL: Socket 0: adding route 0501:0101:0101:0101:0101:0101:0101:0101/48 (port 4)
IP_RSMBL: Socket 0: adding route 0601:0101:0101:0101:0101:0101:0101:0101/48 (port 5)
IP_RSMBL: Socket 0: adding route 0701:0101:0101:0101:0101:0101:0101:0101/48 (port 6)
IP_RSMBL: Socket 0: adding route 0801:0101:0101:0101:0101:0101:0101:0101/48 (port 7)
Checking link status.......................................
done
Port0 Link Up. Speed 10000 Mbps - full-duplex
IP_RSMBL: entering main loop on lcore 1
IP_RSMBL: -- lcoreid=1 portid=0
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
.
.
.
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
IP reassemble failed
^C -- lcoreid=1 portid=0 frag tbl stat:
max entries: 4096;
entries in use: 11;
finds/inserts: 0;
entries added: 0;
entries deleted by timeout: 0;
entries reused by timeout: 0;
total add failures: 0;
add no-space failures: 0;
add hash-collisions failures: 0;
TX bursts: 0
TX packets _queued: 0
TX packets dropped: 0
TX packets send: 0
received signal: 2, exiting
[EDIT-2]: Either Last fragment or first fragment length is 0. I dont know this has anything to do with below details but just mentioning.
NIC(10GB NIC)
Ethernet controller: Intel Corporation Ethernet Controller 10G X550T
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
Address sizes: 39 bits physical, 48 bits virtual
CPU(s): 12
On-line CPU(s) list: 0-11
Thread(s) per core: 2
Core(s) per socket: 6
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 158
Model name: Intel(R) Core(TM) i7-8700 CPU # 3.20GHz
Stepping: 10
CPU MHz: 3185.543
CPU max MHz: 3200.0000
CPU min MHz: 800.0000
BogoMIPS: 6384.00
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 12288K
NUMA node0 CPU(s): 0-11
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d
Output of your code..
EAL: Detected 12 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: Invalid NUMA socket, default to 0
EAL: Invalid NUMA socket, default to 0
EAL: using IOMMU type 1 (Type 1)
EAL: Probe PCI driver: net_ixgbe (8086:15d1) device: 0000:01:00.0 (socket 0)
EAL: Invalid NUMA socket, default to 0
EAL: No legacy callbacks, legacy socket not created
USER1: rte_ip_frag_table_create: allocated of 201326720 bytes at socket 0
Port 0 MAC: b4 96 91 3f 21 b6
RX Thread: Socket ID: 0
RX Thread: lcore count: 12
RX Thread: lcore ID: 0
mb: 0x172980e80
fp: 0x17e05c5c0
offset: 0
, IPLen: 24
, ipflag: 8192
mb_end: (nil)
ERR, IP_RSMBL, Reassemble Failed.
mb: 0x172980540
fp: 0x17e05c5c0
offset: 24
, IPLen: 24
, ipflag: 8192
mb_end: (nil)
ERR, IP_RSMBL, Reassemble Failed.
mb: 0x17297fc00
fp: 0x17e05c5c0
offset: 48
, IPLen: 24
, ipflag: 8192
mb_end: (nil)
ERR, IP_RSMBL, Reassemble Failed.
mb: 0x17297f2c0
fp: 0x17e05c5c0
offset: 72
, IPLen: 24
, ipflag: 8192
idx: 4, frags: 0x4ip_frag_process:145 invalid fragmented packet:
ipv4_frag_pkt: 0x17e05c5c0, key: <ffffffff3b28a8c0, 0xb500>, total_size: 4294967295, frag_size: 96, last_idx: 4
first fragment: ofs: 0, len: 24
last fragment: ofs: 0, len: 0
mb_end: (nil)
ERR, IP_RSMBL, Reassemble Failed.
mb: 0x172b99680
fp: 0x17551e5c0
offset: 96
, IPLen: 24
, ipflag: 8192
mb_end: (nil)
ERR, IP_RSMBL, Reassemble Failed.
mb: 0x172b98d40
fp: 0x17551e5c0
offset: 120
, IPLen: 24
, ipflag: 8192
mb_end: (nil)
ERR, IP_RSMBL, Reassemble Failed.
mb: 0x172b98400
fp: 0x17551e5c0
offset: 144
, IPLen: 12
, ipflag: 0
mb_end: (nil)
ERR, IP_RSMBL, Reassemble Failed.
mb: 0x172c8fb00
fp: 0x17d5885c0
offset: 8
, IPLen: 2028
, ipflag: 0
idx: -1, frags: 0x4ip_frag_process:145 invalid fragmented packet:
ipv4_frag_pkt: 0x17d5885c0, key: <2c28a8c0bbe8, 0x406>, total_size: 2036, frag_size: 4056, last_idx: 2
first fragment: ofs: 0, len: 0
last fragment: ofs: 8, len: 2028
mb_end: (nil)
DPDK API rte_ipv4_frag_reassemble_packet returns NULL in 2 ocassion
an error occurred
not all fragments of the packet are collected yet
Based on the code and logs shared it looks like you are
sending the last fragment multiple times.
setting time out as cur_tsc
Note:
the easiest way to test your packet is run it against ip_reassembly example and cross check the variance.
if (mo == NULL) it only means not sufficient fragments are received.
[edit-1] Hence I request to model your code as dpdk example ip_reassembly since assuming rte_ipv4_frag_reassemble_packet returning NULL is not always a failure.
[edit-2] cleaning up the code and adding missing libraries I am able to get this working with right set of fragment packets
Reassemble is success.dump mbuf at 0x1736966c0, iova=7b3696740, buf_len=2176
pkt_len=5421, ol_flags=10, nb_segs=4, in_port=0
segment at 0x1736966c0, data=0x1736967c0, data_len=1514
Dump data at [0x1736967c0], len=64
00000000: 00 1D 09 94 65 38 68 5B 35 C0 61 B6 08 00 45 00 | ....e8h[5.a...E.
00000010: 15 1F F5 AF 00 00 40 11 00 00 83 B3 C4 DC 83 B3 | ......#.........
00000020: C4 2E 18 DB 18 DB 15 0B DC E2 06 FD 14 FF 07 29 | ...............)
00000030: 08 07 65 78 61 6D 70 6C 65 08 07 74 65 73 74 41 | ..example..testA
segment at 0x1733a8040, data=0x1733a8162, data_len=1480
segment at 0x1733a8980, data=0x1733a8aa2, data_len=1480
segment at 0x1734dde40, data=0x1734ddf62, data_len=947
[edit-3]
traffic generator: ./app/x86_64-native-linuxapp-gcc/pktgen -l 1-4 -- -s 0:test.pcap -P -m [2].0
application: (code snippet edited and compiled as C program) https://pastebin.pl/view/91e533e3
build: gcc $(PKG_CONFIG_PATH=[path-to-dpdk-pkgconfig] pkg-config --static --cflags libdpdk) dpdk.c -Wl,-Bstatic $(PKG_CONFIG_PATH=[path-to-dpdk-pkgconfig] pkg-config --static --libs libdpdk)
run: sudo LD_LIBRARY_PATH=/path-to-dpdk-sahred-library/ ./a.out
[edit-4] based on the live debug, issue appears to be the hub switch connecting the 2 machines. Packets are dropped or not at all forwarded. Requested to have a direct stable connection to check the logic on the #Nirmal machine. Ran the same example and show cased the output in my machine.
Related
OpenOnload ZeroCopy ReceiveQueue Always Full
We are using openonload with zerocopy (for multicast operations) feature to receive and parse the multicast data in network level. Our code(which you can see in below) works in lots of servers and its working without any problem. However recently we got a new server and installed the same operating system(Ubuntu 18.04) and same onload version (7.1.2.141) however when we ran our code in this server the udp receive queue never gets empty, its always full and we are not able to receive and parse the multicast data. I'm also sharing the network configuration below with our code. Does anyone have any idea about this problem Code: int onload_zc_recv(int fd, onload_zc_recv_args *args); onload_zc_callback_rc zc_recv_callback(onload_zc_recv_args *args, int flags){ return clients[((zc_user_info*)(args->user_ptr))->id]->ZCRecvCB(args, flags); } onload_zc_callback_rc ItchClient::ZCRecvCB(onload_zc_recv_args *args, int flags) { uint32_t i = 0; for( i = 0; i < args->msg.msghdr.msg_iovlen; ++i ) { if (args->msg.iov[i].iov_len > 0) { //Our application logic is here } } } return ONLOAD_ZC_TERMINATE; } onload_zc_recv_args args; memset(&args.msg, 0, sizeof(args.msg)); args.cb = &zc_recv_callback; while (!clientStopped.load(std::memory_order_relaxed)) { rc = onload_zc_recv(connection.getConnectionSocket(), &args); } Network Configuration: (We are trying to bind to ens1f0np0 interface) br-80983172fc5d: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.19.0.1 netmask 255.255.0.0 broadcast 172.19.255.255 ether 02:42:73:86:7c:19 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 br-a85649ccece2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255 inet6 fe80::42:e7ff:fed4:6560 prefixlen 64 scopeid 0x20<link> ether 02:42:e7:d4:65:60 txqueuelen 0 (Ethernet) RX packets 3492 bytes 894736 (894.7 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3670 bytes 353542 (353.5 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:a7:6c:f9:da txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens10f0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether 68:05:ca:f3:9c:a2 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0xb8500000-b85fffff ens10f1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether 68:05:ca:f3:9c:a3 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0xb8400000-b84fffff ens10f2: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether 68:05:ca:f3:9c:a4 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0xb8300000-b83fffff ens10f3: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether 68:05:ca:f3:9c:a5 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0xb8200000-b82fffff ens1f0np0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.46.54.133 netmask 255.255.255.224 broadcast 10.46.54.159 inet6 fe80::20f:53ff:fe9a:ef00 prefixlen 64 scopeid 0x20<link> ether 00:0f:53:9a:ef:00 txqueuelen 1000 (Ethernet) RX packets 220301 bytes 50255774 (50.2 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1792 bytes 236826 (236.8 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 18 ens1f1np1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether 00:0f:53:9a:ef:01 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 19 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 9835 bytes 1610054 (1.6 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 9835 bytes 1610054 (1.6 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethe21f54f: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::b488:c1ff:fee1:4029 prefixlen 64 scopeid 0x20<link> ether b6:88:c1:e1:40:29 txqueuelen 0 (Ethernet) RX packets 3492 bytes 943624 (943.6 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3685 bytes 354688 (354.6 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 This is our system log (Which has no error) Mar 11 13:20:38 a1hft kernel: [ 1987.912719] oo:HftSrvProd[7]: Using Cloud Onload 7.1.2.141 [5,hft-udp-p7] Mar 11 13:20:38 a1hft kernel: [ 1987.912720] oo:HftSrvProd[7]: Copyright 2019-2021 Xilinx, 2006-2019 Solarflare Communications, 2002-2005 Level 5 Networks I've also checked all the configurations with our currently working servers , but not able to find anything. Do you have any idea what may cause this problem
I would advise contacting support-nic#xilinx.com - helpful bunch of people. It is best to register as this ensures customer ticket is created.
pktgen cannot send packet in ovs dpdk scenario
The test setup is: pktgen send packet to vhost-user1 port, then ovs forward it vhost-user2, then testpmd received it from vhost-user2. The problem is: pktgen can not send any packets, testpmd received no packet also, I don't know what's the problem. Needs some help, thanks in advance! OVS: 2.9.0 DPDK: 17.11.6 pktgen: 3.4.4 OVS setup: export DB_SOCK=/usr/local/var/run/openvswitch/db.sock export PATH=$PATH:/usr/local/share/openvswitch/scripts rm /usr/local/etc/openvswitch/conf.db ovsdb-tool create /usr/local/etc/openvswitch/conf.db /usr/local/share/openvswitch/vswitch.ovsschema ovsdb-server --remote=punix:/usr/local/var/run/openvswitch/db.sock --remote=db:Open_vSwitch,Open_vSwitch,manager_options --pidfile --detach ovs-vsctl --no-wait init ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true other_config:dpdk-lcore=0x2 other_config:dpdk-socket-mem="1024,0" ovs-vswitchd unix:/usr/local/var/run/openvswitch/db.sock --pidfile --detach ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0x8 ovs-vsctl add-br ovs-br0 -- set bridge ovs-br0 datapath_type=netdev ovs-vsctl add-port ovs-br0 vhost-user0 -- set Interface vhost-user0 type=dpdkvhostuser ovs-vsctl add-port ovs-br0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser ovs-vsctl add-port ovs-br0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser ovs-vsctl add-port ovs-br0 vhost-user3 -- set Interface vhost-user3 type=dpdkvhostuser sudo ovs-ofctl del-flows ovs-br0 sudo ovs-ofctl add-flow ovs-br0 in_port=2,dl_type=0x800,idle_timeout=0,action=output:3 sudo ovs-ofctl add-flow ovs-br0 in_port=3,dl_type=0x800,idle_timeout=0,action=output:2 sudo ovs-ofctl add-flow ovs-br0 in_port=1,dl_type=0x800,idle_timeout=0,action=output:4 sudo ovs-ofctl add-flow ovs-br0 in_port=4,dl_type=0x800,idle_timeout=0,action=output:1 run pktgen: root#k8s:/home/haosp/OVS_DPDK/pktgen-3.4.4# pktgen -c 0xf --master-lcore 0 -n 1 --socket-mem 512,0 --file-prefix pktgen --no-pci \ > --vdev 'net_virtio_user0,mac=00:00:00:00:00:05,path=/usr/local/var/run/openvswitch/vhost-user0' \ > --vdev 'net_virtio_user1,mac=00:00:00:00:00:01,path=/usr/local/var/run/openvswitch/vhost-user1' \ > -- -P -m "1.[0-1]" Copyright (c) <2010-2017>, Intel Corporation. All rights reserved. Powered by DPDK EAL: Detected 4 lcore(s) EAL: Probing VFIO support... EAL: VFIO support initialized Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio Copyright (c) <2010-2017>, Intel Corporation. All rights reserved. Pktgen created by: Keith Wiles -- >>> Powered by DPDK <<< >>> Packet Burst 64, RX Desc 1024, TX Desc 2048, mbufs/port 16384, mbuf cache 2048 === port to lcore mapping table (# lcores 4) === lcore: 0 1 2 3 Total port 0: ( D: T) ( 1: 1) ( 0: 0) ( 0: 0) = ( 1: 1) port 1: ( D: T) ( 1: 1) ( 0: 0) ( 0: 0) = ( 1: 1) Total : ( 0: 0) ( 2: 2) ( 0: 0) ( 0: 0) Display and Timer on lcore 0, rx:tx counts per port/lcore Configuring 2 ports, MBUF Size 2176, MBUF Cache Size 2048 Lcore: 1, RX-TX RX_cnt( 2): (pid= 0:qid= 0) (pid= 1:qid= 0) TX_cnt( 2): (pid= 0:qid= 0) (pid= 1:qid= 0) Port : 0, nb_lcores 1, private 0x5635a661d3a0, lcores: 1 1, nb_lcores 1, private 0x5635a661ff70, lcores: 1 ** Default Info (net_virtio_user0, if_index:0) ** max_rx_queues : 1, max_tx_queues : 1 max_mac_addrs : 64, max_hash_mac_addrs: 0, max_vmdq_pools: 0 rx_offload_capa: 28, tx_offload_capa : 0, reta_size : 0, flow_type_rss_offloads:0000000000000000 vmdq_queue_base: 0, vmdq_queue_num : 0, vmdq_pool_base: 0 ** RX Conf ** pthresh : 0, hthresh : 0, wthresh : 0 Free Thresh : 0, Drop Enable : 0, Deferred Start : 0 ** TX Conf ** pthresh : 0, hthresh : 0, wthresh : 0 Free Thresh : 0, RS Thresh : 0, Deferred Start : 0, TXQ Flags:00000f00 Create: Default RX 0:0 - Memory used (MBUFs 16384 x (size 2176 + Hdr 128)) + 192 = 36865 KB headroom 128 2176 Set RX queue stats mapping pid 0, q 0, lcore 1 Create: Default TX 0:0 - Memory used (MBUFs 16384 x (size 2176 + Hdr 128)) + 192 = 36865 KB headroom 128 2176 Create: Range TX 0:0 - Memory used (MBUFs 16384 x (size 2176 + Hdr 128)) + 192 = 36865 KB headroom 128 2176 Create: Sequence TX 0:0 - Memory used (MBUFs 16384 x (size 2176 + Hdr 128)) + 192 = 36865 KB headroom 128 2176 Create: Special TX 0:0 - Memory used (MBUFs 64 x (size 2176 + Hdr 128)) + 192 = 145 KB headroom 128 2176 Port memory used = 147601 KB Initialize Port 0 -- TxQ 1, RxQ 1, Src MAC 00:00:00:00:00:05 ** Default Info (net_virtio_user1, if_index:0) ** max_rx_queues : 1, max_tx_queues : 1 max_mac_addrs : 64, max_hash_mac_addrs: 0, max_vmdq_pools: 0 rx_offload_capa: 28, tx_offload_capa : 0, reta_size : 0, flow_type_rss_offloads:0000000000000000 vmdq_queue_base: 0, vmdq_queue_num : 0, vmdq_pool_base: 0 ** RX Conf ** pthresh : 0, hthresh : 0, wthresh : 0 Free Thresh : 0, Drop Enable : 0, Deferred Start : 0 ** TX Conf ** pthresh : 0, hthresh : 0, wthresh : 0 Free Thresh : 0, RS Thresh : 0, Deferred Start : 0, TXQ Flags:00000f00 Create: Default RX 1:0 - Memory used (MBUFs 16384 x (size 2176 + Hdr 128)) + 192 = 36865 KB headroom 128 2176 Set RX queue stats mapping pid 1, q 0, lcore 1 Create: Default TX 1:0 - Memory used (MBUFs 16384 x (size 2176 + Hdr 128)) + 192 = 36865 KB headroom 128 2176 Create: Range TX 1:0 - Memory used (MBUFs 16384 x (size 2176 + Hdr 128)) + 192 = 36865 KB headroom 128 2176 Create: Sequence TX 1:0 - Memory used (MBUFs 16384 x (size 2176 + Hdr 128)) + 192 = 36865 KB headroom 128 2176 Create: Special TX 1:0 - Memory used (MBUFs 64 x (size 2176 + Hdr 128)) + 192 = 145 KB headroom 128 2176 Port memory used = 147601 KB Initialize Port 1 -- TxQ 1, RxQ 1, Src MAC 00:00:00:00:00:01 Total memory used = 295202 KB Port 0: Link Up - speed 10000 Mbps - full-duplex <Enable promiscuous mode> !ERROR!: Could not read enough random data for PRNG seed Port 1: Link Up - speed 10000 Mbps - full-duplex <Enable promiscuous mode> !ERROR!: Could not read enough random data for PRNG seed === Display processing on lcore 0 WARNING: Nothing to do on lcore 2: exiting WARNING: Nothing to do on lcore 3: exiting RX/TX processing lcore: 1 rx: 2 tx: 2 For RX found 2 port(s) for lcore 1 For TX found 2 port(s) for lcore 1 Pktgen:/>set 0 dst mac 00:00:00:00:00:03 Pktgen:/>set all rate 10 Pktgen:/>set 0 count 10000 Pktgen:/>set 1 count 20000 Pktgen:/>str | Flags:Port : P--------------:0 P--------------:1 0/0 Link State : P--------------:0 P--------------:1 ----TotalRate---- Pkts/s Max/Rx : <UP-10000-FD> <UP-10000-FD> 0/0 Max/Tx : 0/0 0/0 0/0 MBits/s Rx/Tx : 256/0 256/0 512/0 Broadcast : 0/0 0/0 0/0 Multicast : 0 0 64 Bytes : 0 0 65-127 : 0 0 128-255 : 0 0 256-511 : 0 0 512-1023 : 0 0 1024-1518 : 0 0 Runts/Jumbos : 0 0 Errors Rx/Tx : 0/0 0/0 Total Rx Pkts : 0/0 0/0 Tx Pkts : 0 0 Rx MBs : 256 256 Tx MBs : 0 0 ARP/ICMP Pkts : 0 0 Tx Count/% Rate : 0/0 0/0 Pattern Type : abcd... abcd... Tx Count/% Rate : 10000 /10% 20000 /10%-------------------- PktSize/Tx Burst : 64 / 64 64 / 64 Src/Dest Port : 1234 / 5678 1234 / 5678-------------------- Pkt Type:VLAN ID : IPv4 / TCP:0001 IPv4 / TCP:0001 802.1p CoS : 0 0-------------------- ToS Value: : 0 0 - DSCP value : 0 0-------------------- - IPP value : 0 0 Dst IP Address : 192.168.1.1 192.168.0.1-------------------- Src IP Address : 192.168.0.1/24 192.168.1.1/24 Dst MAC Address : 00:00:00:00:00:03 00:00:00:00:00:05-------------------- Src MAC Address : 00:00:00:00:00:05 00:00:00:00:00:01 VendID/PCI Addr : 0000:0000/00:00.0 0000:0000/00:00.0-------------------- Pktgen:/> str -- Pktgen Ver: 3.4.4 (DPDK 17.11.6) Powered by DPDK -------------------------- Pktgen:/> run testpmd: ./testpmd -c 0xf -n 1 --socket-mem 512,0 --file-prefix testpmd --no-pci \ --vdev 'net_virtio_user2,mac=00:00:00:00:00:02,path=/usr/local/var/run/openvswitch/vhost-user2' \ --vdev 'net_virtio_user3,mac=00:00:00:00:00:03,path=/usr/local/var/run/openvswitch/vhost-user3' \ -- -i -a --burst=64 --txd=2048 --rxd=2048 --coremask=0x4 EAL: Detected 4 lcore(s) EAL: Detected 1 NUMA nodes EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: 1 hugepages of size 1073741824 reserved, but no mounted hugetlbfs found for that size EAL: Probing VFIO support... EAL: VFIO support initialized update_memory_region(): Too many memory regions update_memory_region(): Too many memory regions Interactive-mode selected Auto-start selected Warning: NUMA should be configured manually by using --port-numa-config and --ring-numa-config parameters along with --numa. testpmd: create a new mbuf pool <mbuf_pool_socket_0>: n=171456, size=2176, socket=0 testpmd: preferred mempool ops selected: ring_mp_mc update_memory_region(): Too many memory regions update_memory_region(): Too many memory regions update_memory_region(): Too many memory regions update_memory_region(): Too many memory regions Configuring Port 0 (socket 0) Port 0: 00:00:00:00:00:02 Configuring Port 1 (socket 0) Port 1: 00:00:00:00:00:03 Checking link statuses... Done Start automatic packet forwarding io packet forwarding - ports=2 - cores=1 - streams=2 - NUMA support enabled, MP allocation mode: native Logical Core 2 (socket 0) forwards packets on 2 streams: RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01 RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00 io packet forwarding packets/burst=64 nb forwarding cores=1 - nb forwarding ports=2 port 0: RX queue number: 1 Tx queue number: 1 Rx offloads=0x0 Tx offloads=0x0 RX queue: 0 RX desc=2048 - RX free threshold=0 RX threshold registers: pthresh=0 hthresh=0 wthresh=0 RX Offloads=0x0 TX queue: 0 TX desc=2048 - TX free threshold=0 TX threshold registers: pthresh=0 hthresh=0 wthresh=0 TX offloads=0x0 - TX RS bit threshold=0 port 1: RX queue number: 1 Tx queue number: 1 Rx offloads=0x0 Tx offloads=0x0 RX queue: 0 RX desc=2048 - RX free threshold=0 RX threshold registers: pthresh=0 hthresh=0 wthresh=0 RX Offloads=0x0 TX queue: 0 TX desc=2048 - TX free threshold=0 TX threshold registers: pthresh=0 hthresh=0 wthresh=0 TX offloads=0x0 - TX RS bit threshold=0 testpmd> show port info Bad arguments testpmd> show port stats all ######################## NIC statistics for port 0 ######################## RX-packets: 0 RX-missed: 0 RX-bytes: 0 RX-errors: 0 RX-nombuf: 0 TX-packets: 0 TX-errors: 0 TX-bytes: 0 Throughput (since last show) Rx-pps: 0 Tx-pps: 0 ############################################################################ ######################## NIC statistics for port 1 ######################## RX-packets: 0 RX-missed: 0 RX-bytes: 0 RX-errors: 0 RX-nombuf: 0 TX-packets: 0 TX-errors: 0 TX-bytes: 0 Throughput (since last show) Rx-pps: 0 Tx-pps: 0 ############################################################################ OVS dump-flow show: root#k8s:/home/haosp# ovs-ofctl dump-flows ovs-br0 cookie=0x0, duration=77519.972s, table=0, n_packets=0, n_bytes=0, ip,in_port="vhost-user1" actions=output:"vhost-user2" cookie=0x0, duration=77519.965s, table=0, n_packets=0, n_bytes=0, ip,in_port="vhost-user2" actions=output:"vhost-user1" cookie=0x0, duration=77519.959s, table=0, n_packets=0, n_bytes=0, ip,in_port="vhost-user0" actions=output:"vhost-user3" cookie=0x0, duration=77518.955s, table=0, n_packets=0, n_bytes=0, ip,in_port="vhost-user3" actions=output:"vhost-user0" ovs-ofctl dump-ports ovs-br0 show: root#k8s:/home/haosp# ovs-ofctl dump-ports ovs-br0 OFPST_PORT reply (xid=0x2): 5 ports port "vhost-user3": rx pkts=0, bytes=0, drop=0, errs=0, frame=?, over=?, crc=? tx pkts=0, bytes=0, drop=6, errs=?, coll=? port "vhost-user1": rx pkts=0, bytes=0, drop=0, errs=0, frame=?, over=?, crc=? tx pkts=0, bytes=0, drop=8, errs=?, coll=? port "vhost-user0": rx pkts=0, bytes=0, drop=0, errs=0, frame=?, over=?, crc=? tx pkts=0, bytes=0, drop=8, errs=?, coll=? port "vhost-user2": rx pkts=0, bytes=0, drop=0, errs=0, frame=?, over=?, crc=? tx pkts=0, bytes=0, drop=8, errs=?, coll=? port LOCAL: rx pkts=50, bytes=3732, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=0, bytes=0, drop=0, errs=0, coll=0 ovs-ofctl show ovs-br0 root#k8s:/home/haosp# ovs-ofctl show ovs-br0 OFPT_FEATURES_REPLY (xid=0x2): dpid:0000ca4f2b8e6b4b n_tables:254, n_buffers:0 capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst 1(vhost-user0): addr:00:00:00:00:00:00 config: 0 state: LINK_DOWN speed: 0 Mbps now, 0 Mbps max 2(vhost-user1): addr:00:00:00:00:00:00 config: 0 state: LINK_DOWN speed: 0 Mbps now, 0 Mbps max 3(vhost-user2): addr:00:00:00:00:00:00 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max 4(vhost-user3): addr:00:00:00:00:00:00 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max LOCAL(ovs-br0): addr:ca:4f:2b:8e:6b:4b config: 0 state: 0 current: 10MB-FD COPPER speed: 10 Mbps now, 0 Mbps max OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0 ovs-vsctl show root#k8s:/home/haosp# ovs-vsctl show 635ba448-91a0-4c8c-b6ca-4b9513064d7f Bridge "ovs-br0" Port "vhost-user2" Interface "vhost-user2" type: dpdkvhostuser Port "ovs-br0" Interface "ovs-br0" type: internal Port "vhost-user0" Interface "vhost-user0" type: dpdkvhostuser Port "vhost-user3" Interface "vhost-user3" type: dpdkvhostuser Port "vhost-user1" Interface "vhost-user1" type: dpdkvhostuser It seems that pktgen can not send packets, ovs statatics shows no packet received also, I have no idea yet, it confused me
If the goal is to have packet transfer between Pktgen and testpmd that is connected by OVS-DPDK one has to use net_vhost and virtio_user pair. DPDK Pktgen (net_vhost) <==> OVS-DPDK port-1 (virtio_user) {Rule to forward} OVS-DPDK port-2 (virtio_user) <==> DPDK Pktgen (net_vhost) In the current setup, you will have to make the following changes start DPDK pktgen by changing from --vdev net_virtio_user0,mac=00:00:00:00:00:05,path=/usr/local/var/run/openvswitch/vhost-user0 to --vdev net_vhost0,iface=/usr/local/var/run/openvswitch/vhost-user0 start DPDK testpmd by changing from --vdev 'net_virtio_user2,mac=00:00:00:00:00:02,path=/usr/local/var/run/openvswitch/vhost-user2' to --vdev 'net_vhost0,iface=/usr/local/var/run/openvswitch/vhost-user2' then start DPDK-OVS with --vdev=virtio_user0,path=/usr/local/var/run/openvswitch/vhost-user0 and --vdev=virtio_user1,path=/usr/local/var/run/openvswitch/vhost-user2 add rules to allow the port to port forwarding between pktgen and testpmd Note: please update the command line for multiple ports. screenshot shared below with pktgen and l2fwd setup
How does flow classify example in DPDK works?
I want to test the flow classify example in DPDK 20.08 and I'm trying to modify the given ACL rules file to match all the TCP packets. #file format: #src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask proto/mask priority # 2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0 9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1 9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2 9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3 6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4 6.7.8.9/32 192.168.0.36/32 10 : 0xffff 11 : 0xffff 6/0xfe 5 6.7.8.9/24 192.168.0.36/24 10 : 0xffff 11 : 0xffff 6/0xfe 6 6.7.8.9/16 192.168.0.36/16 10 : 0xffff 11 : 0xffff 6/0xfe 7 6.7.8.9/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 8 #error rules #9.8.7.6/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 9 Should I add 0.0.0.0/0 0.0.0.0/0 0 : 0x0000 0 : 0x0000 6/0xff 0 rule? I tried but there is still no packets matching. ps: This is the file I'm using. #file format: #src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask proto/mask priority # 2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0 9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1 9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2 9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3 6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4 6.7.8.9/32 192.168.0.36/32 10 : 0xffff 11 : 0xffff 6/0xfe 5 6.7.8.9/24 192.168.0.36/24 10 : 0xffff 11 : 0xffff 6/0xfe 6 6.7.8.9/16 192.168.0.36/16 10 : 0xffff 11 : 0xffff 6/0xfe 7 #6.7.8.9/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 8 0.0.0.0/0 0.0.0.0/0 0 : 0x0000 0 : 0x0000 6/0xff 8 #error rules #9.8.7.6/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 9 I ran again, and it goes like: rule [0] query failed ret [-22] rule [1] query failed ret [-22] rule [2] query failed ret [-22] rule [3] query failed ret [-22] rule [4] query failed ret [-22] rule [5] query failed ret [-22] rule [6] query failed ret [-22] rule [7] query failed ret [-22] rule[8] count=2 proto = 6 Segmentation fault I don't know what is causing the Segmentation fault. The command is sudo ./build/flow_classify -l 101 --log-level=pmd,8 -- --rule_ipv4="./ipv4_rules_file_pass.txt" > ~/flow_classify_log and I didn't change the source code. I'm using a two port 82599 NIC. I'm putting the log file down below which contains the output before it shows Segmentation fault flow_classify log Sometimes it can process normally in the first iteration, and sometimes it can't. update 1-3: I modified the code to stop the packet forwarding and free every single packet received to check if it is the forwarding procedure that is causing the problem. in main function: /* if (nb_ports < 2 || (nb_ports & 1)) rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n"); */ if (nb_ports < 1) rte_exit(EXIT_FAILURE, "Error: no port avaliable\n"); in lcore_main function: //in lcore_main function /* Send burst of TX packets, to second port of pair. */ /* const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0, bufs, nb_rx); */ const uint16_t nb_tx = 0; /* Free any unsent packets. */ if (unlikely(nb_tx < nb_rx)) { uint16_t buf; for (buf = nb_tx; buf < nb_rx; buf++) rte_pktmbuf_free(bufs[buf]); } And this is the new log, but I don't think there is any difference. I'm using only one of the two ports on a single 82599ES NIC. Maybe it's the false classification rule I added that is causing the problem, because it ran okay with the default rule settings.
Flow classify requires minimum of 2 ports, always even ports. Flow entries has to be populated in the valid format. Entry in rules: 2.2.2.3/0 2.2.2.7/0 32 : 0xffff 33 : 0xffff 17/0xff 0 2.2.2.3/0 2.2.2.7/0 32 : 0x0 33 : 0x0 6/0xff 1 Packet send: ipv4-TCP Log from flow-classify: rule [0] query failed ret [-22] -- UDP lookup failed rule[1] count=32 -- TCP lookup success proto = 6 Virtual NIC: ./build/flow_classify -c 8 --no-pci --vdev=net_tap0 --vdev=net_tap1 -- --rule_ipv4="ipv4_rules_file.txt" Physical NIC: ./build/flow_classify -c 8 -- --rule_ipv4="ipv4_rules_file.txt" Hence issue faced at your end is because incorrect configuration were only using 1 port
Huge latency spikes while running simple code
I have a simple benchmark that demonstrates performance of busywait threads. It runs in two modes: first one simply gets two timepoints sequentially, second one iterates through vector and measures duration of an iteration. I see that two sequential calls of clock::now() takes about 50 nanoseconds on the average and one average iteration through vector takes about 100 nanoseconds. But sometimes these operations are executed with a huge delay: about 50 microseconds in the first case and 10 milliseconds (!) in the second case. Test runs on single isolated core so context switches do not occur. I also call mlockall in beginning of the program so I assume that page faults do not affect the performance. Following additional optimizations were also applied: kernel boot parameters: intel_idle.max_cstate=0 idle=halt irqaffinity=0,14 isolcpus=4-13,16-27 pti=off spectre_v2=off audit=0 selinux=0 nmi_watchdog=0 nosoftlockup=0 rcu_nocb_poll rcu_nocbs=19-20 nohz_full=19-20; rcu[^c] kernel threads moved to a housekeeping CPU core 0; network card RxTx queues moved to a housekeeping CPU core 0; writeback kernel workqueue moved to a housekeeping CPU core 0; transparent_hugepage disabled; Intel CPU HyperThreading disabled; swap file/partition is not used. Environment: System details: Default Archlinux kernel: 5.1.9-arch1-1-ARCH #1 SMP PREEMPT Tue Jun 11 16:18:09 UTC 2019 x86_64 GNU/Linux that has following PREEMPT and HZ settings: CONFIG_HZ_300=y CONFIG_HZ=300 CONFIG_PREEMPT=y Hardware details: RAM: 256GB CPU(s): 28 On-line CPU(s) list: 0-27 Thread(s) per core: 1 Core(s) per socket: 14 Socket(s): 2 NUMA node(s): 2 Vendor ID: GenuineIntel CPU family: 6 Model: 79 Model name: Intel(R) Xeon(R) CPU E5-2690 v4 # 2.60GHz Stepping: 1 CPU MHz: 3200.011 CPU max MHz: 3500.0000 CPU min MHz: 1200.0000 BogoMIPS: 5202.68 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 35840K NUMA node0 CPU(s): 0-13 NUMA node1 CPU(s): 14-27 Example code: struct TData { std::vector<char> Data; TData() = default; TData(size_t aSize) { for (size_t i = 0; i < aSize; ++i) { Data.push_back(i); } } }; using TBuffer = std::vector<TData>; TData DoMemoryOperation(bool aPerform, const TBuffer& aBuffer, size_t& outBufferIndex) { if (!aPerform) { return TData {}; } const TData& result = aBuffer[outBufferIndex]; if (++outBufferIndex == aBuffer.size()) { outBufferIndex = 0; } return result; } void WarmUp(size_t aCyclesCount, bool aPerform, const TBuffer& aBuffer) { size_t bufferIndex = 0; for (size_t i = 0; i < aCyclesCount; ++i) { auto data = DoMemoryOperation(aPerform, aBuffer, bufferIndex); } } void TestCycle(size_t aCyclesCount, bool aPerform, const TBuffer& aBuffer, Measurings& outStatistics) { size_t bufferIndex = 0; for (size_t i = 0; i < aCyclesCount; ++i) { auto t1 = std::chrono::steady_clock::now(); { auto data = DoMemoryOperation(aPerform, aBuffer, bufferIndex); } auto t2 = std::chrono::steady_clock::now(); auto diff = std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count(); outStatistics.AddMeasuring(diff, t2); } } int Run(int aCpu, size_t aDataSize, size_t aBufferSize, size_t aCyclesCount, bool aAllocate, bool aPerform) { if (mlockall(MCL_CURRENT | MCL_FUTURE)) { throw std::runtime_error("mlockall failed"); } std::cout << "Test parameters" << ":\ndata size=" << aDataSize << ",\nnumber of elements=" << aBufferSize << ",\nbuffer size=" << aBufferSize * aDataSize << ",\nnumber of cycles=" << aCyclesCount << ",\nallocate=" << aAllocate << ",\nperform=" << aPerform << ",\nthread "; SetCpuAffinity(aCpu); TBuffer buffer; if (aPerform) { buffer.resize(aBufferSize); std::fill(buffer.begin(), buffer.end(), TData { aDataSize }); } WaitForKey(); std::cout << "Running..."<< std::endl; WarmUp(aBufferSize * 2, aPerform, buffer); Measurings statistics; TestCycle(aCyclesCount, aPerform, buffer, statistics); statistics.Print(aCyclesCount); WaitForKey(); if (munlockall()) { throw std::runtime_error("munlockall failed"); } return 0; } And following results are received: First: StandaloneTests --run_test=MemoryAccessDelay --cpu=19 --data-size=280 --size=67108864 --count=1000000000 --allocate=1 --perform=0 Test parameters: data size=280, number of elements=67108864, buffer size=18790481920, number of cycles=1000000000, allocate=1, perform=0, thread 14056 on cpu 19 Statistics: min: 16: max: 18985: avg: 18 0 - 10 : 0 (0 %): - 10 - 100 : 999993494 (99 %): min: 40: max: 117130: avg: 40 100 - 1000 : 946 (0 %): min: 380: max: 506236837: avg: 43056598 1000 - 10000 : 5549 (0 %): min: 56876: max: 70001739: avg: 7341862 10000 - 18985 : 11 (0 %): min: 1973150818: max: 14060001546: avg: 3644216650 Second: StandaloneTests --run_test=MemoryAccessDelay --cpu=19 --data-size=280 --size=67108864 --count=1000000000 --allocate=1 --perform=1 Test parameters: data size=280, number of elements=67108864, buffer size=18790481920, number of cycles=1000000000, allocate=1, perform=1, thread 3264 on cpu 19 Statistics: min: 36: max: 4967479: avg: 48 0 - 10 : 0 (0 %): - 10 - 100 : 964323921 (96 %): min: 60: max: 4968567: avg: 74 100 - 1000 : 35661548 (3 %): min: 122: max: 4972632: avg: 2023 1000 - 10000 : 14320 (0 %): min: 1721: max: 33335158: avg: 5039338 10000 - 100000 : 130 (0 %): min: 10010533: max: 1793333832: avg: 541179510 100000 - 1000000 : 0 (0 %): - 1000000 - 4967479 : 81 (0 %): min: 508197829: max: 2456672083: avg: 878824867 Any ideas what is the reason of such huge delays and how it may be investigated?
In: TData DoMemoryOperation(bool aPerform, const TBuffer& aBuffer, size_t& outBufferIndex); It returns a std::vector<char> by value. That involves a memory allocation and data copying. The memory allocations can do a syscall (brk or mmap) and memory mappings related syscalls are notorious for being slow. When timings include syscalls one cannot expect low variance. You may like to run your application with /usr/bin/time --verbose <app> or perf -ddd <app> to see the number of page faults and context switches.
Status thermal printer with libusb on linux ARM
I known there is a lot of question about status printer ... i have a Citizen CT-S310 II, i have managed all the code for write character in USB without problem with libusb_bulk_transfer (Text, Bold, Center, CR, CUT_PAPER etc) : #define ENDPOINT_OUT 0x02 #define ENDPOINT_IN 0x81 struct libusb_device_handle *_handle; [detach kernel driver...] [claim interface...] [etc ...] r = libusb_bulk_transfer(device_handle, ENDPOINT_OUT, Mydata, out_len, &transferred, 1000); Now, i need to receive data from the printer to ckeck the status, my first idea was to send the POS command with the same "bulk_transfer" of the doc : 1D (hexa) 72 (hexa) n n => 1 (Send the papel sensor status) and retrieve the value by "bulk_transfer" with the end point "ENDPOINT_IN" the doc say there is 8 bytes to receive : bit 0,1 => paper found by paper near-end sensor 00H bit 0,1 => paper not found by paper near-end sensor 03H bit 1,2 => paper found by paper-end sensor 00H bit 1,2 => paper not found by paper-end sensor 0CH [...] so two "bulk_transfer", one for send command status (ENDPOINT_OUT) and one for receive the result (ENDPOINT_IN), but i have allways an USB ERROR ("bulk_transfer" in read = -1) Maybe the USB don't work like this ? So my second idea was to use the implemented function in PrinterClass USB with the command "control_transfer" : int r = 0; int out_len = 1; unsigned char* _udata = NULL; uint8_t bmRequestType = LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE; uint8_t bRequest = LIBUSB_REQUEST_GET_STATUS; uint16_t wValue = 0; // the value field for the setup packet (?????) uint16_t wIndex = 0; // N° interface printer (the index field for the setup packet) r = libusb_control_transfer(device_handle, bmRequestType,bRequest,wValue, wIndex,_udata,out_len, USB_TIMEOUT); i don't exactly how to fill all the parameter, i know it depend of my device, but the doc of libsub is not very explicit. What is exactly "wValue" ? What is exactly "wIndex" ? the interface number ?? the parameter LIBUSB_ENDPOINT_IN by default is 0x80, but my printer use 0x81, i must to change this default endpoint ? Bus 001 Device 004: ID 1d90:2060 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x1d90 idProduct 0x2060 bcdDevice 0.02 iManufacturer 1 CITIZEN iProduct 2 Thermal Printer iSerial 3 00000000 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 0mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 7 Printer bInterfaceSubClass 1 Printer bInterfaceProtocol 2 Bidirectional iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Device Status: 0x0001 Self Powered The response of "control_transfer" in my case is always 0 :( with paper or without.How send a good "control_transfer" for request the status of my printer ?? All the help for solve my problem is welcome !!!
finally resolved ! The value of LIBUSB_REQUEST_GET_STATUS is 0x00, but for a printer the request status is 0x01. for check the status of printer with libusb-1.0 : uint8_t bmRequestType = LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE; uint8_t bRequest = 0x01; // Here not LIBUSB_REQUEST_GET_STATUS uint16_t wValue = 0; uint16_t wIndex = 0; r = libusb_control_transfer(device_handle, bmRequestType,bRequest,wValue, wIndex,&_udata,out_len, USB_TIMEOUT);