From 1b6242fc583a6b871304fb995af6dc211b58f69b Mon Sep 17 00:00:00 2001 From: Adrian Dudau Date: Thu, 26 Jun 2014 13:48:23 +0200 Subject: initial commit for Enea Linux 4.0 Migrated from the internal git server on the daisy-enea branch Signed-off-by: Adrian Dudau --- README | 41 + conf/layer.conf | 13 + images-append/enea-image-demo.bbappend | 3 + images-append/enea-image-test-bash.bbappend | 5 + recipes-append/pciutils/pciutils_3.2.1.bbappend | 8 + recipes-core/numactl/numactl-2.0.9/Makefile.patch | 63 ++ recipes-core/numactl/numactl-2.0.9/regress1-parser | 63 ++ recipes-core/numactl/numactl-2.0.9/run-ptest | 5 + recipes-core/numactl/numactl_2.0.9.bb | 52 ++ recipes-core/numad/numad-0.6/Makefile.patch | 50 ++ recipes-core/numad/numad-0.6/numad.conf.patch | 14 + recipes-core/numad/numad-0.6/numad.init.patch | 85 ++ recipes-core/numad/numad-0.6/run-ptest | 20 + recipes-core/numad/numad-0.6/test.patch | 175 ++++ recipes-core/numad/numad_0.6.bb | 51 ++ recipes-core/packagegroups/packagegroup-enea-ip.bb | 18 + recipes-kernel/linux/linux-yocto_3.10.bbappend | 4 + recipes-kernel/linux/linux-yocto_3.14.bbappend | 4 + recipes-networking/dpdk/dpdk_git.bb | 139 +++ .../dpdk/files/igb_ethdev_loopback.patch | 96 +++ recipes-networking/dpdk/files/l2fwd-lpbk/Makefile | 51 ++ recipes-networking/dpdk/files/l2fwd-lpbk/main.c | 929 +++++++++++++++++++++ recipes-networking/dpdk/files/l2fwd-lpbk/main.h | 45 + recipes-networking/dpdk/files/machine-flags.patch | 12 + recipes-networking/dpdk/files/maketest.patch | 41 + .../dpdk/files/rte_kni_module_1_6.patch.x | 206 +++++ recipes-networking/dpdk/files/run-ptest | 195 +++++ recipes-networking/dpdk/files/runtest.patch | 20 + .../dpdk/files/unbreak-makefiles.patch | 87 ++ .../files/0001-openvswitchdpdk-enabled-ptest.patch | 380 +++++++++ .../openvswitchdpdk/files/configure-fix.patch | 12 + .../files/makefile-install-rule.patch | 22 + .../files/openvswitchdpdk-controller | 279 +++++++ .../files/openvswitchdpdk-controller-setup | 29 + .../openvswitchdpdk/files/openvswitchdpdk-switch | 110 +++ .../files/openvswitchdpdk-switch-setup | 16 + .../openvswitchdpdk/files/ovs-ctl-dpdk.patch | 123 +++ .../openvswitchdpdk/files/qemu-makefile.patch | 26 + .../openvswitchdpdk/files/qemu-options-hx.patch | 30 + .../openvswitchdpdk/files/qemu-pixman-config.patch | 26 + recipes-networking/openvswitchdpdk/files/run-ptest | 8 + .../openvswitchdpdk/openvswitchdpdk_0.10.0.bb | 248 ++++++ recipes-test/oftest/oftest_git.bb | 27 + recipes-test/openvswitchdpdk-oftest/files/README | 3 + .../openvswitchdpdk-oftest/files/run-ptest | 284 +++++++ .../openvswitchdpdk-oftest.bb | 20 + 46 files changed, 4138 insertions(+) create mode 100644 README create mode 100644 conf/layer.conf create mode 100644 images-append/enea-image-demo.bbappend create mode 100644 images-append/enea-image-test-bash.bbappend create mode 100644 recipes-append/pciutils/pciutils_3.2.1.bbappend create mode 100644 recipes-core/numactl/numactl-2.0.9/Makefile.patch create mode 100755 recipes-core/numactl/numactl-2.0.9/regress1-parser create mode 100755 recipes-core/numactl/numactl-2.0.9/run-ptest create mode 100644 recipes-core/numactl/numactl_2.0.9.bb create mode 100644 recipes-core/numad/numad-0.6/Makefile.patch create mode 100644 recipes-core/numad/numad-0.6/numad.conf.patch create mode 100644 recipes-core/numad/numad-0.6/numad.init.patch create mode 100755 recipes-core/numad/numad-0.6/run-ptest create mode 100644 recipes-core/numad/numad-0.6/test.patch create mode 100644 recipes-core/numad/numad_0.6.bb create mode 100644 recipes-core/packagegroups/packagegroup-enea-ip.bb create mode 100644 recipes-kernel/linux/linux-yocto_3.10.bbappend create mode 100644 recipes-kernel/linux/linux-yocto_3.14.bbappend create mode 100644 recipes-networking/dpdk/dpdk_git.bb create mode 100644 recipes-networking/dpdk/files/igb_ethdev_loopback.patch create mode 100644 recipes-networking/dpdk/files/l2fwd-lpbk/Makefile create mode 100644 recipes-networking/dpdk/files/l2fwd-lpbk/main.c create mode 100644 recipes-networking/dpdk/files/l2fwd-lpbk/main.h create mode 100644 recipes-networking/dpdk/files/machine-flags.patch create mode 100644 recipes-networking/dpdk/files/maketest.patch create mode 100644 recipes-networking/dpdk/files/rte_kni_module_1_6.patch.x create mode 100644 recipes-networking/dpdk/files/run-ptest create mode 100644 recipes-networking/dpdk/files/runtest.patch create mode 100644 recipes-networking/dpdk/files/unbreak-makefiles.patch create mode 100644 recipes-networking/openvswitchdpdk/files/0001-openvswitchdpdk-enabled-ptest.patch create mode 100644 recipes-networking/openvswitchdpdk/files/configure-fix.patch create mode 100644 recipes-networking/openvswitchdpdk/files/makefile-install-rule.patch create mode 100755 recipes-networking/openvswitchdpdk/files/openvswitchdpdk-controller create mode 100644 recipes-networking/openvswitchdpdk/files/openvswitchdpdk-controller-setup create mode 100644 recipes-networking/openvswitchdpdk/files/openvswitchdpdk-switch create mode 100644 recipes-networking/openvswitchdpdk/files/openvswitchdpdk-switch-setup create mode 100644 recipes-networking/openvswitchdpdk/files/ovs-ctl-dpdk.patch create mode 100644 recipes-networking/openvswitchdpdk/files/qemu-makefile.patch create mode 100644 recipes-networking/openvswitchdpdk/files/qemu-options-hx.patch create mode 100644 recipes-networking/openvswitchdpdk/files/qemu-pixman-config.patch create mode 100644 recipes-networking/openvswitchdpdk/files/run-ptest create mode 100644 recipes-networking/openvswitchdpdk/openvswitchdpdk_0.10.0.bb create mode 100644 recipes-test/oftest/oftest_git.bb create mode 100644 recipes-test/openvswitchdpdk-oftest/files/README create mode 100644 recipes-test/openvswitchdpdk-oftest/files/run-ptest create mode 100644 recipes-test/openvswitchdpdk-oftest/openvswitchdpdk-oftest.bb diff --git a/README b/README new file mode 100644 index 0000000..c2593c0 --- /dev/null +++ b/README @@ -0,0 +1,41 @@ +Enea Linux IP support +================================= + +This layer provides IP support and related tools to Enea Linux. + +Supported Platforms +------------------- + + +Dependencies +------------ +meta-enea: + URI: git://git.enea.com/linux/meta-enea.git + branch: master + +meta-virtualization: + URI: git://git.yoctoproject.org/meta-virtualization + branch: master + +meta-openembedded: + URI: git://git.openembedded.org/meta-openembedded + branch: master + layers: meta-oe + meta-networking + meta-filesystems + +meta-eca: + URI git://git.yoctoproject.org/meta-eca + branch: master + layers: meta-eca + +Maintenance +----------- + +Maintainers: Enea Linux + + +License +------- + +Same as meta-enea diff --git a/conf/layer.conf b/conf/layer.conf new file mode 100644 index 0000000..23f4c8e --- /dev/null +++ b/conf/layer.conf @@ -0,0 +1,13 @@ +# We have a packages directory, add to BBFILES +BBPATH .= ":${LAYERDIR}" + +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb*" +BBFILES += "${LAYERDIR}/images/*.bb*" +BBFILES += "${LAYERDIR}/images-append/*.bb*" + +BBFILE_COLLECTIONS += "enea-ip" +BBFILE_PATTERN_enea-ip := "^${LAYERDIR}/" +BBFILE_PRIORITY_enea-ip = "7" +LAYERDEPENDS_enea-ip = "enea" + +BB_DANGLINGAPPENDS_WARNONLY = "yes" diff --git a/images-append/enea-image-demo.bbappend b/images-append/enea-image-demo.bbappend new file mode 100644 index 0000000..39c0377 --- /dev/null +++ b/images-append/enea-image-demo.bbappend @@ -0,0 +1,3 @@ +IMAGE_INSTALL += " \ + packagegroup-enea-ip \ + " diff --git a/images-append/enea-image-test-bash.bbappend b/images-append/enea-image-test-bash.bbappend new file mode 100644 index 0000000..900e60c --- /dev/null +++ b/images-append/enea-image-test-bash.bbappend @@ -0,0 +1,5 @@ +IMAGE_FSTYPES += "cpio.gz" + +IMAGE_INSTALL += " \ + packagegroup-enea-ip \ + " diff --git a/recipes-append/pciutils/pciutils_3.2.1.bbappend b/recipes-append/pciutils/pciutils_3.2.1.bbappend new file mode 100644 index 0000000..67d18b3 --- /dev/null +++ b/recipes-append/pciutils/pciutils_3.2.1.bbappend @@ -0,0 +1,8 @@ +#use this instead of busybox.lspci + +inherit update-alternatives + +ALTERNATIVE_${PN} += "lspci" +ALTERNATIVE_LINK_NAME[lspci] = "/usr/bin/lspci" +ALTERNATIVE_TARGET[lspci] = "/usr/sbin/lspci" +ALTERNATIVE_PRIORITY[lspci] = "100" diff --git a/recipes-core/numactl/numactl-2.0.9/Makefile.patch b/recipes-core/numactl/numactl-2.0.9/Makefile.patch new file mode 100644 index 0000000..3c6d3e2 --- /dev/null +++ b/recipes-core/numactl/numactl-2.0.9/Makefile.patch @@ -0,0 +1,63 @@ +Add 'test-install' rule. +Do not use getlibdir for 'prefix' variable. +Echo 'SKIP' result for ptest when run on sigle node machine. + +Signed-off-by: Radu Patriu +Upstream-Status: Pending + +Index: numactl-2.0.9-orig/Makefile +=================================================================== +--- numactl-2.0.9-orig.orig/Makefile 2013-10-09 00:34:57.000000000 +0300 ++++ numactl-2.0.9-orig/Makefile 2014-02-07 20:27:21.951902184 +0200 +@@ -42,7 +42,7 @@ + else + prefix := $(PREFIX) + endif +-libdir := ${prefix}/$(shell ./getlibdir) ++libdir := ${prefix}/lib + docdir := ${prefix}/share/doc + + all: numactl migratepages migspeed libnuma.so numademo numamon memhog \ +@@ -197,9 +197,9 @@ + .depend: + ${CC} -MM -DDEPS_RUN -I. ${SOURCES} > .depend.X && mv .depend.X .depend + +-include .depend ++# include .depend + +-Makefile: .depend ++# Makefile: .depend + + .PHONY: test regress1 regress2 + +@@ -215,3 +215,18 @@ + + # test: all regress1 regress2 test_numademo regress3 + test: all regress1 regress2 test_numademo ++ ++TEST_DESTDIR ?= ${prefix}/lib/numactl/ptest ++TEST_FILES = bind_range distance migrate_pages nodemap prefered README regress2 shmtest \ ++ checkaffinity ftok move_pages node-parse printcpu realloc_test regress-io tbitmap \ ++ checktopology mbind_mig_pages mynode pagesize randmap regress runltp tshared ++TEST_FRAME = Makefile getlibdir numactl numademo ++ ++test-install: ++ install -d ${TEST_DESTDIR}/test ++ for file in ${TEST_FILES}; do \ ++ install test/$${file} ${TEST_DESTDIR}/test; \ ++ done ++ for file in ${TEST_FRAME}; do \ ++ install $${file} ${TEST_DESTDIR}; \ ++ done +Index: numactl-2.0.9-orig/test/regress +=================================================================== +--- numactl-2.0.9-orig.orig/test/regress 2013-10-09 00:34:58.000000000 +0300 ++++ numactl-2.0.9-orig/test/regress 2014-02-07 20:27:01.151901373 +0200 +@@ -73,6 +73,7 @@ + if [ $numnodes -lt 2 ] ; then + echo "need at least two nodes with at least $NEEDPAGES each of" + echo "free memory for mempolicy regression tests" ++ echo '========SKIP' + exit 1 + fi + } diff --git a/recipes-core/numactl/numactl-2.0.9/regress1-parser b/recipes-core/numactl/numactl-2.0.9/regress1-parser new file mode 100755 index 0000000..d8e9dea --- /dev/null +++ b/recipes-core/numactl/numactl-2.0.9/regress1-parser @@ -0,0 +1,63 @@ +#!/bin/sh + +test_pattern="=>testing " +test_fail="==FAILED" +test_skip="==SKIP" +test_log="regress1.log" +test_suite="regress1" + +test_name="" +failed="0" +skiped="0" + +while read line +do + substring=${line#$test_pattern*} +# echo "sub>"$substring"<" + if [ "$substring" != "$line" ]; + then + if [ "$test_name" != "" ]; + then + if [ "$failed" = "1" ]; + then + echo "FAIL: $test_name" + else + echo "PASS: $test_name" + fi + fi + test_name=$substring +# echo "name>"$test_name"<" + failed="0" + fi + + if [ "${line#*$test_fail}" != "$line" ]; + then + failed="1" + fi + + if [ "${line#*$test_skip}" != "$line" ]; + then + skiped="1" + fi + +done < $test_log + +if [ "$skiped" = "1" ]; +then + echo "SKIP: $test_suite" + exit 1 +fi + + +if [ "$test_name" = "" ]; +then + echo "FAIL: $test_suite" + exit 1 +fi + +if [ "$failed" = "1" ]; +then + echo "FAIL: $test_name" +else + echo "PASS: $test_name" +fi diff --git a/recipes-core/numactl/numactl-2.0.9/run-ptest b/recipes-core/numactl/numactl-2.0.9/run-ptest new file mode 100755 index 0000000..1d5292e --- /dev/null +++ b/recipes-core/numactl/numactl-2.0.9/run-ptest @@ -0,0 +1,5 @@ +#!/bin/sh + +make regress1 >regress1.log 2>&1 +./regress1-parser +make -k regress2 >regress2.log 2>&1 && echo "PASS: regress2" || echo "FAIL: regress2" diff --git a/recipes-core/numactl/numactl_2.0.9.bb b/recipes-core/numactl/numactl_2.0.9.bb new file mode 100644 index 0000000..a7fee35 --- /dev/null +++ b/recipes-core/numactl/numactl_2.0.9.bb @@ -0,0 +1,52 @@ +SUMMARY = "Simple NUMA policy support" +DESCRIPTION = 'It consists of a numactl program to run \ +other programs with a specific NUMA policy and a libnuma shared library \ +("NUMA API") to set NUMA policy in applications.' +HOMEPAGE = "http://oss.sgi.com/projects/libnuma/" +SECTION = "console/utils" + +RDEPENDS_numactl = "libnuma" + +LICENSE = "GPLv2 & LGPLv2.1" +LICENSE_libnuma = "GPLv2" +LICENSE_numactl = "LGPLv2.1" + +LIC_FILES_CHKSUM = "file://libnuma.c;beginline=1;endline=17;md5=17362df5a5de121a289afcac0d30a9c6 \ + file://numactl.c;beginline=1;endline=16;md5=0c0a67367b1246f7643d6bc2bfe469de" + +SRC_URI = "ftp://oss.sgi.com/www/projects/libnuma/download/numactl-2.0.9.tar.gz \ + file://Makefile.patch \ + file://regress1-parser \ + file://run-ptest" + +SRC_URI[md5sum] = "136685c8eaf9d6569c351fe1d453b30c" +SRC_URI[sha256sum] = "9ca033e6c14c0f26c20379b0cf9299429fd5a354a79c3c7880fd41ef69f7751c" + +S = "${WORKDIR}/numactl-${PV}" + +EXTRA_OEMAKE = "PREFIX=${D}/usr TEST_DESTDIR=${D}${PTEST_PATH}" + +do_install () { + oe_runmake install + rmdir ${D}/usr/share/man/man2 +} + +PACKAGES = "libnuma-dbg ${PN}-dbg ${PN} ${PN}-doc libnuma-staticdev libnuma libnuma-dev libnuma-doc" + +FILES_libnuma-dbg = "${libdir}/.debug" +FILES_libnuma-staticdev = "${libdir}/*.a" +FILES_libnuma = "${libdir}/libnuma.so.*" +FILES_libnuma-dev = "${libdir} ${includedir}" +FILES_libnuma-doc = "${mandir}/man3" + +FILES_${PN}-dbg = "${bindir}/.debug /usr/src/debug" +FILES_${PN} = "${bindir}" +FILES_${PN}-doc = "${mandir}/man8" + +inherit ptest +RDEPENDS_${PN}-ptest += "make" + +do_install_ptest () { + oe_runmake test-install + install ${WORKDIR}/regress1-parser ${D}${PTEST_PATH} +} diff --git a/recipes-core/numad/numad-0.6/Makefile.patch b/recipes-core/numad/numad-0.6/Makefile.patch new file mode 100644 index 0000000..f6a564d --- /dev/null +++ b/recipes-core/numad/numad-0.6/Makefile.patch @@ -0,0 +1,50 @@ +Add 'test-install' rule. +Allow 'prefix' variable to be overloaded. + +Signed-off-by: Radu Patriu +Upstream-Status: Pending + +Index: numad/Makefile +=================================================================== +--- numad.orig/Makefile 2014-05-13 00:17:16.094991993 +0300 ++++ numad/Makefile 2014-05-13 00:22:22.318986948 +0300 +@@ -22,21 +22,23 @@ + BENCH_CFLAGS += -ftree-vectorize + endif + +-CLEANFILES := numad.o numad .depend .depend.X empty.c empty.o ++CLEANFILES := numad.o numad .depend .depend.X empty.c empty.o test.o test + +-SOURCES := numad.c ++SOURCES := numad.c test.c + +-prefix := /usr ++prefix ?= /usr + docdir := ${prefix}/share/doc + + all: numad + + numad: numad.o -lpthread -lrt + ++test: test.o -lnuma ++ + AR ?= ar + RANLIB ?= ranlib + +-.PHONY: install all clean html depend ++.PHONY: install all clean html depend -lpthread -lrt -lnuma + + # BB_FIXME MANPAGES := numa.3 numactl.8 numastat.8 migratepages.8 migspeed.8 + +@@ -46,6 +48,11 @@ + install -m 0755 numad ${prefix}/bin + install -m 0644 numad.8 ${prefix}/share/man/man8 + ++TEST_DESTDIR ?= ${prefix}/lib/numad/ptest ++test-install: test ++ install -d ${TEST_DESTDIR} ++ install test ${TEST_DESTDIR} ++ + clean: + rm -f ${CLEANFILES} + @rm -rf html diff --git a/recipes-core/numad/numad-0.6/numad.conf.patch b/recipes-core/numad/numad-0.6/numad.conf.patch new file mode 100644 index 0000000..0b63ca0 --- /dev/null +++ b/recipes-core/numad/numad-0.6/numad.conf.patch @@ -0,0 +1,14 @@ +Add DIRECTORY_MOUNT_POINT to configuration file. + +Signed-off-by: Radu Patriu +Upstream-Status: Pending + +Index: numad/numad.conf +=================================================================== +--- numad.orig/numad.conf 2014-03-13 17:12:38.000000000 +0200 ++++ numad/numad.conf 2014-03-13 17:40:39.417851081 +0200 +@@ -3,3 +3,4 @@ + # Default INTERVAL is 15 + # modify below to change it + INTERVAL=15 ++DIRECTORY_MOUNT_POINT="/sys/fs/cgroup/cpuset" diff --git a/recipes-core/numad/numad-0.6/numad.init.patch b/recipes-core/numad/numad-0.6/numad.init.patch new file mode 100644 index 0000000..c95f8d6 --- /dev/null +++ b/recipes-core/numad/numad-0.6/numad.init.patch @@ -0,0 +1,85 @@ +Fix source functions path. +Use start-stop-daemon. + +Signed-off-by: Radu Patriu +Upstream-Status: Pending + +Index: numad/numad.init +=================================================================== +--- numad.orig/numad.init 2014-03-13 15:27:26.000000000 +0200 ++++ numad/numad.init 2014-03-13 16:39:13.089952014 +0200 +@@ -6,13 +6,13 @@ + ### BEGIN INIT INFO + # Provides: numad + # Required-Start: cgconfig +-# Required-Stop: +-# Should-Start: +-# Should-Stop: +-# Default-Start: +-# Default-Stop: ++# Required-Stop: ++# Should-Start: ++# Should-Stop: ++# Default-Start: ++# Default-Stop: + # Short-Description: numad control +-# Description: ++# Description: + ### END INIT INFO + + if [ $(id -u) -ne 0 ]; then +@@ -21,7 +21,7 @@ + fi + + # Source function library. +-. /etc/rc.d/init.d/functions ++. /etc/init.d/functions + + exec="/usr/bin/numad" + prog="numad" +@@ -29,32 +29,36 @@ + + [ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog + +-lockfile=/var/lock/subsys/$prog +-base=${0##*/} +- + start() { + [ -x $exec ] || exit 5 + [ -f $config ] || exit 6 + echo -n $"Starting $prog: " + . $config +- daemon "$exec -i $INTERVAL" ++ start-stop-daemon --start --quiet --exec $exec -- -i $INTERVAL -D $DIRECTORY_MOUNT_POINT + retval=$? +- echo +- [ $retval -eq 0 ] && touch $lockfile ++ if [ $retval -eq 0 ] ; then ++ echo "OK" ++ else ++ echo "FAIL" ++ fi + return $retval + } + + stop() { + echo -n $"Stopping $prog: " +- killproc $prog ++ start-stop-daemon --stop --quiet --exec $exec + retval=$? +- echo +- [ $retval -eq 0 ] && rm -f $lockfile ++ if [ $retval -eq 0 ] ; then ++ echo "OK" ++ else ++ echo "FAIL" ++ fi + return $retval + } + + restart() { + stop ++ sleep 1 + start + } + diff --git a/recipes-core/numad/numad-0.6/run-ptest b/recipes-core/numad/numad-0.6/run-ptest new file mode 100755 index 0000000..5c49181 --- /dev/null +++ b/recipes-core/numad/numad-0.6/run-ptest @@ -0,0 +1,20 @@ +#!/bin/sh + +CPUSET_PATH="/tmp/numad-cpuset" + +/etc/init.d/numad.init status +STATUS=$? +/etc/init.d/numad.init stop +mkdir $CPUSET_PATH; mount -t cgroup -ocpuset cpuset $CPUSET_PATH +./test 2>&1& +TEST_PID=$! +sleep 2 +numad -d -S 0 -u 50 -i 5:5 -p $TEST_PID -D $CPUSET_PATH +wait +numad -i 0 +sleep 1 +umount $CPUSET_PATH ; rmdir $CPUSET_PATH +if [ "$STATUS" = "0" ]; then + /etc/init.d/numad.init start +fi + diff --git a/recipes-core/numad/numad-0.6/test.patch b/recipes-core/numad/numad-0.6/test.patch new file mode 100644 index 0000000..762790c --- /dev/null +++ b/recipes-core/numad/numad-0.6/test.patch @@ -0,0 +1,175 @@ +Test output format: ptest style (PASS, FAIL, SKIP) +Description: Allocate memory from a node other than +the current CPU is running on. Wait for numad to modify +memory and CPU policy binding the process to run and allocate on +the same node. +Dependencies: libnuma + +Signed-off-by: Radu Patriu +Upstream-Status: Pending + +Index: numa-test/test.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ numa-test/test.c 2014-02-18 17:22:49.952290472 +0200 +@@ -0,0 +1,160 @@ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define TIMEOUT (1000 * 60) /*60 seconds*/ ++#define LOOP_TIME (1000 * 5) /*5 seconds*/ ++#define MEM_POLICY_CHANGED 1 ++#define NODE_POLICY_CHANGED 2 ++#define TEST_DONE (MEM_POLICY_CHANGED | NODE_POLICY_CHANGED) ++ ++#define TEST_PASS 0 ++#define TEST_FAIL 1 ++#define TEST_SKIP 2 ++ ++#define MEM_SIZE 0.3 /* 30 % node memory */ ++ ++unsigned int numa_bitmask_weight(const struct bitmask *bmp); ++ ++void print_bitmask(struct bitmask *mask) ++{ ++ /*assume 32 max nodes*/ ++ printf("0x%08lx", *(mask->maskp)); ++} ++ ++int test() ++{ ++ int i, j, total_nodes, total_mem_nodes, total_cpus, prefered_node; ++ struct bitmask *allowed_mem_nodes, *allowed_nodes, *cpu_mask, *mem_bind, *bit_mask; ++ long long mem_size, page_size; ++ unsigned char *mem; ++ struct timeval start, end, res; ++ int local_node, local_cpu, other_node, test_complete; ++ ++ allowed_mem_nodes = numa_allocate_nodemask(); ++ allowed_nodes = numa_allocate_nodemask(); ++ mem_bind = numa_allocate_nodemask(); ++ cpu_mask = numa_allocate_cpumask(); ++ if (!(allowed_mem_nodes && allowed_nodes && mem_bind && cpu_mask)) { ++ printf("Error: numa_allocate failed\n"); ++ return TEST_FAIL; ++ } ++ ++ total_nodes = numa_max_node() + 1; ++ printf("total_nodes %d\n", total_nodes); ++ ++ total_mem_nodes = numa_num_configured_nodes(); ++ printf("total_mem_nodes %d\n", total_mem_nodes); ++ ++ total_cpus = numa_num_configured_cpus(); ++ printf("total_cpus %d\n", total_cpus); ++ ++ page_size = numa_pagesize(); ++ printf("page_size %llu\n", page_size); ++ ++ i = 0; ++ test_complete = 0; ++ gettimeofday(&start, NULL); ++ do { ++ printf("\n\n\nLoop %d\n", i); ++ ++ bit_mask = numa_get_mems_allowed(); ++ if (i && !numa_bitmask_equal(bit_mask, allowed_mem_nodes)) { ++ printf("\nInfo: memory policy modified\n\n"); ++ test_complete |= MEM_POLICY_CHANGED; ++ } ++ copy_bitmask_to_bitmask(bit_mask, allowed_mem_nodes); ++ printf("allowed_mem_nodes "); print_bitmask(allowed_mem_nodes); printf("\n"); ++ if ((0 == i) && (1 == numa_bitmask_weight(allowed_mem_nodes))) { ++ printf("Error: need at least two memory nodes\n"); ++ return TEST_SKIP; ++ } ++ ++ bit_mask = numa_get_run_node_mask(); ++ if (i && !numa_bitmask_equal(bit_mask, allowed_nodes)) { ++ printf("\nInfo: node/cpu policy modified\n\n"); ++ test_complete |= NODE_POLICY_CHANGED; ++ } ++ copy_bitmask_to_bitmask(bit_mask, allowed_nodes); ++ printf("allowed_nodes "); print_bitmask(allowed_nodes); printf("\n"); ++ ++ prefered_node = numa_preferred(); ++ printf("prefered_node %d\n", prefered_node); ++ ++ bit_mask = numa_get_membind(); ++ copy_bitmask_to_bitmask(bit_mask, mem_bind); ++ printf("mem_bind "); print_bitmask(mem_bind); printf("\n"); ++ ++ if (numa_sched_getaffinity(0, cpu_mask) < 0) { ++ printf("Error: numa_sched_getaffinity failed\n"); ++ return TEST_FAIL; ++ } ++ printf("sched_affinity "); print_bitmask(cpu_mask); printf("\n"); ++ ++ other_node = -1; ++ local_cpu = sched_getcpu(); ++ local_node = numa_node_of_cpu(local_cpu); ++ for (j = 0; j < total_mem_nodes; ++j) ++ if (numa_bitmask_isbitset(allowed_mem_nodes, j) && (j != local_node)) ++ other_node = j; ++ ++ printf("running on node %d, cpu %d\n", local_node, local_cpu); ++ printf("alloc memory from node %d\n", other_node); ++ ++ mem_size = numa_node_size64(other_node, NULL) * MEM_SIZE; ++ printf("test_mem_size %llu\n", mem_size); ++ ++ /* avoid mbind: Invalid argument */ ++ if (TEST_DONE == test_complete) ++ return TEST_PASS; ++ ++ mem = numa_alloc_onnode(mem_size, other_node); ++ if (!mem) { ++ printf("Error: numa_alloc_onnode failed for node %d\n", other_node); ++ return TEST_FAIL; ++ } ++ ++ gettimeofday(&end, NULL); ++ /* do some work */ ++ do { ++ struct timeval now; ++ memcpy(mem, mem + mem_size/2, mem_size/2); ++ gettimeofday(&now, NULL); ++ timersub(&now, &end, &res); ++ } while((res.tv_sec * 1000 + res.tv_usec / 1000) < LOOP_TIME); ++ ++ numa_free(mem, mem_size); ++ ++i; ++ gettimeofday(&end, NULL); ++ timersub(&end, &start, &res); ++ } while((res.tv_sec * 1000 + res.tv_usec / 1000) < TIMEOUT); ++ ++ return TEST_FAIL; ++} ++ ++int main() ++{ ++ if (numa_available() < 0) { ++ printf("Error: numa not available\n"); ++ printf("SKIP: numad\n"); ++ return 0; ++ } ++ ++ switch(test()) { ++ case TEST_PASS: ++ printf("PASS: numad\n"); ++ break; ++ case TEST_SKIP: ++ printf("FAIL: numad\n"); ++ break; ++ default: ++ printf("FAIL: numad\n"); ++ } ++ ++ return 0; ++} diff --git a/recipes-core/numad/numad_0.6.bb b/recipes-core/numad/numad_0.6.bb new file mode 100644 index 0000000..a6e8ad6 --- /dev/null +++ b/recipes-core/numad/numad_0.6.bb @@ -0,0 +1,51 @@ +SUMMARY = "NUMA load distributing daemon" +DESCRIPTION = 'A user-level daemon that monitors NUMA topology and processes resource \ +consumption to facilitate good NUMA resource access of applications/virtual machines \ +to improve performance and minimize cost of remote memory latencies.' +HOMEPAGE = "https://git.fedorahosted.org/git/numad.git" +SECTION = "console/utils" + +LICENSE = "LGPLv2.1" + +LIC_FILES_CHKSUM = "file://numad.c;beginline=1;endline=19;md5=fc770296e974bef07ddd7033725c8e29" + +SRC_URI = "git://git.fedorahosted.org/git/numad.git;protocol=https;branch=master \ + file://Makefile.patch \ + file://test.patch \ + file://run-ptest \ + file://numad.init.patch \ + file://numad.conf.patch" + +SRCREV = "b621838bf9c8203e87137eca28e19bcc381cde2a" + +S = "${WORKDIR}/git" + +#clear .LIBPATTERNS instead of using VPATH="${STAGING_LIBDIR}:${STAGING_DIR_HOST}/${base_libdir}" +EXTRA_OEMAKE = 'prefix=${D}/usr TEST_DESTDIR=${D}${PTEST_PATH} .LIBPATTERNS=""' + +do_install () { + oe_runmake install + install -d ${D}${sysconfdir}/init.d + install -m 0755 ${S}/numad.init ${D}${sysconfdir}/init.d + install -m 0644 ${S}/numad.conf ${D}${sysconfdir} +} + +inherit update-rc.d ptest + +DEPENDS_${PN}-ptest += "numactl" +RDEPENDS_${PN}-ptest += "libnuma" + +INITSCRIPT_NAME = "numad.init" +#INITSCRIPT_PARAMS = "start 99 5 2 . stop 20 0 1 6 ." +INITSCRIPT_PARAMS = "stop 20 5 2 . stop 20 0 1 6 ." + +#wait for numa.h +do_compile_ptest_base[depends] += "numactl:do_populate_sysroot" + +do_install_ptest () { + oe_runmake test-install +} + +do_compile_ptest () { + oe_runmake test +} diff --git a/recipes-core/packagegroups/packagegroup-enea-ip.bb b/recipes-core/packagegroups/packagegroup-enea-ip.bb new file mode 100644 index 0000000..8cd980d --- /dev/null +++ b/recipes-core/packagegroups/packagegroup-enea-ip.bb @@ -0,0 +1,18 @@ +DESCRIPTION = "Package group for IP" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=3f40d7994397109285ec7b81fdeb3b58 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" +PR = "r0" + +inherit packagegroup + +RDEPENDS_${PN} = "\ + numactl \ + numad \ + dpdk \ + oftest \ + openvswitchdpdk-oftest-ptest \ + openvswitch \ + openvswitchdpdk \ + openvswitchdpdk-qemu \ + " diff --git a/recipes-kernel/linux/linux-yocto_3.10.bbappend b/recipes-kernel/linux/linux-yocto_3.10.bbappend new file mode 100644 index 0000000..dc182c7 --- /dev/null +++ b/recipes-kernel/linux/linux-yocto_3.10.bbappend @@ -0,0 +1,4 @@ +SRC_URI += " \ + file://cfg/00044-numa.cfg \ + file://cfg/00045-pci-stub.cfg \ + " diff --git a/recipes-kernel/linux/linux-yocto_3.14.bbappend b/recipes-kernel/linux/linux-yocto_3.14.bbappend new file mode 100644 index 0000000..dc182c7 --- /dev/null +++ b/recipes-kernel/linux/linux-yocto_3.14.bbappend @@ -0,0 +1,4 @@ +SRC_URI += " \ + file://cfg/00044-numa.cfg \ + file://cfg/00045-pci-stub.cfg \ + " diff --git a/recipes-networking/dpdk/dpdk_git.bb b/recipes-networking/dpdk/dpdk_git.bb new file mode 100644 index 0000000..ed4c2b3 --- /dev/null +++ b/recipes-networking/dpdk/dpdk_git.bb @@ -0,0 +1,139 @@ +SUMMARY = "DPDK" +DESCRIPTION = "DPDK - a novel framework for fast packet I/O" +HOMEPAGE = "http://dpdk.org" +SECTION = "devel" +LICENSE = "GPLv2 | LGPLv2 | BSD" +LIC_FILES_CHKSUM = "file://LICENSE.GPL;md5=751419260aa954499f7abaabaa882bbe \ + file://LICENSE.LGPL;md5=4fbd65380cdd255951079008b364516c \ + file://lib/librte_eal/common/include/rte_version.h;beginline=1;endline=33;md5=ab6d502a4a25ded2bbabf031720bd1f4" + +PR = "r1" +PV = "1.6.0" +DEPENDS += "virtual/kernel" + +inherit module-base + +addtask make_scripts after do_patch before do_compile +do_make_scripts[lockfiles] = "${TMPDIR}/kernel-scripts.lock" +do_make_scripts[deptask] = "do_populate_sysroot" + +SRCREV = "v1.6.0r1" +SRC_URI = "git://dpdk.org/git/dpdk;protocol=http;branch=1.6.0 \ + file://unbreak-makefiles.patch \ + file://runtest.patch \ + file://run-ptest \ + file://igb_ethdev_loopback.patch \ + file://l2fwd-lpbk \ + file://machine-flags.patch \ + file://rte_kni_module_1_6.patch.x \ + " + +DPDK_TARGET_DEFAULT = "${TARGET_ARCH}-default-linuxapp-gcc" +DPDK_TARGET_IVSHMEM = "${TARGET_ARCH}-ivshmem-linuxapp-gcc" + +DPDK_BUILD_DIR = "build" +DPDK_VAR_O = "${S}/${DPDK_BUILD_DIR}" +DPDK_VAR_DESTDIR = "${WORKDIR}/install" + +DPDK_SRC_PATH = "/usr/src/dpdk" +DPDK_INSTALL_PATH = "/opt/dpdk" + +S = "${WORKDIR}/git" +B = "${S}" + +PACKAGES = "${PN}-dbg ${PN} ${PN}-mk ${PN}-scripts" +PACKAGES += "${PN}-default-dbg ${PN}-default-staticdev ${PN}-default" + +RDEPENDS_${PN} += "pciutils" +RDEPENDS_${PN}-default = "${PN}-mk ${PN}-scripts ${PN}-default-staticdev pciutils" +RRECOMMENDS_${PN} += "kernel-module-uio kernel-module-pci-stub" + +FILES_${PN} = "${DPDK_SRC_PATH}" +FILES_${PN}-dbg = "/usr/src/debug" +FILES_${PN}-mk = "${DPDK_INSTALL_PATH}/mk" +FILES_${PN}-scripts = "${DPDK_INSTALL_PATH}/scripts" + +FILES_${PN}-default = "${DPDK_INSTALL_PATH}/${TARGET_ARCH}-default-linuxapp-gcc" +FILES_${PN}-default-dbg = "${DPDK_INSTALL_PATH}/${TARGET_ARCH}-default-linuxapp-gcc/app/.debug" +FILES_${PN}-default-staticdev = "${DPDK_INSTALL_PATH}/${TARGET_ARCH}-default-linuxapp-gcc/lib" + +do_compile() { + cd ${S} && oe_runmake install \ + RTE_KERNELDIR=${STAGING_KERNEL_DIR} \ + RTE_MACHINE=default \ + prefix="" \ + V=1 KBUILD_VERBOSE=1 CROSS=${TARGET_SYS}- \ + O=${DPDK_VAR_O} \ + T=${DPDK_TARGET_DEFAULT} \ + DESTDIR=${DPDK_VAR_DESTDIR} \ + MACHINE_CFLAGS_ALT="${TARGET_CC_ARCH}" + + #patched version of IVSHMEM target for OVS-DPDK - installed to staging only + cd ${S} && git apply ${WORKDIR}/rte_kni_module_1_6.patch.x && \ + oe_runmake install \ + RTE_KERNELDIR=${STAGING_KERNEL_DIR} \ + RTE_MACHINE=default \ + prefix="" \ + V=1 KBUILD_VERBOSE=1 CROSS=${TARGET_SYS}- \ + O=${DPDK_VAR_O} \ + T=${DPDK_TARGET_IVSHMEM} \ + DESTDIR=${DPDK_VAR_DESTDIR} \ + MACHINE_CFLAGS_ALT="${TARGET_CC_ARCH}" \ + EXTRA_CFLAGS=-fPIC && \ + git apply --reverse ${WORKDIR}/rte_kni_module_1_6.patch.x \ +} + +do_install() { + # dpdk + install -d ${D}${DPDK_SRC_PATH} + cd ${S} && find . -depth -not -path "./${DPDK_BUILD_DIR}*" -not -path "./patches*" -not -path "./.*" -print0 |\ + cpio --null -pdlu ${D}${DPDK_SRC_PATH} + + # install sources to staging + cd ${S} && find . -depth -not -path "./${DPDK_BUILD_DIR}*" -not -path "./patches*" -not -path "./.*" -print0 |\ + cpio --null -pdlu ${STAGING_DIR_HOST}${DPDK_SRC_PATH} + + # install build to staging + cd ${DPDK_VAR_DESTDIR} && find . -print0 | cpio --null -pdlu ${STAGING_DIR_HOST}${DPDK_INSTALL_PATH} + + # install build output - skip OVS-DPDK IVSHMEM + install -d ${D}${DPDK_INSTALL_PATH} + cd ${DPDK_VAR_DESTDIR} && find . -depth -not -path "./${DPDK_TARGET_IVSHMEM}*" -print0 |\ + cpio --null -pdlu ${D}${DPDK_INSTALL_PATH} + + # add "scripts" directory to build output and staging, relpath.sh is needed by makefiles + cp -r ${S}/scripts ${D}${DPDK_INSTALL_PATH} + cp -r ${S}/scripts ${STAGING_DIR_HOST}${DPDK_INSTALL_PATH} + # relpath.sh use of $prefix breaks openvswitch + sed -i 's/prefix/path_prefix/g' ${STAGING_DIR_HOST}${DPDK_INSTALL_PATH}/scripts/relpath.sh +} + +COMPATIBLE_HOST = '(x86_64.*|i.86.*)-(linux.*)' + +#test default target + +inherit ptest + +RDEPENDS_${PN}-ptest += "\ + make \ + python-pexpect \ + ${PN}-default \ + ${PN} \ + " + +do_compile_ptest () { + cd ${WORKDIR}/l2fwd-lpbk && oe_runmake RTE_SDK="${DPDK_VAR_DESTDIR}" \ + RTE_TARGET="${DPDK_TARGET_DEFAULT}" RTE_ARCH="${TARGET_ARCH}" + sed -i 's|RTE_SDK=.*|RTE_SDK=${DPDK_INSTALL_PATH}|g' ${WORKDIR}/run-ptest + sed -i 's|RTE_TARGET=.*|RTE_TARGET=${DPDK_TARGET_DEFAULT}|g' ${WORKDIR}/run-ptest + sed -i 's|RTE_ARCH=.*|RTE_ARCH=${TARGET_ARCH}|g' ${WORKDIR}/run-ptest +} + +do_install_ptest () { + #install l2fwd loopback app + install ${WORKDIR}/l2fwd-lpbk/build/app/l2fwd-lpbk ${D}${PTEST_PATH} + + #install original test file to be used by autotest.py + install ${DPDK_VAR_O}/${DPDK_TARGET_DEFAULT}/app/test ${D}${PTEST_PATH} +} + diff --git a/recipes-networking/dpdk/files/igb_ethdev_loopback.patch b/recipes-networking/dpdk/files/igb_ethdev_loopback.patch new file mode 100644 index 0000000..6b979ca --- /dev/null +++ b/recipes-networking/dpdk/files/igb_ethdev_loopback.patch @@ -0,0 +1,96 @@ +Index: dpdk/lib/librte_pmd_e1000/igb_ethdev.c +=================================================================== +--- dpdk.orig/lib/librte_pmd_e1000/igb_ethdev.c 2014-03-11 12:35:49.267083184 +0200 ++++ dpdk/lib/librte_pmd_e1000/igb_ethdev.c 2014-03-11 12:36:23.015082260 +0200 +@@ -701,50 +701,67 @@ + E1000_WRITE_REG(hw, E1000_EITR(0), 0xFFFF); + } + +- /* Setup link speed and duplex */ +- switch (dev->data->dev_conf.link_speed) { +- case ETH_LINK_SPEED_AUTONEG: ++ if (dev->data->dev_conf.lpbk_mode == 1) { ++ uint32_t reg; ++ ++ reg = E1000_READ_REG(hw, E1000_RCTL); ++ reg |= E1000_RCTL_LBM_MAC; ++ E1000_WRITE_REG(hw, E1000_RCTL, reg); ++ ++ reg = E1000_READ_REG(hw, E1000_CTRL); ++ reg |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_FD | ++ E1000_CTRL_SPD_1000); ++ E1000_WRITE_REG(hw, E1000_CTRL, reg); ++ ++ reg = E1000_READ_REG(hw, E1000_EEER); ++ reg |= (1 << 28); ++ E1000_WRITE_REG(hw, E1000_EEER, reg); ++ } else { ++ /* Setup link speed and duplex */ ++ switch (dev->data->dev_conf.link_speed) { ++ case ETH_LINK_SPEED_AUTONEG: + if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) +- hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX; ++ hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX; + else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX) +- hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX; ++ hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX; + else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX) +- hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX; ++ hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX; + else +- goto error_invalid_config; ++ goto error_invalid_config; + break; +- case ETH_LINK_SPEED_10: ++ case ETH_LINK_SPEED_10: + if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) +- hw->phy.autoneg_advertised = E1000_ALL_10_SPEED; ++ hw->phy.autoneg_advertised = E1000_ALL_10_SPEED; + else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX) +- hw->phy.autoneg_advertised = ADVERTISE_10_HALF; ++ hw->phy.autoneg_advertised = ADVERTISE_10_HALF; + else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX) +- hw->phy.autoneg_advertised = ADVERTISE_10_FULL; ++ hw->phy.autoneg_advertised = ADVERTISE_10_FULL; + else +- goto error_invalid_config; ++ goto error_invalid_config; + break; +- case ETH_LINK_SPEED_100: ++ case ETH_LINK_SPEED_100: + if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) +- hw->phy.autoneg_advertised = E1000_ALL_100_SPEED; ++ hw->phy.autoneg_advertised = E1000_ALL_100_SPEED; + else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX) +- hw->phy.autoneg_advertised = ADVERTISE_100_HALF; ++ hw->phy.autoneg_advertised = ADVERTISE_100_HALF; + else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX) +- hw->phy.autoneg_advertised = ADVERTISE_100_FULL; ++ hw->phy.autoneg_advertised = ADVERTISE_100_FULL; + else +- goto error_invalid_config; ++ goto error_invalid_config; + break; +- case ETH_LINK_SPEED_1000: ++ case ETH_LINK_SPEED_1000: + if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) || +- (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)) +- hw->phy.autoneg_advertised = ADVERTISE_1000_FULL; ++ (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)) ++ hw->phy.autoneg_advertised = ADVERTISE_1000_FULL; + else +- goto error_invalid_config; ++ goto error_invalid_config; + break; +- case ETH_LINK_SPEED_10000: +- default: ++ case ETH_LINK_SPEED_10000: ++ default: + goto error_invalid_config; ++ } ++ e1000_setup_link(hw); + } +- e1000_setup_link(hw); + + /* check if lsc interrupt feature is enabled */ + if (dev->data->dev_conf.intr_conf.lsc != 0) diff --git a/recipes-networking/dpdk/files/l2fwd-lpbk/Makefile b/recipes-networking/dpdk/files/l2fwd-lpbk/Makefile new file mode 100644 index 0000000..72d56b7 --- /dev/null +++ b/recipes-networking/dpdk/files/l2fwd-lpbk/Makefile @@ -0,0 +1,51 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2013 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +ifeq ($(RTE_SDK),) +$(error "Please define RTE_SDK environment variable") +endif + +# Default target, can be overriden by command line or environment +RTE_TARGET ?= x86_64-default-linuxapp-gcc + +include $(RTE_SDK)/mk/rte.vars.mk + +# binary name +APP = l2fwd-lpbk + +# all source are stored in SRCS-y +SRCS-y := main.c + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +include $(RTE_SDK)/mk/rte.extapp.mk diff --git a/recipes-networking/dpdk/files/l2fwd-lpbk/main.c b/recipes-networking/dpdk/files/l2fwd-lpbk/main.c new file mode 100644 index 0000000..ff22b66 --- /dev/null +++ b/recipes-networking/dpdk/files/l2fwd-lpbk/main.c @@ -0,0 +1,929 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" + +#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 + +#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) +#define NB_MBUF 8192 + +/* + * RX and TX Prefetch, Host, and Write-back threshold values should be + * carefully set for optimal performance. Consult the network + * controller's datasheet and supporting DPDK documentation for guidance + * on how these parameters should be set. + */ +#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ +#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ +#define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */ + +/* + * These default values are optimized for use with the Intel(R) 82599 10 GbE + * Controller and the DPDK ixgbe PMD. Consider using other values for other + * network controllers and/or network drivers. + */ +#define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */ +#define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ +#define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ + +#define MAX_PKT_BURST 32 +#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ + +/* + * Configurable number of RX/TX ring descriptors + */ +#define RTE_TEST_RX_DESC_DEFAULT 128 +#define RTE_TEST_TX_DESC_DEFAULT 512 +static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; +static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; + +/* ethernet addresses of ports */ +static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS]; + +/* mask of enabled ports */ +static uint32_t l2fwd_enabled_port_mask = 0; + +/* list of enabled ports */ +static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS]; + +static unsigned int l2fwd_rx_queue_per_lcore = 1; + +#define MIN_TX_SIZE 64 +#define MAX_TX_SIZE 2048 +static int l2fwd_tx_size = MIN_TX_SIZE; + +#define MAX_TX_COUNT 128 +static int l2fwd_tx_count = 0; + +static int l2fwd_loopback = 0; + +struct mbuf_table { + unsigned len; + struct rte_mbuf *m_table[MAX_PKT_BURST]; +}; + +#define MAX_RX_QUEUE_PER_LCORE 16 +#define MAX_TX_QUEUE_PER_PORT 16 +struct lcore_queue_conf { + unsigned n_rx_port; + unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; + struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS]; + +} __rte_cache_aligned; +struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; + +static struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled */ + .hw_ip_checksum = 0, /**< IP checksum offload disabled */ + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ + .hw_strip_crc = 0, /**< CRC stripped by hardware */ + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, +}; + +static const struct rte_eth_rxconf rx_conf = { + .rx_thresh = { + .pthresh = RX_PTHRESH, + .hthresh = RX_HTHRESH, + .wthresh = RX_WTHRESH, + }, +}; + +static const struct rte_eth_txconf tx_conf = { + .tx_thresh = { + .pthresh = TX_PTHRESH, + .hthresh = TX_HTHRESH, + .wthresh = TX_WTHRESH, + }, + .tx_free_thresh = 0, /* Use PMD default values */ + .tx_rs_thresh = 0, /* Use PMD default values */ +}; + +struct rte_mempool * l2fwd_pktmbuf_pool = NULL; + +/* Per-port statistics struct */ +struct l2fwd_port_statistics { + uint64_t tx; + uint64_t rx; + uint64_t dropped; + uint64_t loop; +} __rte_cache_aligned; +struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; + +/* A tsc-based timer responsible for triggering statistics printout */ +#define MAX_TIMER_PERIOD 86400 /* 1 day max */ +static int64_t timer_period; +static uint64_t tsc_hz; + +static void l2fwd_init_time(void) +{ + tsc_hz = rte_get_tsc_hz(); + timer_period = 10 * rte_get_tsc_hz(); /* default period is 10 seconds */ +} + +/* Print out statistics on packets dropped */ +static void +print_stats(void) +{ + uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; + unsigned portid; + static uint64_t count = 0; + const char clr[] = { 27, '[', '2', 'J', '\0' }; + const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' }; + + total_packets_dropped = 0; + total_packets_tx = 0; + total_packets_rx = 0; + + /* Clear screen and move to top left */ + printf("%s%s", clr, topLeft); + + printf("\nPort statistics ===================================="); + + for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { + /* skip disabled ports */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + printf("\nStatistics for port %u ------------------------------" + "\nPackets sent: %24"PRIu64 + "\nPackets received: %20"PRIu64 + "\nPackets dropped: %21"PRIu64 + "\nLoop count : %21"PRIu64, + portid, + port_statistics[portid].tx, + port_statistics[portid].rx, + port_statistics[portid].dropped, + port_statistics[portid].loop); + + total_packets_dropped += port_statistics[portid].dropped; + total_packets_tx += port_statistics[portid].tx; + total_packets_rx += port_statistics[portid].rx; + } + printf("\nAggregate statistics ===============================" + "\nTotal packets sent: %18"PRIu64 + "\nTotal packets received: %14"PRIu64 + "\nTotal packets dropped: %15"PRIu64 + "\nPeriod: %"PRIu64, + total_packets_tx, + total_packets_rx, + total_packets_dropped, + count + ); + printf("\n====================================================\n"); + + count++; +} + +/* Send the burst of packets on an output interface */ +static int +l2fwd_send_burst(struct lcore_queue_conf *qconf, unsigned n, uint8_t port) +{ + struct rte_mbuf **m_table; + unsigned ret; + unsigned queueid =0; + + m_table = (struct rte_mbuf **)qconf->tx_mbufs[port].m_table; + + ret = rte_eth_tx_burst(port, (uint16_t) queueid, m_table, (uint16_t) n); + port_statistics[port].tx += ret; + if (unlikely(ret < n)) { + port_statistics[port].dropped += (n - ret); + do { + rte_pktmbuf_free(m_table[ret]); + } while (++ret < n); + } + + return 0; +} + +/* Enqueue packets for TX and prepare them to be sent */ +static int +l2fwd_send_packet(struct rte_mbuf *m, uint8_t port) +{ + unsigned lcore_id, len; + struct lcore_queue_conf *qconf; + + lcore_id = rte_lcore_id(); + + qconf = &lcore_queue_conf[lcore_id]; + len = qconf->tx_mbufs[port].len; + qconf->tx_mbufs[port].m_table[len] = m; + len++; + + /* enough pkts to be sent */ + if (unlikely(len == MAX_PKT_BURST)) { + l2fwd_send_burst(qconf, MAX_PKT_BURST, port); + len = 0; + } + + qconf->tx_mbufs[port].len = len; + return 0; +} + +static void +l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid) +{ + struct ether_hdr *eth; + void *tmp; + unsigned dst_port; + + dst_port = l2fwd_dst_ports[portid]; + + eth = rte_pktmbuf_mtod(m, struct ether_hdr *); + /* 02:00:00:00:00:xx */ + tmp = ð->d_addr.addr_bytes[0]; + *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dst_port << 40); + + /* src addr */ + ether_addr_copy(&l2fwd_ports_eth_addr[dst_port], ð->s_addr); + + l2fwd_send_packet(m, (uint8_t) dst_port); +} + +static inline void +copy_buf_to_pkt(void* buf, unsigned len, struct rte_mbuf *pkt, unsigned offset) +{ + rte_memcpy(((char *) pkt->pkt.data + offset), buf, (size_t) len); +} + +static int +l2fwd_tx(void) +{ + uint8_t portid; + + for (portid = 0; portid < RTE_MAX_ETHPORTS; ++portid) { + struct rte_mbuf *tx_mbuf[MAX_TX_COUNT]; + int pkt; + unsigned queueid = 0; + + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + + for (pkt = 0; pkt < l2fwd_tx_count; ++pkt) { + + tx_mbuf[pkt] = rte_pktmbuf_alloc(l2fwd_pktmbuf_pool); + if (!tx_mbuf[pkt]) + rte_exit(EXIT_FAILURE, + "rte_pktmbuf_alloc failed.\n"); + + /* minimum ethernet header + without this the 82599 will drop the packet if IXGBE_FCTRL_SBP is not set + */ + { + struct ether_hdr *eth_hdr; + /*struct ipv4_hdr *ipv4_hdr;*/ + struct ether_addr mac_addr; + + eth_hdr = rte_pktmbuf_mtod(tx_mbuf[pkt], struct ether_hdr*); + + rte_eth_macaddr_get(portid, &mac_addr); +#if 1 + mac_addr.addr_bytes[0] = 0; + mac_addr.addr_bytes[1] = 2; +#endif + ether_addr_copy(&mac_addr, ð_hdr->s_addr); + ether_addr_copy(&mac_addr, ð_hdr->d_addr); + eth_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4); + + /*ipv4_hdr = (struct ipv4_hdr*)ð_hdr[1];*/ + + tx_mbuf[pkt]->pkt.data_len = l2fwd_tx_size; + tx_mbuf[pkt]->pkt.pkt_len = l2fwd_tx_size; +#if 0 + rte_hexdump(NULL, rte_pktmbuf_mtod(tx_mbuf[pkt], void*), l2fwd_tx_size); +#endif + } + } + + if(rte_eth_tx_burst(portid, queueid, tx_mbuf, l2fwd_tx_count) != l2fwd_tx_count) + rte_exit(EXIT_FAILURE, "Incomplete Tx for port %u\n", portid); + + RTE_LOG(INFO, L2FWD, "sent %u packets on port %u\n", l2fwd_tx_count, portid); + } + + return 0; +} + +/* main processing loop */ +static void +l2fwd_main_loop(void) +{ + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + struct rte_mbuf *m; + unsigned lcore_id; + uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc; + unsigned i, j, portid, nb_rx; + struct lcore_queue_conf *qconf; + const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US; + + prev_tsc = 0; + timer_tsc = 0; + + lcore_id = rte_lcore_id(); + qconf = &lcore_queue_conf[lcore_id]; + + if (qconf->n_rx_port == 0) { + RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); + return; + } + + RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); + + for (i = 0; i < qconf->n_rx_port; i++) { + + portid = qconf->rx_port_list[i]; + RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, + portid); + } + + while (1) { + cur_tsc = rte_rdtsc(); + + /* + * TX burst queue drain + */ + diff_tsc = cur_tsc - prev_tsc; + if (unlikely(diff_tsc > drain_tsc)) { + for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { + if (qconf->tx_mbufs[portid].len == 0) + continue; + l2fwd_send_burst(&lcore_queue_conf[lcore_id], + qconf->tx_mbufs[portid].len, + (uint8_t) portid); + qconf->tx_mbufs[portid].len = 0; + } + /* if timer is enabled */ + if (timer_period > 0) { + + /* advance the timer */ + timer_tsc += diff_tsc; + + /* if timer has reached its timeout */ + if (unlikely(timer_tsc >= (uint64_t) timer_period)) { + + /* do this only on master core */ + if (lcore_id == rte_get_master_lcore()) { + print_stats(); + /* reset the timer */ + timer_tsc = 0; + } + } + } + + prev_tsc = cur_tsc; + } + + /* + * Read packet from RX queues + */ + for (i = 0; i < qconf->n_rx_port; i++) { + portid = qconf->rx_port_list[i]; + nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, + pkts_burst, MAX_PKT_BURST); + + port_statistics[portid].rx += nb_rx; + port_statistics[portid].loop++; + + for (j = 0; j < nb_rx; j++) { + m = pkts_burst[j]; + rte_prefetch0(rte_pktmbuf_mtod(m, void *)); + l2fwd_simple_forward(m, portid); + +#if 0 + rte_hexdump(NULL, rte_pktmbuf_mtod(pkts_burst[j], void*), pkts_burst[j]->pkt.data_len); +#endif + + } + } + } +} + +static int +l2fwd_launch_one_lcore(__attribute__((unused)) void *dummy) +{ + l2fwd_main_loop(); + return 0; +} + +/* display usage */ +static void +l2fwd_usage(const char *prgname) +{ + printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n" + " -p PORTMASK: hexadecimal bitmask of ports to configure\n" + " -q NQ: number of queue (=ports) per lcore (default is 1)\n" + " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n" + " -t TX: number of packets to send before forwarding (0 to disable, 0 default, 128 maximum)\n" + " -l LOOPBACK: loopback mode \n" + " -s SIZE: size of packets to be sent (64 default/minimum, 2048 maximum)\n", + prgname); +} + +static int +l2fwd_parse_portmask(const char *portmask) +{ + char *end = NULL; + unsigned long pm; + + /* parse hexadecimal string */ + pm = strtoul(portmask, &end, 16); + if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + + if (pm == 0) + return -1; + + return pm; +} + +static int +l2fwd_parse_tx_packet_count(const char *q_arg) +{ + char *end = NULL; + int n; + + /* parse number string */ + n = strtol(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + if (n > MAX_TX_COUNT) + return -1; + + return n; +} + +static int +l2fwd_parse_tx_packet_size(const char *q_arg) +{ + char *end = NULL; + int n; + + /* parse number string */ + n = strtol(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + if (n < MIN_TX_SIZE) + return -1; + if (n > MAX_TX_SIZE) + return -1; + + return n; +} + +static unsigned int +l2fwd_parse_nqueue(const char *q_arg) +{ + char *end = NULL; + unsigned long n; + + /* parse hexadecimal string */ + n = strtoul(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return 0; + if (n == 0) + return 0; + if (n >= MAX_RX_QUEUE_PER_LCORE) + return 0; + + return n; +} + +static int +l2fwd_parse_timer_period(const char *q_arg) +{ + char *end = NULL; + int n; + + /* parse number string */ + n = strtol(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + if (n >= MAX_TIMER_PERIOD) + return -1; + + return n; +} + +/* Parse the argument given in the command line of the application */ +static int +l2fwd_parse_args(int argc, char **argv) +{ + int opt, ret; + char **argvopt; + int option_index; + char *prgname = argv[0]; + static struct option lgopts[] = { + {NULL, 0, 0, 0} + }; + + argvopt = argv; + + while ((opt = getopt_long(argc, argvopt, "p:q:T:t:s:l", + lgopts, &option_index)) != EOF) { + + switch (opt) { + /* portmask */ + case 'p': + l2fwd_enabled_port_mask = l2fwd_parse_portmask(optarg); + if (l2fwd_enabled_port_mask == 0) { + printf("invalid portmask\n"); + l2fwd_usage(prgname); + return -1; + } + break; + + /* nqueue */ + case 'q': + l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg); + if (l2fwd_rx_queue_per_lcore == 0) { + printf("invalid queue number\n"); + l2fwd_usage(prgname); + return -1; + } + break; + + /* timer period */ + case 'T': + timer_period = l2fwd_parse_timer_period(optarg) * tsc_hz; + if (timer_period < 0) { + printf("invalid timer period\n"); + l2fwd_usage(prgname); + return -1; + } + break; + + case 't': + l2fwd_tx_count = l2fwd_parse_tx_packet_count(optarg); + if (l2fwd_tx_count < 0) { + printf("invalid tx packet count\n"); + l2fwd_usage(prgname); + return -1; + } + break; + + case 's': + l2fwd_tx_size = l2fwd_parse_tx_packet_size(optarg); + if (l2fwd_tx_size < 0) { + printf("invalid tx packet size\n"); + l2fwd_usage(prgname); + return -1; + } + break; + + case 'l': + l2fwd_loopback = 1; + break; + + /* long options */ + case 0: + l2fwd_usage(prgname); + return -1; + + default: + l2fwd_usage(prgname); + return -1; + } + } + + if (optind >= 0) + argv[optind-1] = prgname; + + ret = optind-1; + optind = 0; /* reset getopt lib */ + return ret; +} + +/* Check the link status of all ports in up to 9s, and print them finally */ +static void +check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) +{ +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ + uint8_t portid, count, all_ports_up, print_flag = 0; + struct rte_eth_link link; + + printf("\nChecking link status"); + fflush(stdout); + for (count = 0; count <= MAX_CHECK_TIME; count++) { + all_ports_up = 1; + for (portid = 0; portid < port_num; portid++) { + if ((port_mask & (1 << portid)) == 0) + continue; + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(portid, &link); + /* print link status if flag set */ + if (print_flag == 1) { + if (link.link_status) + printf("Port %d Link Up - speed %u " + "Mbps - %s\n", (uint8_t)portid, + (unsigned)link.link_speed, + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + ("full-duplex") : ("half-duplex\n")); + else + printf("Port %d Link Down\n", + (uint8_t)portid); + continue; + } + /* clear all_ports_up flag if any link down */ + if (link.link_status == 0) { + all_ports_up = 0; + break; + } + } + /* after finally printing all link status, get out */ + if (print_flag == 1) + break; + + if (all_ports_up == 0) { + printf("."); + fflush(stdout); + rte_delay_ms(CHECK_INTERVAL); + } + + /* set the print_flag if all ports up or timeout */ + if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { + print_flag = 1; + printf("done\n"); + } + } +} + +int +MAIN(int argc, char **argv) +{ + struct lcore_queue_conf *qconf; + struct rte_eth_dev_info dev_info; + int ret; + uint8_t nb_ports; + uint8_t nb_ports_available; + uint8_t portid, last_port; + unsigned lcore_id, rx_lcore_id; + unsigned nb_ports_in_mask = 0; + + setlinebuf(stdout); + setlinebuf(stderr); + + /* init EAL */ + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); + + l2fwd_init_time(); + + argc -= ret; + argv += ret; + + /* parse application arguments (after the EAL ones) */ + ret = l2fwd_parse_args(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n"); + + /* create the mbuf pool */ + l2fwd_pktmbuf_pool = + rte_mempool_create("mbuf_pool", NB_MBUF, + MBUF_SIZE, 32, + sizeof(struct rte_pktmbuf_pool_private), + rte_pktmbuf_pool_init, NULL, + rte_pktmbuf_init, NULL, + rte_socket_id(), 0); + if (l2fwd_pktmbuf_pool == NULL) + rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); + + /* init driver(s) */ + if (rte_pmd_init_all() < 0) + rte_exit(EXIT_FAILURE, "Cannot init pmd\n"); + + if (rte_eal_pci_probe() < 0) + rte_exit(EXIT_FAILURE, "Cannot probe PCI\n"); + + nb_ports = rte_eth_dev_count(); + if (nb_ports == 0) + rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); + + if (nb_ports > RTE_MAX_ETHPORTS) + nb_ports = RTE_MAX_ETHPORTS; + + /* reset l2fwd_dst_ports */ + for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) + l2fwd_dst_ports[portid] = 0; + last_port = 0; + + /* + * Each logical core is assigned a dedicated TX queue on each port. + */ + for (portid = 0; portid < nb_ports; portid++) { + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + + if (l2fwd_loopback) { + l2fwd_dst_ports[portid] = portid; + continue; + } + + if (nb_ports_in_mask % 2) { + l2fwd_dst_ports[portid] = last_port; + l2fwd_dst_ports[last_port] = portid; + } + else + last_port = portid; + + nb_ports_in_mask++; + + rte_eth_dev_info_get(portid, &dev_info); + } + if (!l2fwd_loopback && (nb_ports_in_mask % 2)) { + printf("Notice: odd number of ports in portmask.\n"); + l2fwd_dst_ports[last_port] = last_port; + } + + rx_lcore_id = 0; + qconf = NULL; + + /* Initialize the port/queue configuration of each logical core */ + for (portid = 0; portid < nb_ports; portid++) { + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + + /* get the lcore_id for this port */ + while (rte_lcore_is_enabled(rx_lcore_id) == 0 || + lcore_queue_conf[rx_lcore_id].n_rx_port == + l2fwd_rx_queue_per_lcore) { + rx_lcore_id++; + if (rx_lcore_id >= RTE_MAX_LCORE) + rte_exit(EXIT_FAILURE, "Not enough cores\n"); + } + + if (qconf != &lcore_queue_conf[rx_lcore_id]) + /* Assigned a new logical core in the loop above. */ + qconf = &lcore_queue_conf[rx_lcore_id]; + + qconf->rx_port_list[qconf->n_rx_port] = portid; + qconf->n_rx_port++; + printf("Lcore %u: RX port %u\n", rx_lcore_id, (unsigned) portid); + } + + nb_ports_available = nb_ports; + + if (l2fwd_loopback) + port_conf.lpbk_mode = 1; + + /* Initialise each port */ + for (portid = 0; portid < nb_ports; portid++) { + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) { + printf("Skipping disabled port %u\n", (unsigned) portid); + nb_ports_available--; + continue; + } + /* init port */ + printf("Initializing port %u... ", (unsigned) portid); + fflush(stdout); + + ret = rte_eth_dev_configure(portid, 1, 1, &port_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n", + ret, (unsigned) portid); + + rte_eth_macaddr_get(portid,&l2fwd_ports_eth_addr[portid]); + + /* init one RX queue */ + fflush(stdout); + ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, + rte_eth_dev_socket_id(portid), &rx_conf, + l2fwd_pktmbuf_pool); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n", + ret, (unsigned) portid); + + /* init one TX queue on each port */ + fflush(stdout); + ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, + rte_eth_dev_socket_id(portid), &tx_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n", + ret, (unsigned) portid); + + /* Start device */ + ret = rte_eth_dev_start(portid); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", + ret, (unsigned) portid); + + printf("done: \n"); + + rte_eth_promiscuous_enable(portid); + + printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", + (unsigned) portid, + l2fwd_ports_eth_addr[portid].addr_bytes[0], + l2fwd_ports_eth_addr[portid].addr_bytes[1], + l2fwd_ports_eth_addr[portid].addr_bytes[2], + l2fwd_ports_eth_addr[portid].addr_bytes[3], + l2fwd_ports_eth_addr[portid].addr_bytes[4], + l2fwd_ports_eth_addr[portid].addr_bytes[5]); + + /* initialize port stats */ + memset(&port_statistics, 0, sizeof(port_statistics)); + } + + if (!nb_ports_available) { + rte_exit(EXIT_FAILURE, + "All available ports are disabled. Please set portmask.\n"); + } + + if(!l2fwd_loopback) + check_all_ports_link_status(nb_ports, l2fwd_enabled_port_mask); + + if (l2fwd_tx_count) + l2fwd_tx(); + + /* launch per-lcore init on every lcore */ + rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, NULL, CALL_MASTER); + + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) + return -1; + } + + return 0; +} + diff --git a/recipes-networking/dpdk/files/l2fwd-lpbk/main.h b/recipes-networking/dpdk/files/l2fwd-lpbk/main.h new file mode 100644 index 0000000..93dca37 --- /dev/null +++ b/recipes-networking/dpdk/files/l2fwd-lpbk/main.h @@ -0,0 +1,45 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#ifdef RTE_EXEC_ENV_BAREMETAL +#define MAIN _main +#else +#define MAIN main +#endif + +int MAIN(int argc, char **argv); + +#endif /* _MAIN_H_ */ diff --git a/recipes-networking/dpdk/files/machine-flags.patch b/recipes-networking/dpdk/files/machine-flags.patch new file mode 100644 index 0000000..a6998fd --- /dev/null +++ b/recipes-networking/dpdk/files/machine-flags.patch @@ -0,0 +1,12 @@ +Index: dpdk/mk/machine/native/rte.vars.mk +=================================================================== +--- dpdk.orig/mk/machine/native/rte.vars.mk 2014-04-25 18:53:11.422348174 +0300 ++++ dpdk/mk/machine/native/rte.vars.mk 2014-04-25 18:52:44.042348924 +0300 +@@ -55,4 +55,6 @@ + # CPU_LDFLAGS = + # CPU_ASFLAGS = + +-MACHINE_CFLAGS = -march=native ++MACHINE_CFLAGS_ALT ?= -march=native ++ ++MACHINE_CFLAGS = $(MACHINE_CFLAGS_ALT) diff --git a/recipes-networking/dpdk/files/maketest.patch b/recipes-networking/dpdk/files/maketest.patch new file mode 100644 index 0000000..cae679a --- /dev/null +++ b/recipes-networking/dpdk/files/maketest.patch @@ -0,0 +1,41 @@ +Update test makefiles. + +Signed-off-by: Costin Popescu +Upstream-Status: Pending + +diff --git a/mk/rte.sdkroot.mk b/mk/rte.sdkroot.mk +index 29af6a5..59bf972 100644 +--- a/mk/rte.sdkroot.mk ++++ b/mk/rte.sdkroot.mk +@@ -101,6 +101,10 @@ testall: + install uninstall: + $(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdkinstall.mk $@ + ++.PHONY: test-install ++test-install: ++ $(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdktest.mk $@ ++ + .PHONY: doc help + doc: doc-all + help: doc-help +diff --git a/mk/rte.sdktest.mk b/mk/rte.sdktest.mk +index b2c043e..015aab5 100644 +--- a/mk/rte.sdktest.mk ++++ b/mk/rte.sdktest.mk +@@ -82,3 +82,16 @@ coverage: + else \ + echo "No test found, please do a 'make build' first, or specify O=" ;\ + fi ++ ++test-install: ++ install -d $(TEST_DESTDIR)/app/test ++ install -d $(TEST_DESTDIR)/mk ++ install -d $(TEST_DESTDIR)/$(TARGET_ARCH)-default-linuxapp-gcc ++ install -d $(TEST_DESTDIR)/$(TARGET_ARCH)-default-linuxapp-gcc/app ++ install $(DPDK_SRC_PATH)/$(TARGET_ARCH)-default-linuxapp-gcc/.config $(TEST_DESTDIR)/$(TARGET_ARCH)-default-linuxapp-gcc ++ install $(DPDK_SRC_PATH)/$(TARGET_ARCH)-default-linuxapp-gcc/Makefile $(TEST_DESTDIR)/$(TARGET_ARCH)-default-linuxapp-gcc ++ install $(DPDK_PATH)/$(TARGET_ARCH)-default-linuxapp-gcc/app/* $(TEST_DESTDIR)/$(TARGET_ARCH)-default-linuxapp-gcc/app/ ++ install $(DPDK_SRC_PATH)/app/test/*.py $(TEST_DESTDIR)/app/test ++ install $(DPDK_SRC_PATH)/Makefile $(TEST_DESTDIR) ++ cp -r $(DPDK_SRC_PATH)/mk/* $(TEST_DESTDIR)/mk ++ echo "make test O=$(TARGET_ARCH)-default-linuxapp-gcc" >> $(TEST_DESTDIR)/maketest diff --git a/recipes-networking/dpdk/files/rte_kni_module_1_6.patch.x b/recipes-networking/dpdk/files/rte_kni_module_1_6.patch.x new file mode 100644 index 0000000..48b1849 --- /dev/null +++ b/recipes-networking/dpdk/files/rte_kni_module_1_6.patch.x @@ -0,0 +1,206 @@ +--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h ++++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h +@@ -101,6 +101,7 @@ struct rte_kni_device_info { + + /* mbuf size */ + unsigned mbuf_size; ++ uint64_t mempool_size; + }; + + #define KNI_DEVICE "kni" +--- a/lib/librte_eal/linuxapp/kni/kni_misc.c ++++ b/lib/librte_eal/linuxapp/kni/kni_misc.c +@@ -21,6 +21,19 @@ MODULE_DESCRIPTION("Kernel Module for managing kni devices"); + + #define KNI_MAX_DEVICES 32 + ++#define PCI_VENDOR_ID_IVSHMEM 0x1AF4 ++#define PCI_DEVICE_ID_IVSHMEM 0x1110 ++#define BAR2 2 ++#define IVSHMEM_MAGIC 0x0BADC0DE ++#define IVSHMEM_METADATA_SIZE 0x4000 ++#define KNI_FIFO_COUNT_MAX 1024 ++#define KNI_FIFO_SIZE ((KNI_FIFO_COUNT_MAX) * sizeof(void *) + \ ++ sizeof(struct rte_kni_fifo)) ++ ++#define get_virt_addr(x) get_virt_addr_by_size(x,KNI_FIFO_SIZE) ++#define get_virt_addr_by_size(x,s) (has_ivshmem_metadata ? \ ++ ioremap(x, s) : phys_to_virt(x)) ++ + extern void kni_net_rx(struct kni_dev *kni); + extern void kni_net_init(struct net_device *dev); + extern void kni_net_config_lo_mode(char *lo_str); +@@ -47,6 +60,8 @@ static int kni_thread_single(void *unused); + /* KNI processing for multiple kernel thread mode */ + static int kni_thread_multiple(void *param); + ++static int kni_has_ivshmem_metadata(void); ++ + static struct file_operations kni_fops = { + .owner = THIS_MODULE, + .open = kni_open, +@@ -72,6 +87,7 @@ static unsigned multiple_kthread_on = 0; + + static volatile unsigned long device_in_use; /* device in use flag */ + static struct task_struct *kni_kthread; ++static int has_ivshmem_metadata = 0; + + /* kni list lock */ + static DECLARE_RWSEM(kni_list_lock); +@@ -100,6 +116,10 @@ kni_init(void) + /* Configure the lo mode according to the input parameter */ + kni_net_config_lo_mode(lo_mode); + ++ has_ivshmem_metadata = kni_has_ivshmem_metadata(); ++ KNI_PRINT("IVSHMEM metadata %s \n", ++ has_ivshmem_metadata ? "found" : "NOT found"); ++ + KNI_PRINT("######## DPDK kni module loaded ########\n"); + + return 0; +@@ -178,6 +198,19 @@ kni_release(struct inode *inode, struct file *file) + #endif + kni_dev_remove(dev); + list_del(&dev->list); ++ ++ if (has_ivshmem_metadata) { ++ KNI_PRINT("iounmapping KNI FIFOs for device '%s'\n", dev->name); ++ iounmap(dev->tx_q); ++ iounmap(dev->rx_q); ++ iounmap(dev->alloc_q); ++ iounmap(dev->free_q); ++ iounmap(dev->req_q); ++ iounmap(dev->resp_q); ++ iounmap(dev->sync_kva); ++ iounmap(dev->mbuf_kva); ++ } ++ + } + up_write(&kni_list_lock); + +@@ -339,17 +372,17 @@ kni_ioctl_create(unsigned int ioctl_num, unsigned long ioctl_param) + strncpy(kni->name, dev_info.name, RTE_KNI_NAMESIZE); + + /* Translate user space info into kernel space info */ +- kni->tx_q = phys_to_virt(dev_info.tx_phys); +- kni->rx_q = phys_to_virt(dev_info.rx_phys); +- kni->alloc_q = phys_to_virt(dev_info.alloc_phys); +- kni->free_q = phys_to_virt(dev_info.free_phys); ++ kni->tx_q = get_virt_addr(dev_info.tx_phys); ++ kni->rx_q = get_virt_addr(dev_info.rx_phys); ++ kni->alloc_q = get_virt_addr(dev_info.alloc_phys); ++ kni->free_q = get_virt_addr(dev_info.free_phys); + +- kni->req_q = phys_to_virt(dev_info.req_phys); +- kni->resp_q = phys_to_virt(dev_info.resp_phys); ++ kni->req_q = get_virt_addr(dev_info.req_phys); ++ kni->resp_q = get_virt_addr(dev_info.resp_phys); + kni->sync_va = dev_info.sync_va; +- kni->sync_kva = phys_to_virt(dev_info.sync_phys); ++ kni->sync_kva = get_virt_addr(dev_info.sync_phys); + +- kni->mbuf_kva = phys_to_virt(dev_info.mbuf_phys); ++ kni->mbuf_kva = get_virt_addr_by_size(dev_info.mbuf_phys, dev_info.mempool_size); + kni->mbuf_va = dev_info.mbuf_va; + + #ifdef RTE_KNI_VHOST +@@ -552,6 +585,40 @@ kni_compat_ioctl(struct inode *inode, + return -EINVAL; + } + ++static int ++kni_has_ivshmem_metadata(void) ++{ ++ struct pci_dev *ivshm_dev = NULL; ++ phys_addr_t ivshmem_metadata_addr = 0; ++ void *ivshmem_metadata = NULL; ++ int ivshmem_magic_number; ++ ++ ivshm_dev = pci_get_device(PCI_VENDOR_ID_IVSHMEM, PCI_DEVICE_ID_IVSHMEM, ++ NULL); ++ ++ if (ivshm_dev == NULL) { ++ printk("No IVSHMEM device found!\n"); ++ return 0; ++ } ++ ++ /* IVSHMEM metadata will be received at the very last 4K of the BAR2 */ ++ ivshmem_metadata_addr = (pci_resource_end(ivshm_dev, BAR2) ++ - IVSHMEM_METADATA_SIZE) + 1; ++ ++ ivshmem_metadata = ioremap(ivshmem_metadata_addr, IVSHMEM_METADATA_SIZE); ++ if (ivshmem_metadata == NULL) { ++ printk("Could not ioremap IVSHMEM metadata\n"); ++ return 0; ++ } ++ ++ /* The first sizeof(int) bytes contain the magic number that tells us ++ * ivshmem_metadata is coming from the host */ ++ ivshmem_magic_number = ((int*) ivshmem_metadata)[0]; ++ iounmap(ivshmem_metadata); ++ return !!(ivshmem_magic_number == IVSHMEM_MAGIC); ++} ++ ++ + module_init(kni_init); + module_exit(kni_exit); + +--- a/lib/librte_eal/linuxapp/kni/kni_net.c ++++ b/lib/librte_eal/linuxapp/kni/kni_net.c +@@ -50,15 +50,16 @@ kni_net_open(struct net_device *dev) + struct rte_kni_request req; + struct kni_dev *kni = netdev_priv(dev); + +- if (kni->lad_dev) +- memcpy(dev->dev_addr, kni->lad_dev->dev_addr, ETH_ALEN); +- else +- /* +- * Generate random mac address. eth_random_addr() is the newer +- * version of generating mac address in linux kernel. +- */ +- random_ether_addr(dev->dev_addr); +- ++ if (!is_valid_ether_addr(dev->dev_addr)) { ++ if (kni->lad_dev) ++ memcpy(dev->dev_addr, kni->lad_dev->dev_addr, ETH_ALEN); ++ else ++ /* ++ * Generate random mac address. eth_random_addr() is the newer ++ * version of generating mac address in linux kernel. ++ */ ++ random_ether_addr(dev->dev_addr); ++ } + netif_start_queue(dev); + + memset(&req, 0, sizeof(req)); +@@ -459,6 +460,22 @@ kni_net_tx_timeout (struct net_device *dev) + return; + } + ++static int ++kni_set_mac_address(struct net_device *dev, void *addr_ptr) ++{ ++ struct sockaddr *addr = addr_ptr; ++ ++ if (netif_running(dev)) ++ return -EBUSY; ++ ++ if (!is_valid_ether_addr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ ++ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); ++ ++ return 0; ++} ++ + /* + * Ioctl commands + */ +@@ -608,6 +625,7 @@ static const struct net_device_ops kni_net_netdev_ops = { + .ndo_do_ioctl = kni_net_ioctl, + .ndo_get_stats = kni_net_stats, + .ndo_tx_timeout = kni_net_tx_timeout, ++ .ndo_set_mac_address = kni_set_mac_address, + }; + + void diff --git a/recipes-networking/dpdk/files/run-ptest b/recipes-networking/dpdk/files/run-ptest new file mode 100644 index 0000000..76fd407 --- /dev/null +++ b/recipes-networking/dpdk/files/run-ptest @@ -0,0 +1,195 @@ +#!/bin/sh + +export RTE_SDK=/opt/dpdk +export RTE_TARGET=x86_64-default-linuxapp-gcc +export RTE_ARCH=x86_64 +RTE_SRC=/usr/src/dpdk +HUGE_PAGES_MEM=2097152 #[1024 * 2048kB] + +#check hugetlbfs mount +echo -n "Mounting hugepages..." +mount | grep "nodev on /mnt/huge type hugetlbfs" +if [ $? -ne 0 ]; then + mkdir -p /mnt/huge + mount -t hugetlbfs nodev /mnt/huge +fi +echo "OK!" + +#increase hugepages for all nodes +echo -n "Allocating hugepages..." +#get hugepages sizes +hp_sz=`cat /proc/meminfo | grep Hugepagesize | sed -r "s/Hugepagesize:[^0-9]*([0-9]+) kB/\1/"` +#calculate huge pages number to get the equivalent of 1024 pages of 2MB +huge_pages_no=`expr ${HUGE_PAGES_MEM} / ${hp_sz}` +#get hugepages no +hp=0 +#Find out if this is a NUMA machine +ls /sys/devices/system/node/node* > /dev/null 2>&1 +if [ $? -ne 0 ]; then + hp=`cat /proc/sys/vm/nr_hugepages` + hptest=`expr $hp + $huge_pages_no` + echo $hptest > /proc/sys/vm/nr_hugepages +else + hparray=() + nodes=`ls /sys/devices/system/node | grep node | wc -l` + for (( i=0; $i<$nodes; i++ )) + do + hp=`cat /sys/devices/system/node/node${i}/hugepages/hugepages-${hp_sz}kB/nr_hugepages` + hptest=`expr $hp + $huge_pages_no` + echo $hptest > /sys/devices/system/node/node${i}/hugepages/hugepages-${hp_sz}kB/nr_hugepages + hparray+=("$hp") + done +fi +echo "OK!" +echo "Allocated ${huge_pages_no} x ${hp_sz}kB" + +#run l2fwd loopback test +DEVS=("I350" "82599") +PCI_UTIL=${RTE_SRC}/tools/pci_unbind.py +IGB_UIO=${RTE_SDK}/${RTE_TARGET}/kmod/igb_uio.ko +RTE_KNI=${RTE_SDK}/${RTE_TARGET}/kmod/rte_kni.ko + +rmmod rte_kni > /dev/null 2>&1 +rmmod igb_uio > /dev/null 2>&1 +modprobe uio && insmod ${IGB_UIO} + +#insert igb_uio, needed by some dpdk tests +if [ $? -ne 0 ]; then + echo "FAIL: uio/igb_uio load" + DEVS=() +else + echo "PASS: uio/igb_uio load" +fi + +#insert rte_kni driver in loopback mode, needed by KNI tests +insmod ${RTE_KNI} lo_mode=lo_mode_fifo + +if [ $? -ne 0 ]; then + echo "FAIL: rte_kni load" + DEVS=() +else + echo "PASS: rte_kni load" +fi + +#bind devices to igb_uio, needed by some dpdk tests +drvarray=() +pciarray=() +for dev in ${DEVS[@]} +do + DEV_INFO=`${PCI_UTIL} --status|grep ${dev}|grep -v -i 'active'|head -n 1` + if [ -z "$DEV_INFO" ] || [ "$DEV_INFO" == " " ] ; then + continue + fi + + DEV_PCI_ADDR=`echo ${DEV_INFO}|sed -r "s/([^ ]*) .*/\1/"` + DEV_NAME=`echo ${DEV_INFO}|sed -r "s/.*'(.*)'.*/\1/"` + DEV_ETH=`echo ${DEV_INFO}|grep eth=|sed -r "s/.*if=([^ ]*).*/\1/"` + DEV_DRV=`echo ${DEV_INFO}|sed -r "s/.*drv=([^ ]*).*/\1/"` + + echo "Testing device: $DEV_NAME(pci $DEV_PCI_ADDR, eth $DEV_ETH, drv $DEV_DRV)" + + if [ ! -z ${DEV_ETH} ]; then + ifconfig ${DEV_ETH} down + fi + + ${PCI_UTIL} --bind=igb_uio ${DEV_PCI_ADDR} + drvarray+=("${DEV_DRV}") + pciarray+=("${DEV_PCI_ADDR}") +done + +#run dpdk tests +python ${RTE_SRC}/app/test/autotest.py ./test ${RTE_TARGET} + +#bind devices to initial drivers +for ((i=0;i<${#pciarray[@]};i++)); +do + echo "${PCI_UTIL} --bind=${drvarray[$i]} ${pciarray[$i]}" + ${PCI_UTIL} --bind=${drvarray[$i]} ${pciarray[$i]} +done + +for dev in ${DEVS[@]} +do + DEV_INFO=`${PCI_UTIL} --status|grep ${dev}|grep -v -i 'active'|head -n 1` + if [ -z "$DEV_INFO" ] || [ "$DEV_INFO" == " " ] ; then + echo "SKIP: l2fwd-lpbk ($dev)" + continue + fi + + DEV_PCI_ADDR=`echo ${DEV_INFO}|sed -r "s/([^ ]*) .*/\1/"` + DEV_NAME=`echo ${DEV_INFO}|sed -r "s/.*'(.*)'.*/\1/"` + DEV_ETH=`echo ${DEV_INFO}|grep eth=|sed -r "s/.*if=([^ ]*).*/\1/"` + DEV_DRV=`echo ${DEV_INFO}|sed -r "s/.*drv=([^ ]*).*/\1/"` + + echo "Testing device: $DEV_NAME(pci $DEV_PCI_ADDR, eth $DEV_ETH, drv $DEV_DRV)" + + if [ ! -z ${DEV_ETH} ]; then + ifconfig ${DEV_ETH} down + fi + + ${PCI_UTIL} --bind=igb_uio ${DEV_PCI_ADDR} + + ./l2fwd-lpbk -c 0xff -n 2 --use-device=${DEV_PCI_ADDR} -- -p 0x1 -t 128 -s 64 -T 10 -l > ${DEV_PCI_ADDR}.log 2>&1 & + APP_PID=$! + sleep 20 + kill $APP_PID + + DEV_SENT=`cat ${DEV_PCI_ADDR}.log|grep "Packets sent:"|tail -n 1|sed -r "s/.* ([0-9]*)/\1/"` + DEV_RECV=`cat ${DEV_PCI_ADDR}.log|grep "Packets received:"|tail -n 1|sed -r "s/.* ([0-9]*)/\1/"` + DEV_DROP=`cat ${DEV_PCI_ADDR}.log|grep "Packets dropped:"|tail -n 1|sed -r "s/.* ([0-9]*)/\1/"` + + + echo "Results: sent $DEV_SENT, received $DEV_RECV, dropped $DEV_DROP" + + STATUS=0 + + case "$dev" in + "I350") + if [ ${DEV_SENT} -lt 13000000 ]; then + STATUS=1 + fi + ;; + "82599") + if [ ${DEV_SENT} -lt 110000000 ]; then + STATUS=1 + fi + ;; + esac + + if [ ${STATUS} -ne 0 ]; then + echo "FAIL: l2fwd-lpbk (low throughput)" + fi + + if [ ${STATUS} -eq 0 ] && { [ ${DEV_DROP} -ne 0 ] || [ ${DEV_SENT} -ne ${DEV_RECV} ]; } then + echo "FAIL: l2fwd-lpbk (dropped packets)" + STATUS=1 + fi + + if [ ${STATUS} -eq 0 ]; then + echo "PASS: l2fwd-lpbk ($dev)" + fi + + ${PCI_UTIL} --bind=${DEV_DRV} ${DEV_PCI_ADDR} +done + +if [ ! -z ${DEVS} ]; then + rmmod rte_kni > /dev/null 2>&1 + rmmod igb_uio > /dev/null 2>&1 + rmmod uio > /dev/null 2>&1 +fi + +echo -n "Freeing hugepages..." +#Find out if this is a NUMA machine +ls /sys/devices/system/node/node* > /dev/null 2>&1 +if [ $? -ne 0 ]; then + echo $hp > /proc/sys/vm/nr_hugepages +else + i=0 + for hp in ${hparray[@]} + do + echo $hp > "/sys/devices/system/node/node${i}/hugepages/hugepages-${hp_sz}kB/nr_hugepages" + ((i++)) + done +fi +echo "OK!" +rm -rf /mnt/huge/* + diff --git a/recipes-networking/dpdk/files/runtest.patch b/recipes-networking/dpdk/files/runtest.patch new file mode 100644 index 0000000..0432fb7 --- /dev/null +++ b/recipes-networking/dpdk/files/runtest.patch @@ -0,0 +1,20 @@ +Adapt test output. + +Signed-off-by: Costin Popescu +Upstream-Status: Pending + +diff --git a/app/test/autotest_runner.py b/app/test/autotest_runner.py +index af225ff..33b776a 100644 +--- a/app/test/autotest_runner.py ++++ b/app/test/autotest_runner.py +@@ -267,6 +267,10 @@ class AutotestRunner: + # if test failed and it wasn't a "start" test + if test_result < 0 and not i == 0: + self.fails += 1 ++ if test_result < 0: ++ print "FAIL: %s" % test_name ++ else: ++ print "PASS: %s" % test_name + + # collect logs + self.log_buffers.append(log) diff --git a/recipes-networking/dpdk/files/unbreak-makefiles.patch b/recipes-networking/dpdk/files/unbreak-makefiles.patch new file mode 100644 index 0000000..f96dd68 --- /dev/null +++ b/recipes-networking/dpdk/files/unbreak-makefiles.patch @@ -0,0 +1,87 @@ +Fix makefiles. + +Signed-off-by: Costin Popescu +Upstream-Status: Pending + +diff --git a/mk/rte.app.mk b/mk/rte.app.mk +index d90a0b0..93f1dd9 100644 +--- a/mk/rte.app.mk ++++ b/mk/rte.app.mk +@@ -203,6 +203,7 @@ endif + + ifeq ($(LINK_USING_CC),1) + comma := , ++LDFLAGS := $(patsubst -Wl$(comma)%,%,$(LDFLAGS)) + LDLIBS := $(addprefix -Wl$(comma),$(LDLIBS)) + LDFLAGS := $(addprefix -Wl$(comma),$(LDFLAGS)) + override EXTRA_LDFLAGS := $(addprefix -Wl$(comma),$(EXTRA_LDFLAGS)) +diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk +index a163272..9fb07d8 100644 +--- a/mk/target/generic/rte.vars.mk ++++ b/mk/target/generic/rte.vars.mk +@@ -107,7 +107,7 @@ ifeq ($(KERNELRELEASE),) + include $(RTE_SDK)/mk/rte.cpuflags.mk + + # merge all CFLAGS +-CFLAGS := $(CPU_CFLAGS) $(EXECENV_CFLAGS) $(TOOLCHAIN_CFLAGS) $(MACHINE_CFLAGS) ++CFLAGS += $(CPU_CFLAGS) $(EXECENV_CFLAGS) $(TOOLCHAIN_CFLAGS) $(MACHINE_CFLAGS) + CFLAGS += $(TARGET_CFLAGS) $(EXTERNAL_LIB_CFLAGS) + + # merge all LDFLAGS +@@ -115,7 +115,7 @@ LDFLAGS := $(CPU_LDFLAGS) $(EXECENV_LDFLAGS) $(TOOLCHAIN_LDFLAGS) $(MACHINE_LDFL + LDFLAGS += $(TARGET_LDFLAGS) + + # merge all ASFLAGS +-ASFLAGS := $(CPU_ASFLAGS) $(EXECENV_ASFLAGS) $(TOOLCHAIN_ASFLAGS) $(MACHINE_ASFLAGS) ++ASFLAGS += $(CPU_ASFLAGS) $(EXECENV_ASFLAGS) $(TOOLCHAIN_ASFLAGS) $(MACHINE_ASFLAGS) + ASFLAGS += $(TARGET_ASFLAGS) + + # add default include and lib paths +diff --git a/mk/toolchain/gcc/rte.vars.mk b/mk/toolchain/gcc/rte.vars.mk +index 0edb93f..adba7d4 100644 +--- a/mk/toolchain/gcc/rte.vars.mk ++++ b/mk/toolchain/gcc/rte.vars.mk +@@ -40,21 +40,20 @@ + # examples for RTE_TOOLCHAIN: gcc, icc + # + +-CC = $(CROSS)gcc +-CPP = $(CROSS)cpp +-# for now, we don't use as but nasm. +-# AS = $(CROSS)as +-AS = nasm +-AR = $(CROSS)ar +-LD = $(CROSS)ld +-OBJCOPY = $(CROSS)objcopy +-OBJDUMP = $(CROSS)objdump +-STRIP = $(CROSS)strip +-READELF = $(CROSS)readelf +-GCOV = $(CROSS)gcov ++CC ?= $(CROSS)gcc ++CPP ?= $(CROSS)cpp ++AS ?= $(CROSS)as ++#AS ?= nasm ++AR ?= $(CROSS)ar ++LD ?= $(CROSS)ld ++OBJCOPY ?= $(CROSS)objcopy ++OBJDUMP ?= $(CROSS)objdump ++STRIP ?= $(CROSS)strip ++READELF ?= $(CROSS)readelf ++GCOV ?= $(CROSS)gcov + +-HOSTCC = gcc +-HOSTAS = as ++HOSTCC ?= gcc ++HOSTAS ?= as + + TOOLCHAIN_ASFLAGS = + TOOLCHAIN_CFLAGS = +@@ -68,7 +67,7 @@ ifeq (,$(findstring -O0,$(EXTRA_CFLAGS))) + endif + endif + +-WERROR_FLAGS := -W -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes ++WERROR_FLAGS := -W -Wall -Wstrict-prototypes -Wmissing-prototypes + WERROR_FLAGS += -Wmissing-declarations -Wold-style-definition -Wpointer-arith + WERROR_FLAGS += -Wcast-align -Wnested-externs -Wcast-qual + WERROR_FLAGS += -Wformat-nonliteral -Wformat-security diff --git a/recipes-networking/openvswitchdpdk/files/0001-openvswitchdpdk-enabled-ptest.patch b/recipes-networking/openvswitchdpdk/files/0001-openvswitchdpdk-enabled-ptest.patch new file mode 100644 index 0000000..10f0df8 --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/0001-openvswitchdpdk-enabled-ptest.patch @@ -0,0 +1,380 @@ +From 1ea34b3e5bf1d386b9931f11dee89bc03f224852 Mon Sep 17 00:00:00 2001 +From: Radu Patriu +Date: Tue, 6 May 2014 13:02:10 +0000 +Subject: [PATCH] openvswitchdpdk: enabled ptest + +Signed-off-by: Radu Patriu +--- + openvswitch/Makefile.am | 1 + + openvswitch/test.mk | 47 ++++++++++++++++++++++++++++++++++++ + openvswitch/tests/dpdk-datapath.at | 48 ++++++++++++++++++------------------- + openvswitch/tests/dpdk-link.at | 2 +- + openvswitch/tests/dpif-dpdk.at | 30 +++++++++++------------ + openvswitch/tests/flowgen.pl | 0 + openvswitch/tests/netdev-dpdk.at | 2 +- + openvswitch/tests/ofproto-macros.at | 2 +- + openvswitch/tests/ovs-vport.at | 10 ++++---- + 9 files changed, 95 insertions(+), 47 deletions(-) + create mode 100644 openvswitch/test.mk + mode change 100644 => 100755 openvswitch/tests/flowgen.pl + +diff --git a/openvswitch/Makefile.am b/openvswitch/Makefile.am +index d0edfa2..107ca89 100644 +--- a/openvswitch/Makefile.am ++++ b/openvswitch/Makefile.am +@@ -311,3 +311,4 @@ include xenserver/automake.mk + include python/automake.mk + include python/compat/automake.mk + include tutorial/automake.mk ++include test.mk +\ No newline at end of file +diff --git a/openvswitch/test.mk b/openvswitch/test.mk +new file mode 100644 +index 0000000..10f3629 +--- /dev/null ++++ b/openvswitch/test.mk +@@ -0,0 +1,47 @@ ++TEST_DEST ?= ${prefix}/lib/openvswitchdpdk/ptest ++TEST_ROOT ?= ${prefix}/lib/openvswitchdpdk/ptest ++TEST_DEPEND = ++ ++if HAVE_OPENSSL ++TEST_DEPEND += $(TESTPKI_FILES) ++endif ++ ++test-install: $(TEST_DEPEND) ++ @list='$(noinst_PROGRAMS) $(EXTRA_DIST) $(dist_check_SCRIPTS) $(TEST_DEPEND) tests/atlocal tests/atconfig' ;\ ++ install -d $(TEST_DEST)/tests ;\ ++ install -d $(TEST_DEST)/python ;\ ++ install -d $(TEST_DEST)/python/ovs ;\ ++ install -d $(TEST_DEST)/python/ovs/db ;\ ++ install -d $(TEST_DEST)/python/ovs/unixctl ;\ ++ install -d $(TEST_DEST)/vswitchd ;\ ++ install vswitchd/vswitch.ovsschema $(TEST_DEST)/vswitchd ;\ ++ install -d $(TEST_DEST)/debian ;\ ++ install debian/ovs-monitor-ipsec $(TEST_DEST)/debian ;\ ++ install -d $(TEST_DEST)/build-aux ;\ ++ install build-aux/check-structs $(TEST_DEST)/build-aux ;\ ++ install -d $(TEST_DEST)/xenserver ;\ ++ install xenserver/usr_share_openvswitch_scripts_ovs-xapi-sync $(TEST_DEST)/xenserver ;\ ++ install xenserver/opt_xensource_libexec_interface-reconfigure $(TEST_DEST)/xenserver ;\ ++ install xenserver/opt_xensource_libexec_InterfaceReconfigure.py $(TEST_DEST)/xenserver ;\ ++ install xenserver/opt_xensource_libexec_InterfaceReconfigureBridge.py $(TEST_DEST)/xenserver ;\ ++ install xenserver/opt_xensource_libexec_InterfaceReconfigureVswitch.py $(TEST_DEST)/xenserver ;\ ++ for p in $$list ; do \ ++ echo $$p ;\ ++ p=$${p#./} ;\ ++ pre=$${p#tests\/} ;\ ++ if test $$pre != $$p ; then \ ++ echo installing $$p to $(TEST_DEST)/tests/$$pre ;\ ++ install $$p $(TEST_DEST)/tests/$$pre ;\ ++ continue ;\ ++ fi ;\ ++ pre=$${p#python\/ovs\/} ;\ ++ if test $$pre != $$p ; then \ ++ echo installing $$p to $(TEST_DEST)/python/ovs/$$pre ;\ ++ install $$p $(TEST_DEST)/python/ovs/$$pre ;\ ++ continue ;\ ++ fi; \ ++ done ;\ ++ sed -i 's|abs_builddir=.*|abs_builddir='"'"'$(TEST_ROOT)/tests'"'"'|g' $(TEST_DEST)/tests/atconfig ++ sed -i 's|abs_srcdir=.*|abs_srcdir='"'"'$(TEST_ROOT)/tests'"'"'|g' $(TEST_DEST)/tests/atconfig ++ sed -i 's|abs_top_srcdir=.*|abs_top_srcdir='"'"'$(TEST_ROOT)'"'"'|g' $(TEST_DEST)/tests/atconfig ++ sed -i 's|abs_top_builddir=.*|abs_top_builddir='"'"'$(TEST_ROOT)'"'"'|g' $(TEST_DEST)/tests/atconfig +diff --git a/openvswitch/tests/dpdk-datapath.at b/openvswitch/tests/dpdk-datapath.at +index 5472ae3..16c5f3d 100644 +--- a/openvswitch/tests/dpdk-datapath.at ++++ b/openvswitch/tests/dpdk-datapath.at +@@ -28,47 +28,47 @@ + m4_define([OVDK_CHECK_ACTION_EXECUTE], + [AT_BANNER([action_execute unit tests - dpdk datapath]) + AT_SETUP([execute an output action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_output], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_output], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute an output action with invalid parameters]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_output__invalid_params], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_output__invalid_params], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute a corrupt action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_output__corrupt_action], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_output__corrupt_action], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute a drop action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_drop], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_drop], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute a pop VLAN action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_pop_vlan], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_pop_vlan], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute a set ethernet action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_set_ethernet], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_set_ethernet], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute a set ipv4 action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_set_ipv4], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_set_ipv4], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute a push VLAN vid action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_push_vlan__vid], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_push_vlan__vid], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute a push VLAN pcp action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_push_vlan__pcp], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_push_vlan__pcp], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute multiple actions with three output actions]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_multiple_actions__three_output], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_multiple_actions__three_output], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([execute multiple actions with a pop vlan and output action]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_multiple_actions__pop_vlan_and_output], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- action_execute_multiple_actions__pop_vlan_and_output], [0], [ignore], []) + AT_CLEANUP + ]) + +@@ -77,31 +77,31 @@ AT_CLEANUP + m4_define([OVDK_CHECK_FLOW_TABLE], + [AT_BANNER([flow table unit tests - dpdk datapath]) + AT_SETUP([add a flow to the flow table]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_add_flow], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_add_flow], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([delete a flow from the flow table]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_del_flow], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_del_flow], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([delete all flows from the flow table]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_del_all], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_del_all], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([get a flow from the flow table]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_get_flow], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_get_flow], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([modify a flow in the flow table]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_mod_flow], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_mod_flow], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([get the first flow from the flow table]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_get_first_flow], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_get_first_flow], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([get the next flow from the flow table]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_get_next_flow], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- flow_table_get_next_flow], [0], [ignore], []) + AT_CLEANUP + ]) + +@@ -110,27 +110,27 @@ AT_CLEANUP + m4_define([OVDK_CHECK_STATS], + [AT_BANNER([stats unit tests - dpdk datapath]) + AT_SETUP([increment stats for all vports]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vport_xxx_increment], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vport_xxx_increment], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([get stats for all vports]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vport_xxx_get], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vport_xxx_get], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([clear stats for all vports]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vport_xxx_clear], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vport_xxx_clear], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([increment stats for the vswitch]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vswitch_increment], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vswitch_increment], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([get stats for the vswitch]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vswitch_get], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vswitch_get], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([clear stats for the vswitch]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vswitch_clear], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-datapath -c 1 -n 4 -- stats_vswitch_clear], [0], [ignore], []) + AT_CLEANUP + ]) + +diff --git a/openvswitch/tests/dpdk-link.at b/openvswitch/tests/dpdk-link.at +index accfde9..c119668 100644 +--- a/openvswitch/tests/dpdk-link.at ++++ b/openvswitch/tests/dpdk-link.at +@@ -29,7 +29,7 @@ + m4_define([CHECK_DPDK_LINK], + [AT_BANNER([dpdk-link tests]) + AT_SETUP([Check negative cases for dpdk-link.c]) +-AT_CHECK([sudo -E $srcdir/test-dpdk-link -c 1 -n 4], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpdk-link -c 1 -n 4], [0], [ignore], []) + AT_CLEANUP + ]) + +diff --git a/openvswitch/tests/dpif-dpdk.at b/openvswitch/tests/dpif-dpdk.at +index 55b3505..b62d146 100644 +--- a/openvswitch/tests/dpif-dpdk.at ++++ b/openvswitch/tests/dpif-dpdk.at +@@ -2,63 +2,63 @@ m4_define([CHECK_DPIF_DPDK], + + [AT_BANNER([Test dpif-dpdk.c ]) + AT_SETUP([Test dpif_dpdk_get_stats]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_get_stats], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_get_stats], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_add]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_add], [0], [ignore], [ignore]) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_add], [0], [ignore], [ignore]) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_del]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_del], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_del], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_query_by_number]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_query_by_number], [0], [ignore], [ignore]) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_query_by_number], [0], [ignore], [ignore]) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_query_by_name]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_query_by_name], [0], [ignore], [ignore]) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_query_by_name], [0], [ignore], [ignore]) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_get_max_ports]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_get_max_ports], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_get_max_ports], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_dump_start]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_dump_start], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_dump_start], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_dump_next]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_dump_next], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_dump_next], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_dump_done]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_dump_done], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_dump_done], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_poll]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_poll], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_poll], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_port_poll_wait]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_poll_wait], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_port_poll_wait], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_flow_put]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_flow_put], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_flow_put], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_flow_del]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_flow_del], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_flow_del], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_flow_dump_start]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_flow_dump_start], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_flow_dump_start], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([Test dpif_dpdk_flow_dump_next]) +-AT_CHECK([sudo -E $srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_flow_dump_next], [0], [ignore], []) ++AT_CHECK([$srcdir/test-dpif-dpdk -c 1 -n 4 -- --dpif_dpdk_flow_dump_next], [0], [ignore], []) + AT_CLEANUP + ]) + CHECK_DPIF_DPDK([]) +diff --git a/openvswitch/tests/flowgen.pl b/openvswitch/tests/flowgen.pl +old mode 100644 +new mode 100755 +diff --git a/openvswitch/tests/netdev-dpdk.at b/openvswitch/tests/netdev-dpdk.at +index df4cd89..d314e3c 100644 +--- a/openvswitch/tests/netdev-dpdk.at ++++ b/openvswitch/tests/netdev-dpdk.at +@@ -3,7 +3,7 @@ m4_define([CHECK_DPIF_DPDK], + [AT_BANNER([Test netdev-dpdk.c ]) + + AT_SETUP([Test netdev_dpdk_change_seq]) +-AT_CHECK([sudo -E $srcdir/test-netdev-dpdk --netdev_dpdk_test_change_seq], [0], [ignore], []) ++AT_CHECK([$srcdir/test-netdev-dpdk --netdev_dpdk_test_change_seq], [0], [ignore], []) + AT_CLEANUP + + ]) +diff --git a/openvswitch/tests/ofproto-macros.at b/openvswitch/tests/ofproto-macros.at +index 839d41f..ef291dd 100644 +--- a/openvswitch/tests/ofproto-macros.at ++++ b/openvswitch/tests/ofproto-macros.at +@@ -73,7 +73,7 @@ m4_define([OVS_VSWITCHD_START], + AT_CHECK([ovs-vsctl --no-wait init]) + + dnl Start ovs-vswitchd. +- AT_CHECK([ovs-vswitchd --detach --no-chdir --pidfile --enable-dummy$3 --disable-system --log-file -vvconn -vofproto_dpif], [0], [], [stderr]) ++ AT_CHECK([ovs-vswitchd -c 1 -n 4 -- --detach --no-chdir --pidfile --enable-dummy$3 --disable-system --log-file -vvconn -vofproto_dpif], [0], [ignore], [stderr]) + AT_CAPTURE_FILE([ovs-vswitchd.log]) + AT_CHECK([[sed < stderr ' + /vlog|INFO|opened log file/d +diff --git a/openvswitch/tests/ovs-vport.at b/openvswitch/tests/ovs-vport.at +index 5f6857c..19d87cc 100644 +--- a/openvswitch/tests/ovs-vport.at ++++ b/openvswitch/tests/ovs-vport.at +@@ -6,23 +6,23 @@ m4_define([OVDK_CHECK_LIBVPORT], + [AT_BANNER([libvport/ovs-vport unit tests - dpdk datapath]) + + AT_SETUP([check vports are valid]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- valid_vport], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- valid_vport], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([check client rings are found]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- vport_client_lookup], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- vport_client_lookup], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([check kni fifos are found]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- vport_kni_lookup], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- vport_kni_lookup], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([check packet mempool is found]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- lookup_packet_mempool], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- lookup_packet_mempool], [0], [ignore], []) + AT_CLEANUP + + AT_SETUP([check port names are valid]) +-AT_CHECK([sudo -E $srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- is_vport_name_valid], [0], [ignore], []) ++AT_CHECK([$srcdir/dpdk/test-ovs-vport -c 1 -n 4 -- is_vport_name_valid], [0], [ignore], []) + AT_CLEANUP + + ]) +-- +1.8.5.2 + diff --git a/recipes-networking/openvswitchdpdk/files/configure-fix.patch b/recipes-networking/openvswitchdpdk/files/configure-fix.patch new file mode 100644 index 0000000..187e8a0 --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/configure-fix.patch @@ -0,0 +1,12 @@ +Index: files/configure.ac +=================================================================== +--- files.orig/openvswitch/configure.ac 2014-03-26 16:49:44.000000000 +0200 ++++ files/openvswitch/configure.ac 2014-04-18 16:47:28.163114309 +0300 +@@ -47,6 +47,7 @@ + AC_SEARCH_LIBS([clock_gettime], [rt]) + AC_SEARCH_LIBS([timer_create], [rt]) + AC_SEARCH_LIBS([pthread_sigmask], [pthread]) ++AC_SEARCH_LIBS([dlopen], [dl]) + AC_FUNC_STRERROR_R + + OVS_CHECK_ESX diff --git a/recipes-networking/openvswitchdpdk/files/makefile-install-rule.patch b/recipes-networking/openvswitchdpdk/files/makefile-install-rule.patch new file mode 100644 index 0000000..2609870 --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/makefile-install-rule.patch @@ -0,0 +1,22 @@ +Index: dpdk-ovs/openvswitch/datapath/dpdk/Makefile +=================================================================== +--- dpdk-ovs.orig/openvswitch/datapath/dpdk/Makefile 2014-04-18 14:06:01.219379540 +0300 ++++ dpdk-ovs/openvswitch/datapath/dpdk/Makefile 2014-04-22 16:24:27.009689498 +0300 +@@ -77,3 +77,6 @@ + + clean-vport_ut: + $(MAKE) -f Makefile.vport_ut clean ++ ++install: ++ +Index: dpdk-ovs/openvswitch/datapath/dpdk/fd_link/Makefile +=================================================================== +--- dpdk-ovs.orig/openvswitch/datapath/dpdk/fd_link/Makefile 2014-04-18 14:06:01.219379540 +0300 ++++ dpdk-ovs/openvswitch/datapath/dpdk/fd_link/Makefile 2014-04-22 16:24:24.185689575 +0300 +@@ -53,3 +53,6 @@ + + check-recursive: + $(warning "This target is not implemented") ++ ++install: ++ diff --git a/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-controller b/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-controller new file mode 100755 index 0000000..fdd5a46 --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-controller @@ -0,0 +1,279 @@ +#!/bin/sh +# +# Copyright (c) 2011 Nicira Networks Inc. +# Copyright (c) 2007, 2009 Javier Fernandez-Sanguino +# +# This is free software; you may redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2, +# or (at your option) any later version. +# +# This is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License with +# the Debian operating system, in /usr/share/common-licenses/GPL; if +# not, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA +# +### BEGIN INIT INFO +# Provides: openvswitch-controller +# Required-Start: $network $local_fs $remote_fs +# Required-Stop: $remote_fs +# Should-Start: $named +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Open vSwitch controller +### END INIT INFO + +INSTALLPREFIX= + +if [ -n "$INSTALLPREFIX" ] +then + PATH=$INSTALLPREFIX/sbin:$INSTALLPREFIX/bin:$PATH +fi + +DAEMON=$INSTALLPREFIX/bin/ovs-controller # Introduce the server's location here +NAME=ovs-controller # Introduce the short server's name here +DESC=ovs-controller # Introduce a short description here +LOGDIR=$INSTALLPREFIX/var/log/openvswitch # Log directory to use + +PIDFILE=$INSTALLPREFIX/var/run/openvswitch/$NAME.pid + +test -x $DAEMON || exit 0 + +. /lib/lsb/init-functions + +# Default options, these can be overriden by the information +# at /etc/default/openvswitchdpdk-controller +DAEMON_OPTS="" # Additional options given to the server + +DODTIME=10 # Time to wait for the server to die, in seconds + # If this value is set too low you might not + # let some servers to die gracefully and + # 'restart' will not work + +LOGFILE=$LOGDIR/$NAME.log # Server logfile +#DAEMONUSER= # User to run the daemons as. If this value + # is set start-stop-daemon will chuid the server + +# Include defaults if available +default=/etc/default/openvswitchdpdk-controller +if [ -f $default ] ; then + . $default +fi + +# Check that the user exists (if we set a user) +# Does the user exist? +if [ -n "$DAEMONUSER" ] ; then + if getent passwd | grep -q "^$DAEMONUSER:"; then + # Obtain the uid and gid + DAEMONUID=`getent passwd |grep "^$DAEMONUSER:" | awk -F : '{print $3}'` + DAEMONGID=`getent passwd |grep "^$DAEMONUSER:" | awk -F : '{print $4}'` + else + log_failure_msg "The user $DAEMONUSER, required to run $NAME does not exist." + exit 1 + fi +fi + + +set -e + +running_pid() { +# Check if a given process pid's cmdline matches a given name + pid=$1 + name=$2 + [ -z "$pid" ] && return 1 + [ ! -d /proc/$pid ] && return 1 + cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1` + # Is this the expected server + [ "$cmd" != "$name" ] && return 1 + return 0 +} + +running() { +# Check if the process is running looking at /proc +# (works for all users) + + # No pidfile, probably no daemon present + [ ! -f "$PIDFILE" ] && return 1 + pid=`cat $PIDFILE` + running_pid $pid $DAEMON || return 1 + return 0 +} + +start_server() { + if [ -z "$LISTEN" ]; then + echo "$default: No connection methods configured, controller disabled" >&2 + exit 0 + fi + + if [ ! -d $INSTALLPREFIX/var/run/openvswitch ]; then + install -d -m 755 -o root -g root $INSTALLPREFIX/var/run/openvswitch + fi + + SSL_OPTS= + case $LISTEN in + *ssl*) + : ${PRIVKEY:=$INSTALLPREFIX/etc/openvswitch-controller/privkey.pem} + : ${CERT:=$INSTALLPREFIX/etc/openvswitch-controller/cert.pem} + : ${CACERT:=$INSTALLPREFIX/etc/openvswitch-controller/cacert.pem} + if test ! -e "$PRIVKEY" || test ! -e "$CERT" || + test ! -e "$CACERT"; then + if test ! -e "$PRIVKEY"; then + echo "$PRIVKEY: private key missing" >&2 + fi + if test ! -e "$CERT"; then + echo "$CERT: certificate for private key missing" >&2 + fi + if test ! -e "$CACERT"; then + echo "$CACERT: CA certificate missing" >&2 + fi + exit 1 + fi + SSL_OPTS="--private-key=$PRIVKEY --certificate=$CERT --ca-cert=$CACERT" + ;; + esac + +# Start the process using the wrapper + if [ -z "$DAEMONUSER" ] ; then + start-stop-daemon --start --pidfile $PIDFILE \ + --exec $DAEMON -- --detach --pidfile=$PIDFILE \ + $LISTEN $DAEMON_OPTS $SSL_OPTS + errcode=$? + else +# if we are using a daemonuser then change the user id + start-stop-daemon --start --quiet --pidfile $PIDFILE \ + --chuid $DAEMONUSER --exec $DAEMON -- \ + --detach --pidfile=$PIDFILE $LISTEN $DAEMON_OPTS \ + $SSL_OPTS + errcode=$? + fi + return $errcode +} + +stop_server() { +# Stop the process using the wrapper + if [ -z "$DAEMONUSER" ] ; then + start-stop-daemon --stop --quiet --pidfile $PIDFILE \ + --exec $DAEMON + errcode=$? + else +# if we are using a daemonuser then look for process that match + start-stop-daemon --stop --quiet --pidfile $PIDFILE \ + --user $DAEMONUSER --exec $DAEMON + errcode=$? + fi + + return $errcode +} + +reload_server() { + [ ! -f "$PIDFILE" ] && return 1 + pid=`cat $PIDFILE` # This is the daemon's pid + # Send a SIGHUP + kill -1 $pid + return $? +} + +force_stop() { +# Force the process to die killing it manually + [ ! -e "$PIDFILE" ] && return + if running ; then + kill -15 $pid + # Is it really dead? + sleep "$DODTIME" + if running ; then + kill -9 $pid + sleep "$DODTIME" + if running ; then + echo "Cannot kill $NAME (pid=$pid)!" + exit 1 + fi + fi + fi + rm -f $PIDFILE +} + + +case "$1" in + start) + log_begin_msg "Starting $DESC " "$NAME" + # Check if it's running first + if running ; then + log_warning_msg "apparently already running" + log_end_msg 0 + exit 0 + fi + if start_server && running ; then + # It's ok, the server started and is running + log_end_msg 0 + else + # Either we could not start it or it is not running + # after we did + # NOTE: Some servers might die some time after they start, + # this code does not try to detect this and might give + # a false positive (use 'status' for that) + log_end_msg 1 + fi + ;; + stop) + log_begin_msg "Stopping $DESC" "$NAME" + if running ; then + # Only stop the server if we see it running + stop_server + log_end_msg $? + else + # If it's not running don't do anything + log_warning_msg "apparently not running" + log_end_msg 0 + exit 0 + fi + ;; + force-stop) + # First try to stop gracefully the program + $0 stop + if running; then + # If it's still running try to kill it more forcefully + log_begin_msg "Stopping (force) $DESC" "$NAME" + force_stop + log_end_msg $? + fi + ;; + restart|force-reload) + log_begin_msg "Restarting $DESC" "$NAME" + stop_server + # Wait some sensible amount, some server need this + [ -n "$DODTIME" ] && sleep $DODTIME + start_server + running + log_end_msg $? + ;; + status) + + log_begin_msg "Checking status of $DESC" "$NAME" + if running ; then + log_begin_msg "running" + log_end_msg 0 + else + log_warning_msg "apparently not running" + log_end_msg 1 + exit 1 + fi + ;; + # Use this if the daemon cannot reload + reload) + log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon" + log_warning_msg "cannot re-read the config file (use restart)." + ;; + *) + N=/etc/init.d/openvswitchdpdk-controller + echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-controller-setup b/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-controller-setup new file mode 100644 index 0000000..507a85e --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-controller-setup @@ -0,0 +1,29 @@ +# This is a POSIX shell fragment -*- sh -*- + +# LISTEN: What OpenFlow connection methods should the controller listen on? +# +# This is a space-delimited list of connection methods: +# +# * "pssl:[PORT]": Listen for SSL connections on the specified PORT +# (default: 6633). The private key, certificate, and CA certificate +# must be specified below. +# +# * "ptcp:[PORT]": Listen for TCP connections on the specified PORT +# (default: 6633). Not recommended for security reasons. +# +LISTEN="ptcp:" + +# PRIVKEY: Name of file containing controller's private key. +# Required if SSL enabled. +PRIVKEY=$INSTALLPREFIX/etc/openvswitch-controller/privkey.pem + +# CERT: Name of file containing certificate for private key. +# Required if SSL enabled. +CERT=$INSTALLPREFIX/etc/openvswitch-controller/cert.pem + +# CACERT: Name of file containing switch CA certificate. +# Required if SSL enabled. +CACERT=$INSTALLPREFIX/etc/openvswitch-controller/cacert.pem + +# Additional options to pass to controller, e.g. "--hub" +DAEMON_OPTS="" diff --git a/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-switch b/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-switch new file mode 100644 index 0000000..051d4d7 --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-switch @@ -0,0 +1,110 @@ +#! /bin/sh +# +# Copyright (C) 2011 Nicira Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +### BEGIN INIT INFO +# Provides: openvswitch-switch +# Required-Start: $network $named $remote_fs $syslog +# Required-Stop: $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Open vSwitch switch +### END INIT INFO + + +INSTALLPREFIX= + +if [ -n "$INSTALLPREFIX" ] +then + PATH=$INSTALLPREFIX/sbin:$INSTALLPREFIX/bin:$PATH +fi + +(test -x $INSTALLPREFIX/sbin/ovs-vswitchd && test -x $INSTALLPREFIX/sbin/ovsdb-server) || exit 0 + +. $INSTALLPREFIX/share/openvswitch/scripts/ovs-lib +test -e /etc/default/openvswitchdpdk-switch && . /etc/default/openvswitchdpdk-switch + +if test X"$BRCOMPAT" = Xyes && test ! -x $INSTALLPREFIX/sbin/ovs-brcompatd; then + BRCOMPAT=no + log_warning_msg "ovs-brcompatd missing, disabling bridge compatibility" +fi + +ovs_ctl () { + set $INSTALLPREFIX/share/openvswitch/scripts/ovs-ctl "$@" + if test X"$BRCOMPAT" = Xyes; then + set "$@" --brcompat + fi + "$@" +} + +load_kmod () { + ovs_ctl load-kmod || exit $? +} + +start () { + if ovs_ctl load-kmod; then + : + else + echo "Module has probably not been built for this kernel." + if ! test -d $INSTALLPREFIX/share/doc/openvswitch-datapath-source; then + echo "Install the openvswitch-datapath-source package, then read" + else + echo "For instructions, read" + fi + echo "$INSTALLPREFIX/share/doc/openvswitch-datapath-source/README.Debian" + fi + set ovs_ctl ${1-start} --system-id=random + if test X"$FORCE_COREFILES" != X; then + set "$@" --force-corefiles="$FORCE_COREFILES" + fi + "$@" || exit $? + + ovs_ctl --protocol=gre enable-protocol +} + +stop () { + ovs_ctl stop +} + +case $1 in + start) + start + ;; + stop | force-stop) + stop + ;; + reload | force-reload) + # The OVS daemons keep up-to-date. + ;; + restart) + stop + start + ;; + status) + ovs_ctl status + ;; + force-reload-kmod) + start force-reload-kmod + ;; + load-kmod) + load_kmod + ;; + *) + echo "Usage: $0 {start|stop|restart|force-reload|status|force-stop|force-reload-kmod|load-kmod}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-switch-setup b/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-switch-setup new file mode 100644 index 0000000..84cea1f --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/openvswitchdpdk-switch-setup @@ -0,0 +1,16 @@ +# This is a POSIX shell fragment -*- sh -*- + +# FORCE_COREFILES: If 'yes' then core files will be enabled. +# FORCE_COREFILES=yes + +# BRCOMPAT: If 'yes' and the openvswitch-brcompat package is installed, then +# Linux bridge compatibility will be enabled. +# BRCOMPAT=yes + +#modify according to platform +export OVS_DPDK_PARAMS=${OVS_DPDK_PARAMS:-"@OVS_DPDK_PARAMS_DEFAULT"} +export OVS_VSWITCHD_PARAMS=${OVS_VSWITCHD_PARAMS:-"@OVS_VSWITCHD_PARAMS_DEFAULT"} +#for debugging redirect to a regular file - this should be done temporary +#if permanent logging is required a service like logrotate is recommended to limit the size of the log file +export OVS_DPDK_LOG=${OVS_DPDK_LOG:-"@OVS_DPDK_LOG_DEFAULT"} + diff --git a/recipes-networking/openvswitchdpdk/files/ovs-ctl-dpdk.patch b/recipes-networking/openvswitchdpdk/files/ovs-ctl-dpdk.patch new file mode 100644 index 0000000..bbe7a32 --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/ovs-ctl-dpdk.patch @@ -0,0 +1,123 @@ +Add ovs-vswitchd dpdk parameters and ovs_dpdk daemon calls. + +Signed-off-by: Radu Patriu +Upstream-Status: Pending + +Index: git/openvswitch/utilities/ovs-ctl.in +=================================================================== +--- git.orig/openvswitch/utilities/ovs-ctl.in 2014-05-22 14:48:48.505319435 +0300 ++++ git/openvswitch/utilities/ovs-ctl.in 2014-05-22 15:05:46.437302665 +0300 +@@ -13,6 +13,15 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + ++#OVS_DPDK_PARAMS_DEFAULT to be replaced by install script ++OVS_DPDK_PARAMS=${OVS_DPDK_PARAMS:-"@OVS_DPDK_PARAMS_DEFAULT"} ++ ++#OVS_VSWITCHD_PARAMS_DEFAULT to be replaced by install script ++OVS_VSWITCHD_PARAMS=${OVS_VSWITCHD_PARAMS:-"@OVS_VSWITCHD_PARAMS_DEFAULT"} ++ ++#OVS_DPDK_LOG_DEFAULT to be replaced by install script ++OVS_DPDK_LOG=${OVS_DPDK_LOG:-"@OVS_DPDK_LOG_DEFAULT"} ++ + case $0 in + */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;; + *) dir0=./ ;; +@@ -106,7 +115,7 @@ + set_system_ids () { + set ovs_vsctl set Open_vSwitch . + +- OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'` ++ OVS_VERSION=`ovs-vswitchd -c 0x01 -n 4 --proc-type=auto -m 4 -- --version | sed -n 's/ovs-vswitchd (Open vSwitch) \(.*\)/\1/p'` + set "$@" ovs-version="$OVS_VERSION" + + case $SYSTEM_ID in +@@ -215,9 +224,39 @@ + db:Open_vSwitch,Open_vSwitch,manager_options + } + ++start_dpdk () { ++ if daemon_is_running ovs_dpdk; then ++ log_success_msg "ovs_dpdk is already running" ++ else ++ modprobe uio ++ test -e /sys/module/igb_uio || insmod $datadir/../openvswitchdpdk/kmod/igb_uio.ko ++ test -e /sys/module/rte_kni || insmod $datadir/../openvswitchdpdk/kmod/rte_kni.ko ++ rm -f $rundir/ovs_dpdk.pid ++ start-stop-daemon --start --quiet --background --make-pidfile --pidfile $rundir/ovs_dpdk.pid --exec /bin/sh -- -c "exec ovs_dpdk $OVS_DPDK_PARAMS >> $OVS_DPDK_LOG 2>&1" ++ #wait for ovs_dpdk to initialize before starting ovs-vswitchd ++ sleep 10 ++ fi ++} ++ ++stop_dpdk () { ++ pid=`cat "$rundir/ovs_dpdk.pid"` ++ rtemaps=`test -e /proc/$pid/maps && cat /proc/$pid/maps | grep -o '/.*rtemap_.*$'` ++ ++ stop_daemon ovs_dpdk ++ ++ #try to clean ++ for rtemap in $rtemaps ++ do ++ rm -f $rtemap ++ done ++ rm -f $rundir/ovs_dpdk.pid ++} ++ + start_forwarding () { + check_force_cores + ++ start_dpdk ++ + insert_mod_if_required || return 1 + + if daemon_is_running ovs-vswitchd; then +@@ -230,9 +269,9 @@ + ulimit -n 7500 + + # Start ovs-vswitchd. +- set ovs-vswitchd unix:"$DB_SOCK" ++ set ovs-vswitchd $OVS_VSWITCHD_PARAMS -- unix:"$DB_SOCK" + set "$@" -vconsole:emer -vsyslog:err -vfile:info +- if test X"$MLOCKALL" != Xno; then ++ if test -"$MLOCKALL" != Xno; then + set "$@" --mlockall + fi + start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@" +@@ -249,6 +288,7 @@ + + stop_forwarding () { + stop_daemon ovs-vswitchd ++ stop_dpdk + } + + ## ----------------- ## +@@ -505,8 +545,10 @@ + MLOCKALL=yes + OVSDB_SERVER_PRIORITY=-10 + OVS_VSWITCHD_PRIORITY=-10 ++ OVS_DPDK_PRIORITY=-10 + OVSDB_SERVER_WRAPPER= + OVS_VSWITCHD_WRAPPER= ++ OVS_DPDK_WRAPPER= + + DB_FILE=$dbdir/conf.db + DB_SOCK=$rundir/db.sock +@@ -601,6 +643,8 @@ + data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR) + user binaries: @bindir@ (--bindir, OVS_BINDIR) + system binaries: @sbindir@ (--sbindir, OVS_SBINDIR) ++ ovs_dpdk params: OVS_DPDK_PARAMS (env only) ++ ovs-vswitchd dpdk params: OVS_VSWITCHD_PARAMS (env only) + + Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details). + EOF +@@ -622,7 +666,7 @@ + } + + daemons () { +- echo ovsdb-server ovs-vswitchd ++ echo ovsdb-server ovs-vswitchd ovs_dpdk + } + + set_defaults diff --git a/recipes-networking/openvswitchdpdk/files/qemu-makefile.patch b/recipes-networking/openvswitchdpdk/files/qemu-makefile.patch new file mode 100644 index 0000000..0ef50da --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/qemu-makefile.patch @@ -0,0 +1,26 @@ +From 7f073eec0d100bddaba59c693505713974a2d4bb Mon Sep 17 00:00:00 2001 +From: Huimin She +Date: Tue, 22 Apr 2014 22:58:11 +0200 +Subject: [PATCH] Add -ldl to qemu Makefile + +Signed-off-by: Huimin She +--- + qemu/Makefile.target | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/qemu/Makefile.target b/qemu/Makefile.target +index 760da1e..72b58d7 100644 +--- a/qemu/Makefile.target ++++ b/qemu/Makefile.target +@@ -117,7 +117,7 @@ obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += memory_mapping.o + obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o + obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o + obj-$(CONFIG_NO_CORE_DUMP) += dump-stub.o +-LIBS+=-lz ++LIBS+=-lz -ldl + + # xen support + obj-$(CONFIG_XEN) += xen-all.o xen-mapcache.o +-- +1.8.3.2 + diff --git a/recipes-networking/openvswitchdpdk/files/qemu-options-hx.patch b/recipes-networking/openvswitchdpdk/files/qemu-options-hx.patch new file mode 100644 index 0000000..d847d9e --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/qemu-options-hx.patch @@ -0,0 +1,30 @@ +diff --git a/qemu/qemu-options.hx b/qemu/qemu-options.hx +index 9d7131a..1000d49 100644 +--- a/qemu/qemu-options.hx ++++ b/qemu/qemu-options.hx +@@ -2075,18 +2075,13 @@ QEMU supports using either local sheepdog devices or remote networked + devices. + + Syntax for specifying a sheepdog device +-@table @list +-``sheepdog:'' +- +-``sheepdog::'' +- +-``sheepdog::'' +- +-``sheepdog:::'' +- +-``sheepdog::::'' +- +-``sheepdog::::'' ++@table @code ++@item sheepdog: ++@item sheepdog:: ++@item sheepdog:: ++@item sheepdog::: ++@item sheepdog:::: ++@item sheepdog:::: + @end table + + Example diff --git a/recipes-networking/openvswitchdpdk/files/qemu-pixman-config.patch b/recipes-networking/openvswitchdpdk/files/qemu-pixman-config.patch new file mode 100644 index 0000000..266b42a --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/qemu-pixman-config.patch @@ -0,0 +1,26 @@ +From 1976f44e3b14653421f67d7d050586348f3d3fa1 Mon Sep 17 00:00:00 2001 +From: Huimin She +Date: Tue, 29 Apr 2014 10:00:30 +0200 +Subject: [PATCH] Add --host for qemu/pixman configure + +Signed-off-by: Huimin She +--- + qemu/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/qemu/Makefile b/qemu/Makefile +index 0d9099a..88b470f 100644 +--- a/qemu/Makefile ++++ b/qemu/Makefile +@@ -131,7 +131,7 @@ subdir-pixman: pixman/Makefile + $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman V="$(V)" all,) + + pixman/Makefile: $(SRC_PATH)/pixman/configure +- (cd pixman; CFLAGS="$(CFLAGS) -fPIC $(extra_cflags) $(extra_ldflags)" $(SRC_PATH)/pixman/configure $(AUTOCONF_HOST) --disable-gtk --disable-shared --enable-static) ++ (cd pixman; CFLAGS="$(CFLAGS) -fPIC $(extra_cflags) $(extra_ldflags)" $(SRC_PATH)/pixman/configure $(AUTOCONF_HOST) --disable-gtk --disable-shared --enable-static --host $(HOST_SYS)) + + $(SRC_PATH)/pixman/configure: + (cd $(SRC_PATH)/pixman; autoreconf -v --install) +-- +1.8.3.2 + diff --git a/recipes-networking/openvswitchdpdk/files/run-ptest b/recipes-networking/openvswitchdpdk/files/run-ptest new file mode 100644 index 0000000..3bf83b6 --- /dev/null +++ b/recipes-networking/openvswitchdpdk/files/run-ptest @@ -0,0 +1,8 @@ +#!/bin/sh + +INSTALLPREFIX= + +PATH=$INSTALLPREFIX/sbin:$INSTALLPREFIX/bin:$PATH + +./tests/testsuite --am-fmt -C tests AUTOTEST_PATH=utilities:vswitchd:ovsdb:tests + diff --git a/recipes-networking/openvswitchdpdk/openvswitchdpdk_0.10.0.bb b/recipes-networking/openvswitchdpdk/openvswitchdpdk_0.10.0.bb new file mode 100644 index 0000000..d6cde8d --- /dev/null +++ b/recipes-networking/openvswitchdpdk/openvswitchdpdk_0.10.0.bb @@ -0,0 +1,248 @@ +SUMMARY = "DPDK vSwitch" +DESCRIPTION = "DPDK vSwitch is a fork of Open vSwitch. It re-creates the kernel forwarding module (data plane) \ +by building the switching logic on top of the DPDK library to significantly boost packet switching throughput" +HOMEPAGE = "https://01.org/packet-processing" +SECTION = "networking" +LICENSE = "Apache-2 & GPLv2 & LGPLv2.1 & BSD" +LIC_FILES_CHKSUM = "file://openvswitch/COPYING;md5=eef486aeb68ddde5446062140eeda540 \ + file://qemu/COPYING;md5=441c28d2cf86e15a37fa47e15a72fbac \ + file://qemu/COPYING.LIB;md5=79ffa0ec772fa86740948cb7327a0cc7 \ + file://guest/ovs_client/ovs_client.c;beginline=1;endline=33;md5=8485efe01bb0513caf69f8bbec5617a0 \ + " +PV = "0.10.0" + +PACKAGES =+ "${PN}-controller ${PN}-switch ${PN}-pki ${PN}-qemu" + +DEPENDS += "dpdk virtual/kernel libtool glib-2.0 expect fuse python perl" + +RDEPENDS_${PN} += "util-linux-uuidgen util-linux-libuuid coreutils \ + python perl perl-module-strict sed gawk grep ${PN}-switch ${PN}-controller" +RRECOMMENDS_${PN} += "kernel-module-openvswitch kernel-module-uio kernel-module-pci-stub" + +RDEPENDS_${PN}-ptest += "python-logging python-syslog python-argparse python-io \ + python-fcntl python-shell python-lang python-xml python-math \ + python-datetime python-netclient python sed ${PN}" + +RDEPENDS_${PN}-pki = "${PN}" +ALLOW_EMPTY_${PN}-pki = "1" + +RDEPENDS_${PN}-controller += "${PN} lsb ${PN}-pki" +RDEPENDS_${PN}-switch = "${PN} openssl procps util-linux-uuidgen" + +OVS_PREFIX = "/opt/${PN}" + +FILES_${PN}-controller = "${sysconfdir}/init.d/openvswitchdpdk-controller \ + ${sysconfdir}/default/openvswitchdpdk-controller \ + ${OVS_PREFIX}/bin/ovs-controller \ + " + +FILES_${PN}-doc += "/share/man" + +FILES_${PN} += "/share" + +FILES_${PN}-switch = "${sysconfdir}/init.d/openvswitchdpdk-switch \ + ${sysconfdir}/default/openvswitchdpdk-switch" + +FILES_${PN}-qemu = "${QEMU_INSTALL_PATH}" + +inherit module-base update-rc.d + +INITSCRIPT_PACKAGES = "${PN}-switch ${PN}-controller" +INITSCRIPT_NAME_${PN}-switch = "openvswitchdpdk-switch" +#to enable at startup use bbappend recipe with INITSCRIPT_PARAMS_${PN}-switch = "defaults 71" +INITSCRIPT_PARAMS_${PN}-switch = "stop 20 5 2 . stop 20 0 1 6 ." + +INITSCRIPT_NAME_${PN}-controller = "openvswitchdpdk-controller" +#to enable at startup use bbappend recipe with INITSCRIPT_PARAMS_${PN}-controller = "defaults 72" +INITSCRIPT_PARAMS_${PN}-controller = "stop 20 5 2 . stop 20 0 1 6 ." + +# Release 0.10.0 +SRCREV = "28318e4004a9010b8bc15ff7e8ac5d886ea47857" +SRC_URI = "git://github.com/01org/dpdk-ovs;branch=master \ + file://configure-fix.patch \ + file://makefile-install-rule.patch \ + file://qemu-makefile.patch \ + file://openvswitchdpdk-switch \ + file://openvswitchdpdk-switch-setup \ + file://openvswitchdpdk-controller \ + file://openvswitchdpdk-controller-setup \ + file://qemu-pixman-config.patch \ + file://qemu-options-hx.patch \ + file://0001-openvswitchdpdk-enabled-ptest.patch \ + file://run-ptest \ + file://ovs-ctl-dpdk.patch \ + " + +S = "${WORKDIR}/git" +B = "${S}" +OVS_S_DIR = "${S}/openvswitch" +QEMU_S_DIR = "${S}/qemu" + +# Install this modified qemu to a different place than the normal qemu +QEMU_INSTALL_PATH = "/opt/dpdk-ovs-qemu" + +SRC_URI[md5sum] = "8d354e5f730292f126f29f85448cfc2d" +SRC_URI[sha256sum] = "6256f9ca96716686030e4456e97eacc2f31b3169e65a1455f73ffafd78f7828a" + +export RTE_SDK = "${STAGING_DIR_HOST}/opt/dpdk" +export RTE_TARGET = "x86_64-ivshmem-linuxapp-gcc" + +OVS_CONFIG_OPTS = "--build=${BUILD_SYS} \ + --host=${HOST_SYS} \ + --target=${TARGET_SYS} \ + --prefix=${OVS_PREFIX} \ + --disable-silent-rules \ + --disable-ssl \ + " + +QEMU_CONFIG_OPTS = "--prefix=${QEMU_INSTALL_PATH} \ + --with-confsuffix="" \ + --mandir=${QEMU_INSTALL_PATH}/share/man \ + --docdir=${QEMU_INSTALL_PATH}/share/doc \ + --datadir=${QEMU_INSTALL_PATH}/share \ + --sysconfdir=${QEMU_INSTALL_PATH}/usr/etc \ + --bindir=${QEMU_INSTALL_PATH}/bin \ + --libdir=${QEMU_INSTALL_PATH}/lib \ + --libexecdir=${QEMU_INSTALL_PATH}/libexec \ + --includedir=${QEMU_INSTALL_PATH}/include \ + --localstatedir=${QEMU_INSTALL_PATH}/var \ + --enable-kvm \ + --dpdkdir=${RTE_SDK} \ + --extra-cflags="-Wno-poison-system-directories" \ + --target-list=x86_64-softmmu \ + --disable-strip \ + " + +PACKAGESPLITFUNCS_prepend = "split_ovs_packages " + +#append OVS_PREFIX to all FILES_* in PACKAGES except for ptest, qemu, switch +# and controller(includes exception, see FILES_${PN}-controller) packages +python split_ovs_packages () { + pkgs = d.getVar('PACKAGES', True) + for pkg in pkgs.split(): + if (pkg.endswith('-ptest') or pkg.endswith('-qemu') or + pkg.endswith('-switch') or pkg.endswith('-controller')): + continue + files = d.getVar('FILES_%s' % pkg, True) + if files is None: + continue + files = [d.getVar('OVS_PREFIX', True) + file for file in files.split()] + files = ' '.join(files) + d.setVar('FILES_%s' % pkg, files) +} + +do_configure () { + cd ${OVS_S_DIR} && ./boot.sh && ./configure ${OVS_CONFIG_OPTS} + cd ${QEMU_S_DIR} && ./configure ${QEMU_CONFIG_OPTS} +} + +do_compile () { + cd ${OVS_S_DIR} && oe_runmake + cd ${S}/guest/ovs_client && oe_runmake + cd ${S}/guest/kni/kni_client && oe_runmake + + # unset the environment variables, so that oe_runmake will not override them + unset bindir mandir docdir sysconfdir datadir libdir libexecdir includedir localstatedir + cd ${QEMU_S_DIR} && oe_runmake +} + +#use simple quotes in the definition of the following "OVS_" prefixed variables +OVS_DPDK_PARAMS_DEFAULT = "-c 0x0f -n 4 --proc-type=primary --huge-dir /mnt/huge -- -p 0x03 -k 2 -n 4 --stats=1 --vswitchd=1 --client_switching_core=0 --config='(0,0,2),(1,0,3)'" +OVS_VSWITCHD_PARAMS_DEFAULT = "-c 0x10 -n 4 --proc-type=secondary" +#for debugging redirect to a regular file - this should be done temporary +#if permanent logging is required a service like logrotate is recommended to limit the size of the log file +OVS_DPDK_LOG_DEFAULT = "/dev/null" + +do_install () { + cd ${OVS_S_DIR} && oe_runmake DESTDIR=${D} install + install ${OVS_S_DIR}/datapath/dpdk/build/app/ovs_dpdk ${D}/${OVS_PREFIX}${base_bindir} + install -d ${D}/${OVS_PREFIX}/share/${PN}/kmod + install -m 644 ${OVS_S_DIR}/datapath/dpdk/fd_link/fd_link.ko ${D}/${OVS_PREFIX}/share/${PN}/kmod + install -m 644 ${RTE_SDK}/${RTE_TARGET}/kmod/*.ko ${D}/${OVS_PREFIX}/share/${PN}/kmod + install ${S}/guest/kni/kni_client/build/kni_client ${D}/${OVS_PREFIX}${base_bindir} + install ${S}/guest/ovs_client/build/ovs_client ${D}/${OVS_PREFIX}${base_bindir} + + install -d ${D}/${sysconfdir}/default/ + install -m 660 ${WORKDIR}/openvswitchdpdk-switch-setup ${D}/${sysconfdir}/default/openvswitchdpdk-switch + install -m 660 ${WORKDIR}/openvswitchdpdk-controller-setup ${D}/${sysconfdir}/default/openvswitchdpdk-controller + + install -d ${D}/${sysconfdir}/init.d/ + install -m 755 ${WORKDIR}/openvswitchdpdk-controller ${D}/${sysconfdir}/init.d/openvswitchdpdk-controller + sed -i 's|INSTALLPREFIX=|INSTALLPREFIX=${OVS_PREFIX}|g' ${D}/${sysconfdir}/init.d/openvswitchdpdk-controller + install -m 755 ${WORKDIR}/openvswitchdpdk-switch ${D}/${sysconfdir}/init.d/openvswitchdpdk-switch + sed -i 's|INSTALLPREFIX=|INSTALLPREFIX=${OVS_PREFIX}|g' ${D}/${sysconfdir}/init.d/openvswitchdpdk-switch + + # Add DPDK default parameters to /etc/default/openvswitchdpdk-switch + sed -i "s|@OVS_DPDK_PARAMS_DEFAULT|${OVS_DPDK_PARAMS_DEFAULT}|g" ${D}/${sysconfdir}/default/openvswitchdpdk-switch + sed -i "s|@OVS_VSWITCHD_PARAMS_DEFAULT|${OVS_VSWITCHD_PARAMS_DEFAULT}|g" ${D}/${sysconfdir}/default/openvswitchdpdk-switch + sed -i "s|@OVS_DPDK_LOG_DEFAULT|${OVS_DPDK_LOG_DEFAULT}|g" ${D}/${sysconfdir}/default/openvswitchdpdk-switch + + # Add DPDK default parameters to ovs-ctl + sed -i "s|@OVS_DPDK_PARAMS_DEFAULT|${OVS_DPDK_PARAMS_DEFAULT}|g" ${D}/${OVS_PREFIX}/share/openvswitch/scripts/ovs-ctl + sed -i "s|@OVS_VSWITCHD_PARAMS_DEFAULT|${OVS_VSWITCHD_PARAMS_DEFAULT}|g" ${D}/${OVS_PREFIX}/share/openvswitch/scripts/ovs-ctl + sed -i "s|@OVS_DPDK_LOG_DEFAULT|${OVS_DPDK_LOG_DEFAULT}|g" ${D}/${OVS_PREFIX}/share/openvswitch/scripts/ovs-ctl + + install -d ${D}/${OVS_PREFIX}${sysconfdir}/openvswitch-controller + + # unset the environment variables, so that oe_runmake will not override them + unset bindir mandir docdir sysconfdir datadir libdir libexecdir includedir localstatedir + + export STRIP="true" + install -d ${D}/${QEMU_INSTALL_PATH}/bin + cd ${QEMU_S_DIR} && oe_runmake DESTDIR=${D} install + + # silence QA error: architecture did not match + rm -f ${D}/${QEMU_INSTALL_PATH}/share/openbios* + rm -f ${D}/${QEMU_INSTALL_PATH}/share/palcode-clipper +} + +pkg_postinst_${PN}-pki () { + # can't do this offline + if [ "x$D" != "x" ]; then + exit 1 + fi + if test ! -d $D/${OVS_PREFIX}/share/${PN}/pki; then + ${OVS_PREFIX}/${base_bindir}/ovs-pki init --dir=$D/${OVS_PREFIX}/share/${PN}/pki + fi +} + +pkg_postinst_${PN}-controller () { + # can't do this offline + if [ "x$D" != "x" ]; then + exit 1 + fi + + if test ! -d $D/${OVS_PREFIX}/share/${PN}/pki; then + ${OVS_PREFIX}/${base_bindir}/ovs-pki init --dir=$D/${OVS_PREFIX}/share/${PN}/pki + fi + + cd $D/${OVS_PREFIX}${sysconfdir}/openvswitch-controller + if ! test -e cacert.pem; then + ln -s $D/${OVS_PREFIX}/share/${PN}/pki/switchca/cacert.pem cacert.pem + fi + if ! test -e privkey.pem || ! test -e cert.pem; then + oldumask=$(umask) + umask 077 + ${OVS_PREFIX}/${base_bindir}/ovs-pki req+sign --dir=$D/${OVS_PREFIX}/share/${PN}/pki tmp controller >/dev/null + mv tmp-privkey.pem privkey.pem + mv tmp-cert.pem cert.pem + mv tmp-req.pem req.pem + chmod go+r cert.pem req.pem + umask $oldumask + fi +} + +inherit ptest + +EXTRA_OEMAKE += "TEST_DEST=${D}${PTEST_PATH} TEST_ROOT=${PTEST_PATH}" + +do_install_ptest() { + cd ${OVS_S_DIR} && oe_runmake test-install + sed -i 's|INSTALLPREFIX=|INSTALLPREFIX=${OVS_PREFIX}|g' ${D}${PTEST_PATH}/run-ptest +} + +# for qemu/pixman configuration +export HOST_SYS + +INHIBIT_PACKAGE_DEBUG_SPLIT = "1" +INSANE_SKIP_${PN} = "installed-vs-shipped" diff --git a/recipes-test/oftest/oftest_git.bb b/recipes-test/oftest/oftest_git.bb new file mode 100644 index 0000000..299c693 --- /dev/null +++ b/recipes-test/oftest/oftest_git.bb @@ -0,0 +1,27 @@ +SUMMARY = "OFTest" +DESCRIPTION = "OFTest - an OpenFlow test framework for switches" +HOMEPAGE = "http://www.projectfloodlight.org/oftest" +SECTION = "networking" +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://LICENSE;md5=7ad8e1e5f1c3d0004a6d449dbce36efe" + +PR = "1" +PV = "0" +RDEPENDS_${PN} = "python-scapy" + +inherit autotools + +SRCREV = "47544e410531732ee3603c5dfd255770009a9d96" +SRC_URI = "git://github.com/floodlight/oftest \ + " + +S = "${WORKDIR}/git" +B = "${S}" + +PACKAGES = "${PN}" +FILES_${PN} += "/opt/${PN}" + +do_install() { + install -d ${D}/opt/${PN} + cp -r ${S}/* ${D}/opt/${PN} +} diff --git a/recipes-test/openvswitchdpdk-oftest/files/README b/recipes-test/openvswitchdpdk-oftest/files/README new file mode 100644 index 0000000..cba3589 --- /dev/null +++ b/recipes-test/openvswitchdpdk-oftest/files/README @@ -0,0 +1,3 @@ +This ptest is intended to test DPDK OVS with OFTest framework. +It requires both DPDK-OVS and OFTest to be installed. + diff --git a/recipes-test/openvswitchdpdk-oftest/files/run-ptest b/recipes-test/openvswitchdpdk-oftest/files/run-ptest new file mode 100644 index 0000000..c08f224 --- /dev/null +++ b/recipes-test/openvswitchdpdk-oftest/files/run-ptest @@ -0,0 +1,284 @@ +#!/bin/sh + +export RTE_SDK=/opt/dpdk +export RTE_TARGET=x86_64-default-linuxapp-gcc +export RTE_ARCH=x86_64 +RTE_SRC=/usr/src/dpdk +HUGE_PAGES_MEM=2097152 #[1024 * 2048kB] +DEVS=("I350" "82599") +PCI_UTIL=${RTE_SRC}/tools/pci_unbind.py +OVS_PREFIX=/opt/openvswitchdpdk +IGB_UIO=$OVS_PREFIX/share/openvswitchdpdk/kmod/igb_uio.ko +RTE_KNI=$OVS_PREFIX/share/openvswitchdpdk/kmod/rte_kni.ko + +#check hugetlbfs mount +echo -n "Mounting hugepages..." +mount | grep "nodev on /mnt/huge type hugetlbfs" +if [ $? -ne 0 ]; then + mkdir -p /mnt/huge + mount -t hugetlbfs nodev /mnt/huge +fi +echo "OK!" + +#increase hugepages for all nodes +echo -n "Allocating hugepages..." +#get hugepages sizes +hp_sz=`cat /proc/meminfo | grep Hugepagesize | sed -r "s/Hugepagesize:[^0-9]*([0-9]+) kB/\1/"` +#calculate huge pages number to get the equivalent of 1024 pages of 2MB +huge_pages_no=`expr ${HUGE_PAGES_MEM} / ${hp_sz}` +#get hugepages no +hp=0 +#Find out if this is a NUMA machine +ls /sys/devices/system/node/node* > /dev/null 2>&1 +if [ $? -ne 0 ]; then + hp=`cat /proc/sys/vm/nr_hugepages` + hptest=`expr $hp + $huge_pages_no` + echo $hptest > /proc/sys/vm/nr_hugepages +else + hparray=() + nodes=`ls /sys/devices/system/node | grep node | wc -l` + for (( i=0; $i<$nodes; i++ )) + do + hp=`cat /sys/devices/system/node/node${i}/hugepages/hugepages-${hp_sz}kB/nr_hugepages` + hptest=`expr $hp + $huge_pages_no` + echo $hptest > /sys/devices/system/node/node${i}/hugepages/hugepages-${hp_sz}kB/nr_hugepages + hparray+=("$hp") + done +fi +echo "OK!" +echo "Allocated ${huge_pages_no} x ${hp_sz}kB" + +#Insert igb_uio and rte_kni modules +echo "Inserting kernel modules" +rmmod openvswitch 2>/dev/null +rmmod -f rte_kni 2>/dev/null +rmmod -f igb_uio 2>/dev/null +rmmod -f uio 2>/dev/null +modprobe uio +insmod ${IGB_UIO} +#insert igb_uio, needed by some dpdk tests +if [ $? -ne 0 ]; then + echo "FAIL: uio/igb_uio load" + DEVS=() +else + echo "PASS: uio/igb_uio load" +fi + +#insert rte_kni driver in loopback mode, needed by KNI tests +#insmod ${RTE_KNI} lo_mode=lo_mode_fifo +insmod ${RTE_KNI} + +if [ $? -ne 0 ]; then + echo "FAIL: rte_kni load" + DEVS=() +else + echo "PASS: rte_kni load" +fi + +#bind devices to igb_uio, needed by dpdk-ovs tests +search_str="" +len=${#DEVS[@]} +tmp=$len +for dev in ${DEVS[@]} +do + tmp=$[$tmp-1] + if [ $tmp -gt 0 ]; then + search_str+="${dev}\|" + else + search_str+=${dev} + fi +done + +#Get devices with link and bind to igb_uio +drvarray=() +pciarray=() +tmp=1 +len=`${PCI_UTIL} --status|grep ${search_str}|grep -v -i 'active'|wc -l` +while [[ $tmp -le $len ]] +do + DEV_INFO=`${PCI_UTIL} --status|grep ${search_str}|grep -v -i 'active'|sed -n ${tmp}p` + tmp=$[$tmp+1] + DEV_PCI_ADDR=`echo ${DEV_INFO}|sed -r "s/([^ ]*) .*/\1/"` + DEV_ETH=`echo ${DEV_INFO}|grep if=|sed -r "s/.*if=([^ ]*).*/\1/"` + if [ "${DEV_ETH}" == "" ]; then + echo "Skipping device ${DEV_PCI_ADDR}" + continue + fi + ifconfig ${DEV_ETH} up + sleep 1 + ifconfig ${DEV_ETH}|grep RUNNING>/dev/null + if [ $? -ne 0 ]; then + echo "Skipping device ${DEV_ETH}" + continue + fi + DEV_NAME=`echo ${DEV_INFO}|sed -r "s/.*'(.*)'.*/\1/"` + DEV_DRV=`echo ${DEV_INFO}|sed -r "s/.*drv=([^ ]*).*/\1/"` + pciarray+=("${DEV_PCI_ADDR}") + drvarray+=("${DEV_DRV}") + echo -n "Binding device ${DEV_PCI_ADDR}..." + ${PCI_UTIL} --bind=igb_uio ${DEV_PCI_ADDR} + echo "OK!" +done + +# Pre test cleanup +rm -f $OVS_PREFIX/etc/openvswitch/conf.db +mkdir -p $OVS_PREFIX/var/run/openvswitch 2>/dev/null +mkdir -p $OVS_PREFIX/etc/openvswitch 2>/dev/null + +# Create OVS schema +echo -n "Create OVS schema..." +$OVS_PREFIX/bin/ovsdb-tool create $OVS_PREFIX/etc/openvswitch/conf.db $OVS_PREFIX/share/openvswitch/vswitch.ovsschema + +sleep 2 +echo "OK!" + +#Start DB server +echo -n "Start DB server..." +$OVS_PREFIX/sbin/ovsdb-server --remote=punix:$OVS_PREFIX/var/run/openvswitch/db.sock --remote=db:Open_vSwitch,Open_vSwitch,manager_options > ovsdb-server.log 2>&1 & +ovsdb_server_pid=$! + +sleep 2 +echo "OK!" + +#init DB +echo -n "Init DB..." +$OVS_PREFIX/bin/ovs-vsctl --no-wait init + +sleep 2 +echo "OK!" + +#Configure DB +echo -n "Configure DB..." +$OVS_PREFIX/bin/ovs-vsctl --no-wait del-br br0 +$OVS_PREFIX/bin/ovs-vsctl --no-wait add-br br0 -- set Bridge br0 datapath_type=dpdk + +#Configure switch to use an OpenFlow controller and disable -n-band management +$OVS_PREFIX/bin/ovs-vsctl --no-wait set-controller br0 tcp:127.0.0.1:6653 +$OVS_PREFIX/bin/ovs-vsctl --no-wait set Bridge br0 other_config:disable-in-band=true + +#Add ports to switch +$OVS_PREFIX/bin/ovs-vsctl --no-wait add-port br0 ovs_dpdk_64 -- set Interface ovs_dpdk_64 type=dpdkveth ofport_request=64 +$OVS_PREFIX/bin/ovs-vsctl --no-wait add-port br0 ovs_dpdk_65 -- set Interface ovs_dpdk_65 type=dpdkveth ofport_request=65 +$OVS_PREFIX/bin/ovs-vsctl --no-wait add-port br0 ovs_dpdk_66 -- set Interface ovs_dpdk_66 type=dpdkveth ofport_request=66 +$OVS_PREFIX/bin/ovs-vsctl --no-wait add-port br0 ovs_dpdk_67 -- set Interface ovs_dpdk_67 type=dpdkveth ofport_request=67 + +sleep 2 +echo "OK!" + +#Start DPDK OVS +echo -n "Start DPDK OVS..." +$OVS_PREFIX/bin/ovs_dpdk -c 0x0f -n 4 --proc-type=primary --socket-mem 1024,1024 -- -p 0x03 -n 2 -v 4 --stats=1 --client_switching_core=1 --config="(0,0,2),(1,0,3)" > ovs_dpdk.log 2>&1 & +ovs_dpdk_pid=$! + +s=0 +delta=5 +tmo=120 +while [[ $s -lt $tmo ]] +do + echo -n "." + sleep $delta + if grep --quiet "APP: Client switching core is" ovs_dpdk.log; then + echo OK! + break + fi + s=$[$s+$delta] +done + +if [ $s -lt $tmo ]; then + echo PASS: Starting DPDK vSwitch + #Start DPDK OVS daemon + echo -n "Start DPDK OVS daemon..." + $OVS_PREFIX/sbin/ovs-vswitchd -c 0x10 --proc-type=secondary > ovs-vswitchd.log 2>&1 & + ovs_vswitchd_pid=$! + s=0 + delta=5 + tmo=120 + while [[ $s -lt $tmo ]] + do + echo -n "." + sleep $delta + if grep --quiet "EAL: Master core" ovs-vswitchd.log; then + echo OK! + break + fi + s=$[$s+$delta] + done + + if [ $s -lt $tmo ]; then + echo PASS: Starting DPDK vSwitch daemon + #Cleanup flows + $OVS_PREFIX/bin/ovs-ofctl del-flows br0 + sleep 40 + + #Configure all interfaces up and promiscuous + ifconfig vEth0 up + ifconfig vEth1 up + ifconfig vEth2 up + ifconfig vEth3 up + ifconfig vEth0 promisc + #ifconfig vEth1 promisc + #ifconfig vEth2 promisc + #ifconfig vEth3 promisc + tcpdump -i vEth0 & + #tcpdump -i vEth2 & + #tcpdump -i vEth3 & + + #Start OFTest + echo -n "Start OFTest..." + cd /opt/oftest/ + ./oft -i 64@vEth0 -i 65@vEth1 -i 66@vEth2 -i 67@vEth3 flow_matches 2>&1 | \ + grep "\.\.\." | sed -r "s/(.*) ... (FAIL)/\2: \1/" | sed -r "s/(.*) ... (ok)/PASS: \1/" + + sleep 2 + echo "Kill processes..." + kill -9 $ovs_vswitchd_pid 2>&1 > /dev/null + sleep 1 + else + echo NOK! + echo FAIL: Starting DPDK vSwitch daemon + cd /opt/oftest/ + ./oft --list-test-names | sed -r "s/(.*)/SKIP: \1/" + echo "Kill processes..." + fi +else + echo NOK! + echo FAIL: Starting DPDK vSwitch + cd /opt/oftest/ + ./oft --list-test-names | sed -r "s/(.*)/SKIP: \1/" + echo "Kill processes..." +fi + +kill -9 $ovs_dpdk_pid 2>&1 > /dev/null +sleep 1 +kill -9 $ovsdb_server_pid 2>&1 > /dev/null +sleep 1 + +#bind devices to initial drivers +for ((i=0;i<${#pciarray[@]};i++)); +do + echo -n "Restoring device ${pciarray[$i]} ..." + ${PCI_UTIL} --bind=${drvarray[$i]} ${pciarray[$i]} + echo "OK!" +done + +rmmod rte_kni +rmmod igb_uio + +echo -n "Freeing hugepages..." +#Find out if this is a NUMA machine +ls /sys/devices/system/node/node* > /dev/null 2>&1 +if [ $? -ne 0 ]; then + echo $hp > /proc/sys/vm/nr_hugepages +else + i=0 + for hp in ${hparray[@]} + do + echo $hp > "/sys/devices/system/node/node${i}/hugepages/hugepages-${hp_sz}kB/nr_hugepages" + ((i++)) + done +fi +echo "OK!" +rm -rf /mnt/huge/* + +echo "Test done!" + diff --git a/recipes-test/openvswitchdpdk-oftest/openvswitchdpdk-oftest.bb b/recipes-test/openvswitchdpdk-oftest/openvswitchdpdk-oftest.bb new file mode 100644 index 0000000..e4b27d3 --- /dev/null +++ b/recipes-test/openvswitchdpdk-oftest/openvswitchdpdk-oftest.bb @@ -0,0 +1,20 @@ +SUMMARY = "DPDK vSwitch - OFTest" +DESCRIPTION = "OFTest based testing for DPDK vSwitch" +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://README;md5=6b96a2f1b1ba742aadcc58002f3e9351 \ + " +RDEPENDS_${PN} = "oftest openvswitchdpdk dpdk python-scapy" + +PR = "r0" +PV = "1.0" + +SRC_REV = "1.0-r0" +SRC_URI = "file://README \ + file://run-ptest \ + " + +S = "${WORKDIR}" +B = "${S}" + +inherit ptest + -- cgit v1.2.3-54-g00ecf