Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nff-go in Azure with NetVSC and failsafe #688

Open
darinkes opened this issue Jan 23, 2020 · 6 comments · May be fixed by #690
Open

nff-go in Azure with NetVSC and failsafe #688

darinkes opened this issue Jan 23, 2020 · 6 comments · May be fixed by #690

Comments

@darinkes
Copy link
Contributor

I read all the issues and docs regarding this topic, but can't figure out if and how this works with nff-go.

We can make our nff-go application work with Mellanox-Driver in a real-world and a virtual setup. But then we don't see all network-traffic in the virtual setup. For example ARP-Replies never reach the nff-go application.

According to this you should use the failsafe-mode for this:

DPDK applications must run over the failsafe PMD that is exposed in Azure. If the application runs directly over the VF PMD, it doesn't receive all packets that are destined to the VM, since some packets show up over the synthetic interface.

https://docs.microsoft.com/en-us/azure/virtual-network/setup-dpdk#failsafe-pmd

Adding --vdev="net_vdev_netvsc0,iface=eth1" to the DPDKArgs in flow.Config results in an init-error since nff-go doesn't link the needed drivers. The given testpmd example works as expected.

So my question is how you should/can use nff-go in an HyperV-VM with SR-IOV?

@darinkes
Copy link
Contributor Author

Cause I'm using Broadcom Network Cards in one server I also added -lrte_pmd_bnxt to internal/low/low_mlx.go

See testpmd-Output below which finds my two ports I would like to use, but nff-go says:

------------***-------- Initializing DPDK --------***------------
EAL: Detected 32 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: No available hugepages reported in hugepages-1048576kB
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=no nonstop_tsc=no -> using unreliable clock cycles !
------------***------ Initializing scheduler -----***------------
DEBUG: Scheduler can use cores: [0 1 2 3 4 5 6 7 8 9 10 11]
ERROR: failed with message and code: Requested receive port exceeds number of ports which can be used by DPDK (bind to DPDK). (3)

$ sudo ./nff-go/dpdk/dpdk/build/app/testpmd --log-level=8 -- -i
EAL: Detected 32 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: No available hugepages reported in hugepages-1048576kB
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=no nonstop_tsc=no -> using unreliable clock cycles !
Interactive-mode 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=395456, size=2176, socket=0
testpmd: preferred mempool ops selected: ring_mp_mc
Configuring Port 0 (socket 0)
Port 0: 00:15:5D:10:1C:07
Configuring Port 2 (socket 0)
Port 2: 00:15:5D:10:1C:08
Checking link statuses...
Done
testpmd> show port summary all
Number of available ports: 2
Port MAC Address       Name         Driver         Status   Link
0    00:15:5D:10:1C:07 net_failsafe_vsc0 net_failsafe   up       10000Mbps
2    00:15:5D:10:1C:08 net_failsafe_vsc1 net_failsafe   up       10000Mbps
testpmd> show port info all

********************* Infos for port 0  *********************
MAC address: 00:15:5D:10:1C:07
Device name: net_failsafe_vsc0
Driver name: net_failsafe
Devargs: fd(141),dev(net_tap_vsc0,remote=eth1)
Connect to socket: 0
memory allocation on the socket: 0
Link status: up
Link speed: 10000 Mbps
Link duplex: full-duplex
MTU: 1500
Promiscuous mode: enabled
Allmulticast mode: disabled
Maximum number of MAC addresses: 1
Maximum number of MAC addresses of hash filtering: 0
VLAN offload:
  strip off
  filter off
  qinq(extend) off
Supported RSS offload flow types:
  ipv4
  ipv4-frag
  ipv4-tcp
  ipv4-udp
  ipv4-other
  ipv6
  ipv6-frag
  ipv6-tcp
  ipv6-udp
  ipv6-other
  user defined 15
  user defined 16
  user defined 17
Minimum size of RX buffer: 0
Maximum configurable length of RX packet: 1522
Current number of RX queues: 1
Max possible RX queues: 16
Max possible number of RXDs per queue: 65535
Min possible number of RXDs per queue: 0
RXDs number alignment: 1
Current number of TX queues: 1
Max possible TX queues: 16
Max possible number of TXDs per queue: 65535
Min possible number of TXDs per queue: 0
TXDs number alignment: 1
Max segment number per packet: 65535
Max segment number per MTU/TSO: 65535

********************* Infos for port 2  *********************
MAC address: 00:15:5D:10:1C:08
Device name: net_failsafe_vsc1
Driver name: net_failsafe
Devargs: fd(146),dev(net_tap_vsc1,remote=eth2)
Connect to socket: 0
memory allocation on the socket: 0
Link status: up
Link speed: 10000 Mbps
Link duplex: full-duplex
MTU: 1500
Promiscuous mode: enabled
Allmulticast mode: disabled
Maximum number of MAC addresses: 1
Maximum number of MAC addresses of hash filtering: 0
VLAN offload:
  strip off
  filter off
  qinq(extend) off
Supported RSS offload flow types:
  ipv4
  ipv4-frag
  ipv4-tcp
  ipv4-udp
  ipv4-other
  ipv6
  ipv6-frag
  ipv6-tcp
  ipv6-udp
  ipv6-other
  user defined 15
  user defined 16
  user defined 17
Minimum size of RX buffer: 0
Maximum configurable length of RX packet: 1522
Current number of RX queues: 1
Max possible RX queues: 16
Max possible number of RXDs per queue: 65535
Min possible number of RXDs per queue: 0
RXDs number alignment: 1
Current number of TX queues: 1
Max possible TX queues: 16
Max possible number of TXDs per queue: 65535
Min possible number of TXDs per queue: 0
TXDs number alignment: 1
Max segment number per packet: 65535
Max segment number per MTU/TSO: 65535
testpmd>
$ sudo ./nff-go/dpdk/dpdk/x86_64-native-linuxapp-gcc-install/usr/local/sbin/dpdk-devbind -s

Other Network devices
=====================
8301:00:02.0 'Device 16bd' unused=
b6e1:00:02.0 'Device 16bd' unused=
b934:00:02.0 'Device 16bd' unused=

@gshimansky
Copy link
Contributor

Do you know which DPDK driver supports Microsoft NetVSC device? You can always add this driver library to the list of DPDK drivers in https://github.com/intel-go/nff-go/blob/master/internal/low/low_mlx.go#L10 or https://github.com/intel-go/nff-go/blob/master/internal/low/low_no_mlx.go#L10 depending on whether you are using MLX enabled build or NO_MLX build. Make sure to add the driver library between -Wl,--whole-archive -Wl,--start-group and -Wl,--end-group -Wl,--no-whole-archive because otherwise the driver will not be linked to the application.

@darinkes
Copy link
Contributor Author

darinkes commented Jan 23, 2020

The driver part seems to work after adding more dpdk libs to nff-go.

diff --git a/internal/low/low.h b/internal/low/low.h
index de591d3..2a00d93 100644
--- a/internal/low/low.h
+++ b/internal/low/low.h
@@ -319,6 +319,8 @@ int port_init(uint16_t port, bool willReceive, struct rte_mempool **mbuf_pools,
         port_conf_default.rxmode.offloads |= dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TIMESTAMP;
     }

+       rte_eth_dev_stop(port);
+
        /* Configure the Ethernet device. */
        int retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf_default);
        if (retval != 0)
diff --git a/internal/low/low_mlx.go b/internal/low/low_mlx.go
index 17f4d2b..bcd33d8 100644
--- a/internal/low/low_mlx.go
+++ b/internal/low/low_mlx.go
@@ -7,6 +7,6 @@
 package low

 /*
-#cgo LDFLAGS: -lrte_distributor -lrte_reorder -lrte_kni -lrte_pipeline -lrte_table -lrte_port -lrte_timer -lrte_jobstats -lrte_lpm -lrte_power -lrte_acl -lrte_meter -lrte_sched -lrte_vhost -lrte_ip_frag -lrte_cfgfile -Wl,--whole-archive -Wl,--start-group -lrte_kvargs -lrte_mbuf -lrte_hash -lrte_ethdev -lrte_mempool -lrte_ring -lrte_mempool_ring -lrte_eal -lrte_cmdline -lrte_net -lrte_bus_pci -lrte_pci -lrte_bus_vdev -lrte_timer -lrte_pmd_bond -lrte_pmd_vmxnet3_uio -lrte_pmd_virtio -lrte_pmd_cxgbe -lrte_pmd_enic -lrte_pmd_i40e -lrte_pmd_fm10k -lrte_pmd_ixgbe -lrte_pmd_e1000 -lrte_pmd_ena -lrte_pmd_ring -lrte_pmd_af_packet -lrte_pmd_null -libverbs -lmnl -lmlx4 -lmlx5 -lrte_pmd_mlx4 -lrte_pmd_mlx5 -Wl,--end-group -Wl,--no-whole-archive -lrt -lm -ldl -lnuma
+#cgo LDFLAGS: -lrte_distributor -lrte_reorder -lrte_kni -lrte_pipeline -lrte_table -lrte_port -lrte_timer -lrte_jobstats -lrte_lpm -lrte_power -lrte_acl -lrte_meter -lrte_sched -lrte_vhost -lrte_ip_frag -lrte_cfgfile -Wl,--whole-archive -Wl,--start-group -lrte_kvargs -lrte_mbuf -lrte_hash -lrte_ethdev -lrte_gso -lrte_mempool -lrte_ring -lrte_mempool_ring -lrte_eal -lrte_cmdline -lrte_net -lrte_bus_pci -lrte_pci -lrte_bus_vdev -lrte_timer -lrte_pmd_bond -lrte_pmd_vmxnet3_uio -lrte_pmd_virtio -lrte_pmd_cxgbe -lrte_pmd_enic -lrte_pmd_i40e -lrte_pmd_fm10k -lrte_pmd_ixgbe -lrte_pmd_e1000 -lrte_pmd_ena -lrte_pmd_ring -lrte_pmd_af_packet -lrte_pmd_null -lrte_pmd_bnxt -lrte_pmd_failsafe -lrte_pmd_tap -lrte_pmd_vdev_netvsc -lrte_bus_vmbus -lrte_pmd_netvsc -libverbs -lmnl -lmlx4 -lmlx5 -lrte_pmd_mlx4 -lrte_pmd_mlx5 -Wl,--end-group -Wl,--no-whole-archive -lrt -lm -ldl -lnuma
 */
 import "C"

But now I have a new problem. The IDs of my Interfaces, as shown above, are 0 and 2.

So if I do "flow.SetReceiver(2)" it fails with:
ERROR: failed with message and code: Requested receive port exceeds number of ports which can be used by DPDK (bind to DPDK). (3)

Doing "flow.SetReceiver(1)" gives me the same interface as 0.

------------***-------- Initializing DPDK --------***------------
2020-01-23 16:16:37 [INFO ] (metrics): Metrics disabled
EAL: Detected 32 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: No available hugepages reported in hugepages-1048576kB
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=no nonstop_tsc=no -> using unreliable clock cycles !
net_vdev_netvsc: probably using routed NetVSC interface "eth1" (index 3)
tun_alloc(): Rx trigger disabled: Device or resource busy
net_vdev_netvsc: probably using routed NetVSC interface "eth2" (index 4)
tun_alloc(): Rx trigger disabled: Device or resource busy
DEBUG: Ports: 2
DEBUG: ID: 0
DEBUG: ID: 1
------------***------ Initializing scheduler -----***------------
DEBUG: Scheduler can use cores: [0 1 2 3 4 5 6 7 8 9 10 11]
------------***---------- Creating ports ---------***------------
Device with port_id=0 already stopped
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
DEBUG: Port 0 MAC address: 00:15:5d:10:1c:07
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
tun_alloc(): Rx trigger disabled: Device or resource busy
DEBUG: Port 1 MAC address: 00:15:5d:10:1c:07
------------***------ Starting FlowFunctions -----***------------    

@gshimansky
Copy link
Contributor

The error that you see about port numbers comes from NFF-Go code where it checks whether specified port index is within the range of DPDK port identifiers. If --vdev switch creates a new interface on the fly then probably this check is not valid. Try to disable it and try again.
We didn't experiment with virtual devices that are created upon DPDK initialization.

@darinkes
Copy link
Contributor Author

@gshimansky Thanks for the answer. I had to change some stuff to make it work.
nff-go makes some assumptions which seem to not apply in virtual/Azure environments.

Ports are not an array with ongoing IDs. So I changed createdPorts to an map instead of an array. I also adjusted the checks in nff-go as you suggested and now it seems to work.

My applications starts and I can do ARP and ICMP. Very nice!
I will try to clean up the diffs, IDs are hardcoded currently, and will send an PR for review.

@gshimansky
Copy link
Contributor

This is the first time someone reported that NFF-Go works successfully on Azure. Thank you very much!

@darinkes darinkes linked a pull request Jan 30, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants