diff options
Diffstat (limited to 'tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd')
16 files changed, 1229 insertions, 0 deletions
diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/Dockerfile b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/Dockerfile new file mode 100644 index 00000000..c56e45cf --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/Dockerfile @@ -0,0 +1,87 @@ +FROM centos:7 + +# +# Install required packages +# +RUN rpm --import https://mirror.go-repo.io/centos/RPM-GPG-KEY-GO-REPO && curl -s https://mirror.go-repo.io/centos/go-repo.repo | tee /etc/yum.repos.d/go-repo.repo +RUN yum groupinstall -y "Development Tools" +RUN yum install -y wget numactl-devel git golang make; yum clean all + +# +# Download and Build APP-NetUtil +# +WORKDIR /root/go/src/ +RUN mkdir github.com && cd github.com && mkdir openshift && cd openshift && git clone https://github.com/openshift/app-netutil +WORKDIR /root/go/src/github.com/openshift/app-netutil +RUN make c_sample +RUN cp bin/libnetutil_api.so /lib64/libnetutil_api.so; cp bin/libnetutil_api.h /usr/include/libnetutil_api.h + +# +# Download and Build DPDK +# +ENV DPDK_VER 20.05 +ENV DPDK_DIR /usr/src/dpdk-${DPDK_VER} +WORKDIR /usr/src/ +RUN wget http://fast.dpdk.org/rel/dpdk-${DPDK_VER}.tar.xz +RUN tar -xpvf dpdk-${DPDK_VER}.tar.xz + +ENV RTE_TARGET=x86_64-native-linuxapp-gcc +ENV RTE_SDK=${DPDK_DIR} +WORKDIR ${DPDK_DIR} +RUN sed -i -e 's/EAL_IGB_UIO=y/EAL_IGB_UIO=n/' config/common_linux +RUN sed -i -e 's/KNI_KMOD=y/KNI_KMOD=n/' config/common_linux +RUN sed -i -e 's/LIBRTE_KNI=y/LIBRTE_KNI=n/' config/common_linux +RUN sed -i -e 's/LIBRTE_PMD_KNI=y/LIBRTE_PMD_KNI=n/' config/common_linux + +# Add vhost patch +COPY ./vhost_substitute.sh ./vhost_substitute.sh +RUN ./vhost_substitute.sh + +RUN make install T=${RTE_TARGET} DESTDIR=${RTE_SDK} + +# +# Build l2fwd +# +WORKDIR ${DPDK_DIR}/examples/l2fwd +COPY ./dpdk-args.c ./dpdk-args.c +COPY ./dpdk-args.h ./dpdk-args.h +COPY ./c_util.c ./c_util.c +COPY ./c_util.h ./c_util.h +COPY ./l2fwd_eal_init.txt ./l2fwd_eal_init.txt +COPY ./l2fwd_parse_args.txt ./l2fwd_parse_args.txt +COPY ./l2fwd_substitute.sh ./l2fwd_substitute.sh +RUN ./l2fwd_substitute.sh +RUN make +RUN cp build/l2fwd /usr/bin/l2fwd + +# +# Build l3fwd +# +WORKDIR ${DPDK_DIR}/examples/l3fwd +COPY ./dpdk-args.c ./dpdk-args.c +COPY ./dpdk-args.h ./dpdk-args.h +COPY ./c_util.c ./c_util.c +COPY ./c_util.h ./c_util.h +COPY ./l3fwd_eal_init.txt ./l3fwd_eal_init.txt +COPY ./l3fwd_parse_args.txt ./l3fwd_parse_args.txt +COPY ./l3fwd_substitute.sh ./l3fwd_substitute.sh +RUN ./l3fwd_substitute.sh +RUN make +RUN cp build/l3fwd /usr/bin/l3fwd + +# Copy default APP +RUN cp /usr/bin/l2fwd /usr/bin/dpdk-app + +# -------- Import stage. +FROM centos +COPY --from=0 /usr/bin/dpdk-app /usr/bin/dpdk-app +COPY --from=0 /usr/bin/l2fwd /usr/bin/l2fwd +COPY --from=0 /usr/bin/l3fwd /usr/bin/l3fwd +COPY --from=0 /usr/bin/testpmd /usr/bin/testpmd +COPY --from=0 /lib64/libnetutil_api.so /lib64/libnetutil_api.so +COPY --from=0 /usr/lib64/libnuma.so.1 /usr/lib64/libnuma.so.1 +COPY --from=0 /root/go/src/github.com/openshift/app-netutil/bin/c_sample /usr/bin/c_sample + +RUN yum install -y pciutils iproute ethtool lshw; yum clean all +# END + diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/c_util.c b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/c_util.c new file mode 100644 index 00000000..73f46a9e --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/c_util.c @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright(c) 2021 Red Hat, Inc. + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "libnetutil_api.h" +#include "c_util.h" + + +extern void dumpInterfaces(struct InterfaceResponse *pIfaceRsp) { + int i, j; + bool printReturn; + + if ((pIfaceRsp) && (pIfaceRsp->pIface)) { + for (i = 0; i < pIfaceRsp->numIfacePopulated; i++) { + printf(" Interface[%d]:\n", i); + + printf(" "); + printf(" DeviceType=%s", + (pIfaceRsp->pIface[i].DeviceType == NETUTIL_TYPE_HOST) ? "host" : + (pIfaceRsp->pIface[i].DeviceType == NETUTIL_TYPE_SRIOV) ? "SR-IOV" : + (pIfaceRsp->pIface[i].DeviceType == NETUTIL_TYPE_PCI) ? "PCI" : + (pIfaceRsp->pIface[i].DeviceType == NETUTIL_TYPE_VHOST) ? "vHost" : + (pIfaceRsp->pIface[i].DeviceType == NETUTIL_TYPE_MEMIF) ? "memif" : + (pIfaceRsp->pIface[i].DeviceType == NETUTIL_TYPE_VDPA) ? "vDPA" : + (pIfaceRsp->pIface[i].DeviceType == NETUTIL_TYPE_UNKNOWN) ? "unknown" : "error"); + + if (pIfaceRsp->pIface[i].NetworkStatus.Name) { + printf(" Name=\"%s\"", pIfaceRsp->pIface[i].NetworkStatus.Name); + } + if (pIfaceRsp->pIface[i].NetworkStatus.Interface) { + printf(" Interface=\"%s\"", pIfaceRsp->pIface[i].NetworkStatus.Interface); + } + printf("\n"); + + printReturn = false; + if (pIfaceRsp->pIface[i].NetworkStatus.Mac) { + if (printReturn == false) { + printReturn = true; + printf(" "); + } + printf(" MAC=\"%s\"", pIfaceRsp->pIface[i].NetworkStatus.Mac); + } + for (j = 0; j < NETUTIL_NUM_IPS; j++) { + if (pIfaceRsp->pIface[i].NetworkStatus.IPs[j]) { + if (printReturn == false) { + printReturn = true; + printf(" DNS Nameservers: "); + } + printf(" IP=\"%s\"", pIfaceRsp->pIface[i].NetworkStatus.IPs[j]); + } + } + if (printReturn) { + printf("\n"); + } + + printReturn = false; + for (j = 0; j < NETUTIL_NUM_DNS_NAMESERVERS; j++) { + if (pIfaceRsp->pIface[i].NetworkStatus.DNS.Nameservers[j]) { + if (printReturn == false) { + printReturn = true; + printf(" DNS Nameservers: "); + } + printf(" \"%s\"", pIfaceRsp->pIface[i].NetworkStatus.DNS.Nameservers[j]); + } + } + if (printReturn) { + printf("\n"); + } + + if (pIfaceRsp->pIface[i].NetworkStatus.DNS.Domain) { + printf(" DNS Domain: \"%s\"\n", pIfaceRsp->pIface[i].NetworkStatus.DNS.Domain); + } + + printReturn = false; + for (j = 0; j < NETUTIL_NUM_DNS_SEARCH; j++) { + if (pIfaceRsp->pIface[i].NetworkStatus.DNS.Search[j]) { + if (printReturn == false) { + printReturn = true; + printf(" DNS Search: "); + } + printf(" \"%s\"", pIfaceRsp->pIface[i].NetworkStatus.DNS.Search[j]); + } + } + if (printReturn) { + printf("\n"); + } + + printReturn = false; + for (j = 0; j < NETUTIL_NUM_DNS_OPTIONS; j++) { + if (pIfaceRsp->pIface[i].NetworkStatus.DNS.Options[j]) { + if (printReturn == false) { + printReturn = true; + printf(" DNS Options: "); + } + printf(" \"%s\"", pIfaceRsp->pIface[i].NetworkStatus.DNS.Options[j]); + } + } + if (printReturn) { + printf("\n"); + } + + switch (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Type) { + case NETUTIL_TYPE_PCI: + printf(" Type=PCI"); + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.PciAddress) { + printf(" PCIAddress=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.PciAddress); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.Vhostnet) { + printf(" Vhostnet=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.Vhostnet); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.RdmaDevice) { + printf(" RdmaDevice=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.RdmaDevice); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.PfPciAddress) { + printf(" PF-PCIAddress=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.PfPciAddress); + } + printf("\n"); + break; + case NETUTIL_TYPE_VHOST: + printf(" Type=vHOST"); + printf(" Mode=%s", + (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.VhostUser.Mode == NETUTIL_VHOST_MODE_CLIENT) ? "client" : + (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.VhostUser.Mode == NETUTIL_VHOST_MODE_SERVER) ? "server" : "error"); + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.VhostUser.Path) { + printf(" Path=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.VhostUser.Path); + } + printf("\n"); + break; + case NETUTIL_TYPE_MEMIF: + printf(" Type=Memif"); + printf(" Role=%s", + (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Role == NETUTIL_MEMIF_ROLE_MASTER) ? "master" : + (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Role == NETUTIL_MEMIF_ROLE_SLAVE) ? "slave" : "error"); + printf(" Mode=%s", + (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Mode == NETUTIL_MEMIF_MODE_ETHERNET) ? "ethernet" : + (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Mode == NETUTIL_MEMIF_MODE_IP) ? "ip" : + (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Mode == NETUTIL_MEMIF_MODE_INJECT_PUNT) ? "inject-punt" : "error"); + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Path) { + printf(" Path=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Path); + } + printf("\n"); + break; + case NETUTIL_TYPE_VDPA: + printf(" Type=vDPA"); + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.ParentDevice) { + printf(" ParentDevice=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.ParentDevice); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.Driver) { + printf(" Driver=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.Driver); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.Path) { + printf(" Path=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.Path); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.PciAddress) { + printf(" PCIAddress=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.PciAddress); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.PfPciAddress) { + printf(" PF-PCIAddress=%s", pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.PfPciAddress); + } + printf("\n"); + break; + } + } + } +} + +extern void freeInterfaces(struct InterfaceResponse *pIfaceRsp) { + int i, j; + + if ((pIfaceRsp) && (pIfaceRsp->pIface)) { + for (i = 0; i < pIfaceRsp->numIfacePopulated; i++) { + if (pIfaceRsp->pIface[i].NetworkStatus.Name) { + free(pIfaceRsp->pIface[i].NetworkStatus.Name); + } + if (pIfaceRsp->pIface[i].NetworkStatus.Interface) { + free(pIfaceRsp->pIface[i].NetworkStatus.Interface); + } + + if (pIfaceRsp->pIface[i].NetworkStatus.Mac) { + free(pIfaceRsp->pIface[i].NetworkStatus.Mac); + } + for (j = 0; j < NETUTIL_NUM_IPS; j++) { + if (pIfaceRsp->pIface[i].NetworkStatus.IPs[j]) { + free(pIfaceRsp->pIface[i].NetworkStatus.IPs[j]); + } + } + + for (j = 0; j < NETUTIL_NUM_DNS_NAMESERVERS; j++) { + if (pIfaceRsp->pIface[i].NetworkStatus.DNS.Nameservers[j]) { + free(pIfaceRsp->pIface[i].NetworkStatus.DNS.Nameservers[j]); + } + } + if (pIfaceRsp->pIface[i].NetworkStatus.DNS.Domain) { + free(pIfaceRsp->pIface[i].NetworkStatus.DNS.Domain); + } + for (j = 0; j < NETUTIL_NUM_DNS_SEARCH; j++) { + if (pIfaceRsp->pIface[i].NetworkStatus.DNS.Search[j]) { + free(pIfaceRsp->pIface[i].NetworkStatus.DNS.Search[j]); + } + } + for (j = 0; j < NETUTIL_NUM_DNS_OPTIONS; j++) { + if (pIfaceRsp->pIface[i].NetworkStatus.DNS.Options[j]) { + free(pIfaceRsp->pIface[i].NetworkStatus.DNS.Options[j]); + } + } + + switch (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Type) { + case NETUTIL_TYPE_PCI: + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.PciAddress) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.PciAddress); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.Vhostnet) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.Vhostnet); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.RdmaDevice) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.RdmaDevice); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.PfPciAddress) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Pci.PfPciAddress); + } + break; + case NETUTIL_TYPE_VHOST: + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.VhostUser.Path) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.VhostUser.Path); + } + break; + case NETUTIL_TYPE_MEMIF: + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Path) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Memif.Path); + } + break; + case NETUTIL_TYPE_VDPA: + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.ParentDevice) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.ParentDevice); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.Driver) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.Driver); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.Path) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.Path); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.PciAddress) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.PciAddress); + } + if (pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.PfPciAddress) { + free(pIfaceRsp->pIface[i].NetworkStatus.DeviceInfo.Vdpa.PfPciAddress); + } + break; + } + } + + free(pIfaceRsp->pIface); + } +} + +extern void dumpHugepages(struct HugepagesResponse *pHugepagesRsp) { + int i; + + if (pHugepagesRsp) { + if (pHugepagesRsp->MyContainerName) { + printf(" MyContainerName=%s\n", pHugepagesRsp->MyContainerName); + } + if (pHugepagesRsp->pHugepages) { + for (i = 0; i < pHugepagesRsp->numStructPopulated; i++) { + printf(" Hugepages[%d]:\n", i); + + printf(" "); + if (pHugepagesRsp->pHugepages[i].ContainerName) { + printf(" ContainerName=%s", pHugepagesRsp->pHugepages[i].ContainerName); + } + printf(" Request: 1G=%ld 2M=%ld Ukn=%ld Limit: 1G=%ld 2M=%ld Ukn=%ld\n", + pHugepagesRsp->pHugepages[i].Request1G, + pHugepagesRsp->pHugepages[i].Request2M, + pHugepagesRsp->pHugepages[i].Request, + pHugepagesRsp->pHugepages[i].Limit1G, + pHugepagesRsp->pHugepages[i].Limit2M, + pHugepagesRsp->pHugepages[i].Limit); + } + } + } +} + +extern void freeHugepages(struct HugepagesResponse *pHugepagesRsp) { + int i; + + if (pHugepagesRsp) { + if (pHugepagesRsp->MyContainerName) { + free(pHugepagesRsp->MyContainerName); + } + if (pHugepagesRsp->pHugepages) { + for (i = 0; i < pHugepagesRsp->numStructPopulated; i++) { + if (pHugepagesRsp->pHugepages[i].ContainerName) { + free(pHugepagesRsp->pHugepages[i].ContainerName); + } + } + free(pHugepagesRsp->pHugepages); + } + } +} + diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/c_util.h b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/c_util.h new file mode 100644 index 00000000..5ce6dfa1 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/c_util.h @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright(c) 2021 Red Hat, Inc. + +extern void dumpInterfaces(struct InterfaceResponse *pIfaceRsp); +extern void freeInterfaces(struct InterfaceResponse *pIfaceRsp); +extern void dumpHugepages(struct HugepagesResponse *pHugepagesRsp); +extern void freeHugepages(struct HugepagesResponse *pHugepagesRsp); diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/docker-entrypoint.sh b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/docker-entrypoint.sh new file mode 100755 index 00000000..bd3b0284 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/docker-entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +echo "DPDK_SAMPLE_APP is set as: $DPDK_SAMPLE_APP" + +if [[ $DPDK_SAMPLE_APP == l2fwd ]] ; then + echo "Calling: l2fwd" + exec "l2fwd" +elif [[ $DPDK_SAMPLE_APP == l3fwd ]] ; then + echo "Calling: l3fwd" + exec "l3fwd" +elif [[ $DPDK_SAMPLE_APP == testpmd ]] ; then + echo "Calling: testpmd" + exec "testpmd" +else + echo "Net set so using default - Calling: $@" + exec "$@" +fi diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/dpdk-args.c b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/dpdk-args.c new file mode 100644 index 00000000..7803a971 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/dpdk-args.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright(c) 2021 Red Hat, Inc. + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <dirent.h> +#include <sys/stat.h> +#include <unistd.h> +#include "libnetutil_api.h" +#include "dpdk-args.h" +#include "c_util.h" + +bool debugArgs = true; + +#define DPDK_ARGS_MAX_ARGS (30) +#define DPDK_ARGS_MAX_ARG_STRLEN (100) +char myArgsArray[DPDK_ARGS_MAX_ARGS][DPDK_ARGS_MAX_ARG_STRLEN]; +char* myArgv[DPDK_ARGS_MAX_ARGS]; + +//#define DPDK_ARGS_MAX_NUM_DIR (30) +//static const char DEFAULT_DIR[] = "/var/lib/cni/"; + +static char STR_MASTER[] = "master"; +static char STR_SLAVE[] = "slave"; +static char STR_ETHERNET[] = "ethernet"; + +/* Large enough to hold: ",mac=aa:bb:cc:dd:ee:ff" */ +#define DPDK_ARGS_MAX_MAC_STRLEN (25) +#define DPDK_ARGS_MAX_CONTAINERNAME_STRLEN (80) + + +static int getInterfaces(int argc, int *pPortCnt, int *pPortMask) { + int i = 0; + int vhostCnt = 0; + int memifCnt = 1; + int sriovCnt = 0; + int err; + struct InterfaceResponse ifaceRsp; + char macStr[DPDK_ARGS_MAX_MAC_STRLEN]; +#if 0 + // Refactor code later to find JSON file. Needs work so commented out for now. + DIR *d; + struct dirent *dir; + int currIndex = 0; + int freeIndex = 0; + char* dirList[DPDK_ARGS_MAX_NUM_DIR]; + char* fileExt; + + memset(dirList, 0, sizeof(char*)*DPDK_ARGS_MAX_NUM_DIR); + + dirList[freeIndex] = malloc(sizeof(char) * (strlen(DEFAULT_DIR)+1)); + strcpy(dirList[freeIndex++], DEFAULT_DIR); + + while (dirList[currIndex] != NULL) { + printf(" Directory:%s\n", dirList[currIndex]); + d = opendir(dirList[currIndex]); + if (d) + { + while ((dir = readdir(d)) != NULL) + { + if ((dir->d_name) && + (strcmp(dir->d_name, ".") != 0) && + (strcmp(dir->d_name, "..") != 0)) + { + printf(" Name:%s %d\n", dir->d_name, dir->d_type); + if (dir->d_type == DT_DIR) { + printf(" Add to Dir List:%s\n", dir->d_name); + dirList[freeIndex] = malloc(sizeof(char) * (strlen(DEFAULT_DIR)+strlen(dir->d_name)+1)); + sprintf(dirList[freeIndex++], "%s%s/", DEFAULT_DIR, dir->d_name); + } + else + { + if (strstr(dir->d_name, "net") != NULL) + { + fileExt = strrchr(dir->d_name, '.'); + if ((fileExt == NULL) || (strcmp(fileExt, ".json") != 0)) { + printf(" Adding to vdev list:%s\n", dir->d_name); + snprintf(&myArgsArray[argc++][0], DPDK_ARGS_MAX_ARG_STRLEN-1, + "--vdev=virtio_user%d,path=%s%s", i, dirList[currIndex], dir->d_name); + i++; + } + else { + printf(" Invalid FileExt\n"); + } + } + } + } + } + closedir(d); + } + free(dirList[currIndex]); + currIndex++; + } +#endif + + ifaceRsp.numIfaceAllocated = NETUTIL_NUM_NETWORKINTERFACE; + ifaceRsp.numIfacePopulated = 0; + ifaceRsp.pIface = malloc(ifaceRsp.numIfaceAllocated * sizeof(struct InterfaceData)); + if (ifaceRsp.pIface) { + memset(ifaceRsp.pIface, 0, (ifaceRsp.numIfaceAllocated * sizeof(struct InterfaceData))); + err = GetInterfaces(&ifaceRsp); + if ((err == NETUTIL_ERRNO_SUCCESS) || (err == NETUTIL_ERRNO_SIZE_ERROR)) { + + if (debugArgs) { + dumpInterfaces(&ifaceRsp); + } + + for (i = 0; i < ifaceRsp.numIfacePopulated; i++) { + switch (ifaceRsp.pIface[i].DeviceType) { + case NETUTIL_TYPE_SRIOV: + if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Pci.PciAddress) { + snprintf(&myArgsArray[argc++][0], DPDK_ARGS_MAX_ARG_STRLEN-1, + "-w %s", ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Pci.PciAddress); + sriovCnt++; + + *pPortMask = *pPortMask | 1 << *pPortCnt; + *pPortCnt = *pPortCnt + 1; + } else { + printf("ERROR: PCI Address not found. Type=%d\n", + ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Type); + } + break; + case NETUTIL_TYPE_VHOST: + if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.VhostUser.Path) { + if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.VhostUser.Mode == NETUTIL_VHOST_MODE_SERVER) { + snprintf(&myArgsArray[argc++][0], DPDK_ARGS_MAX_ARG_STRLEN-1, + "--vdev=virtio_user%d,path=%s,server=1", + vhostCnt, ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.VhostUser.Path); + + vhostCnt++; + *pPortMask = *pPortMask | 1 << *pPortCnt; + *pPortCnt = *pPortCnt + 1; + } + else if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.VhostUser.Mode == NETUTIL_VHOST_MODE_CLIENT) { + snprintf(&myArgsArray[argc++][0], DPDK_ARGS_MAX_ARG_STRLEN-1, + "--vdev=virtio_user%d,path=%s,queues=1", + vhostCnt, ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.VhostUser.Path); + + vhostCnt++; + *pPortMask = *pPortMask | 1 << *pPortCnt; + *pPortCnt = *pPortCnt + 1; + } else { + printf("ERROR: Unknown vHost Mode=%d\n", ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.VhostUser.Mode); + } + } else { + printf("ERROR: vHost Path not found. Type=%d\n", + ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Type); + } + break; + case NETUTIL_TYPE_MEMIF: + if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Path) { + char *pRole = NULL; + char *pMode = NULL; + + if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Role == NETUTIL_MEMIF_ROLE_MASTER) { + pRole = STR_MASTER; + } + else if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Role == NETUTIL_MEMIF_ROLE_SLAVE) { + pRole = STR_SLAVE; + } + else { + printf("ERROR: Unknown memif Role=%d\n", ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Role); + } + + if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Mode == NETUTIL_MEMIF_MODE_ETHERNET) { + pMode = STR_ETHERNET; + } + else if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Mode == NETUTIL_MEMIF_MODE_IP) { + //pMode = "ip"; + printf("ERROR: memif Mode=%d - Not Supported in DPDK!\n", + ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Mode); + } + else if (ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Mode == NETUTIL_MEMIF_MODE_INJECT_PUNT) { + //pMode = "inject-punt""; + printf("ERROR: memif Mode=%d - Not Supported in DPDK!\n", + ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Mode); + } + else { + printf("ERROR: Unknown memif Mode=%d\n", + ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Mode); + } + + if ((ifaceRsp.pIface[i].NetworkStatus.Mac) && + (strcmp(ifaceRsp.pIface[i].NetworkStatus.Mac,"") != 0)) { + snprintf(&macStr[0], DPDK_ARGS_MAX_MAC_STRLEN-1, + ",mac=%s", ifaceRsp.pIface[i].NetworkStatus.Mac); + } + else { + macStr[0] = '\0'; + } + + if ((pRole) && (pMode)) { + snprintf(&myArgsArray[argc++][0], DPDK_ARGS_MAX_ARG_STRLEN-1, + "--vdev=net_memif%d,socket=%s,role=%s%s", memifCnt, + ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Memif.Path, pRole, &macStr[0]); + + memifCnt++; + *pPortMask = *pPortMask | 1 << *pPortCnt; + *pPortCnt = *pPortCnt + 1; + } + } else { + printf("ERROR: Memif Path not found. Type=%d\n", + ifaceRsp.pIface[i].NetworkStatus.DeviceInfo.Type); + } + break; + } + } /* END of FOR EACH Interface */ + + if (sriovCnt == 0) { + strncpy(&myArgsArray[argc++][0], "--no-pci", DPDK_ARGS_MAX_ARG_STRLEN-1); + } + + freeInterfaces(&ifaceRsp); + } + else { + printf("Couldn't get network interface, err code: %d\n", err); + } + } + + return(argc); +} + +static int getHugepages(int argc) { + int i = 0; + int err; + int containerIndex = 0; + int64_t reqMemory = 0; + int64_t hugepageMemory = 1024; + struct HugepagesResponse hugepagesRsp; + + memset(&hugepagesRsp, 0, sizeof(struct HugepagesResponse)); + hugepagesRsp.numStructAllocated = NETUTIL_NUM_HUGEPAGES_DATA; + hugepagesRsp.pHugepages = malloc(hugepagesRsp.numStructAllocated * sizeof(struct HugepagesData)); + if (hugepagesRsp.pHugepages) { + memset(hugepagesRsp.pHugepages, 0, (hugepagesRsp.numStructAllocated * sizeof(struct HugepagesData))); + err = GetHugepages(&hugepagesRsp); + if ((err == NETUTIL_ERRNO_SUCCESS) || (err == NETUTIL_ERRNO_SIZE_ERROR)) { + + if (debugArgs) { + dumpHugepages(&hugepagesRsp); + } + + /* Loop through the list of containers to match container name from env. */ + if (hugepagesRsp.MyContainerName) { + for (i = 0; i < hugepagesRsp.numStructPopulated; i++) { + if (hugepagesRsp.pHugepages[i].ContainerName) { + if (strcmp(hugepagesRsp.MyContainerName, hugepagesRsp.pHugepages[i].ContainerName) == 0) { + containerIndex = i; + printf(" MATCH: ContainerName=%s, Index=%d\n", hugepagesRsp.pHugepages[i].ContainerName, containerIndex); + break; + } + } + } + } + + /* Limit can never be less than Request. So use Limit if non-zero. */ + /* However, for hugepages, Limit and Request should be the same, so */ + /* either value should be fine. */ + reqMemory = + (hugepagesRsp.pHugepages[containerIndex].Limit1G != 0) ? hugepagesRsp.pHugepages[containerIndex].Limit1G : + (hugepagesRsp.pHugepages[containerIndex].Limit2M != 0) ? hugepagesRsp.pHugepages[containerIndex].Limit2M : + (hugepagesRsp.pHugepages[containerIndex].Limit != 0) ? hugepagesRsp.pHugepages[containerIndex].Limit : + (hugepagesRsp.pHugepages[containerIndex].Request1G != 0) ? hugepagesRsp.pHugepages[containerIndex].Request1G : + (hugepagesRsp.pHugepages[containerIndex].Request2M != 0) ? hugepagesRsp.pHugepages[containerIndex].Request2M : + hugepagesRsp.pHugepages[containerIndex].Request; + + if (reqMemory != 0) { + /* Assuming 2 NUMA sockets, only use what container has access too. */ + /* TBD: Manage NUMA properly. */ + hugepageMemory = reqMemory / 2; + } + + freeHugepages(&hugepagesRsp); + + } else { + printf(" Couldn't get Hugepage info, defaulting to %ld, err code: %d\n", hugepageMemory, err); + } + } + + /* Build up memory portion of DPDK Args. */ + strncpy(&myArgsArray[argc++][0], "-m", DPDK_ARGS_MAX_ARG_STRLEN-1); + snprintf(&myArgsArray[argc++][0], DPDK_ARGS_MAX_ARG_STRLEN-1, + "%ld", hugepageMemory); + + strncpy(&myArgsArray[argc++][0], "-n", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "4", DPDK_ARGS_MAX_ARG_STRLEN-1); + + return(argc); +} + +char** GetArgs(int *pArgc, eDpdkAppType appType) +{ + int argc = 0; + int i; + struct CPUResponse cpuRsp; + int err; + int portMask = 0; + int portCnt = 0; + int lcoreBase = 0; + int port; + int length = 0; + + sleep(2); + + memset(&cpuRsp, 0, sizeof(cpuRsp)); + err = GetCPUInfo(&cpuRsp); + if (err) { + printf("Couldn't get CPU info, err code: %d\n", err); + } + if (cpuRsp.CPUSet) { + printf(" cpuRsp.CPUSet = %s\n", cpuRsp.CPUSet); + + // Free the string + free(cpuRsp.CPUSet); + } + + + memset(&myArgsArray[0][0], 0, sizeof(char)*DPDK_ARGS_MAX_ARG_STRLEN*DPDK_ARGS_MAX_ARGS); + memset(&myArgv[0], 0, sizeof(char)*DPDK_ARGS_MAX_ARGS); + + if (pArgc) { + /* + * Initialize EAL Options + */ + strncpy(&myArgsArray[argc++][0], "dpdk-app", DPDK_ARGS_MAX_ARG_STRLEN-1); + + argc = getHugepages(argc); + + //strncpy(&myArgsArray[argc++][0], "--file-prefix=dpdk-app_", DPDK_ARGS_MAX_ARG_STRLEN-1); + + if (appType == DPDK_APP_TESTPMD) { + strncpy(&myArgsArray[argc++][0], "-l", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "1-3", DPDK_ARGS_MAX_ARG_STRLEN-1); + + strncpy(&myArgsArray[argc++][0], "--master-lcore", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "1", DPDK_ARGS_MAX_ARG_STRLEN-1); + + argc = getInterfaces(argc, &portCnt, &portMask); + + /* + * Initialize APP Specific Options + */ + strncpy(&myArgsArray[argc++][0], "--", DPDK_ARGS_MAX_ARG_STRLEN-1); + + strncpy(&myArgsArray[argc++][0], "--auto-start", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "--tx-first", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "--no-lsc-interrupt", DPDK_ARGS_MAX_ARG_STRLEN-1); + + /* testpmd exits if there is not user enteraction, so print stats */ + /* every so often to keep program running. */ + strncpy(&myArgsArray[argc++][0], "--stats-period", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "60", DPDK_ARGS_MAX_ARG_STRLEN-1); + } + else if (appType == DPDK_APP_L3FWD) { + /* NOTE: The l3fwd app requires a TX Queue per lcore. So seeting lcore to 1 */ + /* until additional queues are added to underlying interface. */ + strncpy(&myArgsArray[argc++][0], "-l", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "1", DPDK_ARGS_MAX_ARG_STRLEN-1); + + strncpy(&myArgsArray[argc++][0], "--master-lcore", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "1", DPDK_ARGS_MAX_ARG_STRLEN-1); + lcoreBase = 1; + + argc = getInterfaces(argc, &portCnt, &portMask); + + /* + * Initialize APP Specific Options + */ + strncpy(&myArgsArray[argc++][0], "--", DPDK_ARGS_MAX_ARG_STRLEN-1); + + /* Set the PortMask, Hexadecimal bitmask of ports used by app. */ + strncpy(&myArgsArray[argc++][0], "-p", DPDK_ARGS_MAX_ARG_STRLEN-1); + snprintf(&myArgsArray[argc++][0], DPDK_ARGS_MAX_ARG_STRLEN-1, + "0x%x", portMask); + + /* Set all ports to promiscuous mode so that packets are accepted */ + /* regardless of the packet’s Ethernet MAC destination address. */ + strncpy(&myArgsArray[argc++][0], "-P", DPDK_ARGS_MAX_ARG_STRLEN-1); + + /* Determines which queues from which ports are mapped to which cores. */ + /* Usage: --config="(port,queue,lcore)[,(port,queue,lcore)]" */ + length = 0; + for (port = 0; port < portCnt; port++) { + /* If the first port, add '--config="' to string. */ + if (port == 0) { + length += snprintf(&myArgsArray[argc][length], DPDK_ARGS_MAX_ARG_STRLEN-length, + "--config=\""); + } + /* If not the first port, add a ',' to string. */ + else { + length += snprintf(&myArgsArray[argc][length], DPDK_ARGS_MAX_ARG_STRLEN-length, ","); + } + + /* Add each port data */ + length += snprintf(&myArgsArray[argc][length], DPDK_ARGS_MAX_ARG_STRLEN-length, + "(%d,%d,%d)", port, 0 /* queue */, lcoreBase /*+port*/); + + /* If the last port, add a trailing " to string. */ + if (port == portCnt-1) { + length += snprintf(&myArgsArray[argc][length], DPDK_ARGS_MAX_ARG_STRLEN-length, "\""); + } + } + argc++; + + /* Set to use software to analyze packet type. Without this option, */ + /* hardware will check the packet type. Not sure if vHost supports. */ + strncpy(&myArgsArray[argc++][0], "--parse-ptype", DPDK_ARGS_MAX_ARG_STRLEN-1); + + } + else if (appType == DPDK_APP_L2FWD) { + strncpy(&myArgsArray[argc++][0], "-l", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "1-3", DPDK_ARGS_MAX_ARG_STRLEN-1); + + argc = getInterfaces(argc, &portCnt, &portMask); + + /* + * Initialize APP Specific Options + */ + strncpy(&myArgsArray[argc++][0], "--", DPDK_ARGS_MAX_ARG_STRLEN-1); + + /* Set the PortMask, Hexadecimal bitmask of ports used by app. */ + strncpy(&myArgsArray[argc++][0], "-p", DPDK_ARGS_MAX_ARG_STRLEN-1); + snprintf(&myArgsArray[argc++][0], DPDK_ARGS_MAX_ARG_STRLEN-1, + "0x%x", portMask); + + /* Set the PERIOD, statistics will be refreshed each PERIOD seconds. */ + strncpy(&myArgsArray[argc++][0], "-T", DPDK_ARGS_MAX_ARG_STRLEN-1); + strncpy(&myArgsArray[argc++][0], "120", DPDK_ARGS_MAX_ARG_STRLEN-1); + + /* Set to no-mac-updating. When enabled: */ + /* - source MAC address is replaced by the TX port MAC address */ + /* - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID */ + strncpy(&myArgsArray[argc++][0], "--no-mac-updating", DPDK_ARGS_MAX_ARG_STRLEN-1); + } + + for (i = 0; i < argc; i++) { + myArgv[i] = &myArgsArray[i][0]; + } + *pArgc = argc; + } + + return(myArgv); +} diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/dpdk-args.h b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/dpdk-args.h new file mode 100644 index 00000000..69424c8b --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/dpdk-args.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright(c) 2021 Red Hat, Inc. + +#ifndef __DPDK_ARGS_H__ +#define __DPDK_ARGS_H__ + +typedef enum { + DPDK_APP_TESTPMD = 1, + DPDK_APP_L3FWD, + DPDK_APP_L2FWD, + DPDK_APP_OTHER +} eDpdkAppType; + +extern char** GetArgs(int *pArgc, eDpdkAppType appType); + +#endif /* __DPDK_ARGS_H__ */ diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_eal_init.txt b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_eal_init.txt new file mode 100644 index 00000000..43fd6c91 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_eal_init.txt @@ -0,0 +1,39 @@ +#if 0 + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n"); + argc -= ret; + argv += ret; +#else + int i; + int myArgc = 0; + char **myArgv = NULL; + + printf("ENTER dpdk-app:\n"); + printf(" argc=%d\n", argc); + for (i = 0; i < argc; i++) { + printf(" %s", argv[i]); + } + printf("\n"); + + if (argc > 1) { + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n"); + argc -= ret; + argv += ret; + } else { + myArgv = GetArgs(&myArgc, DPDK_APP_L2FWD); + printf(" myArgc=%d\n", myArgc); + for (i = 0; i < myArgc; i++) { + printf(" %s", myArgv[i]); + } + printf("\n"); + + ret = rte_eal_init(myArgc, myArgv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n"); + myArgc -= ret; + myArgv += ret; + } +#endif diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_parse_args.txt b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_parse_args.txt new file mode 100644 index 00000000..a221ae94 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_parse_args.txt @@ -0,0 +1,9 @@ +#if 0 + ret = l2fwd_parse_args(argc, argv); +#else + if (argc > 1) { + ret = l2fwd_parse_args(argc, argv); + } else { + ret = l2fwd_parse_args(myArgc, myArgv); + } +#endif diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_substitute.sh b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_substitute.sh new file mode 100755 index 00000000..83c5dbdb --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l2fwd_substitute.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# SPDX-License-Identifier: Apache-2.0 +# Copyright(c) 2021 Red Hat, Inc. + + +# Add new app-netutil headerfile to the main code so app-netutil +# can be called to gather parameters. +# +# Search for line with: "#include <rte_mbuf.h>". +# Append line: "#include "dpdk-args.h"". +sed -i -e '/#include <rte_mbuf.h>/a #include "dpdk-args.h"' main.c + + +# Replace the call to rte_eal_init() to call app-netutil code first +# if no input parametes were passed in. app-netutil code generates +# its own set of DPDK parameters that are used instead. If input +# parameters were passed in, call rte_eal_init() with input parameters +# and run as if app-netutil wasn't there. +# +# Search for the line with "ret = rte_eal_init(argc, argv);" +# Create a label 'a' and continue searching and copying until +# line with "argv += ret;" is found. +# Replace that block of code with the contents of file 'l2fwd_eal_init.txt'. +sed -i '/ret = rte_eal_init(argc, argv);/{ +:a;N;/argv += ret;/!ba;N;s/.*\n//g +r l2fwd_eal_init.txt +}' main.c + + +# If no input parametes were passed in, use the parameter list generated +# by app-netutil in the previous patch to call the local parameter +# parsing code, l2fwd_parse_args(). If input parameters were passed in, +# call l2fwd_parse_args() with input parameters and run as if app-netutil +# wasn't there. +# +# Search for the line with "ret = l2fwd_parse_args(argc, argv);" +# Replace that line of code with the contents of file +# 'l2fwd_parse_args.txt'. +sed -i '/ret = l2fwd_parse_args(argc, argv);/{ +s/ret = l2fwd_parse_args(argc, argv);//g +r l2fwd_parse_args.txt +}' main.c + + +# Add new app-netutil source file to the Makefile. +# +# Search for line with: "SRCS-y :=". +# Append line: "SRCS-y += c_util.c dpdk-args.c". +sed -i -e '/SRCS-y :=/a SRCS-y += c_util.c dpdk-args.c' Makefile + + +# Add new app-netutil shared library to the Makefile. +# Contains the C API and GO package which collects the +# interface data. +# +# Search for line with: "SRCS-y += c_util.c dpdk-args.c". +# Append line: "LDLIBS += -lnetutil_api". +sed -i -e '/SRCS-y += c_util.c dpdk-args.c/a LDLIBS += -lnetutil_api' Makefile diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_eal_init.txt b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_eal_init.txt new file mode 100644 index 00000000..80e9af1f --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_eal_init.txt @@ -0,0 +1,39 @@ +#if 0 + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n"); + argc -= ret; + argv += ret; +#else + /* int i; */ + int myArgc = 0; + char **myArgv = NULL; + + printf("ENTER dpdk-app:\n"); + printf(" argc=%d\n", argc); + for (i = 0; i < argc; i++) { + printf(" %s", argv[i]); + } + printf("\n"); + + if (argc > 1) { + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n"); + argc -= ret; + argv += ret; + } else { + myArgv = GetArgs(&myArgc, DPDK_APP_L3FWD); + printf(" myArgc=%d\n", myArgc); + for (i = 0; i < myArgc; i++) { + printf(" %s", myArgv[i]); + } + printf("\n"); + + ret = rte_eal_init(myArgc, myArgv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n"); + myArgc -= ret; + myArgv += ret; + } +#endif diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_parse_args.txt b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_parse_args.txt new file mode 100644 index 00000000..57b4e8d3 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_parse_args.txt @@ -0,0 +1,9 @@ +#if 0 + ret = parse_args(argc, argv); +#else + if (argc > 1) { + ret = parse_args(argc, argv); + } else { + ret = parse_args(myArgc, myArgv); + } +#endif diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_substitute.sh b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_substitute.sh new file mode 100755 index 00000000..020886f5 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/l3fwd_substitute.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# SPDX-License-Identifier: Apache-2.0 +# Copyright(c) 2021 Red Hat, Inc. + + +# Add new app-netutil headerfile to the main code so app-netutil +# can be called to gather parameters. +# +# Search for line with: "#include "l3fwd.h"". +# Append line: "#include "dpdk-args.h"". +sed -i -e '/#include "l3fwd.h"/a #include "dpdk-args.h"' main.c + + +# L3fwd code defaults to using some Checksum Offload that doesn't +# work on all hardware. Turned off. +# +# Search for: ".offloads = DEV_RX_OFFLOAD_CHECKSUM,". +# Replace with: ".offloads = 0, /*DEV_RX_OFFLOAD_CHECKSUM,*/". +sed -i -e 's!.offloads = DEV_RX_OFFLOAD_CHECKSUM,!.offloads = 0, /*DEV_RX_OFFLOAD_CHECKSUM,*/!' main.c + + +# Replace the call to rte_eal_init() to call app-netutil code first +# if no input parametes were passed in. app-netutil code generates +# its own set of DPDK parameters that are used instead. If input +# parameters were passed in, call rte_eal_init() with input parameters +# and run as if app-netutil wasn't there. +# +# Search for the line with "ret = rte_eal_init(argc, argv);" +# Create a label 'a' and continue searching and copying until +# line with "argv += ret;" is found. +# Replace that block of code with the contents of file 'l3fwd_eal_init.txt'. +sed -i '/ret = rte_eal_init(argc, argv);/{ +:a;N;/argv += ret;/!ba;N;s/.*\n//g +r l3fwd_eal_init.txt +}' main.c + + +# If no input parametes were passed in, use the parameter list generated +# by app-netutil in the previous patch to call the local parameter +# parsing code, parse_args(). If input parameters were passed in, +# call parse_args() with input parameters and run as if app-netutil +# wasn't there. +# +# Search for the line with "ret = parse_args(argc, argv);" +# Replace that line of code with the contents of file +# 'l3fwd_parse_args.txt'. +sed -i '/ret = parse_args(argc, argv);/{ +s/ret = parse_args(argc, argv);//g +r l3fwd_parse_args.txt +}' main.c + + +# Add new app-netutil source file to the Makefile. +# +# Search for line with: "SRCS-y :=". +# Append line: "SRCS-y += c_util.c dpdk-args.c". +sed -i -e '/SRCS-y :=/a SRCS-y += c_util.c dpdk-args.c' Makefile + + +# Add new app-netutil shared library to the Makefile. +# Contains the C API and GO package which collects the +# interface data. +# +# Search for line with: "SRCS-y += c_util.c dpdk-args.c". +# Append line: "LDLIBS += -lnetutil_api". +sed -i -e '/SRCS-y += c_util.c dpdk-args.c/a LDLIBS += -lnetutil_api' Makefile diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_eal_init.txt b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_eal_init.txt new file mode 100644 index 00000000..a0da4d50 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_eal_init.txt @@ -0,0 +1,28 @@ +#if 0 + diag = rte_eal_init(argc, argv); +#else + int i; + int myArgc = 0; + char **myArgv = NULL; + + printf("ENTER dpdk-app:\n"); + printf(" argc=%d\n", argc); + for (i = 0; i < argc; i++) { + printf(" %s", argv[i]); + } + printf("\n"); + + if (argc > 1) { + diag = rte_eal_init(argc, argv); + } else { + myArgv = GetArgs(&myArgc, DPDK_APP_TESTPMD); + printf(" myArgc=%d\n", myArgc); + for (i = 0; i < myArgc; i++) { + printf(" %s", myArgv[i]); + } + printf("\n"); + + diag = rte_eal_init(myArgc, myArgv); + } +#endif + diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_launch_args_parse.txt b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_launch_args_parse.txt new file mode 100644 index 00000000..7c2254bf --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_launch_args_parse.txt @@ -0,0 +1,19 @@ +#if 0 + argc -= diag; + argv += diag; + if (argc > 1) + launch_args_parse(argc, argv); +#else + if (argc > 1) { + argc -= diag; + argv += diag; + if (argc > 1) + launch_args_parse(argc, argv); + } else { + myArgc -= diag; + myArgv += diag; + if (myArgc > 1) + launch_args_parse(myArgc, myArgv); + } +#endif + diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_substitute.sh b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_substitute.sh new file mode 100755 index 00000000..30e222e9 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/testpmd_substitute.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# SPDX-License-Identifier: Apache-2.0 +# Copyright(c) 2021 Red Hat, Inc. + + +# Add new app-netutil headerfile to the main code so app-netutil +# can be called to gather parameters. +# +# Search for: "#include "testpmd.h"". +# Append: "#include "dpdk-args.h"". +sed -i -e '/#include "testpmd.h"/a #include "dpdk-args.h"' testpmd.c + + +# Replace the call to rte_eal_init() to call app-netutil code first +# if no input parametes were passed in. app-netutil code generates +# its own set of DPDK parameters that are used instead. If input +# parameters were passed in, call rte_eal_init() with input parameters +# and run as if app-netutil wasn't there. +# +# Search for the line with "diag = rte_eal_init(argc, argv);" +# Replace that line of code with the contents of file +# 'testpmd_eal_init.txt'. +sed -i '/diag = rte_eal_init(argc, argv);/{ +s/diag = rte_eal_init(argc, argv);//g +r testpmd_eal_init.txt +}' testpmd.c + + +# If no input parametes were passed in, use the parameter list generated +# by app-netutil in the previous patch to call the local parameter +# parsing code, launch_args_parse(). If input parameters were passed in, +# call launch_args_parse() with input parameters and run as if app-netutil +# wasn't there. +# +# Search for the line with "argc -= diag;" +# Create a label 'a' and continue searching and copying until +# line with "launch_args_parse(argc, argv);" is found. +# Replace that block of code with the contents of file +# 'testpmd_launch_args_parse.txt'. +sed -i '/argc -= diag;/{ +:a;N;/launch_args_parse(argc, argv);/!ba;N;s/.*\n//g +r testpmd_launch_args_parse.txt +}' testpmd.c + + +# Add new app-netutil source file to the Makefile. +# +# Search for line with: "SRCS-y += parameters.c". +# Replace with line: "SRCS-y += parameters.c c_util.c dpdk-args.c". +sed -i -e 's/SRCS-y += parameters.c/SRCS-y += parameters.c c_util.c dpdk-args.c/' Makefile + + +# Add new app-netutil shared library to the Makefile. +# Contains the C API and GO package which collects the +# interface data. +# +# Search for line with: "SRCS-y += util.c". +# Append line: "LDLIBS += -lnetutil_api". +sed -i -e '/SRCS-y += util.c/a LDLIBS += -lnetutil_api' Makefile + diff --git a/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/vhost_substitute.sh b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/vhost_substitute.sh new file mode 100755 index 00000000..471eecc5 --- /dev/null +++ b/tools/docker/test-containers/dpdk-forwarding-pods/l2l3fwd/vhost_substitute.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# SPDX-License-Identifier: Apache-2.0 +# Copyright(c) 2021 Red Hat, Inc. + + +# The first two commands update one of the 'if' checks to remove +# the check for 'master == VHOST_USER_SET_VRING_CALL'. +# +# Search for: " !(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED) &&". +# Replace with: " !(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED)) {". +sed -i -e 's/ !(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED) &&/ !(dev->flags \& VIRTIO_DEV_VDPA_CONFIGURED)) {/g' lib/librte_vhost/vhost_user.c +# +# Search for line with: " msg.request.master == VHOST_USER_SET_VRING_CALL) {". +# Delete the line. +sed -i -e '/ msg\.request\.master == VHOST_USER_SET_VRING_CALL) {/d' lib/librte_vhost/vhost_user.c + + +# Force an RARP message to be sent out. +# +# Search for line with: " hw->started = true;". +# Append line: " virtio_notify_peers(dev);". +sed -i -e '/ hw->started = true;/a virtio_notify_peers(dev);' drivers/net/virtio/virtio_ethdev.c |