Monday, December 11, 2023

how vmware player run or develop with f-stack(dpdk)

 

f_stack office here

what is this:

    I develop in windows 11, wsl2 and hyper can not support virtual net interface for dpdk, so i installed VMware Workstation 17 Player in windows, and it installed ubuntu 22.04 in vmware to develop my c++ project with f-stack(dpdk). ide is vscode.

why select f_stack:

   no found ipv6 keywords in mtcp, so selected f_stack.


1. for my ubuntu 22.04 in VMware Workstation 17 Player

install 2 virtual net interfaces, 1 for normal, 2 bind for dpdk develop


> modify vmware net driver profile in windows file: {your vm os installed path}\Ubuntu 64.vmx

ethernet0.virtualDev = "vmxnet3"

ethernet1.virtualDev = "vmxnet3"

2. check out f-stack(with dpdk) in ubuntu 22.04

$ sudo -i 

$ git clone https://github.com/F-Stack/f-stack.git

2. prepare install tools

for first timer: 

$ apt-get install libnuma-dev python3 python3-pip meson -y && pip3 install pyelftools gawk gcc make libssl-dev pkg-config  

3. build and install

for dpdk:

$ cd f-stack/dpdk && meson --buildtype=debug -Denable_kmods=true -Ddisable_libs=flow_classify build --debug && ninja -C build && sudo ninja -C build install

(if for release opts: [--buildtype=release])


for f_stack:

for debug uncomment f-stack/lib/Makefile: 

DEBUG=-O0 -gdwarf-2 -g3 -Wno-format-truncation

Compile F-Stack

$ export FF_PATH=/home/lian/work/cppbot/third/repos/f-stack

$ export PKG_CONFIG_PATH=/usr/lib64/pkgconfig:/usr/local/lib64/pkgconfig:/usr/lib/pkgconfig

$ cd $FF_PATH/lib/

$ make

$ make install


prepare dpdk environment(run again after restart os):

$ cd f-stack/dpdk

$ echo 0 > /proc/sys/kernel/randomize_va_space 

$ echo 192 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

$ modprobe uio

$ insmod $(pwd)/build/kernel/linux/igb_uio/igb_uio.ko

$ insmod $(pwd)/build/kernel/linux/kni/rte_kni.ko carrier=on

$ mkdir -p /mnt/huge && sudo mount -t hugetlbfs nodev /mnt/huge


$ python3 usertools/dpdk-devbind.py --status

Network devices using kernel driver

===================================

0000:03:00.0 'VMXNET3 Ethernet Controller 07b0' if=ens160 drv=vmxnet3 unused=igb_uio *Active*

0000:0b:00.0 'VMXNET3 Ethernet Controller 07b0' if=ens192 drv=vmxnet3 unused=igb_uio *Active*


$ ifconfig ens192 down

$ python3 usertools/dpdk-devbind.py --bind=igb_uio ens192 

if your want revert to default driver:

$ python3 usertools/dpdk-devbind.py --bind=ens37 0000:0b:00.0

below is my vmware ubuntu normal route and net information:

$ route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         192.168.136.2   0.0.0.0         UG    100    0        0 ens160

169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 ens160

192.168.136.0   0.0.0.0         255.255.255.0   U     100    0        0 ens160

$ ifconfig

ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

        inet 192.168.136.128  netmask 255.255.255.0  broadcast 192.168.136.255

        inet6 fe80::1039:ef57:1f16:fa53  prefixlen 64  scopeid 0x20<link>

        ether 00:0c:29:a0:2e:30  txqueuelen 1000  (Ethernet)

        RX packets 33198  bytes 7402078 (7.4 MB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 34172  bytes 8247888 (8.2 MB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

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 50593  bytes 9439452 (9.4 MB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 50593  bytes 9439452 (9.4 MB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

$ copy from f-stack/config.ini to your project, and change port0:

[port0]

addr=192.168.136.129

netmask=255.255.255.0

broadcast=192.168.136.255

gateway=192.168.136.2

must sure [port0] gateway network info like with normal route and ifconfig, else can not access internet. 

4. My little socket client connect code:


#define MAX_EVENTS 64

/* kevent set */

struct kevent kevSet;

/* events */

struct kevent events[MAX_EVENTS];

/* kq */

int kq;


memset(&kevSet, 0, sizeof(struct kevent));

memset(&events, 0, sizeof(struct kevent) * MAX_EVENTS);

kq = ff_kqueue();

 

ff_socket(domain, type, protocol);


ff_setsockopt(sockfd, level, optname, optval, (socklen_t)optlen);


ff_connect(fd, (struct linux_sockaddr *)addr, len);

 

EV_SET(&kevSet, fd, filter, EV_ADD, 0, 0, NULL);

res = ff_kevent(kq, &kevSet, 1, NULL, 0, NULL);

 

int do_loop_once() {

    short revents;

    int i, res, res2;

    socklen_t len;

    sdk_op op;

    pollfd* b,*e;

    timespec ts{0, 100'000'000}; // 100 ms

    kevent* event;


    if ( app_running ) { // not while

        res= ff_kevent(kq, NULL, 0, events, MAX_EVENTS, &ts);


        for (i = 0; i < res; ++i) {

            event = &events[i];


            op = op_none;

            res2 = 0;


            if(event->flags & (EV_EOF|EV_ERROR)){

                op = (sdk_op) (op | op_in | op_out);

                len = sizeof(res2);

                res2 = 0;

                ff_getsockopt(event->ident, SOL_SOCKET, SO_ERROR, &res2, &len);

                if(res2 == 0)

                    res2 = -1;

                else if(res2 > 0)

                    res2 = -res2;

            } else if (event->filter == EVFILT_READ) {

                op = (sdk_op) (op | op_in);

            } else if (event->filter == EVFILT_WRITE) {

                op = (sdk_op) (op | op_out);

            }

            // call cb(ctx, event->ident, op, res2);

        }


        if(res < 0)

            printf("poll ret faled: %d %s", res, error_to_string(res));


        //...

    }else{

        exit(-1); // dpdk loop is dead loop

    }

    return 0;

}


ff_run(do_loop_once, arg);


ff_recv(fd, buf, n, flags);


ff_send(fd, buf, n, flags);


X. Last

then develop your project, some net api likes ff_connect(),ff_xxx in f-stack/lib/ff_api.h, attention your app ip is 192.168.136.129.

Thanks.