├── src ├── package │ ├── last_export_ver.vfd │ ├── vfd_debian │ │ ├── README │ │ ├── changelog │ │ ├── compat │ │ ├── rules │ │ ├── control │ │ ├── copyright │ │ ├── postinst │ │ └── postrm │ ├── vfd.exlist │ └── mk_deb.sh ├── support │ ├── tests │ │ ├── __init__.py │ │ ├── strip_vlan_disable │ │ │ ├── __init__.py │ │ │ ├── test_bcastF_mcastF_ucastF.py │ │ │ ├── test_bcastF_mcastT_ucastF.py │ │ │ ├── test_bcastT_mcastT_ucastT.py │ │ │ └── test_bcastT_mcastT_ucastF.py │ │ ├── strip_vlan_enable │ │ │ ├── __init__.py │ │ │ ├── test_bcastF_mcastF_ucastF.py │ │ │ ├── test_bcastF_mcastT_ucastF.py │ │ │ ├── test_bcastT_mcastT_ucastT.py │ │ │ └── test_bcastT_mcastT_ucastF.py │ │ ├── requirements.txt │ │ ├── parse_sample_data.py │ │ ├── helper_functions.py │ │ ├── sample_data.ini.stripT │ │ ├── sample_data.ini │ │ ├── sample_data.ini.stripF │ │ ├── README │ │ └── conftest.py │ ├── linux_scripts │ │ ├── packet.conf │ │ ├── gen_packet.py │ │ └── tcpdump_app.py │ └── dpdk_app │ │ ├── Makefile │ │ └── utils.h ├── lib │ ├── .gitignore │ ├── hot_plug_test.c │ ├── symtab.h │ ├── list_test.c │ ├── pfx_list_test.c │ ├── hot_plug.c │ ├── jwrapper_test.ksh │ ├── Makefile │ ├── id_mgr_test.c │ ├── README │ ├── mkfile │ ├── vf_config_test.c │ ├── jw_xapi.c │ ├── bleat_test.c │ ├── parm_file_test.c │ ├── LICENSE │ ├── jwrapper_test.c │ ├── id_mgr.c │ ├── filesys_test.c │ └── parm_file_test.cfg ├── vfd │ ├── README │ ├── vfd_qos.h │ ├── vfd_nl.h │ ├── vfd_bnxt.h │ ├── vfd_mlx5.h │ ├── vfd_rif.h │ ├── vfd_ixgbe.h │ ├── vfd_dcb.h │ ├── Makefile │ └── vfd_i40e.h ├── system │ ├── README │ ├── mkfile │ ├── Makefile │ ├── vfd_start.sh │ ├── vfd.conf │ └── vfd.cfg.sample ├── vfd-net │ ├── Makefile │ └── vfd-net.h ├── Makefile ├── dpdk_patches │ ├── dpdk1802-ixgbe_macvlan.patch │ ├── dpdk1805-ixgbe_macvlan.patch │ ├── README │ ├── verify_patches.ksh │ └── apply_patches.ksh └── README ├── doc ├── .gitignore ├── operations │ ├── README.md │ ├── iplex_cmd.md │ ├── main_config.md │ └── vf_config.md ├── hackers │ ├── caution.im │ ├── master.mk │ ├── mkfile │ ├── appendix_a.im │ └── figures │ │ └── vfd_process.fig ├── setup_style.im ├── debugging │ ├── README │ ├── ops_chart_append.im │ ├── mkfile │ ├── figures │ │ ├── diag_overview1.fig │ │ ├── diag_mirror1.fig │ │ └── diat_mirror1.fig │ └── strip_issue.xfm ├── qstart │ └── mkfile ├── master.mk ├── overview │ ├── mkfile │ └── figures │ │ ├── vlan_strip.fig │ │ ├── mirror_in.fig │ │ └── mirror_out.fig ├── NOTES ├── virt │ └── openstack_heat_users_guide.md └── setup_image.im ├── LICENSE └── virt └── DEPENDS.md /src/package/last_export_ver.vfd: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/package/vfd_debian/README: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/package/vfd_debian/changelog: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/support/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/lib/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.o 3 | -------------------------------------------------------------------------------- /src/package/vfd_debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_disable/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_enable/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/package/vfd_debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | %: 3 | dh $@ 4 | -------------------------------------------------------------------------------- /src/vfd/README: -------------------------------------------------------------------------------- 1 | 2 | Please see top level README, and the wiki, for details. 3 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | *.eps 2 | *.png 3 | *.ps 4 | *.html 5 | *.ecnfile 6 | *.bcnfile 7 | *.ca 8 | *.md 9 | *.pdf 10 | -------------------------------------------------------------------------------- /doc/operations/README.md: -------------------------------------------------------------------------------- 1 | 2 | #Operations Documentation 3 | 4 | The files in this directory contain documents which are needed from an operational 5 | perspective (e.g. configuration file layouts). 6 | -------------------------------------------------------------------------------- /src/system/README: -------------------------------------------------------------------------------- 1 | This directory contains system tools created to support the VF daemon 2 | (e.g. iplex). 3 | 4 | iplex is a CLI tool which talks to VF daemon 5 | 6 | iplex uses docopt library. 7 | "pip install docopt" 8 | -------------------------------------------------------------------------------- /src/vfd-net/Makefile: -------------------------------------------------------------------------------- 1 | 2 | obj-m = vfd-net.o 3 | 4 | KVERSION = $(shell uname -r) 5 | all: 6 | make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules 7 | clean: 8 | make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean 9 | -------------------------------------------------------------------------------- /src/system/mkfile: -------------------------------------------------------------------------------- 1 | # mk; better than make every day. 2 | 3 | libs = -L../lib -lvfd 4 | vfd_req:: vreq.c ../lib/libvfd.a 5 | gcc -I ../lib ${prereq%% *} -o $target $libs 6 | 7 | clean:V: 8 | rm -f *.o 9 | 10 | nuke:V: 11 | rm -f vreq *.o 12 | -------------------------------------------------------------------------------- /src/system/Makefile: -------------------------------------------------------------------------------- 1 | #mk; is better than make, but if you insist this might work too 2 | 3 | libs = -L../lib -lvfd 4 | vreq_req: vreq.c ../lib/libvfd.a 5 | gcc -I ../lib vreq.c -o vfd_req $(libs) 6 | 7 | clean:: 8 | rm -f *.o vreq 9 | 10 | nuke:: 11 | rm -f *.o vreq 12 | -------------------------------------------------------------------------------- /src/package/vfd.exlist: -------------------------------------------------------------------------------- 1 | src/vfd/build/app/vfd usr/bin/ 2 | src/system/iplex usr/bin/ 3 | src/system/vfd.conf etc/init/ 4 | src/system/dpdk_nic_bind usr/bin/ 5 | src/system/vfd.cfg.sample etc/vfd/ 6 | src/system/vfd_pre_start usr/bin/ 7 | src/system/vfd_req usr/local/bin/ 8 | -------------------------------------------------------------------------------- /src/package/vfd_debian/control: -------------------------------------------------------------------------------- 1 | Source: attlrvfd 2 | Section: misc 3 | Priority: optional 4 | Maintainer: Dhanunjaya Naidu Ravada 5 | Package: attlrvfd 6 | Version: 7 | Architecture: amd64 8 | Depends: python-docopt 9 | Installed-Size: 2048 10 | Description: VFD is a daemon which is used to configures NIC VF's 11 | -------------------------------------------------------------------------------- /src/support/tests/requirements.txt: -------------------------------------------------------------------------------- 1 | asn1crypto==0.22.0 2 | bcrypt==3.1.3 3 | cffi==1.10.0 4 | cryptography>=2.3 5 | enum34==1.1.6 6 | idna==2.5 7 | ipaddress==1.0.18 8 | paramiko==2.2.4 9 | pcapy==0.11.1 10 | py==1.10.0 11 | pyasn1==0.3.1 12 | pycparser==2.18 13 | PyNaCl==1.1.2 14 | pytest==3.0.7 15 | scapy>=2.4.1 16 | six==1.10.0 17 | -------------------------------------------------------------------------------- /src/system/vfd_start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | PCIID="0000:07:00.0 0000:07:00.1" 6 | 7 | MOD=vfio 8 | DRV=vfio-pci 9 | NUM_VFS=4 10 | 11 | modprobe $MOD 12 | modprobe $DRV 13 | 14 | 15 | for i in $PCIID 16 | do 17 | 18 | echo ${NUM_VFS} > /sys/bus/pci/devices/${i}/sriov_numvfs 19 | /home/alexz/dpdk/tools/dpdk_nic_bind.py -b ${DRV} $i 20 | 21 | done 22 | -------------------------------------------------------------------------------- /doc/hackers/caution.im: -------------------------------------------------------------------------------- 1 | 2 | .ln 3 | CAUTION: .br 4 | This document is generated output from {X}fm source. Any modifications made to this file 5 | will certainly be overlaid by subsequent revisions. The proper way of maintaining the 6 | document is to modify the source file(s) in the repo, and generating the desired .pdf or ^.md 7 | versions of the document using {X}fm. 8 | .ln 9 | -------------------------------------------------------------------------------- /src/support/linux_scripts/packet.conf: -------------------------------------------------------------------------------- 1 | # interface,src_mac,dst_mac,src_ip,dst_ip,protocol,dst_port/optional,vlan_id/optional 2 | # optional = None 3 | ################################ 4 | # PACKET GENERATOR "mz" tool # 5 | ################################ 6 | vlan0,a0:36:9f:7d:4d:98,72:2a:7a:27:fb:51,192.168.14.20,192.168.14.101,udp,1234,10 7 | #enp8s0f1,a0:36:9f:7d:4d:9a,82:70:73:23:48:29,192.168.15.20,192.168.15.101,icmp,None,11 8 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # Top level Makefile that would use the functionality of existing makefiles 2 | # inside the lib and vfd directory. This file would build the libraries and the 3 | # vfd source. 4 | all: 5 | (cd lib; make jsmn && make libvfd.a) 6 | (cd vfd; make clean && make) 7 | (cd system; make clean && make) 8 | 9 | clean: 10 | (cd vfd; make clean) 11 | (cd lib; make nuke) 12 | (cd system; make nuke) 13 | (cd lib/jsmn; make clean) 14 | -------------------------------------------------------------------------------- /doc/setup_style.im: -------------------------------------------------------------------------------- 1 | 2 | body { background-color:white; color:black; font-size:1em; font-family:sans-serif } 3 | h1 { font-size:1.75em; font-family:sans-serif; border-top: 1px solid #909090; margin-top:2em; margin-bottom:1em } 4 | h2 { font-size:1.4em; font-family:sans-serif; margin-top:1.3em; margin-bottom:0.25em } 5 | h3 { font-size:1.15em; font-family:sans-serif; margin-top:1.2em; margin-bottom:0em } 6 | h4 { font-size:1em; font-family:sans-serif; margin-top:1em; margin-bottom:0em } 7 | 8 | -------------------------------------------------------------------------------- /doc/hackers/master.mk: -------------------------------------------------------------------------------- 1 | # master makefile for inclusion 2 | 3 | %.eps: %.fig 4 | fig2dev -L eps ${prereq} ${target} 5 | 6 | %_slides : %_slides.xfm 7 | pfm -g 8ix11i ${prereq%% *} $target.ps 8 | 9 | %.ps : %.xfm 10 | pfm ${prereq%% *} $target 11 | 12 | %.html : %.xfm 13 | hfm ${prereq%% *} $target 14 | 15 | %.pdf : %.ps 16 | gs -I/usr/local/share/ghostscript/fonts -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=$target ${prereq% *} 17 | 18 | %.txt : %.xfm 19 | tfm ${prereq%% *} $target 20 | 21 | -------------------------------------------------------------------------------- /src/support/dpdk_app/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(RTE_SDK),) 2 | $(error "Please define RTE_SDK environment variable") 3 | endif 4 | 5 | # Default target, can be overriden by command line or environment 6 | RTE_TARGET ?= x86_64-native-linuxapp-gcc 7 | 8 | include $(RTE_SDK)/mk/rte.vars.mk 9 | 10 | # binary name 11 | APP = ifrate 12 | 13 | # all source are stored in SRCS-y 14 | SRCS-y := ifrate.c utils.c 15 | 16 | CFLAGS += -O3 17 | CFLAGS += $(WERROR_FLAGS) 18 | 19 | include $(RTE_SDK)/mk/rte.extapp.mk 20 | 21 | clean: 22 | rm -rf build/* 23 | -------------------------------------------------------------------------------- /src/dpdk_patches/dpdk1802-ixgbe_macvlan.patch: -------------------------------------------------------------------------------- 1 | --- a/drivers/net/ixgbe/ixgbe_pf.c 2018-01-17 21:10:53.027638657 +0000 2 | +++ b/drivers/net/ixgbe/ixgbe_pf.c 2018-01-17 21:19:49.258188159 +0000 3 | @@ -784,6 +784,10 @@ 4 | if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) 5 | retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf); 6 | break; 7 | + case IXGBE_VF_SET_MACVLAN: 8 | + if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) 9 | + retval = 0; 10 | + break; 11 | default: 12 | PMD_DRV_LOG(DEBUG, "Unhandled Msg %8.8x", (unsigned)msgbuf[0]); 13 | retval = IXGBE_ERR_MBX; 14 | -------------------------------------------------------------------------------- /src/dpdk_patches/dpdk1805-ixgbe_macvlan.patch: -------------------------------------------------------------------------------- 1 | --- a/drivers/net/ixgbe/ixgbe_pf.c 2018-01-17 21:10:53.027638657 +0000 2 | +++ b/drivers/net/ixgbe/ixgbe_pf.c 2018-01-17 21:19:49.258188159 +0000 3 | @@ -784,6 +784,10 @@ 4 | if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) 5 | retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf); 6 | break; 7 | + case IXGBE_VF_SET_MACVLAN: 8 | + if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) 9 | + retval = 0; 10 | + break; 11 | default: 12 | PMD_DRV_LOG(DEBUG, "Unhandled Msg %8.8x", (unsigned)msgbuf[0]); 13 | retval = IXGBE_ERR_MBX; 14 | -------------------------------------------------------------------------------- /src/lib/hot_plug_test.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Mneminic: hot_plug_test.c 4 | Abstract: Unit test for the hot-plug functions. 5 | Date: 26 May 2016 6 | Author: E. Scott Daniels 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "vfdlib.h" 17 | 18 | int main( int argc, char** argv ) { 19 | int rc; 20 | 21 | if( argc < 3 ) { 22 | fprintf( stderr, "usage: %s user-id command string\n", argv[0] ); 23 | exit( 1 ); 24 | } 25 | 26 | rc = user_cmd( atoi( argv[1] ), argv[2] ); 27 | fprintf( stderr, "rc from detach: %d\n", rc ); 28 | 29 | exit( rc ); // bad exit if we failed a test 30 | } 31 | -------------------------------------------------------------------------------- /src/support/tests/parse_sample_data.py: -------------------------------------------------------------------------------- 1 | from ConfigParser import ConfigParser 2 | 3 | # This will return sample data object 4 | def sample_data_obj(): 5 | data = ConfigParser() 6 | data.read("sample_data.ini") 7 | return data 8 | 9 | # return section dict object 10 | def section_map(section): 11 | dict_obj = {} 12 | options = sample_data_obj().options(section) 13 | for opt in options: 14 | try: 15 | dict_obj[opt] = sample_data_obj().get(section, opt) 16 | except: 17 | dict_obj[opt] = None 18 | return dict_obj 19 | 20 | if __name__ == '__main__': 21 | dict_obj = section_map('TARGET_VF1') 22 | print [mac.strip() for mac in dict_obj['valid_vlans'].strip().split(',')] 23 | -------------------------------------------------------------------------------- /doc/debugging/README: -------------------------------------------------------------------------------- 1 | 2 | This directory contains source for various documents that 3 | relate to debugging packet flow to/from SR-IOV guests 4 | using VFs managed by VFd. 5 | 6 | Documents are compiled into PDF, and markdown output. The 7 | markdown output is placed into the VFd wiki: 8 | 9 | 1) clone the wiki 10 | git clone https://github.com/att/vfd.wiki.git 11 | 12 | 2) switch to the vfd.wiki directory 13 | 14 | 3) copy in the updated markdown file, or add a new 15 | one if it wasn't a part of the wiki 16 | 17 | 4) commit and push the changes 18 | 19 | 20 | The document name in the wiki repo should be of the form 21 | Foo-Bar-Is-Good.md where the dashes (-) will be replaced 22 | on the wiki table of contents making an easily read title. 23 | 24 | -------------------------------------------------------------------------------- /src/support/tests/helper_functions.py: -------------------------------------------------------------------------------- 1 | from tests.packet import Packet 2 | from tests.parse_sample_data import section_map 3 | 4 | # global dict to hold config 5 | config = {} 6 | 7 | def read_sample_data(target_vf): 8 | config['smac'] = section_map('PG')['mac'] 9 | config['iface'] = section_map('PG')['iface'] 10 | config['mcast_mac'] = section_map(target_vf)['mcast_mac'] 11 | config['bcast_mac'] = section_map(target_vf)['bcast_mac'] 12 | 13 | def build_packet(**options): 14 | pkt = Packet(pkt_type='VLAN_UDP') 15 | pkt.config_layer('ether', {'dst': options['dmac'], 'src': config['smac']}) 16 | pkt.config_layer('ipv4', {'dst': '1.1.1.1', 'src': '2.2.2.2'}) 17 | pkt.config_layer('vlan', {'vlan': options['valid_vlan']}) 18 | return pkt 19 | -------------------------------------------------------------------------------- /src/package/vfd_debian/copyright: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------- 2 | Copyright (c) 2016 AT&T Intellectual Property 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at: 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | --------------------------------------------------------------------------- 16 | -------------------------------------------------------------------------------- /doc/debugging/ops_chart_append.im: -------------------------------------------------------------------------------- 1 | 2 | &h1( Appendix &app_letter -- Dianosis Flow Charts ) 3 | 4 | The following flow chart is intended to provide a logical sequence of 5 | steps while attempting to diagnose the problem where a guest application 6 | is unable to send and/or receive packets using one or more SR-IOV 7 | devices. 8 | In geneeral, process boxes with a orange exiting arrow imply a question 9 | of &ital( problem still exists ) along that path; if the answer is &ital( No, ) 10 | then following through the chart ceases at that point, and continues when the 11 | answer is &ital( Yes. ) 12 | Process boxes which have an exiting black arrow indicate an unconditional 13 | flow into the next element. 14 | 15 | 16 | &image( figures/flow1.eps x=.25i close proportional : 6 : Basic diagnostic flow chart. : &{image_url_base}/flow1.png) 17 | 18 | -------------------------------------------------------------------------------- /doc/qstart/mkfile: -------------------------------------------------------------------------------- 1 | 2 | # plan9 style mk 3 | 4 | <../master.mk 5 | 6 | fig_src = 7 | 8 | all:V: vfd_quick_start.pdf vfd_quick_start.md vfd_quick_start.html 9 | 10 | #figures:V: ${fig_src:%=figures/%.eps} 11 | #images:V: ${fig_src:%=figures/%.png} 12 | 13 | vfd_quick_start.html:: ../setup.im quick_start.xfm 14 | hfm quick_start.xfm vfd_quick_start.html 15 | 16 | vfd_quick_start.ps:: ../setup.im quick_start.xfm 17 | pfm quick_start.xfm vfd_quick_start.ps 18 | 19 | vfd_quick_start.md:: ../setup.im quick_start.xfm 20 | MARKDOWN=1 tfm quick_start.xfm vfd_quick_start.o 21 | sed 's/^ //' vfd_quick_start.o >vfd_quick_start.md 22 | rm vfd_quick_start.o 23 | 24 | # ditch _everything_ that can be rebuilt 25 | nuke:V: clean 26 | rm -f *.ps *.pdf *.md 27 | 28 | # ditch only intermediates and tmp files 29 | clean:V: 30 | rm -f *.ecnfile *.bcnfile *.ca *.sp 31 | -------------------------------------------------------------------------------- /src/package/vfd_debian/postinst: -------------------------------------------------------------------------------- 1 | echo "running attlrvfd post initialisation..." 2 | 3 | if [ ! -d /etc/vfd ] 4 | then 5 | mkdir -p /etc/vfd 6 | fi 7 | 8 | if [ $? -ne 0 ] 9 | then 10 | echo "unable to create /etc/vfd " 11 | exit 0 12 | fi 13 | 14 | if [ ! -d /var/log/vfd ] 15 | then 16 | mkdir -p /var/log/vfd 17 | fi 18 | 19 | if [ $? -ne 0 ] 20 | then 21 | echo "unable to create /var/log/vfd " 22 | exit 0 23 | fi 24 | 25 | if [ ! -d /var/lib/vfd/config ] 26 | then 27 | mkdir -p /var/lib/vfd/config 28 | fi 29 | 30 | if [ $? -ne 0 ] 31 | then 32 | echo "unable to create /var/lib/vfd/config " 33 | exit 0 34 | fi 35 | 36 | if [ -f /etc/vfd/vfd.cfg.sample ] 37 | then 38 | chmod 0644 /etc/vfd/vfd.cfg.sample 39 | fi 40 | 41 | if [ $? -ne 0 ] 42 | then 43 | echo "no file found /etc/vfd/vfd.cfg.sample" 44 | fi 45 | 46 | echo "post initialisation completed" 47 | -------------------------------------------------------------------------------- /src/package/vfd_debian/postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | case "$1" in 4 | remove) 5 | if [ -d /var/log/vfd ]; then 6 | echo "leaving logs in /var/log/vfd for historical purposes" 7 | fi 8 | 9 | if [ -d /etc/vfd ]; then 10 | echo "leaving vfd configuration in /etc/vfd for historical purposes" 11 | fi 12 | ;; 13 | 14 | purge) 15 | if [ -f /etc/init/vfd.conf ]; then 16 | rm -f /etc/init/vfd.conf 17 | rmdir --ignore-fail-on-non-empty /etc/vfd/ 18 | fi 19 | 20 | if [ -d /var/log/vfd ]; then 21 | rm -rf /var/log/vfd 22 | fi 23 | 24 | if [ -d /var/lib/vfd ]; then 25 | rm -rf /var/lib/vfd 26 | fi 27 | 28 | if [ -d /etc/vfd ]; then 29 | rm -rf /etc/vfd/vfd.conf 30 | fi 31 | ;; 32 | 33 | upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) 34 | ;; 35 | 36 | *) 37 | echo "postrm called with unknown argument '$1'" >&2 38 | exit 1 39 | ;; 40 | esac 41 | -------------------------------------------------------------------------------- /doc/hackers/mkfile: -------------------------------------------------------------------------------- 1 | # plan9 mk 2 | 3 | # NOTE: 4 | # this requires fig2dev to be installed which is used to xlate Xfig figures to .eps format for pfm 5 | # It's possible to generate markdown without this as no figures are required for markdown 6 | 7 | vfd_hackers.md 27 | rm vfd_hackers.o 28 | 29 | clean:V: 30 | rm -f *.ps *.sp figures/*.eps *.ca *.ecnfile *.bcnfile 31 | -------------------------------------------------------------------------------- /doc/master.mk: -------------------------------------------------------------------------------- 1 | # master makefile for inclusion 2 | 3 | # install transfig package to get fig2dev 4 | %.eps: %.fig 5 | fig2dev -L eps ${prereq} ${target} 6 | 7 | %.png: %.fig 8 | fig2dev -L png ${prereq} ${target} 9 | 10 | %.png: %.fig 11 | fig2dev -L png ${prereq} ${target} 12 | 13 | 14 | %_slides : %_slides.xfm 15 | pfm -g 8ix11i ${prereq%% *} $target.ps 16 | 17 | %.ps : %.xfm 18 | pfm ${prereq%% *} $target 19 | 20 | %.html : %.xfm 21 | hfm ${prereq%% *} $target 22 | 23 | %.pdf : %.ps 24 | gs -I/usr/local/share/ghostscript/fonts -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=$target ${prereq% *} 25 | 26 | %.txt : %.xfm 27 | tfm ${prereq%% *} $target 28 | 29 | # generate into a temporary file, then strip first column blank 30 | # because markdown is bloody space sensitive. 31 | # 32 | %.md:: %.xfm 33 | MARKDOWN=1 tfm ${prereq##* } mdtf.o 34 | sed 's/^ //' mdtf.o >$target 35 | rm -f mdtf.o 36 | 37 | 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | This licence applies to all files in this repository unless otherwise specifically 3 | stated inside of the file. 4 | 5 | --------------------------------------------------------------------------- 6 | Copyright (c) 2016 AT&T Intellectual Property 7 | 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at: 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | --------------------------------------------------------------------------- 20 | -------------------------------------------------------------------------------- /doc/overview/mkfile: -------------------------------------------------------------------------------- 1 | 2 | # plan9 mk 3 | 4 | <../master.mk 5 | 6 | fig_src = overview mirror_out mirror_in vlan_strip 7 | 8 | all:V: vfd_overview.pdf vfd_overview.md vfd_overview.html vfd_overview.txt figures 9 | 10 | figures:V: ${fig_src:%=figures/%.eps} 11 | images:V: ${fig_src:%=figures/%.png} 12 | 13 | vfd_overview.html:: ../setup.im overview.xfm figures 14 | hfm overview.xfm vfd_overview.html 15 | 16 | vfd_overview.ps:: ../setup.im overview.xfm figures 17 | pfm overview.xfm vfd_overview.ps 18 | 19 | vfd_overview.txt:: ../setup.im overview.xfm figures 20 | MARKDOWN=0 tfm overview.xfm vfd_overview.txt 21 | 22 | vfd_overview.md:: ../setup.im overview.xfm figures 23 | MARKDOWN=1 tfm overview.xfm vfd_overview.o 24 | sed 's/^ //' vfd_overview.o >vfd_overview.md 25 | rm vfd_overview.o 26 | 27 | # ditch _everything_ that can be rebuilt 28 | nuke:V: clean 29 | rm -f *.ps *.pdf *.md 30 | 31 | # ditch only intermediates and tmp files 32 | clean:V: 33 | rm -f *.ecnfile *.bcnfile *.ca *.sp 34 | -------------------------------------------------------------------------------- /virt/DEPENDS.md: -------------------------------------------------------------------------------- 1 | 2 | #Depenencies 3 | The following are known depenencies of patches which are contained in this directory. 4 | 5 | init-system-helpers 6 | 1.18~bpo70+1~u14.04+mos1 1.14 7 | 8 | libjs-sphinxdoc 9 | 1.3.1-6~u14.04+mos3 1.2.2+dfsg-1ubuntu 10 | 11 | libmysqlclient18:amd64 12 | 5.5.47-0ubuntu0.14.04.1 5.5.49-0ubuntu0.14 13 | 14 | libnl-3-200:amd64 15 | 3.2.24-2 3.2.21-1 16 | 17 | libnl-genl-3-200:amd64 18 | 3.2.24-2 3.2.21-1 19 | 20 | libnl-route-3-200:amd64 21 | 3.2.24-2 3.2.21-1 22 | 23 | libnss3:amd64 24 | 2:3.19.2.1-0ubuntu0.14.04.2 2:3.21-0ubuntu0.14 25 | 26 | libnss3-nssdb 27 | 2:3.19.2.1-0ubuntu0.14.04.2 2:3.21-0ubuntu0.14 28 | 29 | librados2 30 | 0.94.6-1~u14.04+mos1 0.94.6-0ubuntu0.15 31 | 32 | librbd1 33 | 0.94.6-1~u14.04+mos1 0.94.6-0ubuntu0.15 34 | 35 | libudev1:amd64 36 | 204-5ubuntu20.19 204-5ubuntu20.18 37 | 38 | libvirt0 39 | 1.2.9.3-9~u14.04+mos10 1.2.12-0ubuntu14.4 40 | 41 | libvirt-bin 42 | 1.2.9.3-9~u14.04+mos10 1.2.12-0ubuntu14.4 43 | 44 | -------------------------------------------------------------------------------- /doc/debugging/mkfile: -------------------------------------------------------------------------------- 1 | 2 | # plan9 mk 3 | 4 | <../master.mk 5 | 6 | # ops_trouble figures 7 | ot_fig_src = diag_mirror1 diag_overview1 diat_mirror1 flow1 8 | 9 | 10 | all:V: png_figures eps_figures vfd_debug.pdf vfd_debug.md strip_issue.pdf strip_issue.md ops_trouble.pdf ops_trouble.md 11 | 12 | eps_figures:V: ${ot_fig_src:%=figures/%.eps} 13 | png_figures:V: ${ot_fig_src:%=figures/%.png} 14 | 15 | strip_issue.ps:: ../setup.im strip_issue.xfm 16 | pfm strip_issue.xfm strip_issue.ps 17 | 18 | strip_issue.md:: ../setup.im strip_issue.xfm 19 | MARKDOWN=1 tfm strip_issue.xfm strip_issue.o 20 | sed 's/^ //' strip_issue.o >vfd_strip_issue.md 21 | rm strip_issue.o 22 | 23 | vfd_debug.ps:: ../setup.im debug.xfm 24 | pfm debug.xfm vfd_debug.ps 25 | 26 | vfd_debug.md:: ../setup.im debug.xfm 27 | MARKDOWN=1 tfm debug.xfm vfd_debug.o 28 | sed 's/^ //' vfd_debug.o >vfd_debug.md 29 | rm vfd_debug.o 30 | 31 | ops_trouble.ps:: ../setup.im figures ops_trouble.xfm 32 | pfm ${prereq##* } $target 33 | 34 | ops_trouble.md:: ../setup.im figures ops_chart_append.im ops_trouble.xfm 35 | -------------------------------------------------------------------------------- /src/lib/symtab.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* --------- symtab ---------------- */ 4 | #define UT_FL_NOCOPY 0x00 /* use user pointer */ 5 | #define UT_FL_COPY 0x01 /* make a copy of the string data */ 6 | #define UT_FL_FREE 0x02 /* free val when deleting */ 7 | 8 | 9 | /* ------------ symtab ----------------------------- */ 10 | extern void sym_clear( void *s ); 11 | extern void sym_dump( void *s ); 12 | extern void *sym_alloc( int size ); 13 | extern void sym_del( void *s, const char *name, unsigned int class ); 14 | extern void sym_free( void *vtable ); 15 | extern int sym_fmap( void *vtable, const char *name, unsigned int class, void *val ); 16 | extern void *sym_get( void *s, const char *name, unsigned int class ); 17 | extern int sym_put( void *s, const char *name, unsigned int class, void *val ); 18 | extern int sym_map( void *s, const char *name, unsigned int class, void *val ); 19 | extern void sym_stats( void *s, int level ); 20 | //extern void sym_foreach_class( void *st, unsigned int space, void (* user_fun)(), void *user_data ); 21 | extern void sym_foreach_class( void *vst, unsigned int space, void (* user_fun)( void*, void*, const char*, void*, void* ), void *user_data ); 22 | -------------------------------------------------------------------------------- /src/lib/list_test.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Mneminic: list_test.c 4 | Abstract: Unit test for the list module. 5 | Tests obvious things, may miss edge cases. 6 | 7 | Parms: directory suffix [suffix...] 8 | Date: 08 March 2016 9 | Author: E. Scott Daniels 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "vfdlib.h" 21 | 22 | 23 | int main( int argc, char** argv ) { 24 | int i; 25 | int j; 26 | char** list; 27 | int llen; 28 | 29 | if( argv[1] == NULL ) { 30 | fprintf( stderr, "usage: %s dir-name suffix1 [suffix2...]\n", argv[0] ); 31 | exit( 1 ); 32 | } 33 | 34 | for( i = 2; i < argc; i++ ) { 35 | list = list_files( argv[1], argv[i], 1, &llen ); 36 | if( list != NULL ) { 37 | fprintf( stderr, "list contains %d entries\n", llen ); 38 | for( j = 0; j < llen; j++ ) { 39 | if( list[j] ) { 40 | fprintf( stderr, "[%d] %s\n", j, list[j] ); 41 | } else { 42 | fprintf( stderr, "[%d] NULL\n", j ); 43 | } 44 | } 45 | 46 | } else { 47 | fprintf( stderr, "list was null: %s\n", strerror( errno ) ); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/vfd/vfd_qos.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mnemonic: qos.h 3 | Abstract: Headers specifically for the qos (hard coded) implementation. 4 | As these (if these?) ever make it to DPDK, then this file should 5 | go the way of the dodo. 6 | Author: E. Scott Daniels 7 | Date: 26 Augusg 2016 8 | */ 9 | 10 | #ifndef _VFD_QOS_H 11 | #define _VFD_QOS_H 12 | // traffic class related flags 13 | #define QOS_TCFL_GSP 0x01 // group strict priority (the actual value of each of these is VERY SIGNIFICANT!) 14 | #define QOS_TCFL_LSP 0x02 // link strict priority 15 | 16 | /* 17 | Manages the various things that can be configured for a traffic class. 18 | This struct is passed from the main application into the qos functions. 19 | */ 20 | typedef struct { 21 | uint32_t bw_group; // bandwidth group the TC is assigned to 22 | uint32_t max_credits; // max credits the TC is allowed to cary 23 | uint32_t credit_refil; // the number of credits refilled on each cycle 24 | uint8_t flags; // QOS_FL constants for link and group strict priority 25 | } qos_tc_t; 26 | 27 | 28 | 29 | // ------------ prototypes ------------------------------------------------------------- 30 | 31 | extern int enable_dcb_qos( sriov_port_t *port, int* pctgs, int tc8_mode, int option ); 32 | 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/dpdk_patches/README: -------------------------------------------------------------------------------- 1 | 2 | This directory contains patches that must be applied against DPDK in order to 3 | support VFd. These patches, along with the command(s) to apply them to DPDK 4 | should be described below. Patches will be removed from this directory when 5 | they are available in the current DPDK release. 6 | 7 | We assume that VFD_SRC is the path to the VFd src directory. 8 | 9 | dpdk-ixgbe_pf_host_configure.patch 10 | This patch prevents the PF code in DPDK from returning a failure indication when a 11 | set macvlan callback is made. This is a work around; the final fix in DPDK will be 12 | more complex 13 | 14 | cd $RTE_SDK 15 | git apply --ignore-whitespace $VFD_PATH/dpdk_patches/dpdk-ixgbe_pf_host_configure.patch 16 | 17 | Starting in 2018, patches will be named with a leading dpdk- to indicate 18 | the release year and month (dpdk) that the patch applies to. Patches will be 19 | removed after a bit of time, but should allow for the regression of dpdk by 20 | a couple of releases in order to evaluate VFd code against older DPDK versions 21 | if necessary. 22 | 23 | dpdk 1802 patches: 24 | dpdk1802-ixgbe_macvlan.patch 25 | This patch prevents RX hang for ixgbe controlled devices 26 | 27 | cd $RTE_SDK 28 | git apply --ignore-whitespace $VFD_PATH/dpdk_patches/dpdk1802-ixgbe_macvlan.patch 29 | 30 | -------------------------------------------------------------------------------- /doc/operations/iplex_cmd.md: -------------------------------------------------------------------------------- 1 | #Iplex Commandline Interface 2 | 3 | Iplex is the command line tool which is used to communicate with VFd. 4 | Commands such as add a VF, delete a VF, show status are supported. 5 | The following describes the command line options and parameters for iplex. 6 | 7 | ``` 8 | python iplex.py --help 9 | iplex 10 | Usage: 11 | iplex {add | delete} [--loglevel=] [--debug] 12 | iplex show {|all} [--loglevel=] [--debug] 13 | iplex -h | --help 14 | iplex --version 15 | Options: 16 | -h, --help show this help message and exit 17 | --version show version and exit 18 | --debug show debugging output 19 | --loglevel= Default logvalue [default: 0]python iplex.py --help 20 | iplex 21 | Usage: 22 | iplex {add | delete} [--loglevel=] [--debug] 23 | iplex show {|all} [--loglevel=] [--debug] 24 | iplex -h | --help 25 | iplex --version 26 | Options: 27 | -h, --help show this help message and exit 28 | --version show version and exit 29 | --debug show debugging output 30 | --loglevel= Default logvalue [default: 0] 31 | ``` 32 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_disable/test_bcastF_mcastF_ucastF.py: -------------------------------------------------------------------------------- 1 | from tests import packet 2 | import tests.helper_functions as hf 3 | import pytest 4 | 5 | @pytest.mark.valid_vlan_bcastF_mcastF_ucastF 6 | def test_mcast_valid_vlan(vf3_valid_vlan): 7 | hf.read_sample_data('TARGET_VF3') 8 | pkt = hf.build_packet(dmac=hf.config['mcast_mac'], valid_vlan=int(vf3_valid_vlan)) 9 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 10 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 11 | pkts = packet.load_sniff_packets(inst) 12 | vlan = None 13 | for pkt in pkts: 14 | vlan = pkt.pktgen.strip_vlan('vlan') 15 | break 16 | assert vlan == None 17 | 18 | @pytest.mark.invalid_vlan_bcastF_mcastF_ucastF 19 | def test_mcast_invalid_vlan(vf3_invalid_vlan): 20 | hf.read_sample_data('TARGET_VF3') 21 | pkt = hf.build_packet(dmac=hf.config['mcast_mac'], valid_vlan=int(vf3_invalid_vlan)) 22 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 23 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 24 | pkts = packet.load_sniff_packets(inst) 25 | vlan = None 26 | for pkt in pkts: 27 | vlan = pkt.pktgen.strip_vlan('vlan') 28 | break 29 | assert vlan == None 30 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_disable/test_bcastF_mcastT_ucastF.py: -------------------------------------------------------------------------------- 1 | from tests import packet 2 | import tests.helper_functions as hf 3 | import pytest 4 | 5 | @pytest.mark.valid_vlan_bcastF_mcastT_ucastF 6 | def test_bcast_valid_vlan(vf2_valid_vlan): 7 | hf.read_sample_data('TARGET_VF2') 8 | pkt = hf.build_packet(dmac=hf.config['bcast_mac'], valid_vlan=int(vf2_valid_vlan)) 9 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 10 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 11 | pkts = packet.load_sniff_packets(inst) 12 | vlan = None 13 | for pkt in pkts: 14 | vlan = pkt.pktgen.strip_vlan('vlan') 15 | break 16 | assert vlan == None 17 | 18 | @pytest.mark.invalid_vlan_bcastF_mcastT_ucastF 19 | def test_bcast_invalid_vlan(vf2_invalid_vlan): 20 | hf.read_sample_data('TARGET_VF2') 21 | pkt = hf.build_packet(dmac=hf.config['bcast_mac'], valid_vlan=int(vf2_invalid_vlan)) 22 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 23 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 24 | pkts = packet.load_sniff_packets(inst) 25 | vlan = None 26 | for pkt in pkts: 27 | vlan = pkt.pktgen.strip_vlan('vlan') 28 | break 29 | assert vlan == None 30 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_enable/test_bcastF_mcastF_ucastF.py: -------------------------------------------------------------------------------- 1 | from tests import packet 2 | import tests.helper_functions as hf 3 | import pytest 4 | 5 | @pytest.mark.valid_vlan_bcastF_mcastF_ucastF 6 | def test_mcast_valid_vlan(vf3_valid_vlan): 7 | hf.read_sample_data('TARGET_VF3') 8 | pkt = hf.build_packet(dmac=hf.config['mcast_mac'], valid_vlan=int(vf3_valid_vlan)) 9 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 10 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 11 | pkts = packet.load_sniff_packets(inst) 12 | vlan = None 13 | for pkt in pkts: 14 | vlan = pkt.pktgen.strip_vlan('vlan') 15 | break 16 | assert vlan == None 17 | 18 | @pytest.mark.invalid_vlan_bcastF_mcastF_ucastF 19 | def test_mcast_invalid_vlan(vf3_invalid_vlan): 20 | hf.read_sample_data('TARGET_VF3') 21 | pkt = hf.build_packet(dmac=hf.config['mcast_mac'], valid_vlan=int(vf3_invalid_vlan)) 22 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 23 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 24 | pkts = packet.load_sniff_packets(inst) 25 | vlan = None 26 | for pkt in pkts: 27 | vlan = pkt.pktgen.strip_vlan('vlan') 28 | break 29 | assert vlan == None 30 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_enable/test_bcastF_mcastT_ucastF.py: -------------------------------------------------------------------------------- 1 | from tests import packet 2 | import tests.helper_functions as hf 3 | import pytest 4 | 5 | @pytest.mark.valid_vlan_bcastF_mcastT_ucastF 6 | def test_bcast_valid_vlan(vf2_valid_vlan): 7 | hf.read_sample_data('TARGET_VF2') 8 | pkt = hf.build_packet(dmac=hf.config['bcast_mac'], valid_vlan=int(vf2_valid_vlan)) 9 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 10 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 11 | pkts = packet.load_sniff_packets(inst) 12 | vlan = None 13 | for pkt in pkts: 14 | vlan = pkt.pktgen.strip_vlan('vlan') 15 | break 16 | assert vlan == None 17 | 18 | @pytest.mark.invalid_vlan_bcastF_mcastT_ucastF 19 | def test_bcast_invalid_vlan(vf2_invalid_vlan): 20 | hf.read_sample_data('TARGET_VF2') 21 | pkt = hf.build_packet(dmac=hf.config['bcast_mac'], valid_vlan=int(vf2_invalid_vlan)) 22 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 23 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 24 | pkts = packet.load_sniff_packets(inst) 25 | vlan = None 26 | for pkt in pkts: 27 | vlan = pkt.pktgen.strip_vlan('vlan') 28 | break 29 | assert vlan == None 30 | -------------------------------------------------------------------------------- /src/lib/pfx_list_test.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Mneminic: pfx_list_test.c 4 | Abstract: Unit test for the prefix list files function. 5 | Tests obvious things, may miss edge cases. 6 | Date: 02 June 2016 7 | Author: E. Scott Daniels 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "vfdlib.h" 19 | 20 | 21 | int main( int argc, char** argv ) { 22 | int i; 23 | int j; 24 | char** list; 25 | int llen; 26 | 27 | if( argv[1] == NULL ) { 28 | fprintf( stderr, "usage: %s directory prefix-string1 [prefix2...]\n", argv[0] ); 29 | exit( 1 ); 30 | } 31 | 32 | for( i = 2; i < argc; i++ ) { 33 | list = list_pfiles( argv[1], argv[i], 10, &llen ); // 10 tests the ability to properly set the flag 34 | if( list != NULL ) { 35 | fprintf( stderr, "list contains %d entries\n", llen ); 36 | for( j = 0; j < llen; j++ ) { 37 | if( list[j] ) { 38 | fprintf( stderr, "[%d] %s\n", j, list[j] ); 39 | } else { 40 | fprintf( stderr, "[%d] NULL\n", j ); 41 | } 42 | } 43 | 44 | free_list( list, llen ); 45 | fprintf( stderr, "\n" ); 46 | } else { 47 | fprintf( stderr, "list was null: %s\n", strerror( errno ) ); 48 | } 49 | } 50 | 51 | fprintf( stderr, "test complete\n" ); 52 | } 53 | -------------------------------------------------------------------------------- /src/vfd/vfd_nl.h: -------------------------------------------------------------------------------- 1 | // vi: sw=4 ts=4 noet: 2 | /* 3 | Mnemonic: vfd_nl.h 4 | Abstract: Main header file for netlonk related stuff. 5 | 6 | Date: October 2017 7 | Authors: Alex Zelezniak (original code) 8 | E. Scott Daniels 9 | 10 | 11 | */ 12 | 13 | #ifndef _VFD_NL_H_ 14 | #define _VFD_NL_H_ 15 | 16 | 17 | #define _GNU_SOURCE 18 | 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | #include "sriov.h" 42 | #include "../vfd-net/vfd-net.h" 43 | 44 | 45 | // -------------------------------------------------------------------------------------- 46 | #define NETLINK_CONNECTOR 11 47 | 48 | #define CN_VFD_IDX CN_NETLINK_USERS + 3 49 | #define CN_VFD_VAL 0x456 50 | 51 | 52 | 53 | int get_port_by_pci(const char * pciaddr); 54 | int get_vf_stats(int pf, int vf, struct rte_eth_stats *stats); 55 | 56 | void netlink_init(void); 57 | void netlink_connect(void); 58 | int netlink_send(int s, struct cn_msg *msg); 59 | int send_message(struct cn_msg *msg); 60 | 61 | void get_all_devices(void); 62 | void device_message(int p, int v, int req, int resp); 63 | 64 | 65 | #endif /* _VFD_NL_H_ */ -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_disable/test_bcastT_mcastT_ucastT.py: -------------------------------------------------------------------------------- 1 | from tests import packet 2 | import tests.helper_functions as hf 3 | import pytest 4 | 5 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastT 6 | def test_invalid_mac_valid_vlan(vf4_invalid_mac, vf4_valid_vlan): 7 | hf.read_sample_data('TARGET_VF4') 8 | pkt = hf.build_packet(dmac=vf4_invalid_mac, valid_vlan=int(vf4_valid_vlan)) 9 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 10 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 11 | pkts = packet.load_sniff_packets(inst) 12 | vlan = None 13 | for pkt in pkts: 14 | vlan = pkt.pktgen.strip_vlan('vlan') 15 | break 16 | # Here we dont recv packet because antispoff rules enabled, "iplex show all" will show the incremented spoof counter 17 | assert vlan == None 18 | 19 | @pytest.mark.invalid_vlan_bcastT_mcastT_ucastT 20 | def test_invalid_mac_invalid_vlan(vf4_invalid_mac, vf4_invalid_vlan): 21 | hf.read_sample_data('TARGET_VF4') 22 | pkt = hf.build_packet(dmac=vf4_invalid_mac, valid_vlan=int(vf4_invalid_vlan)) 23 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 24 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 25 | pkts = packet.load_sniff_packets(inst) 26 | vlan = None 27 | for pkt in pkts: 28 | vlan = pkt.pktgen.strip_vlan('vlan') 29 | break 30 | assert vlan == None 31 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_enable/test_bcastT_mcastT_ucastT.py: -------------------------------------------------------------------------------- 1 | from tests import packet 2 | import tests.helper_functions as hf 3 | import pytest 4 | 5 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastT 6 | def test_invalid_mac_valid_vlan(vf4_invalid_mac, vf4_valid_vlan): 7 | hf.read_sample_data('TARGET_VF4') 8 | pkt = hf.build_packet(dmac=vf4_invalid_mac, valid_vlan=int(vf4_valid_vlan)) 9 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 10 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 11 | pkts = packet.load_sniff_packets(inst) 12 | vlan = None 13 | for pkt in pkts: 14 | vlan = pkt.pktgen.strip_vlan('vlan') 15 | break 16 | # Here we dont recv packet because antispoff rules enabled, "iplex show all" will show the incremented spoof counter 17 | assert vlan == None 18 | 19 | @pytest.mark.invalid_vlan_bcastT_mcastT_ucastT 20 | def test_invalid_mac_invalid_vlan(vf4_invalid_mac, vf4_invalid_vlan): 21 | hf.read_sample_data('TARGET_VF4') 22 | pkt = hf.build_packet(dmac=vf4_invalid_mac, valid_vlan=int(vf4_invalid_vlan)) 23 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 24 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 25 | pkts = packet.load_sniff_packets(inst) 26 | vlan = None 27 | for pkt in pkts: 28 | vlan = pkt.pktgen.strip_vlan('vlan') 29 | break 30 | assert vlan == None 31 | -------------------------------------------------------------------------------- /src/support/tests/sample_data.ini.stripT: -------------------------------------------------------------------------------- 1 | # strip_stag = false/true 2 | # allow_bcast = true 3 | # allow_mcast = true 4 | # allow_unicast = false 5 | [TARGET_VF1] 6 | invalid_macs=6f:4d:45:a3:30:67,8d:b5:0d:78:8c:fc 7 | valid_vlans=104 8 | invalid_vlans=99, 999 9 | mcast_mac=01:00:5E:00:00:30 10 | bcast_mac=ff:ff:ff:ff:ff:ff 11 | mac_list=ec:f4:bb:dc:fb:30,ec:f4:bb:dc:fb:d4,ec:f4:bb:dd:9f:88 12 | 13 | # strip_stag = false/true 14 | # allow_bcast = false 15 | # allow_mcast = true 16 | # allow_unicast = false 17 | [TARGET_VF2] 18 | invalid_macs=20:49:14:c4:14:c5 19 | valid_vlans=202 20 | invalid_vlans=101, 104, 100, 103 21 | mcast_mac=01:00:5E:00:00:30 22 | bcast_mac=ff:ff:ff:ff:ff:ff 23 | mac_list=ec:f4:bb:de:ad:ac,ee:da:c2:58:34:9d 24 | 25 | # strip_stag = false/true 26 | # allow_bcast = false 27 | # allow_mcast = false 28 | # allow_unicast = false 29 | [TARGET_VF3] 30 | invalid_macs=dc:c2:67:26:0c:62 31 | valid_vlans=300 32 | invalid_vlans=200, 201, 202 33 | mcast_mac=01:00:5E:00:00:30 34 | bcast_mac=ff:ff:ff:ff:ff:ff 35 | mac_list=ec:f4:bb:dc:e2:68 36 | 37 | # strip_stag = false/true 38 | # allow_bcast = true 39 | # allow_mcast = true 40 | # allow_unicast = true 41 | [TARGET_VF4] 42 | invalid_macs=64:9d:07:2b:5f:c5,22:07:90:9e:8b:cb,8d:d5:44:22:c7:8b 43 | valid_vlans=401 44 | invalid_vlans=200, 202, 103, 101, 999 45 | mcast_mac=01:00:5E:00:00:30 46 | bcast_mac=ff:ff:ff:ff:ff:ff 47 | mac_list=ec:f4:bb:dc:e2:24,ec:f4:bb:de:24:e8 48 | 49 | # packet generator host interface 50 | [PG] 51 | iface=enp8s0f0 52 | mac=a0:36:9f:7d:4d:98 53 | -------------------------------------------------------------------------------- /src/support/tests/sample_data.ini: -------------------------------------------------------------------------------- 1 | # strip_stag = false/true 2 | # allow_bcast = true 3 | # allow_mcast = true 4 | # allow_unicast = false 5 | [TARGET_VF1] 6 | invalid_macs=6f:4d:45:a3:30:67,8d:b5:0d:78:8c:fc 7 | valid_vlans=100, 101, 102, 103, 104 8 | invalid_vlans=99, 999 9 | mcast_mac=01:00:5E:00:00:30 10 | bcast_mac=ff:ff:ff:ff:ff:ff 11 | mac_list=ec:f4:bb:dc:fb:30,ec:f4:bb:dc:fb:d4,ec:f4:bb:dd:9f:88 12 | 13 | # strip_stag = false/true 14 | # allow_bcast = false 15 | # allow_mcast = true 16 | # allow_unicast = false 17 | [TARGET_VF2] 18 | invalid_macs=20:49:14:c4:14:c5 19 | valid_vlans=200, 201, 202 20 | invalid_vlans=101, 104, 100, 103 21 | mcast_mac=01:00:5E:00:00:30 22 | bcast_mac=ff:ff:ff:ff:ff:ff 23 | mac_list=ec:f4:bb:de:ad:ac,ee:da:c2:58:34:9d 24 | 25 | # strip_stag = false/true 26 | # allow_bcast = false 27 | # allow_mcast = false 28 | # allow_unicast = false 29 | [TARGET_VF3] 30 | invalid_macs=dc:c2:67:26:0c:62 31 | valid_vlans=300 32 | invalid_vlans=200, 201, 202 33 | mcast_mac=01:00:5E:00:00:30 34 | bcast_mac=ff:ff:ff:ff:ff:ff 35 | mac_list=ec:f4:bb:dc:e2:68 36 | 37 | # strip_stag = false/true 38 | # allow_bcast = true 39 | # allow_mcast = true 40 | # allow_unicast = true 41 | [TARGET_VF4] 42 | invalid_macs=64:9d:07:2b:5f:c5,22:07:90:9e:8b:cb,8d:d5:44:22:c7:8b 43 | valid_vlans=400, 401 44 | invalid_vlans=200, 202, 103, 101, 999 45 | mcast_mac=01:00:5E:00:00:30 46 | bcast_mac=ff:ff:ff:ff:ff:ff 47 | mac_list=ec:f4:bb:dc:e2:24,ec:f4:bb:de:24:e8 48 | 49 | # packet generator host interface 50 | [PG] 51 | iface=enp8s0f0 52 | mac=a0:36:9f:7d:4d:98 53 | -------------------------------------------------------------------------------- /src/support/tests/sample_data.ini.stripF: -------------------------------------------------------------------------------- 1 | # strip_stag = false/true 2 | # allow_bcast = true 3 | # allow_mcast = true 4 | # allow_unicast = false 5 | [TARGET_VF1] 6 | invalid_macs=6f:4d:45:a3:30:67,8d:b5:0d:78:8c:fc 7 | valid_vlans=100, 101, 102, 103, 104 8 | invalid_vlans=99, 999 9 | mcast_mac=01:00:5E:00:00:30 10 | bcast_mac=ff:ff:ff:ff:ff:ff 11 | mac_list=ec:f4:bb:dc:fb:30,ec:f4:bb:dc:fb:d4,ec:f4:bb:dd:9f:88 12 | 13 | # strip_stag = false/true 14 | # allow_bcast = false 15 | # allow_mcast = true 16 | # allow_unicast = false 17 | [TARGET_VF2] 18 | invalid_macs=20:49:14:c4:14:c5 19 | valid_vlans=200, 201, 202 20 | invalid_vlans=101, 104, 100, 103 21 | mcast_mac=01:00:5E:00:00:30 22 | bcast_mac=ff:ff:ff:ff:ff:ff 23 | mac_list=ec:f4:bb:de:ad:ac,ee:da:c2:58:34:9d 24 | 25 | # strip_stag = false/true 26 | # allow_bcast = false 27 | # allow_mcast = false 28 | # allow_unicast = false 29 | [TARGET_VF3] 30 | invalid_macs=dc:c2:67:26:0c:62 31 | valid_vlans=300 32 | invalid_vlans=200, 201, 202 33 | mcast_mac=01:00:5E:00:00:30 34 | bcast_mac=ff:ff:ff:ff:ff:ff 35 | mac_list=ec:f4:bb:dc:e2:68 36 | 37 | # strip_stag = false/true 38 | # allow_bcast = true 39 | # allow_mcast = true 40 | # allow_unicast = true 41 | [TARGET_VF4] 42 | invalid_macs=64:9d:07:2b:5f:c5,22:07:90:9e:8b:cb,8d:d5:44:22:c7:8b 43 | valid_vlans=400, 401 44 | invalid_vlans=200, 202, 103, 101, 999 45 | mcast_mac=01:00:5E:00:00:30 46 | bcast_mac=ff:ff:ff:ff:ff:ff 47 | mac_list=ec:f4:bb:dc:e2:24,ec:f4:bb:de:24:e8 48 | 49 | # packet generator host interface 50 | [PG] 51 | iface=enp8s0f0 52 | mac=a0:36:9f:7d:4d:98 53 | -------------------------------------------------------------------------------- /src/lib/hot_plug.c: -------------------------------------------------------------------------------- 1 | // :vim sw=4 ts=4 nocindent noexpandtab: 2 | 3 | /* 4 | Mnemonic: hot_plug.c 5 | Abstract: Functions that allow the creator of a VF configuration file 6 | to have a command executed just after VFd restart, and just 7 | before VFd shutdown. This allows for a device to be hot-unplugged, 8 | reinserted, etc. if it is necessary. Some drivers must have the device 9 | removed/added by the virtulalisation manager in order for the VM to 10 | continue working after VFd has been restarted. 11 | Author: E. Scott Daniels 12 | Date: 26 May 2016 13 | 14 | Mods: 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "vfdlib.h" 27 | 28 | // ------------------------------------------------------------------------------------- 29 | #define SFREE(p) if((p)){free(p);} // safe free (free shouldn't balk on nil, but don't chance it) 30 | 31 | 32 | 33 | /* 34 | Run the user command as the user given (e.g. sudo -u user command). User command output goes to 35 | either stderr or stdout and won't go to a bleat log file. 36 | */ 37 | int user_cmd( uid_t uid, char* cmd ) { 38 | char* cmd_buf; 39 | int cmd_len; 40 | int rc = 0; // under dpdk the result of the system call always seems to be -1 41 | 42 | if( uid < 0 ) { 43 | return -1; 44 | } 45 | 46 | cmd_len = strlen( cmd ) + 128; 47 | cmd_buf = (char *) malloc( sizeof( char ) * cmd_len ); 48 | if( cmd_buf == NULL ) { 49 | return -1; 50 | } 51 | 52 | snprintf( cmd_buf, cmd_len, "sudo -u '#%d' %s", uid, cmd ); 53 | rc = system( cmd_buf ); 54 | free( cmd_buf ); 55 | return rc; 56 | } 57 | -------------------------------------------------------------------------------- /src/lib/jwrapper_test.ksh: -------------------------------------------------------------------------------- 1 | 2 | json='{ 3 | "active_patient": true, 4 | "last_visit": "2015/02/03", 5 | "referred_by": Null, 6 | 7 | "patient_info": { 8 | "first_name": "Fred", 9 | "last_name": "Flintsone", 10 | "dob": "1963/04/03", 11 | "sex": "M", 12 | "weight_kilo": 65.2, 13 | "drug_alergies": [ "asprin","darvaset" ] 14 | } 15 | 16 | "notes": { 17 | "over_weight": true, 18 | "smoker": false, 19 | "weight_trend": "gaining", 20 | } 21 | 22 | "Contact_info": { 23 | "name": "Wilma", "relation": "wife", "phone": "972.612.8918" 24 | } 25 | }' 26 | 27 | 28 | # "comment": "array with objects", 29 | # "ob_array": [ 30 | # { "a": 1, "x": 2, "y": 3 }, 31 | # { "x": 3, "y": 4, "z": 5 }, 32 | # { "x": 4, "y": 5, "k": 6, "j": 7 }, 33 | # { "x": 5, "y": 6 } ] 34 | # 35 | json_file=/tmp/PID$$.json 36 | output=/tmp/PID$$>out 37 | echo $json >$json_file 38 | 39 | ( 40 | jwrapper_test $json_file "patient_info.dob" "patient_info.drug_alergies" 1 41 | jwrapper_test $json_file "last_visit" 42 | jwrapper_test $json_file "patient_info.weight_kilo" 43 | jwrapper_test $json_file "notes.over_weight" 44 | echo "" 45 | echo "testing for value which is null -- expect: 'failed to find name: referred_by'" 46 | jwrapper_test $json_file "referred_by" 47 | ) >$output 2>&1 48 | 49 | md5sum $output |read value junk 50 | if [[ $value != "8349f6f812a412e021dbb0948e8f375e" ]] # didn't match what we expected 51 | then 52 | echo "------ test output below -----" 53 | cat $output 54 | echo "------------------------------" 55 | echo "value=$value expected=8349f6f812a412e021dbb0948e8f375e" 56 | echo "[FAIL] output didn't match what was expected" 57 | rm /tmp/PID$$.* 58 | exit 1 59 | fi 60 | 61 | echo "[PASS]" 62 | rm /tmp/PID$$.* 63 | exit 0 64 | 65 | -------------------------------------------------------------------------------- /src/support/linux_scripts/gen_packet.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # vi: sw=4 ts=4: 3 | 4 | import argparse 5 | import re 6 | import subprocess 7 | import time 8 | 9 | def parse_args(): 10 | ap = argparse.ArgumentParser() 11 | ap.add_argument('-d', '--debug', action='store_true', default=False, help='Show debugging output') 12 | ap.add_argument('-f', '--filename', action='store', default="packet.conf", help="Path to data file") 13 | return ap.parse_args() 14 | 15 | def gen_packet(pkt_num, iface, s_mac, d_mac, s_ip, d_ip, proto, dport, vlan_id): 16 | if dport == None and vlan_id != None: 17 | cmd = 'mz %s -a %s -b %s -A %s -B %s -t %s -P "Hello Test Packet %s" -Q %s' % (iface, s_mac, d_mac, s_ip, d_ip, proto, pkt_num, vlan_id) 18 | elif dport != None and vlan_id != None: 19 | cmd = 'mz %s -a %s -b %s -A %s -B %s -t %s "dp=%s" -P "Hello Test Packet %s" -Q %s' % (iface, s_mac, d_mac, s_ip, d_ip, proto, dport, pkt_num, vlan_id) 20 | else: 21 | cmd = 'mz %s -a %s -b %s -A %s -B %s -t %s -P "Hello Test Packet %s"' % (iface, s_mac, d_mac, s_ip, d_ip, proto, pkt_num) 22 | try: 23 | subprocess.check_call(cmd, shell=True) 24 | return True 25 | except subprocess.CalledProcessError: 26 | return False 27 | 28 | def read_config(file_path): 29 | with open(file_path, 'r') as f: 30 | line_num = 0 31 | for file_entry in f.readlines(): 32 | line_num += 1 33 | if re.match('#.*', file_entry): 34 | continue 35 | (iface, s_mac, d_mac, s_ip, d_ip, proto, dport, vlan_id) = file_entry.split(",") 36 | if args.debug: 37 | print iface, s_mac, d_mac, s_ip, d_ip, proto, dport, vlan_id 38 | pkt_num = 1 39 | for i in xrange(5): 40 | gen_packet(pkt_num, iface, s_mac, d_mac, s_ip, d_ip, proto, dport, vlan_id) 41 | time.sleep(1) 42 | pkt_num = pkt_num + 1 43 | 44 | if __name__ == '__main__': 45 | args = parse_args() 46 | read_config(args.filename) 47 | -------------------------------------------------------------------------------- /src/system/vfd.conf: -------------------------------------------------------------------------------- 1 | description "Service to configure virtual functions" 2 | 3 | start on (starting nova-compute) 4 | stop on (stopped networking) 5 | 6 | expect fork 7 | respawn 8 | respawn limit 5 5 9 | 10 | env VFD_UPSTART_LOG=/var/log/vfd/vfd_upstart.log 11 | 12 | script 13 | exec /usr/bin/vfd >/var/log/vfd/vfd.std 2>&1 14 | end script 15 | 16 | post-start script 17 | echo "[`date`] VFd iplex ping... ">> $VFD_UPSTART_LOG 18 | timeout 240 iplex ping 19 | echo "[`date`] VFd started... ">> $VFD_UPSTART_LOG 20 | end script 21 | 22 | pre-start script 23 | echo "[`date`] VFD starting...." >> $VFD_UPSTART_LOG 24 | 25 | if [ ! -f /etc/vfd/vfd.cfg ] 26 | then 27 | echo "[`date`] Failed to start, daemon /etc/vfd/vfd.cfg is missing" >> $VFD_UPSTART_LOG 28 | exit 0 29 | fi 30 | 31 | if [ ! -d /var/log/vfd ] 32 | then 33 | echo "[`date`] Failed to start daemon, /var/log/vfd is missing" >> $VFD_UPSTART_LOG 34 | exit 0 35 | fi 36 | 37 | if [ ! -d /var/lib/vfd/config ] 38 | then 39 | echo "[`date`] Failed to start daemon, /var/lib/vfd/config is missing" >> $VFD_UPSTART_LOG 40 | exit 0 41 | fi 42 | 43 | if [ "$(grep nova /etc/passwd | cut -d: -f1)" = "nova" ] 44 | then 45 | chown -R nova:nova /var/lib/vfd/config 46 | fi 47 | chmod 775 /var/lib/vfd/config 48 | 49 | touch /var/run/vfd.pid 50 | 51 | exec vfd_pre_start 1>> $VFD_UPSTART_LOG 2>&1 52 | 53 | if [ $? -ne 0 ] 54 | then 55 | echo "Failed to start vfd_pre_start " 1>> $VFD_UPSTART_LOG 2>&1 56 | fi 57 | 58 | if [ -f /var/log/vfd/vfd.std ] 59 | then 60 | cp /var/log/vfd/vfd.std /var/log/vfd/vfd.std- 61 | fi 62 | 63 | end script 64 | 65 | post-stop script 66 | rm /var/run/vfd.pid 67 | echo "[`date`] VFD stopping...." >> $VFD_UPSTART_LOG 68 | end script 69 | -------------------------------------------------------------------------------- /src/lib/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # the mkfile is still the file of record as mk uses nicer syntax and allows 3 | # complete shell recipes rather than one-liners. This will do a basic build 4 | # of the library and maybe the test scripts (eventually). 5 | 6 | MKSHELL = ksh 7 | 8 | # jsmn no longer builds into a library 9 | jsmn_lib = 10 | vfd_lib = -L . -lvfd 11 | 12 | cflags = -I jsmn -g 13 | CC = gcc $(cflags) 14 | cc = gcc $(cflags) 15 | 16 | binaries = jwrapper_test parm_file_test list_test fifo_test bleat_test id_mgr_test 17 | 18 | all: jsmn libvfd.a 19 | 20 | lib = libvfd.a 21 | lib_src = jwrapper jw_xapi symtab config ng_flowmgr fifo list_files bleat hot_plug id_mgr filesys 22 | $(lib): $(lib_src:=.o) 23 | ar r $(lib) $^ 24 | 25 | 26 | # --------- tests ---------------------------------------------------- 27 | jwrapper_test: jwrapper_test.c 28 | $(cc) $(cflags) jwrapper_test.c -o jwrapper_test $(vfd_lib) $(jsmn_lib) 29 | 30 | parm_file_test: parm_file_test.c $(lib) 31 | $(cc) $(cflags) parm_file_test.c -o parm_file_test -L. -lvfd $(jsmn_lib) 32 | 33 | vf_config_test: vf_config_test.c $(lib) 34 | $(cc) $(cflags) vf_config_test.c -o vf_config_test -L. -lvfd $(jsmn_lib) 35 | 36 | fifo_test: fifo_test.c $(lib) 37 | $(cc) $(cflags) fifo_test.c -o fifo_test -L. -lvfd $(jsmn_lib) 38 | 39 | bleat_test: bleat_test.c $(lib) 40 | $(cc) $(cflags) bleat_test.c -o bleat_test -L. -lvfd $(jsmn_lib) 41 | 42 | list_test: list_test.c $(lib) 43 | $(cc) $(cflags) list_test.c -o list_test -L. -lvfd $(jsmn_lib) 44 | 45 | hot_plug: hot_plug.c $(lib) 46 | $(cc) $(cflags) hot_plug.c -o hot_plug -L. -lvfd $(jsmn_lib) 47 | 48 | id_mgr_test:: id_mgr_test.c $lib 49 | $cc $cflags id_mgr_test.c -o id_mgr_test -L. -lvfd $jsmn_lib 50 | 51 | 52 | 53 | tests: $(binaries) 54 | 55 | nuke: 56 | rm -f *.o *.a $(binaries) 57 | 58 | 59 | # ------ clone (if needed) and update and build jsmn ------- 60 | jsmn:: 61 | @if [ ! -d jsmn ] ;\ 62 | then \ 63 | git clone https://github.com/zserge/jsmn ;\ 64 | fi 65 | cd jsmn; git pull; make 66 | 67 | -------------------------------------------------------------------------------- /src/README: -------------------------------------------------------------------------------- 1 | 2 | Top level source directory. Things which maybe aren't obvious are described 3 | in this file. 4 | 5 | 6 | 7 | This code makes use of DPDK 17.11 features which are currently in the master 8 | branch. Pull the DPDK repo, and attempt to checkout v17.11. 9 | 10 | Once the dpdk repo has been cloned, it must be built before anything in the 11 | vfd source tree can be built. To do this follow the following steps: 12 | 13 | - cd build # where ever you plan to clone/build it 14 | - git clone http://dpdk.org/git/dpdk # if you need to clone 15 | - cd dpdk # where ever you installed it 16 | - git checkout 17 | - make config T=x86_64-native-linuxapp-gcc 18 | - make 19 | - usertools/dpdk-setup.sh 20 | + select the option which corresponds to the correct 21 | environment, most likely: x86_64-native-linuxapp-gcc 22 | This will go through another make process which sets 23 | libraries and such up and 'installs'. If there are link 24 | errors during the build, it is likely this step was not 25 | executed, or didn't finish correctly 26 | 27 | - export RTE_SDK=$PWD # wise to put these in your profile 28 | - export RTE_TARGET=x86_64-native-linuxapp-gcc 29 | 30 | 31 | Once DPDK has been built, any patches in the dpdk_patch directory must be 32 | applied. See the README in that directory for details 33 | 34 | Building VFd Itself: 35 | After DPDK is built, and patched, the following comands can be used to 36 | build VFd. 37 | 38 | - make all 39 | 40 | This should: 41 | 1) switch to the lib directory and checkout/pull jsmn from github 42 | 2) build jsmn and the VFd library 43 | 3) switch to the vfd directory and build VFd 44 | 45 | The binary should reside in vfd/buid/app/vfd 46 | 47 | Manual steps if using make in this directory is not desired: 48 | - cd vfd # which ever directory you cloned the vfd repo into 49 | - cd lib 50 | - make jsmn # will clone and build the jsmn library 51 | - make libvfd.a # will build vfd support library 52 | - cd ../vfd 53 | - make clean 54 | - make 55 | -------------------------------------------------------------------------------- /src/vfd/vfd_bnxt.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef VFD_BNXT_H 3 | #define VFD_BNXT_H 4 | 5 | #include "sriov.h" 6 | 7 | #include 8 | #include 9 | 10 | 11 | 12 | // ------------- prototypes ---------------------------------------------- 13 | 14 | int vfd_bnxt_ping_vfs(uint16_t port, int16_t vf); 15 | int vfd_bnxt_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on); 16 | int vfd_bnxt_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on); 17 | int vfd_bnxt_set_tx_loopback(uint16_t port, uint8_t on); 18 | int vfd_bnxt_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on); 19 | int vfd_bnxt_set_vf_multicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on); 20 | int vfd_bnxt_set_vf_mac_addr(uint16_t port, uint16_t vf_id, struct ether_addr *mac_addr); 21 | int vfd_bnxt_set_vf_default_mac_addr( uint16_t port_id, uint16_t vf_id, struct ether_addr *mac_addr ); 22 | int vfd_bnxt_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on); 23 | int vfd_bnxt_set_vf_vlan_insert(uint16_t port, uint16_t vf_id, uint16_t vlan_id); 24 | int vfd_bnxt_set_vf_broadcast(uint16_t port, uint16_t vf_id, uint8_t on); 25 | int vfd_bnxt_set_vf_vlan_tag(uint16_t port, uint16_t vf_id, uint8_t on); 26 | int vfd_bnxt_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id, uint64_t vf_mask, uint8_t on); 27 | int vfd_bnxt_get_vf_stats(uint16_t port, uint16_t vf_id, struct rte_eth_stats *stats); 28 | int vfd_bnxt_reset_vf_stats(uint16_t port, uint16_t vf_id); 29 | 30 | int vfd_bnxt_vf_msb_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param, void* data ); 31 | 32 | int vfd_bnxt_allow_untagged(uint16_t port, uint16_t vf_id, uint8_t on); 33 | 34 | int vfd_bnxt_set_all_queues_drop_en(uint16_t port_id, uint8_t on); 35 | uint32_t vfd_bnxt_get_pf_spoof_stats(uint16_t port_id); 36 | uint32_t vfd_bnxt_get_vf_spoof_stats(uint16_t port_id, uint16_t vf_id); 37 | int vfd_bnxt_is_rx_queue_on(uint16_t port_id, uint16_t vf_id, int* mcounter); 38 | void vfd_bnxt_set_rx_drop(uint16_t port_id, uint16_t vf_id, int state); 39 | void vfd_bnxt_set_split_erop(uint16_t port_id, uint16_t vf_id, int state); 40 | int vfd_bnxt_dump_all_vlans(uint16_t port_id); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/vfd/vfd_mlx5.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _VFD_MLX5_H 3 | #define _VFD_MLX5_H 4 | 5 | #include "vfdlib.h" 6 | #include "sriov.h" 7 | 8 | struct mlx5_tc_cfg { 9 | char policy[8]; 10 | int32_t min_bw; 11 | int32_t max_bw; 12 | }; 13 | 14 | // ------------- prototypes ---------------------------------------------- 15 | int vfd_mlx5_get_ifname(uint16_t port_id, char *ifname); 16 | 17 | int vfd_mlx5_set_vf_mac_addr(uint16_t port_id, uint16_t vf_id, const char* mac, uint8_t on); 18 | int vfd_mlx5_set_vf_def_mac_addr(uint16_t port, uint16_t vf_id, const char *mac_addr); 19 | int vfd_mlx5_vf_mac_remove(uint16_t port_id, uint16_t vf_id); 20 | int vfd_mlx5_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on); 21 | int vfd_mlx5_set_vf_vlan_insert(uint16_t port, uint16_t vf_id, uint16_t vlan_id); 22 | int vfd_mlx5_set_vf_cvlan_insert(uint16_t port_id, uint16_t vf_id, uint16_t vlan_id); 23 | int vfd_mlx5_set_vf_mac_anti_spoof(uint16_t port_id, uint16_t vf_id, uint8_t on); 24 | int vfd_mlx5_set_vf_min_rate(uint16_t port_id, uint16_t vf_id, uint16_t rate); 25 | int vfd_mlx5_set_vf_rate_limit(uint16_t port_id, uint16_t vf_id, uint16_t rate); 26 | int vfd_mlx5_set_vf_link_status(uint16_t port_id, uint16_t vf_id, int status); 27 | uint32_t vfd_mlx5_get_pf_spoof_stats(uint16_t port_id); 28 | int vfd_mlx5_get_num_vfs(uint16_t port_id); 29 | int vfd_mlx5_get_vf_stats(uint16_t port_id, uint16_t vf_id, struct rte_eth_stats *stats); 30 | uint64_t vfd_mlx5_get_vf_sysfs_counter(char *ifname, const char *counter, uint16_t vf_id); 31 | uint64_t vfd_mlx5_get_vf_ethtool_counter(char *ifname, const char *counter); 32 | uint64_t vfd_mlx5_get_vf_spoof_stats(uint16_t port_id, uint16_t vf_id); 33 | int vfd_mlx5_pf_vf_offset(char *pciid); 34 | int vfd_mlx5_set_vf_vlan_filter(uint16_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on); 35 | int vfd_mlx5_set_vf_promisc(uint16_t port_id, uint16_t vf_id, uint8_t on); 36 | int vfd_mlx5_set_qos_pf(uint16_t port_id, tc_class_t **tc_config, uint8_t ntcs); 37 | int vfd_mlx5_set_prio_trust(uint16_t port_id); 38 | int vfd_mlx5_set_mirror( uint16_t port_id, uint32_t vf, uint8_t target, uint8_t direction); 39 | int vfd_mlx5_set_vf_tcqos( uint16_t port_id, uint32_t vf, uint8_t tc, uint32_t rate ); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/vfd/vfd_rif.h: -------------------------------------------------------------------------------- 1 | // vi: sw=4 ts=4 noet: 2 | 3 | /* 4 | Mnemonic: vfd_rif.h 5 | Abstract: Request interface header. 6 | Author: E. Scott Daniels 7 | Date: 11 October 2016 8 | */ 9 | 10 | #ifndef _VFD_RIF_H 11 | #define _VFD_RIF_H 12 | 13 | #define ADDED 1 // updated states 14 | #define DELETED (-1) 15 | #define UNCHANGED 0 16 | #define RESET 2 17 | 18 | #define RESP_ERROR 1 // states for response bundler 19 | #define RESP_OK 0 20 | 21 | #define RT_NOP 0 // request types 22 | #define RT_ADD 1 23 | #define RT_DEL 2 24 | #define RT_SHOW 3 25 | #define RT_PING 4 26 | #define RT_VERBOSE 5 27 | #define RT_DUMP 6 28 | #define RT_MIRROR 7 // mirror on/off command 29 | #define RT_CPU_ALARM 8 // set the cpu alarm threshold 30 | #define RT_EXPORT 9 // copy a live config file to given filename 31 | #define RT_UNKNOWN 100 32 | 33 | #define BUF_1K 1024 // simple buffer size constants 34 | #define BUF_10K BUF_1K * 10 35 | 36 | typedef struct request { 37 | int rtype; // type: RT_ const 38 | char* resource; // parm file name, show target, etc. 39 | char* output; // filename where any external output from the request should be sent 40 | char* resp_fifo; // name of the return pipe 41 | int log_level; // for verbose 42 | char* vfd_rid; // request id that must be placed into the response (allows single response pipe by request process) 43 | } req_t; 44 | 45 | // ------------------ prototypes --------------------------------------------- 46 | extern int vfd_init_fifo( parms_t* parms ); 47 | extern int check_tcs( struct sriov_port_s* port, uint8_t *tc_pctgs ); 48 | extern void vfd_add_ports( parms_t* parms, sriov_conf_t* conf ); 49 | extern int vfd_add_vf( sriov_conf_t* conf, char* fname, char** reason ); 50 | extern void vfd_add_all_vfs( parms_t* parms, sriov_conf_t* conf ); 51 | extern int vfd_del_vf( parms_t* parms, sriov_conf_t* conf, char* fname, char** reason ); 52 | extern int vfd_write( int fd, const char* buf, int len ); 53 | extern void vfd_response( char* rpipe, int state, const_str vfd_rid, const char* msg ); 54 | extern void vfd_free_request( req_t* req ); 55 | extern req_t* vfd_read_request( parms_t* parms ); 56 | extern int vfd_req_if( parms_t *parms, sriov_conf_t* conf, int forever ); 57 | 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/vfd-net/vfd-net.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef __devexit_p 4 | #define __devexit_p(x) &(x) 5 | #endif 6 | 7 | #ifndef __devexit 8 | #define __devexit 9 | #endif 10 | 11 | 12 | #define NL_PF_RESP_OK 0x0 13 | #define NL_PF_RESP_ERR 0x1 14 | 15 | 16 | #define NL_VF_STATS_RQ 0x1 17 | #define NL_VF_GETINFO_RQ 0x2 18 | #define NL_VF_SETMTU_RQ 0x4 19 | #define NL_VF_IFUP_RQ 0x8 20 | #define NL_VF_IFDOWN_RQ 0x10 21 | 22 | #define NL_PF_RES_DEV_RQ 0x0 23 | #define NL_VF_GET_DEV_RQ 0x100 24 | #define NL_PF_ADD_DEV_RQ 0x400 25 | #define NL_PF_DEL_DEV_RQ 0x800 26 | #define NL_PF_UPD_DEV_RQ 0x1000 27 | 28 | #define MAX_PF 16 29 | #define MAX_VF 254 30 | 31 | #define PCIADDR_LEN 12 32 | 33 | 34 | struct dev_stats 35 | { 36 | __u32 rx_packets; /* total packets received */ 37 | __u32 tx_packets; /* total packets transmitted */ 38 | __u32 rx_bytes; /* total bytes received */ 39 | __u32 tx_bytes; /* total bytes transmitted */ 40 | __u32 rx_errors; /* bad packets received */ 41 | __u32 tx_errors; /* packet transmit problems */ 42 | __u32 rx_dropped; /* no space in linux buffers */ 43 | __u32 tx_dropped; /* no space available in linux */ 44 | __u32 multicast; /* multicast packets received */ 45 | __u32 collisions; 46 | 47 | /* detailed rx_errors: */ 48 | __u32 rx_length_errors; 49 | __u32 rx_over_errors; /* receiver ring buff overflow */ 50 | __u32 rx_crc_errors; /* recved pkt with crc error */ 51 | __u32 rx_frame_errors; /* recv'd frame alignment error */ 52 | __u32 rx_fifo_errors; /* recv'r fifo overrun */ 53 | __u32 rx_missed_errors; /* receiver missed packet */ 54 | 55 | /* detailed tx_errors */ 56 | __u32 tx_aborted_errors; 57 | __u32 tx_carrier_errors; 58 | __u32 tx_fifo_errors; 59 | __u32 tx_heartbeat_errors; 60 | __u32 tx_window_errors; 61 | 62 | /* for cslip etc */ 63 | __u32 rx_compressed; 64 | __u32 tx_compressed; 65 | }; 66 | 67 | 68 | struct dev_info 69 | { 70 | __u32 link_state; 71 | __u32 link_speed; 72 | __u32 link_duplex; 73 | __u32 mtu; 74 | __u32 n_queues; 75 | char * mac; 76 | struct dev_stats *stats; 77 | }; 78 | 79 | struct vfd_nl_message { 80 | uint32_t req; 81 | uint32_t resp; 82 | uint32_t port; 83 | uint32_t vf; 84 | char * pciaddr; 85 | struct dev_info *info; 86 | }; 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/lib/id_mgr_test.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "vfdlib.h" 15 | 16 | int main( ) { 17 | void* id; 18 | int i; 19 | 20 | id = mk_idm( 311 ); 21 | for( i = 0; i < 313; i++ ) { 22 | if( idm_alloc( id ) < 0 ) { 23 | if( i != 311 ) { 24 | printf( "[FAIL] error allocating at %d\n", i ); 25 | return 1; 26 | } 27 | break; 28 | } 29 | } 30 | printf( "[OK] we got %d before we ran out which is what we tried to create\n", i ); 31 | 32 | idm_return( id, 250 ); 33 | idm_return( id, 111 ); 34 | idm_return( id, 17 ); 35 | idm_return( id, 11 ); 36 | idm_return( id, 29 ); 37 | idm_return( id, 29 ); // these should have no effect 38 | idm_return( id, 29 ); 39 | idm_return( id, 29 ); 40 | 41 | i = idm_use( id, 11 ); // attempt to assign directly 42 | if( i != 1 ) { 43 | printf( "[FAIL] Attempted to directly assign id 11 expected 1 as return, got %d\n", i ); 44 | return 1; 45 | } else { 46 | printf( "[OK] Attempted to directly assign id 11 and was successful\n" ); 47 | } 48 | 49 | i = idm_is_used( id, 11 ); // should return that this is used 50 | if( i != 1 ) { 51 | printf( "[FAIL] Attempted to query state of id 11; expected 1 as return, got %d\n", i ); 52 | return 1; 53 | } else { 54 | printf( "[OK] Attempt to query state of used ID was good.\n" ); 55 | } 56 | 57 | i = idm_is_used( id, 29 ); // should return that this is not used 58 | if( i != 0 ) { 59 | printf( "[FAIL] Attempted to query state of id 29; expected 0 as return, got %d\n", i ); 60 | return 1; 61 | } else { 62 | printf( "[OK] Attempt to query state of unused ID was good.\n" ); 63 | } 64 | 65 | printf( "[INFO] trying to get more\n" ); 66 | for( i = 0; i < 256; i++ ) { // should only get the four back 67 | int v; 68 | 69 | if( (v=idm_alloc( id )) < 0 ) { 70 | if( i != 4 ) { 71 | printf( "[FAIL] got %d before we ran out; expected to get 4\n", i ); 72 | } else { 73 | printf( "[OK] expected to allocate 4 more and got %d before we ran out\n", i ); 74 | } 75 | 76 | break; 77 | } 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /doc/NOTES: -------------------------------------------------------------------------------- 1 | 2 | Obviously, this directory contains documentation. From the 3 | various source files (*.xfm) we can build postscript, html, 4 | ascii text and markdown output; postscript can be converted 5 | to PDF by ghostscript or a similar tool. {X}fm is a document 6 | formatting utilty set which reads DCF script source and 7 | generates one of three output formats: postscript, text or 8 | html. Using a macro set, the text output can be made to look 9 | like markdown provided that the leading space is removed. 10 | 11 | We use one of the documents here (probably overview) as the 12 | main readme for VFd, and running 'mk readme' in this directory 13 | will generate the .md version of the document and copy it to 14 | the proper place. You will need to commit it into the repo 15 | to push up the changes. 16 | 17 | The setup files here (*.im) are used to provide a common 18 | look and feel across documents, and to provide the necessary 19 | macros which enable the generation of markdown output. The 20 | image setup file is the only 'tricky' one as it provides support 21 | to float the image to the next page when generating .ps output. 22 | 23 | Illustrations for the documents are created using xfig as it 24 | saves figures as plain ASCII text which can easily be versioned 25 | as source in a repo. Further, they are easily converted to 26 | embedded postscript or image (.png, .jpg) files as are needed. 27 | Executing 'mk images' in each directory should generate .png 28 | files, if any, needed for the wiki pages. 29 | 30 | Image files (.eps, .png, etc.) are NOT stashed into this repo. 31 | In order to reference them in markdown documents included either 32 | on the wiki or the main README, they will need to be stashed in 33 | the wiki repo under the proper directory in images/ and referenced 34 | with the following URL base: 35 | 36 | https://raw.githubusercontent.com/wiki/att/vfd/images/ 37 | 38 | 39 | Other documentation here is used to populate the repo's wiki 40 | pages. To update the wiki, including adding updated images 41 | use the following steps: 42 | 43 | 1) generate the desired .md file (e.g. hackers.md) 44 | 2) clone the wiki from the repo: 45 | git clone https://github.com/att/vfd.wiki.git 46 | 3) overlay the document in the wiki repo 47 | 4) commit the change and verify on github 48 | 49 | -------------------------------------------------------------------------------- /src/lib/README: -------------------------------------------------------------------------------- 1 | 2 | Library modules 3 | 4 | Symtab 5 | Library which provides a symbol table (a.k.a. named hash or map) 6 | This is code I wrote, and opensourced prior to joining AT&T. A 7 | dirivitive was used in Ningaui. 8 | 9 | Jwrapper 10 | Library which provides a nice interface to the underlying jsmn json 11 | parser. Jsmn is pulled from github (mk jsmn) and built. The contents 12 | of the jsmn directory should NOT be checked into git. The jsmn license 13 | is added to the LICENCE file in this directory per the stipulation in 14 | their license. 15 | 16 | See jwrapper_test as an example for use. 17 | 18 | Config 19 | This contains parsers which read the various configuration files (parms 20 | in /etc/vfd/vfd.cfg, and vf config files written by nova). Unit tests: 21 | vf_config_test [config-file] 22 | parm_file_test [config-file] 23 | 24 | list_files 25 | Simple mechanism to open a directory and build a list of the files in 26 | the directory which have the supplied suffix (e.g. all .cfg files). 27 | Optionally, the names returned can be qualified with the path given. 28 | Unit test: 29 | 30 | list_test dir-name suffix1 [suffix2...] 31 | 32 | fifo 33 | Provides support for opening and reading to a fifo (named pipe). Reads 34 | are _nonblocking_ (returning a zero byte buffer if nothing is available. 35 | The reader is configured to return 'blocks' of data from the pipe where 36 | a block is designated with two successive newline characters. Unit test: 37 | fifo_test pipe-name 38 | 39 | 40 | Building 41 | The plan-9 mk tool is sitll the preferred tool to make the library and 42 | fetch/build the required jsmn repo/library. There is a Makefile which 43 | should match, but is likely untested (replace mk with gmake in the 44 | example below). 45 | 46 | # clone the jsmn repo and build its library 47 | mk jsmn 48 | 49 | # build the vfd library 50 | mk 51 | 52 | DPDK Reference 53 | The att/dpdk library is an extended version of dpdk 1607 and can be 54 | fetched from github. The best way to reference it is to add a symlink 55 | to the library in this directory, e.g.: 56 | ln -s dpdk 57 | 58 | Once the link is in place, the code in the ../vfd library can be 59 | successfully built. See the README in this directory's parent for 60 | DPDK configuration/build notes (if needed). 61 | -------------------------------------------------------------------------------- /src/vfd/vfd_ixgbe.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _VFD_IXGBE_H 3 | #define _VFD_IXGBE_H 4 | 5 | 6 | #include 7 | #include 8 | 9 | 10 | // ------------- prototypes ---------------------------------------------- 11 | 12 | int vfd_ixgbe_ping_vfs(uint16_t port, int16_t vf); 13 | int vfd_ixgbe_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on); 14 | int vfd_ixgbe_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on); 15 | int vfd_ixgbe_set_tx_loopback(uint16_t port, uint8_t on); 16 | int vfd_ixgbe_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on); 17 | int vfd_ixgbe_set_vf_multicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on); 18 | int vfd_ixgbe_set_vf_mac_addr(uint16_t port, uint16_t vf_id, struct ether_addr *mac_addr); 19 | int vfd_ixgbe_set_vf_default_mac_addr( uint16_t port_id, uint16_t vf, struct ether_addr *mac_addr ); 20 | int vfd_ixgbe_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on); 21 | int vfd_ixgbe_set_vf_vlan_insert(uint16_t port, uint16_t vf_id, uint16_t vlan_id); 22 | int vfd_ixgbe_set_vf_broadcast(uint16_t port, uint16_t vf_id, uint8_t on); 23 | int vfd_ixgbe_allow_untagged(uint16_t port, uint16_t vf_id, uint8_t on); 24 | int vfd_ixgbe_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id, uint64_t vf_mask, uint8_t on); 25 | int vfd_ixgbe_get_vf_stats(uint16_t port, uint16_t vf_id, struct rte_eth_stats *stats); 26 | int vfd_ixgbe_reset_vf_stats(uint16_t port, uint16_t vf_id); 27 | int vfd_ixgbe_set_vf_rate_limit(uint16_t port_id, uint16_t vf_id, uint16_t tx_rate, uint64_t q_msk); 28 | int vfd_ixgbe_set_all_queues_drop_en(uint16_t port, uint8_t on); 29 | 30 | int vfd_ixgbe_vf_msb_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *data, void* param ); 31 | 32 | 33 | uint32_t vfd_ixgbe_get_pf_spoof_stats(uint16_t port_id); 34 | uint32_t vfd_ixgbe_get_vf_spoof_stats(uint16_t port_id, uint16_t vf_id); 35 | 36 | void vfd_ixgbe_disable_default_pool(uint16_t port_id); 37 | int vfd_ixgbe_is_rx_queue_on(uint16_t port_id, uint16_t vf_id, int* mcounter); 38 | 39 | 40 | void vfd_ixgbe_set_pfrx_drop(uint16_t port_id, int state ); 41 | void vfd_ixgbe_set_rx_drop(uint16_t port_id, uint16_t vf_id, int state); 42 | void vfd_ixgbe_set_split_erop(uint16_t port_id, uint16_t vf_id, int state); 43 | int vfd_ixgbe_get_split_ctlreg(uint16_t port_id, uint16_t vf_id); 44 | int vfd_ixgbe_dump_all_vlans(uint16_t port_id); 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /doc/virt/openstack_heat_users_guide.md: -------------------------------------------------------------------------------- 1 | VFd Openstack HEAT Integration User Guide 2 | ----------------------------------------- 3 | 4 | The patches provided in the virt/openstack-mos-kilo directory of the 5 | VFd source tree provide patches for AT&T's version of Openstack 6 | (called AIC). AIC is based on Mirantis OpenStack (MOS), and so, these 7 | patches should work with vanilla Openstack with one notable exception. 8 | Vanilla Openstack uses ML2 plugins for VF/vNIC config but since AIC 9 | uses a monolithic contrail plugin for as its neutron network provider, 10 | a ML2 approach is not feasible. Instead, the patches modify nova's 11 | vif.py directly to create VFd VF config files and invoke the iplex 12 | command to allow VFd to configure them. 13 | 14 | Using these patches, the tenant can configure VFd VFs through 15 | attributes specified through HEAT, and attached to a neutron port 16 | definition. 17 | 18 | The first step is to create a neutron provider network and subnet that 19 | is based on the physnet that is associated with the SR-IOV NIC (see 20 | the associated configuration guide on how to set up the physnet-NIC 21 | association when setting up OpenStack). 22 | 23 | resources: 24 | my_net: 25 | type: OS::Neutron::ProviderNet 26 | properties: 27 | provider:network_type: flat 28 | name: "my_net" 29 | network_type: flat 30 | physical_network: physnet 31 | 32 | my_subnet: 33 | type: OS::Neutron::Subnet 34 | properties: 35 | name: "my_subnet" 36 | network: "my_net" 37 | 38 | Then, neutron ports can be created against this subnet. VFd per-VF 39 | parameters are specified in the port definition as follows. 40 | 41 | heat_template_version: 2015-04-30 42 | resources: 43 | server1_port: 44 | type: OS::Neutron::Port 45 | properties: 46 | name: test_port 47 | network_id: my_subnet 48 | ATT_VF_VLAN_FILTER: [100] 49 | ATT_VF_MAC_FILTER: ['aa:aa:aa:aa:aa:aa'] 50 | ATT_VF_VLAN_STRIP: true 51 | ATT_VF_BROADCAST_ALLOW: true 52 | ATT_VF_UNKNOWN_MULTICAST_ALLOW: true 53 | ATT_VF_UNKNOWN_UNICAST_ALLOW: true 54 | ATT_VF_INSERT_STAG: true 55 | ATT_VF_LINK_STATUS: "auto" 56 | ATT_VF_MAC_ANTI_SPOOF_CHECK: true 57 | ATT_VF_VLAN_ANTI_SPOOF_CHECK: true 58 | binding:vnic_type: direct 59 | 60 | See the VFd users guide in the doc/operations/vf_config.md of the VFd 61 | source tree for documentation on the parameter values accepted by VFd. 62 | 63 | -------------------------------------------------------------------------------- /doc/operations/main_config.md: -------------------------------------------------------------------------------- 1 | #VFd Main Configuration File 2 | 3 | 4 | The main configuration file for VFd by default resides in /etc/vfd/vfd.cfg and 5 | is expected to contain a single json object with the following format. 6 | 7 | 8 | ``` 9 | { 10 | "log_dir": "/var/log/vfd", 11 | "log_keep": 30, 12 | "log_level": 1, 13 | "init_log_level": 2, 14 | "config_dir": "/var/lib/vfd/config", 15 | "fifo": "/var/lib/vfd/request", 16 | "cpu_mask": "0x01", 17 | "dpdk_log_level": 2, 18 | "dpdk_init_log_level": 8, 19 | "default_mtu": 9000, 20 | "pciids": [ 21 | { 22 | "id": "0000:07:00.0", 23 | "mtu": 1500, 24 | "enable_loopback": true 25 | }, 26 | { 27 | "id": "0000:07:00.1", 28 | "mtu": 9000 29 | } 30 | ] 31 | } 32 | ``` 33 | 34 | ## Main json fields 35 | Fields which are optional have the default value listed in parenthesis following the description. 36 | 37 | 38 | `log_dir` is the directory where log files are to be placed. (/var/log/vfd) 39 | 40 | `log_keep` is the number of days that VFd log files are to be kept. (30) 41 | 42 | `log_level` is the verbosity level for log messages after initialisation is complete. (0) 43 | 44 | `init_log_level` is the verbosity level for log messages during initialisation. (1) 45 | 46 | `config_dir` is the directory where configuration files are expected to be placed. (/var/lib/vfd/config) 47 | 48 | `fifo` is the path of the fifo that VFd will create for iplex to use to make requests. (/var/lib/vfd/request) 49 | 50 | `cpu_mask` is the default cpu mask which is used when doing EAL initialisation. Must be nonzero. 51 | 52 | `dpdk_log_level` is the verbose level requested of the DPDK library after initialisation. (0) 53 | 54 | `dpdk_init_log_level` is the verbose level requested of the DPDK library during initialisation. (0) 55 | 56 | `default_mtu` is the MTU value used for any pci defined with out a value. (9000) 57 | 58 | `pciids` is an array of pci information 'objects' 59 | 60 | 61 | ### Pci object fields 62 | 63 | `id` is the address of the pci device 64 | 65 | `mtu` is the specific MTU which should be used. (default_mtu coded in main section) 66 | 67 | `enable_loopback` if true causes the bridging value to be set for the PF allowing VM to VM packet flow across the NIC. (false) 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/vfd/vfd_dcb.h: -------------------------------------------------------------------------------- 1 | 2 | // .mq_mode = ETH_MQ_RX_VMDQ_DCB, 3 | 4 | #ifndef VFD_DCB_H 5 | #define VFD_DCB_H 6 | 7 | #include "sriov.h" 8 | 9 | /* 10 | Default dcb settings. While pools here are set to 32, the actual number of queues per pool 11 | is 'forced' by the DPDK functions and is strictly based on the number of VFs which exist 12 | for a PF. In fact, if the Number of VFs is >= 32, then the queues per pool value is set to 2, 13 | and if the number of VFs is < 16, then queues per pool are forced to 8 (like it or not). We may 14 | have to jump through some hoops should we ever wish to allow fewer than 31 VFs to be configured. 15 | */ 16 | static const struct rte_eth_conf eth_dcb_default = { 17 | .rxmode = { 18 | #if RTE_VER_YEAR > 18 || (RTE_VER_YEAR >= 18 && RTE_VER_MONTH > 8) 19 | .offloads = (DEV_RX_OFFLOAD_CHECKSUM | DEV_RX_OFFLOAD_VLAN_STRIP), 20 | #else 21 | .offloads = (DEV_RX_OFFLOAD_CHECKSUM | DEV_RX_OFFLOAD_CRC_STRIP | DEV_RX_OFFLOAD_VLAN_STRIP), 22 | #endif 23 | /* 24 | .mq_mode = ETH_MQ_RX_VMDQ_DCB, // both sr-iov and dcb support 25 | .split_hdr_size = 0, 26 | .header_split = 0, 27 | .hw_ip_checksum = 0, 28 | .hw_vlan_filter = 0, 29 | .jumbo_frame = 0, 30 | */ 31 | }, 32 | .txmode = { 33 | .mq_mode = ETH_MQ_TX_VMDQ_DCB, // vmdq causes vt mode to be set which is what we want 34 | }, 35 | .rx_adv_conf = { 36 | .vmdq_dcb_conf = { 37 | .nb_queue_pools = ETH_32_POOLS, // it seems that this will be overridden based on number of vfs which exist 38 | .enable_default_pool = 0, 39 | .default_pool = 0, 40 | .nb_pool_maps = 0, // up to 64 41 | .pool_map = {{0, 0},}, // {vlanID,pools} pools is a bit mask(64) of which pool(s) the vlan id maps to 42 | .dcb_tc = {0}, // up to num-user-priorities; 'selects a queue in a pool' what ever thef that means 43 | }, 44 | .dcb_rx_conf = { 45 | .nb_tcs = ETH_4_TCS, 46 | .dcb_tc = {0}, 47 | }, 48 | .vmdq_rx_conf = { 49 | .nb_queue_pools = ETH_32_POOLS, 50 | .enable_default_pool = 0, 51 | .default_pool = 0, 52 | .nb_pool_maps = 0, 53 | .pool_map = {{0, 0},}, 54 | }, 55 | }, 56 | .tx_adv_conf = { 57 | .vmdq_dcb_tx_conf = { 58 | .nb_queue_pools = ETH_32_POOLS, 59 | .dcb_tc = {0}, 60 | }, 61 | }, 62 | }; 63 | 64 | // ------------- prototypes ---------------------------------------------- 65 | 66 | extern int vfd_dcb_config( sriov_port_t *pf ); 67 | int dcb_port_init( sriov_port_t *pf, __attribute__((__unused__)) struct rte_mempool *mbuf_pool); 68 | 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/support/tests/README: -------------------------------------------------------------------------------- 1 | TESTS: 2 | 3 | To run the tests we need two nodes(HOST1, HOST2 with Linux installed) connected with crossover cable. 4 | 5 | HOST1 (Install VFd and run "gobbler" dpdk app) 6 | HOST2 (The test scripts to run) 7 | 8 | HOST2 setup: 9 | apt install -y python-dev && libpcap-dev 10 | apt install -y python-virtualenv 11 | virtualenv venv 12 | source venv/bin/activate 13 | pip install -U pip 14 | pip install -r requirements.txt 15 | 16 | tests 17 | ├── conftest.py 18 | ├── helper_functions.py 19 | ├── __init__.py 20 | ├── packet.py 21 | ├── parse_sample_data.py 22 | ├── README 23 | ├── requirements.txt 24 | ├── sample_data.ini 25 | ├── sample_data.ini.stripF 26 | ├── sample_data.ini.stripT 27 | ├── strip_vlan_disable 28 | │   ├── __init__.py 29 | │   ├── test_bcastF_mcastF_ucastF.py 30 | │   ├── test_bcastF_mcastT_ucastF.py 31 | │   ├── test_bcastT_mcastT_ucastF.py 32 | │   └── test_bcastT_mcastT_ucastT.py 33 | └── strip_vlan_enable 34 | ├── __init__.py 35 | ├── test_bcastF_mcastF_ucastF.py 36 | ├── test_bcastF_mcastT_ucastF.py 37 | ├── test_bcastT_mcastT_ucastF.py 38 | └── test_bcastT_mcastT_ucastT.py 39 | 40 | sample_data.ini -> Where we feed the VF config details 41 | sample_data.ini.stripF -> sample data for strip disabled 42 | sample_data.ini.stripT -> sample data for strip enabled (strip=true, works with only single vlan for now) 43 | strip_vlan_disable/ -> test scripts with strip disabled in the VF config 44 | strip_vlan_enable/ -> test scripts with strip enabled in the VF config 45 | 46 | NOTE: 47 | Don't try to create all the VF configs (in this case VF1, VF2, VF3, VF4) once on HOST1 (VFd running). 48 | 49 | HOST1: 50 | iplex add vf1_config 51 | HOST2: 52 | pytest -v strip_vlan_disable/test_bcastT_mcastT_ucastF.py (This tag will run TARGET_VF1 config, bcast = true, mcast = true, unicast = false) 53 | 54 | HOST1: 55 | iplex delete vf1_config 56 | iplex add vf2_config 57 | HOST2: 58 | pytest -v strip_vlan_disable/test_bcastF_mcastT_ucastF.py (This tag will run TARGET_VF2 config, bcast = false, mcast = true, unicast = false) 59 | 60 | HOST1: 61 | iplex delete vf2_config 62 | iplex add vf3_config 63 | HOST2: 64 | pytest -v strip_vlan_disable/test_bcastF_mcastF_ucastF.py (This tag will run TARGET_VF3 config, bcast = false, mcast = false, unicast = false) 65 | 66 | HOST1: 67 | iplex delete vf3_config 68 | iplex add vf4_config 69 | HOST2: 70 | pytest -v strip_vlan_disable/test_bcastT_mcastT_ucastT.py (This tag will run TARGET_VF4 config, bcast = true, mcast = true, unicast = true) 71 | 72 | Repeat the above steps for strip enable case. 73 | 74 | TODO: 75 | - Auotmate the configuration of VF's on HOST1 and run the tests on HOST2 76 | - Remove the duplicate code 77 | - Add QinQ test cases 78 | - Add vlan antispoof test cases 79 | - Add MTU test cases 80 | -------------------------------------------------------------------------------- /src/lib/mkfile: -------------------------------------------------------------------------------- 1 | # mk is better (see plan-9) 2 | MKSHELL = ksh 3 | 4 | # jsmn no longer builds into a library 5 | jsmn_lib = 6 | cc = gcc 7 | cflags = -I jsmn -g 8 | 9 | binaries = jwrapper_test parm_file_test list_test fifo_test bleat_test id_mgr_test filesys_test pfx_list_test vf_config_test 10 | 11 | %.o: %.c 12 | $cc $cflags -c $prereq 13 | 14 | all:V: jsmn libvfd.a 15 | 16 | lib = libvfd.a 17 | lib_src = jwrapper jw_xapi symtab config ng_flowmgr fifo list_files bleat hot_plug id_mgr filesys 18 | $lib(%.o):N: %.o 19 | $lib: ${lib_src:%=$lib(%.o)} 20 | ksh '( 21 | set -e 22 | names="${newprereq//$lib\(}" # pluck off lib.*( from each in newprereq 23 | ar r $lib ${names//\)/} && rm ${names//\)/} # archive and remove after ditching trailing ) from each name 24 | ranlib $lib ||true 25 | )' 26 | 27 | # deprecated; now in main .h 28 | #jwrapper.h: jwrapper.c 29 | # grep "^extern.*{$" jwrapper.c | sed 's/ {$/;/' >jwrapper.h 30 | 31 | # --------- tests ---------------------------------------------------- 32 | jwrapper_test:: jwrapper_test.c vfdlib.h jwrapper.o symtab.o 33 | $cc $cflags jwrapper_test.c -o jwrapper_test jwrapper.o symtab.o $jsmn_lib 34 | 35 | jwrapper_test2:: jwrapper_test2.c vfdlib.h jwrapper.o symtab.o 36 | $cc $cflags jwrapper_test2.c -o jwrapper_test2 jwrapper.o symtab.o $jsmn_lib 37 | 38 | parm_file_test:: parm_file_test.c $lib 39 | $cc $cflags parm_file_test.c -o parm_file_test -L. -lvfd $jsmn_lib 40 | 41 | vf_config_test:: vf_config_test.c $lib 42 | $cc $cflags vf_config_test.c -o vf_config_test -L. -lvfd $jsmn_lib 43 | 44 | fifo_test:: fifo_test.c $lib 45 | $cc $cflags fifo_test.c -o fifo_test -L. -lvfd $jsmn_lib 46 | 47 | bleat_test:: bleat_test.c $lib 48 | $cc $cflags bleat_test.c -o bleat_test -L. -lvfd $jsmn_lib 49 | 50 | list_test:: list_test.c $lib 51 | $cc $cflags list_test.c -o list_test -L. -lvfd $jsmn_lib 52 | 53 | old_list_test:: old_list_test.c $lib 54 | $cc $cflags old_list_test.c -o old_list_test -L. -lvfd $jsmn_lib 55 | 56 | pfx_list_test:: pfx_list_test.c $lib 57 | $cc $cflags pfx_list_test.c -o pfx_list_test -L. -lvfd $jsmn_lib 58 | 59 | id_mgr_test:: id_mgr_test.c $lib 60 | $cc $cflags id_mgr_test.c -o id_mgr_test -L. -lvfd $jsmn_lib 61 | 62 | filesys_test:: filesys_test.c $lib 63 | $cc $cflags filesys_test.c -o filesys_test -L. -lvfd $jsmn_lib 64 | 65 | hot_plug_test:: hot_plug_test.c $lib 66 | $cc $cflags hot_plug_test.c -o hot_plug_test -L. -lvfd $jsmn_lib 67 | 68 | 69 | all_tests:V: $binaries 70 | 71 | #jwrapper_test jwrapper_test2 parm_file_test vf_config_test fifo_test bleat_test \ 72 | # list_test pfx_list_test id_mgr_test filesys_test hot_plug_test hot_plug_test 73 | 74 | 75 | test:V: 76 | ksh jwrapper_test.ksh 77 | 78 | nuke:V: 79 | rm -f *.o *.a $binaries 80 | 81 | 82 | # ------ clone (if needed) and update and build jsmn ------- 83 | jsmn:V: 84 | if [[ ! -d jsmn ]] 85 | then 86 | git clone https://github.com/zserge/jsmn 87 | fi 88 | cd jsmn 89 | git pull 90 | make 91 | -------------------------------------------------------------------------------- /src/vfd/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Mnemonic: Makefile 3 | # Abstract: Builds vfd and related components 4 | # CAUTION: this imports dpdk make things and behaviour is thus somewhat 5 | # non-standard/unpredictable at times. 6 | # Author: Alex Zelezniak 7 | # Date: February 2016 8 | # Mods: 28 Oct 2016 - Add version string based on commit 9 | # ------------------------------------------------------------------------------------- 10 | 11 | 12 | #### change this if needed 13 | #libconf = /usr/lib/x86_64-linux-gnu/libconfig.a 14 | libvfd = $(PWD)/../lib/libvfd.a 15 | 16 | # jsmn no longer builds into a library 17 | libjsmn = 18 | headers = $(PWD)/../lib/vfdlib.h 19 | patch_dir = $(PWD)/../dpdk_patches 20 | 21 | ifeq ($(RTE_SDK),) 22 | $(error "Please define RTE_SDK environment variable") 23 | endif 24 | 25 | VFD_KERNEL=0 26 | 27 | # Default target, can be overridden by command line or environment 28 | RTE_TARGET ?= x86_64-vfd-linuxapp-gcc 29 | 30 | include $(RTE_SDK)/mk/rte.vars.mk 31 | 32 | 33 | # binary name (all build rules are in rte.extapp.mk in the dpdk clone) 34 | APP = vfd 35 | 36 | # Build the version string. Would have been better to do in a local script 37 | # but dpdk make process shifts things away to the point that invoking a 38 | # script here seemed even more dodgy. 39 | # 40 | 41 | VFD_VERSION = $(shell junk=$$( (git log -n 1 2>/dev/null || echo Commit non-git-build ) | awk '/^[Cc]ommit / { cid=$$NF; exit(0); } /Date:/ {$$1=""; d=$$0} END { printf( "%s|%s\n", cid, d ) }' );\ 42 | cid="$${junk%%\|*}";\ 43 | date="$${junk\#\#*\|}";\ 44 | tag=$$( git tag -l --contains $$cid 2>/dev/null | head -1 );\ 45 | patches=$$( $(patch_dir)/verify_patches.ksh -d $(patch_dir) -b 2>/dev/null | head -1 );\ 46 | mod=$$( git status 2>/dev/null | awk '/modified:/ { m="+++" } END { print m }' );\ 47 | printf "%s%s%s\n" "$$mod" "$$cid-$${tag:-notag}-$${patches}" "$$date"; ) 48 | 49 | 50 | 51 | 52 | # all source are stored in SRCS-y (again, for the dpdk mk file) 53 | #SRCS-y := main.c sriov.c /usr/local/lib/libconfig.a 54 | ifeq ($(VFD_KERNEL),1) 55 | SRCS-y := main.c sriov.c qos.c vfd_mac.c vfd_rif.c vfd_dcb.c vfd_i40e.c vfd_ixgbe.c vfd_bnxt.c vfd_mlx5.c vfd_nl.c $(libvfd) $(libjsmn) 56 | else 57 | SRCS-y := main.c sriov.c qos.c vfd_mac.c vfd_rif.c vfd_dcb.c vfd_i40e.c vfd_ixgbe.c vfd_bnxt.c vfd_mlx5.c $(libvfd) $(libjsmn) 58 | endif 59 | 60 | CFLAGS += $(WERROR_FLAGS) -I $(PWD)/../lib/ -I $(RTE_SDK) -DVFD_KERNEL=${VFD_KERNEL} 61 | CFLAGS += -DALLOW_EXPERIMENTAL_API 62 | 63 | #-lconfig 64 | 65 | # workaround for a gcc bug with noreturn attribute 66 | # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603 67 | ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) 68 | CFLAGS_main.o += -Wno-return-type 69 | endif 70 | 71 | 72 | EXTRA_CFLAGS += -O3 -pg -Wfatal-errors -DVFD_VERSION='"$(VFD_VERSION)"' 73 | 74 | 75 | 76 | include $(RTE_SDK)/mk/rte.extapp.mk 77 | 78 | clean: 79 | rm -rf build 80 | 81 | verify: 82 | echo "$(VFD_VERSION)" 83 | $(patch_dir)/verify_patches.ksh -d $${PWD%/*}/dpdk_patches -f -v 84 | -------------------------------------------------------------------------------- /src/support/dpdk_app/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** az 4 | ** 5 | */ 6 | 7 | #ifndef __UTILS_H_ 8 | #define __UTILS_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #define NETWORK_ENTRY 0 29 | #define NETMASK_ENTRY 1 30 | #define BROADCAST_ENTRY 2 31 | #define NETMASK_V6_ENTRY 3 32 | #define INVALIDNETMASK -1 33 | 34 | #define NETWORK_SIZE 4 /* [0]=network, [1]=mask, [2]=broadcast [3]=mask v6 */ 35 | #define IPALLEN 4 36 | 37 | 38 | 39 | #define TRACE_EMERG 0, __FILE__, __LINE__ /* system is unusable */ 40 | #define TRACE_ALERT 1, __FILE__, __LINE__ /* action must be taken immediately */ 41 | #define TRACE_CRIT 2, __FILE__, __LINE__ /* critical conditions */ 42 | #define TRACE_ERROR 3, __FILE__, __LINE__ /* error conditions */ 43 | #define TRACE_WARNING 4, __FILE__, __LINE__ /* warning conditions */ 44 | #define TRACE_NORMAL 5, __FILE__, __LINE__ /* normal but significant condition */ 45 | #define TRACE_INFO 6, __FILE__, __LINE__ /* informational */ 46 | #define TRACE_DEBUG 7, __FILE__, __LINE__ /* debug-level messages */ 47 | 48 | 49 | #define simpe_atomic_swap(var, newval) __sync_lock_test_and_set(&var, newval) 50 | #define barrier() __sync_synchronize() 51 | 52 | 53 | typedef unsigned char __u8; 54 | typedef unsigned int uint128_t __attribute__((mode(TI))); 55 | 56 | 57 | #define __UINT128__ 58 | 59 | int traceLevel; 60 | int useSyslog; 61 | int logFacility; 62 | char * prog_name; 63 | 64 | int trace_lock; 65 | 66 | //static u_char syslog_opened = 0; 67 | 68 | inline uint64_t ntohll(uint64_t in); 69 | inline uint64_t htonll(uint64_t in); 70 | 71 | inline void ntoh128(uint128_t *src, uint128_t *dst); 72 | inline void hton128(uint128_t *src, uint128_t *dst); 73 | 74 | //inline int xdigit (char c); 75 | 76 | void hex_dump(const char *pref, u_int8_t *buf, size_t len, unsigned int width); 77 | void str2eth(u_int8_t *addr, const char *str); 78 | inline int int2bits(int number); 79 | inline uint32_t str2addr(char *address); 80 | inline void str2v6addr (char *str, struct in6_addr *addr); 81 | inline int dotted2bits(char *mask); 82 | inline int charMask2bits(char *mask); 83 | inline uint32_t bits2mask(int bits); 84 | inline uint128_t bits2mask128(int bits); 85 | inline int lcmp(ulong *a, ulong *b); 86 | 87 | //void print_stats(struct e1000_handle *h); 88 | char * _intoaV4(unsigned int addr, char * buf, u_short bufLen); 89 | void traceLog(int eventTraceLevel, const char * file, int line, const char * format, ...); 90 | void daemonize(void); 91 | 92 | #endif 93 | 94 | -------------------------------------------------------------------------------- /doc/overview/figures/vlan_strip.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 0 32 #e0e0e0 11 | 0 33 #00e0a0 12 | 6 1755 405 7515 1125 13 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 14 | 3330 405 5400 405 5400 1080 3330 1080 3330 405 15 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 16 | 5400 405 7470 405 7470 1080 5400 1080 5400 405 17 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 18 | 1755 405 3330 405 3330 1080 1755 1080 1755 405 19 | 2 2 0 1 0 24 60 -1 20 0.000 0 0 -1 0 0 5 20 | 1755 450 7515 450 7515 1125 1755 1125 1755 450 21 | 4 0 0 50 -1 6 8 0.0000 4 105 1095 3375 585 Protocol Header\001 22 | 4 0 0 50 -1 6 8 0.0000 4 135 540 5490 585 Payload\001 23 | 4 0 0 50 -1 6 8 0.0000 4 105 1110 1845 585 Ethernet header\001 24 | -6 25 | 6 1260 1305 7515 2025 26 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 27 | 1260 1305 3330 1305 3330 1980 1260 1980 1260 1305 28 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 29 | 3330 1305 5400 1305 5400 1980 3330 1980 3330 1305 30 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 31 | 5400 1305 7470 1305 7470 1980 5400 1980 5400 1305 32 | 2 2 0 1 0 24 60 -1 20 0.000 0 0 -1 0 0 5 33 | 1260 1350 7515 1350 7515 2025 1260 2025 1260 1350 34 | 2 2 0 1 0 33 45 -1 20 0.000 0 0 -1 0 0 5 35 | 2520 1305 3015 1305 3015 1980 2520 1980 2520 1305 36 | 4 0 0 50 -1 6 8 0.0000 4 105 1110 1350 1485 Ethernet header\001 37 | 4 0 0 50 -1 6 8 0.0000 4 105 1095 3375 1485 Protocol Header\001 38 | 4 0 0 50 -1 6 8 0.0000 4 135 540 5490 1485 Payload\001 39 | -6 40 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 41 | 3330 2250 5400 2250 5400 2925 3330 2925 3330 2250 42 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 43 | 5400 2250 7470 2250 7470 2925 5400 2925 5400 2250 44 | 2 2 0 1 0 7 50 -1 20 0.000 0 0 -1 0 0 5 45 | 765 2250 3330 2250 3330 2925 765 2925 765 2250 46 | 2 2 0 1 0 33 45 -1 20 0.000 0 0 -1 0 0 5 47 | 2520 2250 3015 2250 3015 2925 2520 2925 2520 2250 48 | 2 2 0 1 0 32 45 -1 20 0.000 0 0 -1 0 0 5 49 | 2025 2250 2520 2250 2520 2925 2025 2925 2025 2250 50 | 2 2 0 1 0 24 60 -1 20 0.000 0 0 -1 0 0 5 51 | 810 2295 7515 2295 7515 2970 810 2970 810 2295 52 | 2 1 0 3 -1 7 50 -1 -1 0.000 0 0 -1 0 1 2 53 | 2 1 4.00 105.00 180.00 54 | 8010 675 8010 2655 55 | 2 1 0 3 -1 7 50 -1 -1 0.000 0 0 -1 0 1 2 56 | 2 1 4.00 105.00 180.00 57 | 495 2700 495 720 58 | 2 1 0 1 -1 7 40 -1 -1 0.000 0 0 -1 1 0 3 59 | 1 1 1.00 60.00 120.00 60 | 3060 3195 2700 3195 2700 2700 61 | 2 1 0 1 -1 7 40 -1 -1 0.000 0 0 -1 1 0 3 62 | 1 1 1.00 60.00 120.00 63 | 3060 3420 2250 3420 2250 2655 64 | 4 0 -1 50 -1 6 14 0.0000 4 180 270 7875 2925 Rx\001 65 | 4 0 -1 50 -1 6 14 0.0000 4 180 225 360 675 Tx\001 66 | 4 0 0 50 -1 6 8 0.0000 4 105 1095 3375 2430 Protocol Header\001 67 | 4 0 0 50 -1 6 8 0.0000 4 135 540 5490 2430 Payload\001 68 | 4 0 0 50 -1 6 8 0.0000 4 105 1110 855 2430 Ethernet header\001 69 | 4 0 -1 50 -1 6 14 1.5708 4 225 975 8280 2295 Strip Tag\001 70 | 4 0 -1 50 -1 6 14 1.5708 4 225 1095 405 2070 Insert Tag\001 71 | 4 0 -1 55 -1 6 10 0.0000 4 150 1335 3105 3240 Inner 802.1q 'tag'\001 72 | 4 0 -1 55 -1 6 10 0.0000 4 150 1410 3150 3510 Outer 802.1q 'tag'\001 73 | -------------------------------------------------------------------------------- /src/lib/vf_config_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | Mneminic: vf_config_test.c 3 | Abstract: Unit test for vf config file parsing (part of config.c). 4 | Tests obvious things, may miss edge cases. 5 | Date: 04 February 2016 6 | Author: E. Scott Daniels 7 | 8 | Mods: 29 Nov 2016 - Added qshare verification. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "vfdlib.h" 19 | 20 | 21 | 22 | int main( int argc, char** argv ) { 23 | char* fname = "vf.cfg"; 24 | vf_config_t* vfc; 25 | int rc = 0; 26 | int i; 27 | 28 | if( argv[1] != NULL ) { 29 | fname = argv[1]; 30 | } 31 | vfc = read_config( fname ); 32 | if( vfc == NULL ) { 33 | fprintf( stderr, "[FAIL] unable to read and/or parse config file %s: %s\n", fname, strerror( errno ) ); 34 | rc = 1; 35 | } else { 36 | fprintf( stderr, "[OK] Able to open, read and parse json in config file\n" ); 37 | fprintf( stderr, " configs read:\n" ); 38 | fprintf( stderr, "\towner: %d\n", vfc->owner ); 39 | fprintf( stderr, "\tname: %s\n", vfc->name ); 40 | fprintf( stderr, "\tvfid: %d\n", vfc->vfid ); 41 | fprintf( stderr, "\tpciid: %s\n", vfc->pciid ); 42 | if( vfc->start_cb != NULL ) { 43 | fprintf( stderr, "\tstart_cb: %s\n", vfc->start_cb ); 44 | } else { 45 | fprintf( stderr, "\tstart_cb: not supplied\n" ); 46 | } 47 | if( vfc->stop_cb != NULL ) { 48 | fprintf( stderr, "\tstop_cb: %s\n", vfc->stop_cb ); 49 | } else { 50 | fprintf( stderr, "\tstop_cb: not supplied\n" ); 51 | } 52 | fprintf( stderr, "\tstrip_stag: %d\n", vfc->strip_stag ); 53 | fprintf( stderr, "\tallow_bcast: %d\n", vfc->allow_bcast ); 54 | fprintf( stderr, "\tallow_mcast: %d\n", vfc->allow_mcast ); 55 | fprintf( stderr, "\tallow_un_ucast: %d\n", vfc->allow_un_ucast ); 56 | fprintf( stderr, "\tantispoof_mac: %d\n", vfc->antispoof_mac ); 57 | fprintf( stderr, "\tantispoof_vlan: %d\n", vfc->antispoof_vlan ); 58 | fprintf( stderr, "\tvm_mac: %s\n", vfc->vm_mac ); 59 | fprintf( stderr, "\tlink_status: %s\n", vfc->link_status ); 60 | fprintf( stderr, "\tmirror_dir: %d\n", vfc->mirror_dir ); 61 | fprintf( stderr, "\tmirror_target: %d\n", vfc->mirror_target ); 62 | 63 | fprintf( stderr, "\tnvlans: %d\n", vfc->nvlans ); 64 | for( i = 0; i < vfc->nvlans; i++ ) { 65 | fprintf( stderr, "\t\tvlan[%d] = %d\n", i, vfc->vlans[i] ); 66 | } 67 | fprintf( stderr, "\tnmacs: %d\n", vfc->nmacs ); 68 | for( i = 0; i < vfc->nmacs; i++ ) { 69 | fprintf( stderr, "\t\tmac[%d] = %s\n", i, vfc->macs[i] ); 70 | } 71 | 72 | fprintf( stderr, "\tqshares: " ); 73 | for( i = 0; i < 8; i++ ) { 74 | fprintf( stderr, "%3d ", vfc->qshare[i] ); 75 | } 76 | fprintf( stderr, "\n" ); 77 | 78 | free_config( vfc ); 79 | } 80 | 81 | 82 | // ensure that we get a failure if the file isn't there 83 | vfc = read_config( "/hosuchdir/nosuchfile" ); 84 | if( vfc == NULL ) { 85 | fprintf( stderr, "[OK] attempt to open a nonexistant file was rejected, as expected\n" ); 86 | } else { 87 | fprintf( stderr, "[FAIL] attempt to open a nonexistant file was NOT rejected as expected\n" ); 88 | rc = 1; 89 | } 90 | 91 | exit( rc ); // bad exit if we failed a test 92 | } 93 | -------------------------------------------------------------------------------- /doc/operations/vf_config.md: -------------------------------------------------------------------------------- 1 | 2 | #VF Configuration File Layout 3 | 4 | 5 | A VF configuration file is expected to be written by the virtualisation manager (e.g. openstack) 6 | into the config directory listed in the main VFd configuration file in the /etc/vdd directory. 7 | The file is a single json 'object' which identifies the VF (by pci address and interface number) and 8 | supplies the configuration information. 9 | 10 | The following is the expected syntax of the file: 11 | 12 | 13 | 14 | ``` 15 | { 16 | "name": "name/uuid", 17 | "pciid": "0000:07:00.1", 18 | "vfid": 0, 19 | "strip_stag": {true|false}, 20 | "allow_bcast": {true|false}, 21 | "allow_mcast": {true|false}, 22 | "allow_un_ucast": {true|false}, 23 | "link_status": "{on|off|auto}", 24 | "stop_cb": "/path/command parms", 25 | "start_cb": "/path/command parms", 26 | "vlans": [ 10, 11, 12, 33 ], 27 | "macs": [ "aa:bb:cc:dd:ee:f0", "11:22:33:44:55:66", "ff:ff:ff:ff:ff:ff" ] 28 | } 29 | ``` 30 | 31 | ## Field Descriptions 32 | The following are descriptions of the various fields supported. If the field is optional a default value 33 | is given in parenthisis following the description. 34 | 35 | `name` A string which identifies the VF. VFd does not use the name; it is only for the convenience of the creator. (blank) 36 | 37 | `pciid` The address of the PF on which the VF is allocated 38 | 39 | `vfid` The id (0-31) of the VF that is being configured 40 | 41 | `strip_stag` A boolean value that when true will cause the NIC to remove the VLAN ID from packets before they are given to the VF. 42 | When true, this option implies that VLAN ID is inserted as packets are sent (there is no separate insert option). (false) 43 | 44 | `allow_bcast` A boolean value which when true allows broadcast messages to be received by the VF from the wire. (true) 45 | 46 | `allow_mcast` A boolean value which when true allows multicast messages to be received by the VF from the wire. (true) 47 | 48 | `allow_un_ucast` A boolean value which when true allows unicast messages to MACs not belonging to the VF to be received by the VF from the wire, i.e., promiscous mode. (true) 49 | 50 | `link_status` Sets one of three possible modes: on (status always reported to the VF), off (status never reported), auto (NIC decides when to report) (auto) 51 | 52 | `stop_cb` The command line of a command that VFd will execute just prior to VFd shutdown. (empty) 53 | 54 | `start_cb` The command line of a command that VFd will execute immediately following initialisation (before any new ipelx requests are processed). (empty) 55 | 56 | `vlans` An array of VLAN IDs which are used as a filter for the VF; only packets with these IDs will be passed by the NIC. If the 57 | list contains more than one value, then `strip_stag` *must* be false or VFd will toss and error and refuse to add the VF. 58 | 59 | `macs` An array of mac addresses which are used to filter outgoing packets to the wire. I.e., this acts as an anti-spoof filter. The MAC address of the VF is always an implied member. So, this array may be empty (e.g. []) to indicate the current MAC address of the VF is the only address which should be used as a filter. 60 | -------------------------------------------------------------------------------- /src/system/vfd.cfg.sample: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "sample VFd configuration", 3 | "huge": true, 4 | "log_dir": "/var/log/vfd", 5 | "log_keep": 10, 6 | "log_level": 1, 7 | "init_log_level": 3, 8 | "dpdk_log_level": 1, 9 | "dpdk_init_log_level": 2, 10 | "config_dir": "/var/lib/vfd/config", 11 | "fifo": "/var/lib/vfd/request", 12 | "cpu_mask": "0x01", 13 | "cpu_alarm": "15%", 14 | "cpu_alarm_type": "WRN:", 15 | "numa_mem": "64,64", 16 | "default_mtu": 1500, 17 | "enable_qos": false, 18 | "enable_flowcontrol": false, 19 | 20 | "pciids": [ 21 | { "id": "0000:08:00.0", 22 | "promiscuous": false, 23 | "mtu": 9240, 24 | "hw_strip_crc": true, 25 | "enable_loopback": true, 26 | "pf_driver": "igb-uio", 27 | "vf_driver": "vfio-pci", 28 | "vf_oversubscription": true, 29 | 30 | "tc_comment": "traffic classes define human readable name, tc number (priority) and other parms", 31 | "tclasses": [ 32 | { 33 | "name": "best effort", 34 | "pri": 0, 35 | "llatency": false, 36 | "lsp": false, 37 | "bsp": false, 38 | "max_bw": 100, 39 | "min_bw": 10 40 | }, 41 | { 42 | "name": "realtime", 43 | "pri": 1, 44 | "llatency": false, 45 | "lsp": false, 46 | "bsp": false, 47 | "max_bw": 100, 48 | "min_bw": 40 49 | }, 50 | { 51 | "name": "voice", 52 | "pri": 2, 53 | "llatency": false, 54 | "lsp": false, 55 | "bsp": false, 56 | "max_bw": 100, 57 | "min_bw": 40 58 | }, 59 | { 60 | "name": "control", 61 | "pri": 3, 62 | "llatency": false, 63 | "lsp": false, 64 | "bsp": false, 65 | "max_bw": 100, 66 | "min_bw": 10 67 | } 68 | ], 69 | 70 | "bwg_comment": "groups traffic classes together, min derived from TC values", 71 | "bw_grps": 72 | { 73 | "bwg0": [0], 74 | "bwg1": [1, 2], 75 | "bwg2": [3] 76 | } 77 | }, 78 | 79 | { "id": "0000:08:00.1", 80 | "hw_strip_crc": false, 81 | "promiscuous": false, 82 | "mtu": 9240, 83 | "enable_loopback": true, 84 | "pf_driver": "igb-uio", 85 | "vf_driver": "vfio-pci", 86 | "vf_oversubscription": false, 87 | 88 | "tclasses": [ 89 | { 90 | "name": "best effort", 91 | "pri": 0, 92 | "llatency": false, 93 | "lsp": false, 94 | "bsp": false, 95 | "max_bw": 100, 96 | "min_bw": 10 97 | }, 98 | { 99 | "name": "realtime", 100 | "pri": 1, 101 | "llatency": false, 102 | "lsp": false, 103 | "bsp": false, 104 | "max_bw": 100, 105 | "min_bw": 40 106 | }, 107 | { 108 | "name": "voice", 109 | "pri": 2, 110 | "llatency": false, 111 | "lsp": false, 112 | "bsp": false, 113 | "max_bw": 100, 114 | "min_bw": 40 115 | }, 116 | { 117 | "name": "control", 118 | "pri": 3, 119 | "llatency": false, 120 | "lsp": false, 121 | "bsp": false, 122 | "max_bw": 100, 123 | "min_bw": 10 124 | } 125 | ], 126 | 127 | "bw_grps": 128 | { 129 | "bwg0": [0], 130 | "bwg1": [1, 2], 131 | "bwg2": [3] 132 | } 133 | } 134 | ] 135 | } 136 | -------------------------------------------------------------------------------- /src/lib/jw_xapi.c: -------------------------------------------------------------------------------- 1 | //vi: ts=4 sw=4 noet: 2 | /* 3 | Mnemonic: jw_xapi.c 4 | Abstract: This is an extended api set for the 'primatives' in jwrapper. 5 | Author: E. Scott Daniels 6 | Date: 11 Feb 2017 7 | 8 | Mods: 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #define JSMN_STATIC 1 // jsmn no longer builds into a library; this pulls as static functions 16 | #include 17 | 18 | #include "vfdlib.h" 19 | #include "symtab.h" 20 | 21 | 22 | /* 23 | Look up a boolean returning the default if it's not a boolean or not defined. 24 | */ 25 | extern int jwx_get_bool( void* jblob, char const* field_name, int def_value ) { 26 | if( !jw_is_bool( jblob, field_name ) ) { 27 | return def_value; 28 | } 29 | 30 | return jw_value( jblob, field_name ); 31 | } 32 | 33 | /* 34 | Return the value from the json blob, or the default if it is not a value 35 | */ 36 | extern float jwx_get_value( void* jblob, char const* field_name, float def_value ) { 37 | if( !jw_is_value( jblob, field_name ) ) { 38 | return def_value; 39 | } 40 | 41 | return jw_value( jblob, field_name ); 42 | } 43 | 44 | /* 45 | Return the value from the json blob as an integer, or the default if it is not a value 46 | */ 47 | extern int jwx_get_ivalue( void* jblob, char const* field_name, int def_value ) { 48 | if( !jw_is_value( jblob, field_name ) ) { 49 | return def_value; 50 | } 51 | 52 | return (int) jw_value( jblob, field_name ); 53 | } 54 | 55 | /* 56 | There are cases where we need a 57 | For cases where a 'value' needs to be used as a string, this will pull the 58 | value from the blob and converts it using the format type passed in. If the 59 | field name is a string in the blob it is returned as is. If the field name 60 | does not exist, the default is returned. 61 | Fmt is one of the JWFMT_ constants. 62 | */ 63 | extern char* jwx_get_value_as_str( void* jblob, char const* field_name, char const* def_value, int fmt ) { 64 | float jvalue; // value from json 65 | char stuff[128]; // should be more than enough :) 66 | char* jstr; // if represented in json as a string 67 | 68 | if( jw_is_value( jblob, field_name ) ) { 69 | jvalue = jw_value( jblob, field_name ); 70 | switch( fmt ) { 71 | case JWFMT_INT: 72 | snprintf( stuff, sizeof( stuff ), "%d", (int) jvalue ); 73 | break; 74 | case JWFMT_FLOAT: 75 | snprintf( stuff, sizeof( stuff ), "%f", jvalue ); 76 | 77 | case JWFMT_HEX: 78 | snprintf( stuff, sizeof( stuff ), "0x%x", (int) jvalue ); 79 | } 80 | return strdup( stuff ); 81 | } 82 | 83 | if( (jstr = jw_string( jblob, field_name )) ) { // if already a string, return that 84 | return strdup( jstr ); 85 | } 86 | 87 | if( def_value ) { // neither way in json, so use default if supplied 88 | return strdup( def_value ); 89 | } 90 | 91 | return NULL; 92 | } 93 | 94 | /* 95 | Looks up field name and returns the value from jblob if its a string. 96 | If it's not a string in the json, then the def_value string is duplicated 97 | and returned. 98 | */ 99 | extern char* jwx_get_str( void* jblob, char const* field_name, char const* def_value ) { 100 | char* stuff; 101 | 102 | if( (stuff = jw_string( jblob, field_name )) ) { 103 | return strdup( stuff ); 104 | } 105 | 106 | if( def_value ) { 107 | return strdup( def_value ); 108 | } 109 | 110 | return NULL; 111 | } 112 | -------------------------------------------------------------------------------- /src/lib/bleat_test.c: -------------------------------------------------------------------------------- 1 | // :vi ts=4 sw=4: 2 | /* 3 | Mneminic: bleat_test.c 4 | Abstract: Unit test for the bleat module. 5 | Tests obvious things, may miss edge cases. 6 | 7 | bleat_test [roll-seconds] [purge-seconds dir log_prefix] 8 | 9 | If seconds are given, then a test of purging log files 10 | in the current directory is made. Log files older than 11 | seconds should be purged when the log file is rolled during 12 | the test. 13 | 14 | 15 | Date: 08 March 2016 16 | Author: E. Scott Daniels 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "vfdlib.h" 28 | 29 | int main( int argc, char** argv ) { 30 | int id = 0; 31 | int psec = 0; 32 | int rsec = 0; // seconds to wait when testing log roll 33 | 34 | 35 | id = getppid(); 36 | 37 | if( argc > 1 ) { 38 | rsec = atoi( argv[1] ); 39 | if( rsec < 300 ) { 40 | fprintf( stderr, "roll second test requires a wait of at least 300s; using 300\n" ); 41 | rsec = 300; 42 | } 43 | } 44 | 45 | if( argc > 4 ) { // if purg-seconds directory, prefix, seconds supplied 46 | if( (psec = atoi( argv[2] )) < 5 ) { 47 | fprintf( stderr, "purge seconds must be >= 5; using 5 seconds\n" ); 48 | psec = 5; 49 | } 50 | fprintf( stderr, "setting purge threshold to %d\n", psec ); 51 | bleat_set_purge( argv[3], argv[4], psec ); 52 | } 53 | 54 | // these should go to stderr 55 | bleat_set_lvl( 1 ); 56 | bleat_printf( 1, "this is a level 1 message should be SEEN" ); 57 | bleat_printf( 2, "this message should NOT be seen it is level 2" ); 58 | bleat_printf( 0, "this is a level 0 should be SEEN data: %d", id ); // test ability to add printf style data 59 | 60 | bleat_push_lvl( 2 ); 61 | bleat_printf( 2, "level set to 2 so this should be SEEN " ); 62 | bleat_pop_lvl( ); 63 | bleat_printf( 2, "level reset so this should NOT be seen " ); 64 | 65 | bleat_set_lvl( 2 ); // hard level set test 66 | bleat_printf( 2, "level set to 2 so this should be SEEN " ); 67 | bleat_printf( 3, "lvl 3 msg: but level is currently set to 2 so this should be NOT be seen" ); 68 | bleat_set_lvl( 1 ); // hard set back 69 | bleat_printf( 2, "lvl 2 msg: level reverted to 1 so this should NOT be seen" ); 70 | 71 | // these should to to foo.log (no rolling) in the current directory 72 | bleat_printf( 0, "setting log to foo.log, look there for other messages" ); 73 | bleat_set_log( "foo.log", 0 ); 74 | bleat_printf( 1, "this is a level 1 message should be SEEN" ); 75 | bleat_printf( 2, "this message should NOT be seen it is level 2" ); 76 | bleat_printf( 0, "this is a level 0 should be SEEN data: %d", id ); 77 | 78 | if( rsec > 0 ) { 79 | // these should to to foo.log. in the current directory, hms should be added and the 80 | // log should 'roll' on rsec boundaries 81 | bleat_printf( 0, "setting log to foo.log., look there for other messages" ); 82 | bleat_set_log( "foo.log", rsec ); 83 | bleat_printf( 1, "this is a level 1 message should be SEEN" ); 84 | bleat_printf( 2, "this message should NOT be seen it is level 2" ); 85 | bleat_printf( 0, "this is a level 0 should be SEEN data: %d", id ); 86 | 87 | fprintf( stderr, "sleeping %d sec to test log file date rolling, next roll = %ld\n", rsec, (long )bleat_next_roll() ); 88 | sleep( rsec ); 89 | bleat_printf( 0, "this bleat should be SEEN in the rolled log file" ); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/support/tests/conftest.py: -------------------------------------------------------------------------------- 1 | from tests.parse_sample_data import section_map 2 | import pytest 3 | 4 | vf1_macs_list = [mac.strip() for mac in section_map('TARGET_VF1')['mac_list'].split(',')] 5 | vf1_invalid_macs_list = [mac.strip() for mac in section_map('TARGET_VF1')['invalid_macs'].split(',')] 6 | vf1_valid_vlans_list = [vlan.strip() for vlan in section_map('TARGET_VF1')['valid_vlans'].split(',')] 7 | vf1_invalid_vlans_list = [vlan.strip() for vlan in section_map('TARGET_VF1')['invalid_vlans'].split(',')] 8 | 9 | vf2_macs_list = [mac.strip() for mac in section_map('TARGET_VF2')['mac_list'].split(',')] 10 | vf2_invalid_macs_list = [mac.strip() for mac in section_map('TARGET_VF2')['invalid_macs'].split(',')] 11 | vf2_valid_vlans_list = [vlan.strip() for vlan in section_map('TARGET_VF2')['valid_vlans'].split(',')] 12 | vf2_invalid_vlans_list = [vlan.strip() for vlan in section_map('TARGET_VF2')['invalid_vlans'].split(',')] 13 | 14 | vf3_macs_list = [mac.strip() for mac in section_map('TARGET_VF3')['mac_list'].split(',')] 15 | vf3_invalid_macs_list = [mac.strip() for mac in section_map('TARGET_VF3')['invalid_macs'].split(',')] 16 | vf3_valid_vlans_list = [vlan.strip() for vlan in section_map('TARGET_VF3')['valid_vlans'].split(',')] 17 | vf3_invalid_vlans_list = [vlan.strip() for vlan in section_map('TARGET_VF3')['invalid_vlans'].split(',')] 18 | 19 | vf4_macs_list = [mac.strip() for mac in section_map('TARGET_VF4')['mac_list'].split(',')] 20 | vf4_invalid_macs_list = [mac.strip() for mac in section_map('TARGET_VF4')['invalid_macs'].split(',')] 21 | vf4_valid_vlans_list = [vlan.strip() for vlan in section_map('TARGET_VF4')['valid_vlans'].split(',')] 22 | vf4_invalid_vlans_list = [vlan.strip() for vlan in section_map('TARGET_VF4')['invalid_vlans'].split(',')] 23 | 24 | @pytest.fixture(params=vf1_macs_list) 25 | def vf1_mac(request): 26 | return request.param 27 | 28 | @pytest.fixture(params=vf1_invalid_macs_list) 29 | def vf1_invalid_mac(request): 30 | return request.param 31 | 32 | @pytest.fixture(params=vf1_valid_vlans_list) 33 | def vf1_valid_vlan(request): 34 | return request.param 35 | 36 | @pytest.fixture(params=vf1_invalid_vlans_list) 37 | def vf1_invalid_vlan(request): 38 | return request.param 39 | 40 | @pytest.fixture(params=vf2_macs_list) 41 | def vf2_mac(request): 42 | return request.param 43 | 44 | @pytest.fixture(params=vf2_invalid_macs_list) 45 | def vf2_invalid_mac(request): 46 | return request.param 47 | 48 | @pytest.fixture(params=vf2_valid_vlans_list) 49 | def vf2_valid_vlan(request): 50 | return request.param 51 | 52 | @pytest.fixture(params=vf2_invalid_vlans_list) 53 | def vf2_invalid_vlan(request): 54 | return request.param 55 | 56 | @pytest.fixture(params=vf3_macs_list) 57 | def vf3_mac(request): 58 | return request.param 59 | 60 | @pytest.fixture(params=vf3_invalid_macs_list) 61 | def vf3_invalid_mac(request): 62 | return request.param 63 | 64 | @pytest.fixture(params=vf3_valid_vlans_list) 65 | def vf3_valid_vlan(request): 66 | return request.param 67 | 68 | @pytest.fixture(params=vf3_invalid_vlans_list) 69 | def vf3_invalid_vlan(request): 70 | return request.param 71 | 72 | @pytest.fixture(params=vf4_macs_list) 73 | def vf4_mac(request): 74 | return request.param 75 | 76 | @pytest.fixture(params=vf4_invalid_macs_list) 77 | def vf4_invalid_mac(request): 78 | return request.param 79 | 80 | @pytest.fixture(params=vf4_valid_vlans_list) 81 | def vf4_valid_vlan(request): 82 | return request.param 83 | 84 | @pytest.fixture(params=vf4_invalid_vlans_list) 85 | def vf4_invalid_vlan(request): 86 | return request.param 87 | -------------------------------------------------------------------------------- /src/vfd/vfd_i40e.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _VFD_I40E_H 3 | #define _VFD_I40E_H 4 | 5 | 6 | #include 7 | 8 | /* Opcodes for VF-PF communication. These are placed in the v_opcode field 9 | * of the virtchnl_msg structure. 10 | */ 11 | enum i40e_virtchnl_ops { 12 | /* The PF sends status change events to VFs using 13 | * the I40E_VIRTCHNL_OP_EVENT opcode. 14 | * VFs send requests to the PF using the other ops. 15 | */ 16 | I40E_VIRTCHNL_OP_UNKNOWN = 0, 17 | I40E_VIRTCHNL_OP_VERSION = 1, /* must ALWAYS be 1 */ 18 | I40E_VIRTCHNL_OP_RESET_VF = 2, 19 | I40E_VIRTCHNL_OP_GET_VF_RESOURCES = 3, 20 | I40E_VIRTCHNL_OP_CONFIG_TX_QUEUE = 4, 21 | I40E_VIRTCHNL_OP_CONFIG_RX_QUEUE = 5, 22 | I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES = 6, 23 | I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP = 7, 24 | I40E_VIRTCHNL_OP_ENABLE_QUEUES = 8, 25 | I40E_VIRTCHNL_OP_DISABLE_QUEUES = 9, 26 | I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS = 10, 27 | I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS = 11, 28 | I40E_VIRTCHNL_OP_ADD_VLAN = 12, 29 | I40E_VIRTCHNL_OP_DEL_VLAN = 13, 30 | I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE = 14, 31 | I40E_VIRTCHNL_OP_GET_STATS = 15, 32 | I40E_VIRTCHNL_OP_FCOE = 16, 33 | I40E_VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */ 34 | #ifdef I40E_SOL_VF_SUPPORT 35 | I40E_VIRTCHNL_OP_GET_ADDNL_SOL_CONFIG = 19, 36 | #endif 37 | I40E_VIRTCHNL_OP_CONFIG_RSS_KEY = 23, 38 | I40E_VIRTCHNL_OP_CONFIG_RSS_LUT = 24, 39 | I40E_VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25, 40 | I40E_VIRTCHNL_OP_SET_RSS_HENA = 26, 41 | I40E_VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27, 42 | I40E_VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28, 43 | I40E_VIRTCHNL_OP_REQUEST_QUEUES = 29, 44 | }; 45 | 46 | // ------------- prototypes ---------------------------------------------- 47 | 48 | int vfd_i40e_ping_vfs(uint16_t port, int16_t vf); 49 | int vfd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on); 50 | int vfd_i40e_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on); 51 | int vfd_i40e_set_tx_loopback(uint16_t port, uint8_t on); 52 | int vfd_i40e_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on); 53 | int vfd_i40e_set_vf_multicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on); 54 | int vfd_i40e_set_vf_mac_addr(uint16_t port, uint16_t vf_id, struct ether_addr *mac_addr); 55 | int vfd_i40e_set_vf_default_mac_addr(uint16_t port_id, uint16_t vf, struct ether_addr *mac_addr ); 56 | int vfd_i40e_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on); 57 | int vfd_i40e_set_vf_vlan_insert(uint16_t port, uint16_t vf_id, uint16_t vlan_id); 58 | int vfd_i40e_set_vf_broadcast(uint16_t port, uint16_t vf_id, uint8_t on); 59 | int vfd_i40e_allow_untagged(uint16_t port, uint16_t vf_id, uint8_t on); 60 | int vfd_i40e_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id, uint64_t vf_mask, uint8_t on); 61 | int vfd_i40e_get_vf_stats(uint16_t port, uint16_t vf_id, struct rte_eth_stats *stats); 62 | int vfd_i40e_reset_vf_stats(uint16_t port, uint16_t vf_id); 63 | int vfd_i40e_set_all_queues_drop_en(uint16_t port_id, uint8_t on); 64 | int vfd_i40e_vf_msb_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param, void *data); 65 | uint32_t vfd_i40e_get_pf_spoof_stats(uint16_t port_id); 66 | uint32_t vfd_i40e_get_vf_spoof_stats(uint16_t port_id, uint16_t vf_id); 67 | int vfd_i40e_is_rx_queue_on(uint16_t port_id, uint16_t vf_id, int* mcounter); 68 | void vfd_i40e_set_pfrx_drop(uint16_t port_id, int state ); 69 | void vfd_i40e_set_rx_drop(uint16_t port_id, uint16_t vf_id, int state); 70 | void vfd_i40e_set_split_erop(uint16_t port_id, uint16_t vf_id, int state); 71 | int vfd_i40e_get_split_ctlreg(uint16_t port_id, uint16_t vf_id); 72 | int vfd_i40e_dump_all_vlans(uint16_t port_id); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /doc/debugging/figures/diag_overview1.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 6 1890 1530 3060 2430 11 | 2 2 0 1 0 7 53 -1 20 0.000 0 0 -1 0 0 5 12 | 1890 1530 3060 1530 3060 2430 1890 2430 1890 1530 13 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 14 | 1890 1935 3015 1935 15 | 4 0 0 50 -1 4 10 0.0000 4 150 915 2025 1800 Application\001 16 | 4 0 0 50 -1 4 10 0.0000 4 120 855 2070 2250 DPDK PMD\001 17 | -6 18 | 6 3645 1305 4005 2205 19 | 2 4 0 1 0 19 53 -1 30 0.000 0 0 7 0 0 5 20 | 4005 1305 4005 2205 3645 2205 3645 1305 4005 1305 21 | 4 0 0 50 -1 4 10 1.5708 4 120 435 3915 2025 Driver\001 22 | -6 23 | 6 9810 1485 10260 2790 24 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 25 | 9810 1485 10260 1485 10260 2790 9810 2790 9810 1485 26 | 4 0 0 50 -1 4 10 1.5708 4 120 855 10080 2565 TO* Switch\001 27 | -6 28 | 6 7110 585 8100 1080 29 | 2 4 0 1 0 22 55 -1 30 0.000 0 0 7 0 0 5 30 | 8100 1080 7110 1080 7110 585 8100 585 8100 1080 31 | 4 0 0 50 -1 6 14 0.0000 4 180 450 7380 945 VFd\001 32 | -6 33 | 6 5715 720 6615 1080 34 | 2 4 0 1 0 19 55 -1 30 0.000 0 0 7 0 0 5 35 | 6615 1080 5715 1080 5715 720 6615 720 6615 1080 36 | 4 0 0 50 -1 4 10 0.0000 4 120 435 5940 945 Driver\001 37 | -6 38 | 2 2 0 1 0 7 52 -1 20 0.000 0 0 -1 0 0 5 39 | 4185 1395 4905 1395 4905 1665 4185 1665 4185 1395 40 | 2 2 0 1 0 7 52 -1 20 0.000 0 0 -1 0 0 5 41 | 4185 1800 4905 1800 4905 2070 4185 2070 4185 1800 42 | 2 2 0 1 0 6 55 -1 30 0.000 0 0 -1 0 0 5 43 | 6525 1575 9450 1575 9450 2925 6525 2925 6525 1575 44 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 45 | 6525 1845 9405 1845 46 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 47 | 6525 2070 9405 2070 48 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 49 | 6525 2295 9405 2295 50 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 51 | 6525 2520 9405 2520 52 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 53 | 6525 2700 9405 2700 54 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 55 | 9360 2430 9855 2430 56 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 57 | 4905 1530 6525 1935 58 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 59 | 4905 1935 6525 2610 60 | 2 2 0 1 0 17 55 -1 30 0.000 0 0 -1 0 0 5 61 | 1800 1125 4635 1125 4635 2790 1800 2790 1800 1125 62 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 63 | 1 1 1.00 60.00 120.00 64 | 1 1 1.00 60.00 120.00 65 | 3060 2115 3645 1845 66 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 67 | 3960 1485 4275 1485 68 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 69 | 3960 1890 4275 1890 70 | 2 2 0 1 0 31 60 -1 32 0.000 0 0 -1 0 0 5 71 | 1350 225 9225 225 9225 3150 1350 3150 1350 225 72 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 73 | 9360 1710 9855 1710 74 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 75 | 1 1 1.00 60.00 120.00 76 | 1 1 1.00 60.00 120.00 77 | 6840 1575 6165 1080 78 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 79 | 1 1 1.00 60.00 120.00 80 | 1 1 1.00 60.00 120.00 81 | 7110 810 6570 810 82 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 83 | 1 1 1.00 60.00 120.00 84 | 7290 945 7290 1530 85 | 4 0 0 50 -1 4 10 0.0000 4 120 375 4410 1575 vNIC\001 86 | 4 0 0 50 -1 4 10 0.0000 4 120 375 4365 1980 vNIC\001 87 | 4 0 0 50 -1 4 10 0.0000 4 120 270 6660 1755 PF0\001 88 | 4 0 0 50 -1 4 10 0.0000 4 120 270 6615 2475 PF1\001 89 | 4 0 0 50 -1 4 10 0.0000 4 120 285 6660 2025 VF0\001 90 | 4 0 0 50 -1 4 10 0.0000 4 120 285 6615 2655 VF0\001 91 | 4 0 0 50 -1 4 10 0.0000 4 120 300 6660 2250 VFn\001 92 | 4 0 0 50 -1 4 10 0.0000 4 120 300 6615 2880 VFn\001 93 | 4 0 0 50 -1 4 10 6.0214 4 120 540 5535 1620 SR-IOV\001 94 | 4 0 0 50 -1 6 12 0.0000 4 195 1185 8280 1530 Physical NIC\001 95 | 4 0 0 50 -1 4 14 0.0000 4 180 675 1890 1350 Guest\001 96 | 4 0 0 50 -1 6 14 0.0000 4 225 1485 1440 495 Physical Host\001 97 | -------------------------------------------------------------------------------- /doc/overview/figures/mirror_in.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 0 32 #909090 11 | 0 33 #b0b0b0 12 | 0 34 #c0c0c0 13 | 0 35 #707070 14 | 6 94 470 1461 2417 15 | 6 94 470 1461 1017 16 | 2 4 0 1 7 8 61 -1 20 0.000 0 0 7 0 0 5 17 | 1461 1017 126 1017 126 507 1461 507 1461 1017 18 | 2 4 0 1 0 7 60 -1 20 0.000 0 0 7 0 0 5 19 | 1429 980 94 980 94 470 1429 470 1429 980 20 | -6 21 | 6 94 1140 1461 1687 22 | 2 4 0 1 7 8 61 -1 20 0.000 0 0 7 0 0 5 23 | 1461 1687 126 1687 126 1177 1461 1177 1461 1687 24 | 2 4 0 1 0 7 60 -1 20 0.000 0 0 7 0 0 5 25 | 1429 1650 94 1650 94 1140 1429 1140 1429 1650 26 | -6 27 | 6 94 1870 1461 2417 28 | 2 4 0 1 7 8 61 -1 20 0.000 0 0 7 0 0 5 29 | 1461 2417 126 2417 126 1907 1461 1907 1461 2417 30 | 2 4 0 1 0 7 60 -1 20 0.000 0 0 7 0 0 5 31 | 1429 2380 94 2380 94 1870 1429 1870 1429 2380 32 | -6 33 | -6 34 | 6 2311 167 5291 3487 35 | 2 4 0 1 0 7 65 -1 20 0.000 0 0 7 0 0 5 36 | 5241 3437 2311 3437 2311 167 5241 167 5241 3437 37 | 2 4 0 1 7 18 66 -1 20 0.000 0 0 7 0 0 5 38 | 5291 3487 2361 3487 2361 217 5291 217 5291 3487 39 | -6 40 | 6 4500 1320 4635 2490 41 | 4 0 0 50 -1 18 10 0.0000 4 120 120 4507 1440 B\001 42 | 4 0 0 50 -1 18 10 0.0000 4 120 120 4507 1650 R\001 43 | 4 0 0 50 -1 18 10 0.0000 4 120 45 4545 1860 I\001 44 | 4 0 0 50 -1 18 10 0.0000 4 120 120 4507 2070 D\001 45 | 4 0 0 50 -1 18 10 0.0000 4 120 135 4500 2280 G\001 46 | 4 0 0 50 -1 18 10 0.0000 4 120 105 4515 2490 E\001 47 | -6 48 | 6 2610 360 4050 990 49 | 2 4 0 1 0 34 60 -1 20 0.000 0 0 7 0 0 5 50 | 3977 945 2642 945 2642 435 3977 435 3977 945 51 | 2 4 0 1 35 35 61 -1 20 0.000 0 0 7 0 0 5 52 | 4009 982 2674 982 2674 472 4009 472 4009 982 53 | -6 54 | 6 2610 1080 4050 1710 55 | 2 4 0 1 0 34 60 -1 20 0.000 0 0 7 0 0 5 56 | 3977 1619 2642 1619 2642 1109 3977 1109 3977 1619 57 | 2 4 0 1 35 35 61 -1 20 0.000 0 0 7 0 0 5 58 | 4009 1656 2674 1656 2674 1146 4009 1146 4009 1656 59 | -6 60 | 6 2610 1710 4050 2340 61 | 2 4 0 1 0 34 60 -1 20 0.000 0 0 7 0 0 5 62 | 3971 2252 2636 2252 2636 1742 3971 1742 3971 2252 63 | 2 4 0 1 35 35 61 -1 20 0.000 0 0 7 0 0 5 64 | 4003 2289 2668 2289 2668 1779 4003 1779 4003 2289 65 | -6 66 | 6 2610 2610 4050 3240 67 | 2 4 0 1 0 34 60 -1 20 0.000 0 0 7 0 0 5 68 | 3977 3139 2642 3139 2642 2629 3977 2629 3977 3139 69 | 2 4 0 1 35 35 61 -1 20 0.000 0 0 7 0 0 5 70 | 4009 3176 2674 3176 2674 2666 4009 2666 4009 3176 71 | -6 72 | 2 1 0 3 0 7 61 -1 -1 0.000 0 0 -1 0 0 2 73 | 1381 737 2651 737 74 | 2 1 0 3 0 7 61 -1 -1 0.000 0 0 -1 0 0 2 75 | 1391 1397 2661 1397 76 | 2 1 0 3 0 7 61 -1 -1 0.000 0 0 -1 0 0 2 77 | 1401 2127 2671 2127 78 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 79 | 5220 1620 5940 1620 80 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 81 | 5220 2160 5940 2160 82 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 83 | 4410 630 4860 630 4860 3060 4410 3060 4410 630 84 | 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 4 85 | 1 1 3.00 90.00 180.00 86 | 5895 1800 4770 1800 4770 810 3780 810 87 | 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 88 | 1 1 3.00 90.00 180.00 89 | 3780 810 1350 810 90 | 2 1 1 2 4 7 50 -1 -1 6.000 0 0 -1 1 0 2 91 | 1 1 3.00 90.00 180.00 92 | 4770 1260 3600 1260 93 | 2 1 1 2 4 7 50 -1 -1 6.000 0 0 -1 1 0 2 94 | 1 1 3.00 90.00 180.00 95 | 3600 1260 1350 1260 96 | 4 0 0 50 -1 18 10 0.0000 4 120 315 3143 2986 VFn\001 97 | 4 0 0 50 -1 18 10 0.0000 4 120 300 3143 2056 VF2\001 98 | 4 0 0 50 -1 18 10 0.0000 4 120 300 3179 752 VF0\001 99 | 4 0 0 50 -1 18 10 0.0000 4 120 300 3171 1436 VF1\001 100 | 4 0 0 50 -1 18 10 0.0000 4 120 645 351 777 Guest A\001 101 | 4 0 0 50 -1 18 10 0.0000 4 120 645 351 1457 Guest B\001 102 | 4 0 0 50 -1 18 10 0.0000 4 120 645 351 2177 Guest C\001 103 | -------------------------------------------------------------------------------- /src/lib/parm_file_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | Mneminic: parm_file_test.c 3 | Abstract: Unit test for parm file parsing (part of config.c). 4 | Tests obvious things, may miss edge cases. 5 | usage: parm_file_test cfg-file-name 6 | 7 | Date: 03 February 2016 8 | Author: E. Scott Daniels 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "vfdlib.h" 19 | 20 | 21 | void pprint( parms_t* parms ) { 22 | int i, j, k, l; 23 | tc_class_t* tcp; // pointer at a traffic class block 24 | 25 | if( ! parms ) { 26 | fprintf( stderr, "[FAIL] parm pointer was nil\n" ); 27 | return; 28 | } 29 | 30 | fprintf( stderr, " parms read:\n" ); 31 | fprintf( stderr, "\tlog dir: (%s)\n", parms->log_dir ); // in parens to verify trim function 32 | fprintf( stderr, "\tconfig_dir: (%s)\n", parms->config_dir ); 33 | fprintf( stderr, "\tlog_level: %d\n", parms->log_level ); 34 | fprintf( stderr, "\tlog_keep: %d\n", parms->log_keep ); 35 | fprintf( stderr, "\tdelete_keep: %d\n", parms->delete_keep ); 36 | fprintf( stderr, "\tfifo: %s\n", parms->fifo_path ); 37 | fprintf( stderr, "\tcpu_mask: %s\n", parms->cpu_mask ); 38 | fprintf( stderr, "\tdpdk_log_level: %d\n", parms->dpdk_log_level ); 39 | fprintf( stderr, "\tdpdk_init_log_level: %d\n", parms->dpdk_init_log_level ); 40 | fprintf( stderr, "\trflags: 0x%02x\n", parms->rflags ); 41 | 42 | fprintf( stderr, "\tnpciids: %d\n", parms->npciids ); 43 | for( i = 0; i < parms->npciids; i++ ) { 44 | fprintf( stderr, "\tpciid[%d]: %s %d flags=%02x\n", i, parms->pciids[i].id, parms->pciids[i].mtu, parms->pciids[i].flags ); 45 | fprintf( stderr, "\t\thw_strip_crc=%d\n", parms->pciids[i].hw_strip_crc ); 46 | fprintf( stderr, "\t\tpromisc=%d\n", !!(parms->pciids[i].flags & PFF_PROMISC) ); 47 | for( j = 0; j < parms->pciids[i].ntcs; j++ ) { 48 | if( (tcp = parms->pciids[i].tcs[j]) != NULL ) { // traffic class defined for this priority 49 | fprintf( stderr, "\t\ttclasses[%d]: %s, flags=%02x, max_bw: %d, min_bw: %d\n", j, tcp->hr_name, tcp->flags, tcp->max_bw, tcp->min_bw ); 50 | } else { 51 | fprintf( stderr, "\t\ttclasses[%d] not found\n", j ); 52 | } 53 | } 54 | for( k = 0; k < sizeof(parms->pciids[i].bw_grps)/sizeof(bw_grp_t); k++) { 55 | fprintf(stderr, "\t\tbw_grps[%d]", k); 56 | for( l = 0; l < parms->pciids[i].bw_grps[k].ntcs; l++) { 57 | fprintf( stderr, " %d", parms->pciids[i].bw_grps[k].tcs[l]); 58 | } 59 | fprintf(stderr, "\n" ); 60 | } 61 | } 62 | } 63 | 64 | int main( int argc, char** argv ) { 65 | char* fname; 66 | parms_t* parms; 67 | int rc = 0; 68 | 69 | if( argv[1] != NULL ) { 70 | fname = argv[1]; 71 | } else { 72 | fprintf( stderr, "[FAIL] missing parm file name on command line\n" ); 73 | exit( 1 ); 74 | } 75 | 76 | parms = read_parms( fname ); 77 | if( parms == NULL ) { 78 | fprintf( stderr, "[FAIL] unable to read parm file %s: %s\n", fname, strerror( errno ) ); 79 | free_parms( parms ); 80 | rc = 1; 81 | } else { 82 | fprintf( stderr, "[OK] Able to open, read and parse json in parm file\n" ); 83 | pprint( parms ); 84 | } 85 | free_parms( parms ); 86 | 87 | parms = read_parms( "/hosuchdir/nosuchfile" ); // should return defaults all round rather than failing 88 | if( parms != NULL ) { 89 | fprintf( stderr, "[OK] opening nonexisting file resulted in default struct:\n" ); 90 | pprint( parms ); 91 | free_parms( parms ); 92 | } else { 93 | fprintf( stderr, "[FAIL] attempt to open a nonexistant file was rejected; should have returned a struct with defaults\n" ); 94 | rc = 1; 95 | } 96 | 97 | exit( rc ); // bad exit if we failed a test 98 | } 99 | -------------------------------------------------------------------------------- /doc/overview/figures/mirror_out.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 0 32 #909090 11 | 0 33 #b0b0b0 12 | 0 34 #c0c0c0 13 | 0 35 #707070 14 | 6 2401 257 5381 3577 15 | 2 4 0 1 0 7 65 -1 20 0.000 0 0 7 0 0 5 16 | 5331 3527 2401 3527 2401 257 5331 257 5331 3527 17 | 2 4 0 1 7 18 66 -1 20 0.000 0 0 7 0 0 5 18 | 5381 3577 2451 3577 2451 307 5381 307 5381 3577 19 | -6 20 | 6 184 560 1551 2507 21 | 6 184 560 1551 1107 22 | 2 4 0 1 7 8 61 -1 20 0.000 0 0 7 0 0 5 23 | 1551 1107 216 1107 216 597 1551 597 1551 1107 24 | 2 4 0 1 0 7 60 -1 20 0.000 0 0 7 0 0 5 25 | 1519 1070 184 1070 184 560 1519 560 1519 1070 26 | -6 27 | 6 184 1230 1551 1777 28 | 2 4 0 1 7 8 61 -1 20 0.000 0 0 7 0 0 5 29 | 1551 1777 216 1777 216 1267 1551 1267 1551 1777 30 | 2 4 0 1 0 7 60 -1 20 0.000 0 0 7 0 0 5 31 | 1519 1740 184 1740 184 1230 1519 1230 1519 1740 32 | -6 33 | 6 184 1960 1551 2507 34 | 2 4 0 1 7 8 61 -1 20 0.000 0 0 7 0 0 5 35 | 1551 2507 216 2507 216 1997 1551 1997 1551 2507 36 | 2 4 0 1 0 7 60 -1 20 0.000 0 0 7 0 0 5 37 | 1519 2470 184 2470 184 1960 1519 1960 1519 2470 38 | -6 39 | -6 40 | 6 4590 1410 4725 2580 41 | 4 0 0 50 -1 18 10 0.0000 4 120 120 4597 1530 B\001 42 | 4 0 0 50 -1 18 10 0.0000 4 120 120 4597 1740 R\001 43 | 4 0 0 50 -1 18 10 0.0000 4 120 45 4635 1950 I\001 44 | 4 0 0 50 -1 18 10 0.0000 4 120 120 4597 2160 D\001 45 | 4 0 0 50 -1 18 10 0.0000 4 120 135 4590 2370 G\001 46 | 4 0 0 50 -1 18 10 0.0000 4 120 105 4605 2580 E\001 47 | -6 48 | 6 2700 450 4140 1080 49 | 2 4 0 1 0 34 60 -1 20 0.000 0 0 7 0 0 5 50 | 4067 1035 2732 1035 2732 525 4067 525 4067 1035 51 | 2 4 0 1 35 35 61 -1 20 0.000 0 0 7 0 0 5 52 | 4099 1072 2764 1072 2764 562 4099 562 4099 1072 53 | -6 54 | 6 2700 1170 4140 1800 55 | 2 4 0 1 0 34 60 -1 20 0.000 0 0 7 0 0 5 56 | 4067 1709 2732 1709 2732 1199 4067 1199 4067 1709 57 | 2 4 0 1 35 35 61 -1 20 0.000 0 0 7 0 0 5 58 | 4099 1746 2764 1746 2764 1236 4099 1236 4099 1746 59 | -6 60 | 6 2700 1800 4140 2430 61 | 2 4 0 1 0 34 60 -1 20 0.000 0 0 7 0 0 5 62 | 4061 2342 2726 2342 2726 1832 4061 1832 4061 2342 63 | 2 4 0 1 35 35 61 -1 20 0.000 0 0 7 0 0 5 64 | 4093 2379 2758 2379 2758 1869 4093 1869 4093 2379 65 | -6 66 | 6 2700 2700 4140 3330 67 | 2 4 0 1 0 34 60 -1 20 0.000 0 0 7 0 0 5 68 | 4067 3229 2732 3229 2732 2719 4067 2719 4067 3229 69 | 2 4 0 1 35 35 61 -1 20 0.000 0 0 7 0 0 5 70 | 4099 3266 2764 3266 2764 2756 4099 2756 4099 3266 71 | -6 72 | 2 1 0 3 0 7 61 -1 -1 0.000 0 0 -1 0 0 2 73 | 1471 827 2741 827 74 | 2 1 0 3 0 7 61 -1 -1 0.000 0 0 -1 0 0 2 75 | 1481 1487 2751 1487 76 | 2 1 0 3 0 7 61 -1 -1 0.000 0 0 -1 0 0 2 77 | 1491 2217 2761 2217 78 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 79 | 5310 1710 6030 1710 80 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 81 | 5310 2250 6030 2250 82 | 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 1 2 83 | 1 1 3.00 90.00 180.00 84 | 3870 900 1440 900 85 | 2 1 1 2 4 7 50 -1 -1 6.000 0 0 -1 1 0 2 86 | 1 1 3.00 90.00 180.00 87 | 4860 1350 3690 1350 88 | 2 1 1 2 4 7 50 -1 -1 6.000 0 0 -1 1 0 2 89 | 1 1 3.00 90.00 180.00 90 | 3690 1350 1440 1350 91 | 2 2 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 5 92 | 4500 720 4950 720 4950 3150 4500 3150 4500 720 93 | 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 1 4 94 | 1 1 3.00 90.00 180.00 95 | 5940 1890 4860 1890 4860 900 3870 900 96 | 4 0 0 50 -1 18 10 0.0000 4 120 315 3233 3076 VFn\001 97 | 4 0 0 50 -1 18 10 0.0000 4 120 300 3233 2146 VF2\001 98 | 4 0 0 50 -1 18 10 0.0000 4 120 300 3269 842 VF0\001 99 | 4 0 0 50 -1 18 10 0.0000 4 120 300 3261 1526 VF1\001 100 | 4 0 0 50 -1 18 10 0.0000 4 120 645 441 867 Guest A\001 101 | 4 0 0 50 -1 18 10 0.0000 4 120 645 441 1547 Guest B\001 102 | 4 0 0 50 -1 18 10 0.0000 4 120 645 441 2267 Guest C\001 103 | -------------------------------------------------------------------------------- /src/dpdk_patches/verify_patches.ksh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ksh 2 | 3 | # Mnemonic: verify_patches.ksh 4 | # Abstract: This scirpt will suss out the dpdk version based on the current branch 5 | # checked out in RTE_SDK and then look to see if we have any patches that 6 | # are not applied. If all are applied, then we exit good. 7 | # Auhtor: E. Scott Daniels 8 | # Date: 18 October 2018 9 | # --------------------------------------------------------------------------------------- 10 | 11 | function usage 12 | { 13 | echo "usage: $0 [-b] [-d patch_dir] [-f] [-v] " 14 | echo "-b causes final message to be printed in a brief good/bad format" 15 | echo "-f forces the exit code to be 0 even if unapplied patches were found" 16 | } 17 | 18 | # flips to the dpdk directory and attemptes to figure out what the version is based 19 | # on the current branch name. We assume that the branche (e.g. v18.02) is checked 20 | # out for build. 21 | # 22 | function dpdk_ver { 23 | if [[ -n $force_ver ]] # -V ver given on command line; pretend that is what is there 24 | then 25 | echo "$force_ver" 26 | return 27 | fi 28 | 29 | ( 30 | cd $RTE_SDK; 31 | git branch -l|grep "*"| awk ' 32 | { 33 | gsub( ")", "" ); 34 | gsub( "v", "" ); 35 | gsub( "\\.", "" ); 36 | print $NF 37 | }' 38 | ) 39 | } 40 | 41 | # --------------------------------------------------------------------------------- 42 | 43 | VFD_PATH=$PWD 44 | 45 | force=0 46 | patch_dir=. 47 | summary="--stat --summary" # git options 48 | verbose=0 49 | brief=0 # final message is just good/bad and no text 50 | 51 | while [[ $1 == -* ]] 52 | do 53 | case $1 in 54 | -b) brief=1;; 55 | -d) VFD_PATH=$2; shift;; 56 | -f) force=1;; 57 | 58 | -v) verbose=1;; 59 | -V) force_ver=$2; shift;; # force a version -- allows dpdk master to be used as version V 60 | 61 | *) 62 | echo "option $1 was not recognised" 63 | usage 64 | exit 1 65 | ;; 66 | esac 67 | 68 | shift 69 | done 70 | 71 | if [[ ! -d $VFD_PATH ]] 72 | then 73 | echo "patch directory smells: $VFD_PATH" 74 | exit 1 75 | fi 76 | 77 | if [[ ! -d ${RTE_SDK:-no-such-directory} ]] 78 | then 79 | echo "cannot find dpdk directory: ${RTE_SDK:-RTE_SDK is not set}" 80 | exit 1 81 | fi 82 | 83 | 84 | version=$( dpdk_ver ) # get the dpdk version 85 | version=${version%%-*} # if 1802-rc1 strip the rc crap 86 | if (( verbose )) 87 | then 88 | echo "looking for patches of the form dpdk$version" >&2 89 | fi 90 | 91 | 92 | patches=$( ls $VFD_PATH/dpdk$version-* 2>/dev/null ) 93 | 94 | if [[ -z $patches ]] 95 | then 96 | if (( brief )) 97 | then 98 | echo "0/0" 99 | else 100 | echo "there are no patches for dpdk$version" 101 | fi 102 | exit 0 103 | fi 104 | 105 | tried=0 106 | bad=0 107 | for patch in $patches 108 | do 109 | (( tried++ )) 110 | ( 111 | rc=0 112 | cd $RTE_SDK 113 | 114 | git apply -v --check --ignore-whitespace $patch 2>&1|awk '/does not apply/ { found=1 } END { exit( !(found+0) ) }' 115 | if (( $? == 0 )) 116 | then 117 | if (( verbose )) 118 | then 119 | echo "[OK] DPDK patch was already applied, or is not valid for this version: $patch" >&2 120 | fi 121 | else 122 | rc=1 123 | echo " ### ERROR ### patch NOT applied to DPDK version: $patch" >&2 124 | fi 125 | 126 | exit $rc # a return from the subshell, not from the overall script! 127 | ) 128 | (( bad += $? )) 129 | done 130 | 131 | if (( brief )) 132 | then 133 | echo "$(( tried - bad ))/$bad" 134 | else 135 | if (( verbose )) 136 | then 137 | echo "$(( tried - bad )) dpdk ($version) patches were applied, $bad patches were not applied" 138 | fi 139 | fi 140 | 141 | if (( force )) # make may force a good return so that it can just capture the verbose good/bad count string and continue 142 | then 143 | exit 0 144 | fi 145 | exit $(( bad > 0 )) 146 | -------------------------------------------------------------------------------- /src/support/linux_scripts/tcpdump_app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # vi: sw=4 ts=4: 3 | 4 | import socket 5 | import argparse 6 | import subprocess 7 | import sys 8 | import os 9 | import dpkt 10 | from dpkt.ip import IP 11 | from dpkt.ethernet import Ethernet 12 | from dpkt.arp import ARP 13 | 14 | fname = "/tmp/" + str(os.getpid()) + ".pcap" 15 | 16 | def parse_args(): 17 | ap = argparse.ArgumentParser() 18 | ap.add_argument('-d', '--debug', action='store_true', default=False, help='Show debugging output') 19 | ap.add_argument('-i', '--iface', action='store', required=True, help='Interface to capture packets') 20 | ap.add_argument('-c', '--count', default=1, action='store', help='Count no of packets to capture') 21 | return ap.parse_args() 22 | 23 | def mac_addr(address): 24 | return ':'.join('%02x' % ord(b) for b in address) 25 | 26 | def capture_pkt(iface, count, debug): 27 | cmd = 'tcpdump -e -nnvXSs 1514 -c %s -i %s -w %s' % (count, iface, fname) 28 | if debug: 29 | print cmd 30 | try: 31 | subprocess.check_call(cmd, shell=True) 32 | except subprocess.CalledProcessError: 33 | print "subprocess module exception" 34 | sys.exit(0) 35 | 36 | def mac_addr(address): 37 | return ':'.join('%02x' % ord(b) for b in address) 38 | 39 | def ip_to_str(address): 40 | return socket.inet_ntop(socket.AF_INET, address) 41 | 42 | def pkt_generator(iface, m_dst, m_src, i_dst, i_src, proto, dport, vlanid): 43 | cmd = None 44 | if vlanid and dport: 45 | cmd = 'mz %s -a %s -b %s -A %s -B %s -t %s "dp=%s" -Q %s' % (iface, m_src, m_dst, i_src, i_dst, proto, dport, vlanid) 46 | print cmd 47 | elif vlanid and not dport: 48 | cmd = 'mz %s -a %s -b %s -A %s -B %s -t %s -Q %s' % (iface, m_src, m_dst, i_src, i_dst, proto, vlanid) 49 | print cmd 50 | elif dport and not vlanid: 51 | cmd = 'mz %s -a %s -b %s -A %s -B %s -t %s "dp=%s"' % (iface, m_src, m_dst, i_src, i_dst, proto, dport) 52 | print cmd 53 | else: 54 | cmd = 'mz %s -a %s -b %s -A %s -B %s -t %s' % (iface, m_src, m_dst, i_src, i_dst, proto) 55 | print cmd 56 | try: 57 | subprocess.check_call(cmd, shell=True) 58 | except subprocess.CalledProcessError: 59 | print "'mz:' something failed while sending packets" 60 | 61 | 62 | if __name__ == '__main__': 63 | args = parse_args() 64 | capture_pkt(args.iface, args.count, args.debug) 65 | f = open(fname) 66 | pcap = dpkt.pcap.Reader(f) 67 | for ts, buf in pcap: 68 | proto = dport = vlanid = None 69 | eth = dpkt.ethernet.Ethernet(buf) 70 | if eth.type != dpkt.ethernet.ETH_TYPE_IP: 71 | print 'Non IP Packet type not supported' 72 | continue 73 | ip = eth.data 74 | proto_data = ip.data 75 | do_not_fragment = bool(dpkt.ip.IP_DF) 76 | more_fragments = bool(dpkt.ip.IP_MF) 77 | fragment_offset = ip.off & dpkt.ip.IP_OFFMASK 78 | proto = type(proto_data).__name__.lower() 79 | if hasattr(proto_data, 'dport'): 80 | dport = proto_data.dport 81 | if hasattr(eth, 'vlanid'): 82 | vlanid = eth.vlanid 83 | m_src = mac_addr(eth.src) 84 | m_dst = mac_addr(eth.dst) 85 | i_src = ip_to_str(ip.src) 86 | i_dst = ip_to_str(ip.dst) 87 | if dport and vlanid: 88 | print "Resv: %s > %s | Eth Type: %s | (%s) > (%s) | protocol: %s | dport: %s | vlanid: %s" % (m_src, m_dst, eth.type, i_src, i_dst, proto, dport, vlanid) 89 | elif dport and not vlanid: 90 | print "Resv: %s > %s | Eth Type: %s | (%s) > (%s) | protocol: %s | dport: %s" % (m_src, m_dst, eth.type, i_src, i_dst, proto, dport) 91 | elif not dport and not vlanid: 92 | print "Resv: %s > %s | Eth Type: %s | (%s) > (%s) | protocol: %s" % (m_src, m_dst, eth.type, i_src, i_dst, proto) 93 | else: 94 | print "Resv: %s > %s | Eth Type: %s | (%s) > (%s) | protocol: %s | vlanid: %s" % (m_src, m_dst, eth.type, i_src, i_dst, proto, vlanid) 95 | pkt_generator(args.iface, m_src, m_dst, i_src, i_dst, proto, dport, vlanid) 96 | f.close() 97 | os.remove(fname) 98 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_disable/test_bcastT_mcastT_ucastF.py: -------------------------------------------------------------------------------- 1 | from tests import packet 2 | import tests.helper_functions as hf 3 | import pytest 4 | 5 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastF 6 | def test_invalid_mac_valid_vlan(vf1_invalid_mac, vf1_valid_vlan): 7 | hf.read_sample_data('TARGET_VF1') 8 | pkt = hf.build_packet(dmac=vf1_invalid_mac, valid_vlan=int(vf1_valid_vlan)) 9 | inst = packet.sniff_packets(hf.config['iface'], timeout=5, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 10 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 11 | pkts = packet.load_sniff_packets(inst) 12 | vlan = None 13 | for pkt in pkts: 14 | vlan = pkt.pktgen.strip_vlan('vlan') 15 | break 16 | assert vlan == None 17 | 18 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastF 19 | def test_valid_macs_valid_vlan(vf1_mac, vf1_valid_vlan): 20 | hf.read_sample_data('TARGET_VF1') 21 | pkt = hf.build_packet(dmac=vf1_mac, valid_vlan=int(vf1_valid_vlan)) 22 | inst = packet.sniff_packets(hf.config['iface'], timeout=5, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 23 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 24 | pkts = packet.load_sniff_packets(inst) 25 | vlan = None 26 | for pkt in pkts: 27 | vlan = pkt.pktgen.strip_vlan('vlan') 28 | break 29 | assert vlan == int(vf1_valid_vlan) 30 | 31 | @pytest.mark.invalid_vlan_bcastT_mcastT_ucastF 32 | def test_valid_macs_invalid_vlan(vf1_mac, vf1_invalid_vlan): 33 | hf.read_sample_data('TARGET_VF1') 34 | pkt = hf.build_packet(dmac=vf1_mac, valid_vlan=int(vf1_invalid_vlan)) 35 | inst = packet.sniff_packets(hf.config['iface'], timeout=5, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 36 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 37 | pkts = packet.load_sniff_packets(inst) 38 | vlan = None 39 | for pkt in pkts: 40 | vlan = pkt.pktgen.strip_vlan('vlan') 41 | break 42 | assert vlan == None 43 | 44 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastF 45 | def test_bcast_valid_vlan(vf1_valid_vlan): 46 | hf.read_sample_data('TARGET_VF1') 47 | pkt = hf.build_packet(dmac=hf.config['bcast_mac'], valid_vlan=int(vf1_valid_vlan)) 48 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 49 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 50 | pkts = packet.load_sniff_packets(inst) 51 | vlan = None 52 | for pkt in pkts: 53 | vlan = pkt.pktgen.strip_vlan('vlan') 54 | break 55 | assert vlan == int(vf1_valid_vlan) 56 | 57 | @pytest.mark.invalid_vlan_bcastT_mcastT_ucastF 58 | def test_bcast_invalid_vlan(vf1_invalid_vlan): 59 | hf.read_sample_data('TARGET_VF1') 60 | pkt = hf.build_packet(dmac=hf.config['bcast_mac'], valid_vlan=int(vf1_invalid_vlan)) 61 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 62 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 63 | pkts = packet.load_sniff_packets(inst) 64 | vlan = None 65 | for pkt in pkts: 66 | vlan = pkt.pktgen.strip_vlan('vlan') 67 | break 68 | assert vlan == None 69 | 70 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastF 71 | def test_mcast_valid_vlan(vf1_valid_vlan): 72 | hf.read_sample_data('TARGET_VF1') 73 | pkt = hf.build_packet(dmac=hf.config['mcast_mac'], valid_vlan=int(vf1_valid_vlan)) 74 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 75 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 76 | pkts = packet.load_sniff_packets(inst) 77 | vlan = None 78 | for pkt in pkts: 79 | vlan = pkt.pktgen.strip_vlan('vlan') 80 | break 81 | assert vlan == int(vf1_valid_vlan) 82 | 83 | @pytest.mark.invalid_vlan_bcastT_mcastT_ucastF 84 | def test_mcast_invalid_vlan(vf1_invalid_vlan): 85 | hf.read_sample_data('TARGET_VF1') 86 | pkt = hf.build_packet(dmac=hf.config['mcast_mac'], valid_vlan=int(vf1_invalid_vlan)) 87 | inst = packet.sniff_packets(hf.config['iface'], timeout=5, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 88 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 89 | pkts = packet.load_sniff_packets(inst) 90 | vlan = None 91 | for pkt in pkts: 92 | vlan = pkt.pktgen.strip_vlan('vlan') 93 | break 94 | assert vlan == None 95 | -------------------------------------------------------------------------------- /src/support/tests/strip_vlan_enable/test_bcastT_mcastT_ucastF.py: -------------------------------------------------------------------------------- 1 | from tests import packet 2 | import tests.helper_functions as hf 3 | import pytest 4 | 5 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastF 6 | def test_invalid_mac_valid_vlan(vf1_invalid_mac, vf1_valid_vlan): 7 | hf.read_sample_data('TARGET_VF1') 8 | pkt = hf.build_packet(dmac=vf1_invalid_mac, valid_vlan=int(vf1_valid_vlan)) 9 | inst = packet.sniff_packets(hf.config['iface'], timeout=5, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 10 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 11 | pkts = packet.load_sniff_packets(inst) 12 | vlan = None 13 | for pkt in pkts: 14 | vlan = pkt.pktgen.strip_vlan('vlan') 15 | break 16 | assert vlan == None 17 | 18 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastF 19 | def test_valid_macs_valid_vlan(vf1_mac, vf1_valid_vlan): 20 | hf.read_sample_data('TARGET_VF1') 21 | pkt = hf.build_packet(dmac=vf1_mac, valid_vlan=int(vf1_valid_vlan)) 22 | inst = packet.sniff_packets(hf.config['iface'], timeout=5, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 23 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 24 | pkts = packet.load_sniff_packets(inst) 25 | vlan = None 26 | for pkt in pkts: 27 | vlan = pkt.pktgen.strip_vlan('vlan') 28 | break 29 | assert vlan == int(vf1_valid_vlan) 30 | 31 | @pytest.mark.invalid_vlan_bcastT_mcastT_ucastF 32 | def test_valid_macs_invalid_vlan(vf1_mac, vf1_invalid_vlan): 33 | hf.read_sample_data('TARGET_VF1') 34 | pkt = hf.build_packet(dmac=vf1_mac, valid_vlan=int(vf1_invalid_vlan)) 35 | inst = packet.sniff_packets(hf.config['iface'], timeout=5, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 36 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 37 | pkts = packet.load_sniff_packets(inst) 38 | vlan = None 39 | for pkt in pkts: 40 | vlan = pkt.pktgen.strip_vlan('vlan') 41 | break 42 | assert vlan == None 43 | 44 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastF 45 | def test_bcast_valid_vlan(vf1_valid_vlan): 46 | hf.read_sample_data('TARGET_VF1') 47 | pkt = hf.build_packet(dmac=hf.config['bcast_mac'], valid_vlan=int(vf1_valid_vlan)) 48 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 49 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 50 | pkts = packet.load_sniff_packets(inst) 51 | vlan = None 52 | for pkt in pkts: 53 | vlan = pkt.pktgen.strip_vlan('vlan') 54 | break 55 | assert vlan == int(vf1_valid_vlan) 56 | 57 | @pytest.mark.invalid_vlan_bcastT_mcastT_ucastF 58 | def test_bcast_invalid_vlan(vf1_invalid_vlan): 59 | hf.read_sample_data('TARGET_VF1') 60 | pkt = hf.build_packet(dmac=hf.config['bcast_mac'], valid_vlan=int(vf1_invalid_vlan)) 61 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 62 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 63 | pkts = packet.load_sniff_packets(inst) 64 | vlan = None 65 | for pkt in pkts: 66 | vlan = pkt.pktgen.strip_vlan('vlan') 67 | break 68 | assert vlan == None 69 | 70 | @pytest.mark.valid_vlan_bcastT_mcastT_ucastF 71 | def test_mcast_valid_vlan(vf1_valid_vlan): 72 | hf.read_sample_data('TARGET_VF1') 73 | pkt = hf.build_packet(dmac=hf.config['mcast_mac'], valid_vlan=int(vf1_valid_vlan)) 74 | inst = packet.sniff_packets(hf.config['iface'], timeout=8, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 75 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 76 | pkts = packet.load_sniff_packets(inst) 77 | vlan = None 78 | for pkt in pkts: 79 | vlan = pkt.pktgen.strip_vlan('vlan') 80 | break 81 | assert vlan == int(vf1_valid_vlan) 82 | 83 | @pytest.mark.invalid_vlan_bcastT_mcastT_ucastF 84 | def test_mcast_invalid_vlan(vf1_invalid_vlan): 85 | hf.read_sample_data('TARGET_VF1') 86 | pkt = hf.build_packet(dmac=hf.config['mcast_mac'], valid_vlan=int(vf1_invalid_vlan)) 87 | inst = packet.sniff_packets(hf.config['iface'], timeout=5, filters=[{'layer': 'ether', 'config': {'type': '0x8100'}}]) 88 | pkt.send_pkt(tx_port=hf.config['iface'], count=1) 89 | pkts = packet.load_sniff_packets(inst) 90 | vlan = None 91 | for pkt in pkts: 92 | vlan = pkt.pktgen.strip_vlan('vlan') 93 | break 94 | assert vlan == None 95 | -------------------------------------------------------------------------------- /doc/hackers/appendix_a.im: -------------------------------------------------------------------------------- 1 | 2 | .** appendix 3 | 4 | .cc 1000 5 | &h1( Appendix A -- Configuration File Examples ) 6 | 7 | 8 | &h2( Main VFd Configuration file ) 9 | &ex_start 10 | 11 | { 12 | "comment": "config for agave207", 13 | "log_dir": "/var/log/vfd", 14 | "log_keep": 9, 15 | "log_level": 3, 16 | "init_log_level": 2, 17 | "config_dir": "/var/lib/vfd/config", 18 | "fifo": "/var/lib/vfd/request", 19 | "cpu_mask": "0x01", 20 | "numa_mem": "64,64", 21 | "dpdk_log_level": 2, 22 | "dpdk_init_log_level": 8, 23 | "default_mtu": 9000, 24 | "enable_qos": true, 25 | 26 | "pciids": [ 27 | { "id": "0000:08:00.0", 28 | "mtu": 9000, 29 | "enable_loopback": false, 30 | "pf_driver": "igb-uio", 31 | "vf_driver": "vfio-pci", 32 | "vf_oversubscription": true, 33 | 34 | "tc_comment": "traffic classes define human readable name, tc number (priority) and other parms", 35 | "tclasses": [ 36 | { 37 | "name": "best effort", 38 | "pri": 0, 39 | "llatency": false, 40 | "lsp": false, 41 | "bsp": false, 42 | "max_bw": 100, 43 | "min_bw": 10 44 | }, 45 | { 46 | "name": "realtime", 47 | "pri": 1, 48 | "llatency": false, 49 | "lsp": false, 50 | "bsp": false, 51 | "max_bw": 100, 52 | "min_bw": 40 53 | }, 54 | { 55 | "name": "voice", 56 | "pri": 2, 57 | "llatency": false, 58 | "lsp": false, 59 | "bsp": false, 60 | "max_bw": 100, 61 | "min_bw": 40 62 | }, 63 | { 64 | "name": "control", 65 | "pri": 3, 66 | "llatency": false, 67 | "lsp": false, 68 | "bsp": false, 69 | "max_bw": 100, 70 | "min_bw": 10 71 | } 72 | ], 73 | "bwg_comment": "groups traffic classes together, min derived from TC values", 74 | "bw_grps": 75 | { 76 | "bwg0": [0], 77 | "bwg1": [1, 2], 78 | "bwg2": [3] 79 | } 80 | }, 81 | 82 | { "id": "0000:08:00.1", 83 | "mtu": 9000, 84 | "enable_loopback": false, 85 | "pf_driver": "igb-uio", 86 | "vf_driver": "vfio-pci", 87 | "vf_oversubscription": false, 88 | "tclasses": [ 89 | { 90 | "name": "best effort", 91 | "pri": 0, 92 | "llatency": false, 93 | "lsp": false, 94 | "bsp": false, 95 | "max_bw": 100, 96 | "min_bw": 10 97 | }, 98 | { 99 | "name": "realtime", 100 | "pri": 1, 101 | "llatency": false, 102 | "lsp": false, 103 | "bsp": false, 104 | "max_bw": 100, 105 | "min_bw": 40 106 | }, 107 | { 108 | "name": "voice", 109 | "pri": 2, 110 | "llatency": false, 111 | "lsp": false, 112 | "bsp": false, 113 | "max_bw": 100, 114 | "min_bw": 40 115 | }, 116 | { 117 | "name": "control", 118 | "pri": 3, 119 | "llatency": false, 120 | "lsp": false, 121 | "bsp": false, 122 | "max_bw": 100, 123 | "min_bw": 10 124 | } 125 | ], 126 | "bw_grps": 127 | { 128 | "bwg0": [0], 129 | "bwg1": [1, 2], 130 | "bwg2": [3] 131 | } 132 | } 133 | ] 134 | } 135 | &ex_end 136 | 137 | &h2( VF Configuration file ) 138 | &ex_start 139 | { 140 | "comments": "", 141 | 142 | "name": "daniels_0_1", 143 | "pciid": "0000:08:00.0", 144 | "vfid": 2, 145 | "strip_stag": true, 146 | "allow_bcast": true, 147 | "allow_mcast": true, 148 | "allow_un_ucast": false, 149 | "vlan_anti_spoof": true, 150 | "mac_anti_spoof": true, 151 | "vlans": [ 10 ], 152 | "macs": [ "04:30:86:11:04:17" ], 153 | 154 | "queues": [ 155 | { "priority": 0, "share": "10%" }, 156 | { "priority": 1, "share": "10%" }, 157 | { "priority": 2, "share": "10%" }, 158 | { "priority": 3, "share": "10%" }, 159 | ] 160 | } 161 | &ex_end 162 | 163 | 164 | -------------------------------------------------------------------------------- /doc/hackers/figures/vfd_process.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 5098.846 3426.923 6525 5040 5715 5490 5085 5580 11 | 2 1 1.00 60.00 120.00 12 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 3930.000 3495.000 3375 5535 2925 5355 2070 4500 13 | 2 1 1.00 60.00 120.00 14 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 5346.562 4201.875 6075 2070 6615 2340 7065 2745 15 | 2 1 1.00 60.00 120.00 16 | 5 1 0 1 0 7 50 -1 -1 0.000 0 1 1 0 8850.000 4492.500 7515 3600 7335 3960 7245 4545 17 | 2 1 1.00 60.00 120.00 18 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 6001.875 5073.750 5895 4050 6435 4140 6885 4545 19 | 2 1 1.00 60.00 120.00 20 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 5355.218 4883.811 5940 3195 6795 3825 7110 4545 21 | 2 1 1.00 60.00 120.00 22 | 5 1 0 1 0 7 51 -1 -1 0.000 0 1 1 0 3796.532 4925.242 4230 2970 3195 3015 2295 3600 23 | 2 1 1.00 60.00 120.00 24 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 1 0 3617.678 5263.393 3150 4095 3600 4005 4185 4140 25 | 2 1 1.00 60.00 120.00 26 | 6 4185 3780 5895 4725 27 | 5 1 0 1 0 7 51 -1 -1 0.000 0 1 0 0 5040.000 2565.000 4185 4500 4995 4680 5895 4500 28 | 1 1 0 1 0 7 51 -1 -1 0.000 1 0.0000 5040 3870 855 90 5040 3870 5895 3960 29 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 30 | 4185 3870 4185 4500 31 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 32 | 5895 3870 5895 4500 33 | -6 34 | 6 3375 5130 5085 6075 35 | 5 1 0 1 0 7 51 -1 -1 0.000 0 1 0 0 4230.000 3915.000 3375 5850 4185 6030 5085 5850 36 | 1 1 0 1 0 7 51 -1 -1 0.000 1 0.0000 4230 5220 855 90 4230 5220 5085 5310 37 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 38 | 3375 5220 3375 5850 39 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 40 | 5085 5220 5085 5850 41 | -6 42 | 6 4230 2565 5940 3510 43 | 6 4230 2565 5940 3510 44 | 5 1 0 1 0 7 51 -1 -1 0.000 0 1 0 0 5085.000 1350.000 4230 3285 5040 3465 5940 3285 45 | 1 1 0 1 0 7 51 -1 -1 0.000 1 0.0000 5085 2655 855 90 5085 2655 5940 2745 46 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 47 | 4230 2655 4230 3285 48 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 49 | 5940 2655 5940 3285 50 | -6 51 | 4 0 0 51 -1 10 12 0.0000 4 195 1695 4230 3105 /etc/vfd/vfd.cfg\001 52 | -6 53 | 6 4905 1485 6300 2295 54 | 5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5247.391 1870.435 5085 1620 4950 1845 5175 2160 55 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 5422.500 1901.250 5085 1710 5310 1530 5535 1530 56 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 5694.643 1787.143 5445 1620 5850 1530 5985 1710 57 | 5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5494.891 1689.457 5130 2115 5490 2250 5715 2205 58 | 5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 5993.036 1954.286 5895 1710 6165 1755 6255 1980 59 | 5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5827.500 1732.500 5625 2205 6030 2205 6300 1935 60 | -6 61 | 6 6705 2070 9990 3645 62 | 6 6705 2700 8415 3645 63 | 5 1 0 1 0 7 51 -1 -1 0.000 0 1 0 0 7560.000 1485.000 6705 3420 7515 3600 8415 3420 64 | 1 1 0 1 0 7 51 -1 -1 0.000 1 0.0000 7560 2790 855 90 7560 2790 8415 2880 65 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 66 | 6705 2790 6705 3420 67 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 68 | 8415 2790 8415 3420 69 | -6 70 | 6 7470 2385 9180 3285 71 | 5 1 0 1 0 7 51 -1 -1 0.000 0 1 0 0 8423.654 1054.039 8415 3240 8865 3195 9180 3105 72 | 1 1 0 1 0 7 51 -1 -1 0.000 1 0.0000 8325 2475 855 90 8325 2475 9180 2565 73 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 74 | 7470 2475 7470 2700 75 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 76 | 9180 2475 9180 3105 77 | -6 78 | 6 8280 2070 9990 2970 79 | 5 1 0 1 0 7 51 -1 -1 0.000 0 1 0 0 9233.654 739.039 9225 2925 9675 2880 9990 2790 80 | 1 1 0 1 0 7 51 -1 -1 0.000 1 0.0000 9135 2160 855 90 9135 2160 9990 2250 81 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 82 | 8280 2160 8280 2385 83 | 2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 84 | 9990 2160 9990 2790 85 | -6 86 | 4 0 0 50 -1 10 12 0.0000 4 195 1125 7020 3240 config.json\001 87 | -6 88 | 2 4 0 1 0 6 55 -1 30 0.000 0 0 7 0 0 5 89 | 3150 4500 1395 4500 1395 3600 3150 3600 3150 4500 90 | 2 4 0 1 0 10 55 -1 30 0.000 0 0 7 0 0 5 91 | 8280 5445 6525 5445 6525 4545 8280 4545 8280 5445 92 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 3 93 | 2 1 1.00 60.00 120.00 94 | 4995 1845 2430 2790 1845 3600 95 | 4 0 0 50 -1 10 16 0.0000 4 195 555 7155 5130 VFd\001 96 | 4 0 0 50 -1 10 16 0.0000 4 255 690 1980 4095 Iplex\001 97 | 4 0 0 50 -1 10 12 0.0000 4 180 840 4590 4275 Request\001 98 | 4 0 0 50 -1 10 12 0.0000 4 180 465 4770 4500 (fifo)\001 99 | 4 0 0 50 -1 10 12 0.0000 4 180 975 3780 5625 Response\001 100 | 4 0 0 50 -1 10 12 0.0000 4 180 465 4005 5805 (fifo)\001 101 | 4 0 0 50 -1 10 12 0.0000 4 135 510 5400 1980 Nova\001 102 | -------------------------------------------------------------------------------- /src/lib/LICENSE: -------------------------------------------------------------------------------- 1 | The following are licenses from the libraries/software that are explicitly pulled 2 | and compiled to suport this library. These licenses are included here per 3 | their requets and remain in their original code where supplied. 4 | 5 | --------------------------------------------------------------------------------- 6 | Jsmn 7 | https://github.com/zserge/jsmn. 8 | Used by jwrapper 9 | 10 | Copyright (c) 2010 Serge A. Zaitsev 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. 29 | 30 | --------------------------------------------------------------------------------- 31 | 32 | symtab (published in 2000, before joining AT&T) 33 | We manage our own copy as it was extended to better support table creation churn. 34 | Used by jwrapper 35 | 36 | (c) Copyright 1995-2011 By E. Scott Daniels. All rights reserved. 37 | 38 | Redistribution and use in source and binary forms, with or without modification, are 39 | permitted provided that the following conditions are met: 40 | 41 | 1. Redistributions of source code must retain the above copyright notice, this list of 42 | conditions and the following disclaimer. 43 | 44 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 45 | of conditions and the following disclaimer in the documentation and/or other materials 46 | provided with the distribution. 47 | 48 | THIS SOFTWARE IS PROVIDED BY E. Scott Daniels ``AS IS'' AND ANY EXPRESS OR IMPLIED 49 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 50 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL E. Scott Daniels OR 51 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 53 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 54 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 55 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 56 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 57 | 58 | The views and conclusions contained in the software and documentation are those of the 59 | authors and should not be interpreted as representing official policies, either expressed 60 | or implied, of E. Scott Daniels. 61 | 62 | ---------------------------------------------------------------------------------------- 63 | ng_flowmgr.c We manage our own copy to remove some ningaui dependencies. 64 | 65 | /* 66 | * ======================================================================== v1.0/0a157 67 | * 68 | * This software is part of the AT&T Ningaui distribution 69 | * 70 | * Copyright (c) 2001-2009 by AT&T Intellectual Property. All rights reserved 71 | * AT&T and the AT&T logo are trademarks of AT&T Intellectual Property. 72 | * 73 | * Ningaui software is licensed under the Common Public 74 | * License, Version 1.0 by AT&T Intellectual Property. 75 | * 76 | * A copy of the License is available at 77 | * http://www.opensource.org/licenses/cpl1.0.txt 78 | * 79 | * Information and Software Systems Research 80 | * AT&T Labs 81 | * Florham Park, NJ 82 | * 83 | * Send questions, comments via email to ningaui_support@research.att.com. 84 | * 85 | * 86 | * ======================================================================== 0a229 87 | */ 88 | -------------------------------------------------------------------------------- /doc/setup_image.im: -------------------------------------------------------------------------------- 1 | 2 | 3 | .if false 4 | Mnemonic: setup_image.im 5 | Abstract: A 'super macro' of sorts which allows for floating images to 6 | be placed into a postscript document with minimal coding effort. 7 | Corresponding image macros for other formatters are also generated 8 | so that the doc source does not need to generate them. 9 | 10 | Macros available after imbedding this file: 11 | &image( ... ) - Generate an image with figure text 12 | &cimage(...) - Generate image centered (html) with figure text 13 | (For other formatters the result is the same as 14 | &image().) 15 | 16 | The parms for both are: 17 | pfm-ep-parms : space : figure-text : URL 18 | 19 | where: 20 | space is the number of inches required on the page 21 | pfm-ep-parms are like x=.25i close proportional 22 | URL is the reference to the image (hfm and markdown only) 23 | 24 | For the pfm case, where floating an image to the next page/col is 25 | important, the image macro is used to imbed an image. The macro defines: 26 | - the needed .ep parameters ($1) 27 | - the required vertical space (inches) to trigger page eject ($2) 28 | - the figure text placed immediately after the image 29 | 30 | To make use of this, imbed this file at any time before using 31 | &image(....). 32 | 33 | The inner workings of this code: 34 | When this file is embedded, it does two things: 35 | Creates the image macro and creates a the 'super macro' which is written 36 | to the _image.ca file. 37 | 38 | When the &image() macro is used in the document, it first saves parms 39 | passed on the macro into variables, then 'invokes' the super macro by 40 | imbedding the _image.ca file. 41 | 42 | When the _image.ca file is imbedded, an image specific capture file is 43 | created as image_N.ca (where N is an integer). Then the current space 44 | remaining on the page is queried and compared against the required space 45 | provided as a parameter to the macro. If there is enough room on the page 46 | then the image specific capture file is imbedded which causes the image 47 | to be placed into the document at the current location. If there is not 48 | enough space on the current page, then the command to imbed the image specific 49 | capture file is placed onto the 'on eject' stack for inclusion at the next 50 | eject event. 51 | 52 | Example: 53 | Assuming the eps file foo_bar.eps is to be incuded, and needs 3 inches of 54 | space on the page, the following &image() statement in the document would 55 | cause that to happen: 56 | 57 | &image( foo_bar.eps x=.25i close : 3 : A foo-bar in its cage ) 58 | 59 | The third parameter is used as the figure text which is inserted immediately 60 | following the image. 61 | 62 | To avoid variable collisions with the user's document, all variables created 63 | by this are prefixed with _iim_. 64 | 65 | Date: 20 February 2018 66 | Author: E. Scott Daniels 67 | .fi 68 | 69 | .dv _iim_icount 0 70 | 71 | .if pfm 72 | .dv image .dv _iim_image_needs $2 ^: .dv _iim_fig_text $3 ^: .dv _iim_eps_cmds $1 ^: .im _iim_image.ca 73 | .dv cimage .dv _iim_image_needs $2 ^: .dv _iim_fig_text $3 ^: .dv _iim_eps_cmds $1 ^: .im _iim_image.ca 74 | .ei 75 | .if hfm 76 | .dv image .br ^ .br .fg $3 ^: .sp 1 77 | .dv cimage .bc start .br ^ .br .bc end .fg $3 ^: .sp 1 78 | .ei 79 | .if tfm 80 | .if &markdown 0 > 81 | .dv image ![cannot display: $4]($4) ^&break .fg $3 ^: .sp 1 82 | .dv cimage ![cannot display: $4]($4) ^&break .fg $3 ^: .sp 1 83 | .ei 84 | .dv image .br ^[image not supported] ^&br .fg $3 ^: .br 85 | .dv cimage .br ^[image not supported] ^&br .fg $3 ^: .br 86 | .fi 87 | .fi 88 | .fi 89 | .fi 90 | 91 | .** Create the 'super macro' in the _iim_image.ca file. This is used ONLY for pfm generated 92 | .** documents as for html and txt output images are never floated to the next page. 93 | .** Shift allows us to indent the nested capture end command by 1 tab making our code look pretty. 94 | .** Vars are expanded only by the inner capture (into the image specific file) 95 | .** 96 | .ca shift start _iim_image.ca 97 | .ca expand start _iim_image_&{_iim_icount}.ca 98 | .ep &_iim_eps_cmds l=&{_iim_image_needs}i 99 | &cfig( &_iim_fig_text ) 100 | .sp 1 101 | .ca end 102 | 103 | .gv remain 104 | .if [ .4 &_iim_image_needs + ] &_iremain > 105 | .oe page .im _iim_image_&{_iim_icount}.ca 106 | .ei 107 | .sp .5 108 | .im _iim_image_&{_iim_icount}.ca 109 | .fi 110 | .dv _iim_icount [ &_iim_icount 1 + ] 111 | .ca end 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/dpdk_patches/apply_patches.ksh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ksh 2 | 3 | # Mnemonic: apply_patches.ksh 4 | # Abstract: Apply all dpdk-* patches where yymm is given on the command line. 5 | # Any matching patch will be tested to see if it's been applied, and if 6 | # not an attempt will be made to apply it. This script assumes that the 7 | # DPDK source is in the directory referenced by the RTE_SDK environment var. 8 | # Auhtor: E. Scott Daniels 9 | # Date: 2 February 2018 10 | # --------------------------------------------------------------------------------------- 11 | 12 | function usage 13 | { 14 | echo "usage: $0 [-d patch_dir] [-f] [-n] [-s] [-v]" 15 | echo " where yymm is the year/month of the dpdk release" 16 | echo " -n is no execute mode" 17 | } 18 | 19 | # flips to the dpdk directory and attemptes to figure out what the version is based 20 | # on the current branch name. We assume that the branche (e.g. v18.02) is checked 21 | # out for build. 22 | # 23 | function dpdk_ver { 24 | ( 25 | cd $RTE_SDK; 26 | git branch -l|grep "*"| awk ' 27 | { 28 | gsub( ")", "" ); 29 | gsub( "v", "" ); 30 | gsub( "\\.", "" ); 31 | print $NF 32 | }' 33 | ) 34 | } 35 | 36 | VFD_PATH=$PWD 37 | 38 | vlevel=0 39 | forreal="" 40 | verify=0 41 | action="appling: " 42 | past_action="applied" 43 | patch_dir=. 44 | force=0 45 | 46 | while [[ $1 == -* ]] 47 | do 48 | case $1 in 49 | -d) VFD_PATH=$2; shift;; 50 | -f) force=1;; 51 | -n) forreal="echo would execute: ";; 52 | 53 | -s) 54 | action="summarise: " 55 | past_action="summarised" 56 | summary="--stat --summary" 57 | ;; 58 | 59 | -V) verify=1;; 60 | -v) vlevel=1; verbose="-v";; 61 | 62 | *) usage 63 | exit 1 64 | ;; 65 | esac 66 | 67 | shift 68 | done 69 | 70 | if [[ ! -d $VFD_PATH ]] 71 | then 72 | echo "patch directory smells: $VFD_PATH" 73 | exit 1 74 | fi 75 | 76 | if [[ ! -d ${RTE_SDK:-no-such-directory} ]] 77 | then 78 | echo "cannot find dpdk directory: ${RTE_SDK:-RTE_SDK is not set}" 79 | exit 1 80 | fi 81 | 82 | 83 | if [[ -n $1 ]] # version given 84 | then 85 | if [[ $1 == "v"*"."* ]] # something like v18.02 given 86 | then 87 | version=${1//[v.]/} 88 | version=${version%%_*} # chop _rc2 or something similar 89 | else 90 | version=$1 91 | fi 92 | if [[ $dver != $version ]] 93 | then 94 | echo "### ERROR ### version from command line ($version) does NOT match checked out version in RTE_SDK ($dver)" 95 | if (( ! force )) 96 | then 97 | exit 1 98 | fi 99 | 100 | echo "### WARN ### force mode enabled, continuing even though in error state" 101 | fi 102 | else 103 | version=$( dpdk_ver ) # just use what we suss out 104 | if [[ $version == "master" ]] # this seems wrong unless -f is on 105 | then 106 | echo "### ERROR ### dpdk branch in RTE_SDK is master and this seems wrong" 107 | if (( ! force )) 108 | then 109 | exit 1 110 | fi 111 | echo "### WARN ### force mode enabled, continuing even though in error state" 112 | fi 113 | fi 114 | 115 | 116 | 117 | patches=$( ls $VFD_PATH/dpdk$version-* 2>/dev/null ) 118 | 119 | if [[ -z $patches ]] 120 | then 121 | echo "there are no patches for dpdk$1" 122 | exit 0 123 | fi 124 | 125 | if [[ ! -d ${RTE_SDK} ]] 126 | then 127 | echo "abort: cannot find rte sdk directory: ${RTE_SDK:-undefined}" 128 | echo "ensure RTE_SDK is defined and exported" 129 | exit 1 130 | fi 131 | 132 | log=/tmp/PID$$.log # so we can know whta $$ is since generated in subshell 133 | for patch in $patches 134 | do 135 | if (( vlevel )) 136 | then 137 | echo "" 138 | fi 139 | 140 | if (( verify )) # prompt user to let them pick patches to apply from the list 141 | then 142 | printf "verify: apply $patch ?" 143 | read ans 144 | if [[ $ans != y* ]] 145 | then 146 | continue 147 | fi 148 | fi 149 | 150 | ( 151 | cd $RTE_SDK 152 | 153 | git apply -v --check --ignore-whitespace $patch 2>&1|awk '/does not apply/ { found=1 } END { exit( !(found+0) ) }' 154 | if (( $? == 0 )) 155 | then 156 | if (( vlevel )) 157 | then 158 | echo "[OK] DPDK patch already applied, or is not needed for this version: $patch" 159 | fi 160 | else 161 | if (( vlevel )) 162 | then 163 | echo "[INFO] applying patch: $patch" 164 | fi 165 | 166 | if [[ -z $forreal ]] 167 | then 168 | echo "$action $patch" 169 | fi 170 | $forreal git apply $verbose $summary --ignore-whitespace $patch >$log 2>&1 # if summary is on, apply is off 171 | fi 172 | ) 173 | if (( $? != 0 )) 174 | then 175 | echo "abort: error applying patch $patch" 176 | echo "" 177 | if [[ -f $log ]] 178 | then 179 | cat $log 180 | fi 181 | exit 1 182 | fi 183 | 184 | if (( vlevel )) 185 | then 186 | if [[ -f $log ]] 187 | then 188 | cat $log 189 | fi 190 | fi 191 | done 192 | 193 | rm -f $log 194 | -------------------------------------------------------------------------------- /src/lib/jwrapper_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | Mnemonic: jwrapper_test 3 | Abstract: This will attempt to put the jwrapper code through its paces. 4 | 5 | It accepts as argv[1] a string of json and causes it to be parsed. 6 | argv[2] is the name of an element to find in the json. 7 | argv[3] (optional) is an array element and argv[4] is an index into 8 | the array of a string element to find. 9 | 10 | Example: 11 | json='{ 12 | "active_patient": true, 13 | "last_visit": "2015/02/03", 14 | 15 | "patient_info": { 16 | "first_name": "Fred", 17 | "last_name": "Flintsone", 18 | "dob": "1963/04/03", 19 | "sex": "M", 20 | "weight_kilo": 65, 21 | "drug_alergies": [ "asprin","darvaset" ] 22 | } 23 | 24 | "Contact_info": { 25 | "name": "Wilma", "relation": "wife", "phone": "972.612.8918" 26 | } 27 | }' 28 | 29 | jwrapper_test "$json" "patient_info.dob" "patient_info.drug_alergies" 1 30 | jwrapper_test "$json" "last_visit" 31 | jwrapper_test "$json" "patient_info.weight_kilo" 32 | 33 | 34 | 35 | Author: E. Scott Daniels 36 | Date: 24 February 2016 37 | 38 | Mods: 2017 23 Jan - Fix leading tabstops that had been converted to spaces. 39 | */ 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include "vfdlib.h" 50 | 51 | /* 52 | Read an entire file into a buffer. We assume for config files 53 | they will be smallish and so this won't be a problem. 54 | Returns a pointer to the buffer, or NULL. Caller must free. 55 | Terminates the buffer with a nil character for string processing. 56 | 57 | 58 | If uid is not a nil pointer, then the user number of the owner of the file 59 | is returned to the caller via this pointer. 60 | 61 | If we cannot stat the file, we assume it's empty or missing and return 62 | an empty buffer, as opposed to a NULL, so the caller can generate defaults 63 | or error if an empty/missing file isn't tolerated. 64 | */ 65 | static char* file_into_buf( char* fname, uid_t* uid ) { 66 | struct stat stats; 67 | off_t fsize = 8192; // size of the file 68 | off_t nread; // number of bytes read 69 | int fd; 70 | char* buf; // input buffer 71 | 72 | if( uid != NULL ) { 73 | *uid = -1; // invalid to begin with 74 | } 75 | 76 | if( (fd = open( fname, O_RDONLY )) >= 0 ) { 77 | if( fstat( fd, &stats ) >= 0 ) { 78 | if( stats.st_size <= 0 ) { // empty file 79 | close( fd ); 80 | fd = -1; 81 | } else { 82 | fsize = stats.st_size; // stat ok, save the file size 83 | if( uid != NULL ) { 84 | *uid = stats.st_uid; // pass back the user id 85 | } 86 | } 87 | } else { 88 | fsize = 8192; // stat failed, we'll leave the file open and try to read a default max of 8k 89 | } 90 | } 91 | 92 | if( fd < 0 ) { // didn't open or empty 93 | if( (buf = (char *) malloc( sizeof( char ) * 128 )) == NULL ) { 94 | return NULL; 95 | } 96 | 97 | *buf = 0; 98 | return buf; 99 | } 100 | 101 | if( (buf = (char *) malloc( sizeof( char ) * fsize + 2 )) == NULL ) { 102 | close( fd ); 103 | errno = ENOMEM; 104 | return NULL; 105 | } 106 | 107 | nread = read( fd, buf, fsize ); 108 | if( nread < 0 || nread > fsize ) { // too much or two little 109 | errno = EFBIG; // likely too much to handle 110 | close( fd ); 111 | return NULL; 112 | } 113 | 114 | buf[nread] = 0; 115 | 116 | close( fd ); 117 | return buf; 118 | } 119 | 120 | 121 | int main( int argc, char **argv ) { 122 | void *jblob; // parsed json stuff 123 | char *stuff; 124 | float value; 125 | char* buf; 126 | 127 | if( argc <= 2 ) { 128 | fprintf( stderr, "usage: %s file-name\n", argv[0] ); 129 | exit( 1 ); 130 | } 131 | 132 | if ((buf = file_into_buf(argv[1], NULL)) == NULL) { 133 | fprintf( stderr, "[FAIL] unable to read a json file into buffer\n" ); 134 | exit( EXIT_FAILURE ); 135 | } 136 | 137 | if (*buf == 0) { 138 | free(buf); 139 | buf = strdup("{ \"empty\": true }"); 140 | } 141 | 142 | if( (jblob = jw_new( buf )) == NULL ) { 143 | fprintf( stderr, "failed to create wrapper\n" ); 144 | exit( 1 ); 145 | } 146 | 147 | if( (stuff = jw_string( jblob, argv[2] )) ) { 148 | fprintf( stderr, "found name (as a string): %s = (%s)\n", argv[2], stuff ); 149 | } else { 150 | if( (value = jw_value( jblob, argv[2] )) ) { 151 | fprintf( stderr, "found name (as a value): %s = (%0.2f)\n", argv[2], value ); 152 | } else { 153 | fprintf( stderr, "failed to find name: %s\n", argv[2] ); 154 | } 155 | } 156 | 157 | if( argc > 3 ) { // assume array and index are parms 3, 4 158 | fprintf( stderr, "array %s has %d elements\n", argv[3], jw_array_len( jblob, argv[3] ) ); 159 | 160 | // TODO -- add a value element test though vf_config_test tests this too! 161 | if( (stuff = jw_string_ele( jblob, argv[3], atoi(argv[4]) )) ) { 162 | fprintf( stderr, "found array element: %s[%s] = %s\n", argv[3], argv[4], stuff ); 163 | } else { 164 | fprintf( stderr, "failed to find string element for: %s[%s]\n", argv[3], argv[4] ); 165 | } 166 | } 167 | 168 | jw_nuke( jblob ); 169 | free(buf); 170 | } 171 | -------------------------------------------------------------------------------- /src/lib/id_mgr.c: -------------------------------------------------------------------------------- 1 | //:vi sw=4 ts=4 noet: 2 | 3 | /* 4 | Mnemonic: id_mgr.c 5 | Abstract: Functions to manage a range of numeric IDs. 6 | Create a new id manager with mk_idm() and then the caller can allocate 7 | new IDs in the range of 0 through num_ids-1, and can return them 8 | when finshed so they can be allocated again. 9 | 10 | Author: E. Scott Daniels 11 | Date: 28 June 2017 12 | 13 | Mod: 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | 28 | typedef struct id { 29 | int num_ids; // number of ids supported 30 | int nallocated; // number of ids allocated 31 | int pool_len; // bytes allocated in the pool 32 | unsigned char *bit_pool; // bits that represent the allocated ids 33 | } idm_t; 34 | 35 | /* 36 | Make a new manager block, ititialise it and return. Num_ids is the number 37 | of total IDs to support. 38 | */ 39 | extern void* mk_idm( int num_ids ) { 40 | idm_t* id; 41 | 42 | id = (idm_t *) malloc( sizeof( idm_t ) ); 43 | if( id == NULL ) { 44 | return NULL; 45 | } 46 | 47 | id->pool_len = sizeof( unsigned char) * (((num_ids-1) / 8) + 1); 48 | id->bit_pool = (unsigned char *) malloc( id->pool_len ); 49 | if( id->bit_pool == NULL ) { 50 | free( id ); 51 | return NULL; 52 | } 53 | 54 | memset( id->bit_pool, 0, id->pool_len ); 55 | id->nallocated = 0; 56 | id->num_ids = num_ids; 57 | 58 | return (void *) id; 59 | } 60 | 61 | /* 62 | Allocate an unused ID. Returns -1 if there are none. 63 | */ 64 | extern int idm_alloc( void* vid ) { 65 | idm_t *id; 66 | int i; 67 | int j; 68 | unsigned char bit; 69 | int k; 70 | 71 | if( vid == NULL ) { 72 | return -1; 73 | } 74 | 75 | id = (idm_t *) vid; 76 | if( id->nallocated >= id->num_ids ) { 77 | return -1; 78 | } 79 | 80 | for( i = 0; i < id->pool_len; i++ ) { 81 | if( id->bit_pool[i] != 0xff ) { // hole in this one 82 | bit = 1; 83 | 84 | for( j = 0; j < 8; j++ ) { 85 | if( !(id->bit_pool[i] & bit) ) { // this is a hole 86 | k = (8 * i) + j; // possible id, but could be out of range 87 | if( k <= id->num_ids ) { 88 | id->bit_pool[i] |= bit; // fill the hole 89 | id->nallocated++; 90 | return k; // and return the id number 91 | } else { 92 | return -1; // extra bits in the last pool bytes can't be used 93 | } 94 | } 95 | 96 | bit <<= 1; 97 | } 98 | } 99 | } 100 | 101 | return -1; 102 | } 103 | 104 | /* 105 | Allows the user to allocate a specific ID; returns 1 if 106 | the ID was unused and is now marked in use, and 0 if the ID 107 | was already assigned and should not otherwise be used. A return 108 | of -1 indicated an error (bad value passed in etc.). 109 | */ 110 | extern int idm_use( void* vid, int id_val ) { 111 | idm_t* id; 112 | int i; 113 | unsigned char bit; 114 | 115 | if( vid == NULL ){ 116 | return -1; 117 | } 118 | 119 | id = (idm_t *) vid; 120 | 121 | if( id_val > id->num_ids || id_val < 0 ) { 122 | return -1; 123 | } 124 | 125 | i = id_val / 8; // offset into bit poool 126 | if( i > id->nallocated ) { // shouldn't happen, but prevent accidents 127 | return -1; 128 | } 129 | 130 | bit = 1 << (id_val % 8); // bit to flip 131 | if( id->bit_pool[i] & bit ) { // set, so return in use 132 | return 0; 133 | } 134 | 135 | id->bit_pool[i] |= bit; // mark used 136 | id->nallocated++; 137 | 138 | return 1; 139 | } 140 | 141 | /* 142 | Returns 1 if in use, 0 if not. Returns -1 on error (bad value). 143 | */ 144 | extern int idm_is_used( void* vid, int id_val ) { 145 | idm_t* id; 146 | int i; 147 | unsigned char bit; 148 | 149 | if( vid == NULL ){ 150 | return -1; 151 | } 152 | 153 | id = (idm_t *) vid; 154 | 155 | if( id_val > id->num_ids || id_val < 0 ) { 156 | return -1; 157 | } 158 | 159 | i = id_val / 8; // offset into bit poool 160 | if( i > id->nallocated ) { // shouldn't happen, but prevent accidents 161 | return -1; 162 | } 163 | 164 | bit = 1 << (id_val % 8); // bit to flip 165 | if( id->bit_pool[i] & bit ) { // set, so return in use 166 | return 1; 167 | } 168 | 169 | return 0; // not in use 170 | } 171 | 172 | 173 | /* 174 | Return the id value to the pool. 175 | */ 176 | extern void idm_return( void* vid, int id_val ) { 177 | idm_t* id; 178 | int i; 179 | unsigned char bit; 180 | 181 | if( vid == NULL ){ 182 | return; 183 | } 184 | 185 | id = (idm_t *) vid; 186 | 187 | if( id_val > id->num_ids || id_val < 0 ) { 188 | return; 189 | } 190 | 191 | i = id_val / 8; // offset into bit poool 192 | if( i > id->nallocated ) { // shouldn't happen, but prevent accidents 193 | return; 194 | } 195 | 196 | bit = 1 << (id_val % 8); // bit to flip 197 | if( !( id->bit_pool[i] & bit) ) { // not set, do nothing 198 | return; 199 | } 200 | 201 | id->bit_pool[i] &= ~bit; // open the hole up 202 | if( id->nallocated > 0 ) { 203 | id->nallocated--; 204 | } 205 | 206 | } 207 | 208 | /* 209 | Free the associated storage. 210 | */ 211 | extern void idm_free( void* vid ) { 212 | idm_t* id; 213 | 214 | if( vid == NULL ) { 215 | return; 216 | } 217 | 218 | id = (idm_t *) vid; 219 | 220 | free( id->bit_pool ); 221 | free( id ); 222 | 223 | return; 224 | } 225 | 226 | -------------------------------------------------------------------------------- /src/lib/filesys_test.c: -------------------------------------------------------------------------------- 1 | // :vi ts=4 sw=4 noet : 2 | /* 3 | Mneminic: filesys_test.c 4 | Abstract: Unit test for the filesys module. 5 | Tests obvious things, may miss edge cases. 6 | 7 | 8 | Date: 14 February 2018 9 | Author: E. Scott Daniels 10 | 11 | Mods: 04 Apr 2018 - Add copy and convenience file tests. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "vfdlib.h" 23 | 24 | #include "filesys.c" 25 | 26 | #define FALSE 0 27 | #define TRUE 1 28 | 29 | static int verbose = 0; 30 | 31 | int main( int argc, char** argv ) { 32 | char* fname = ""; 33 | char* target = ""; 34 | int rc = 0; 35 | int errors = 0; 36 | char* ok_str = "[OK] "; 37 | char* fail_str = "[FAIL]"; 38 | char* dir; 39 | char wbuf[1024]; 40 | 41 | 42 | if( argc < 6 ) { 43 | fprintf( stderr, "%s delete-file move-file dir1 dir-2 backup-file\n", argv[0] ); 44 | fprintf( stderr, "delete file will be deleted, move file will be renamed, and backup file will be renamed with trailing -\n" ); 45 | fprintf( stderr, "target directory is a directory in the same filesystem as move-file and will be where the file is moved\n" ); 46 | fprintf( stderr, "both dir1 and dir2 should NOT exist, and one of dir1 and dir2 should be a fully quallified path, and the other should be relative\n" ); 47 | fprintf( stderr, "dir1 will be used to move the move-file to\n" ); 48 | exit( 0 ); 49 | } 50 | 51 | errno = 0; 52 | dir = argv[3]; 53 | rc = ensure_dir( dir ); 54 | fprintf( stderr, "%s creating directory: %s %s\n", rc ? ok_str : fail_str, dir, strerror( errno ) ); 55 | errors += !rc; 56 | 57 | if( rc ) { // only try this if we were sucessful above 58 | errno = 0; // second test to create same file should also succeed :) 59 | dir = argv[3]; 60 | rc = ensure_dir( dir ); 61 | fprintf( stderr, "%s creating existing directory: %s %s\n", rc ? ok_str : fail_str, dir, strerror( errno ) ); 62 | errors += !rc; 63 | } 64 | 65 | errno = 0; 66 | dir = argv[4]; // assume fully qualified, or not if dir1 was, but tests all branches in ensure_dir() 67 | rc = ensure_dir( dir ); 68 | fprintf( stderr, "%s creating directory: %s %s\n", rc ? ok_str : fail_str, dir, strerror( errno ) ); 69 | errors += rc ? 0 : 1; 70 | 71 | errno = 0; 72 | rc = is_dir( argv[3] ); 73 | errors += !rc; // true is good, so add 0 on good :) 74 | fprintf( stderr, "%s is_dir() test: %s\n", rc ? ok_str : fail_str, strerror( errno ) ); // test is_dir() and file_exists() functions 75 | 76 | rc = file_exists( argv[3] ); 77 | errors += !rc; // true is good, so add 0 on good :) 78 | fprintf( stderr, "%s file_exists() (directory) test: %s\n", rc ? ok_str : fail_str, strerror( errno ) ); 79 | 80 | rc = file_exists( argv[1] ); 81 | errors += !rc; // true is good, so add 0 on good :) 82 | fprintf( stderr, "%s file_exists() (file) test: %s\n", rc ? ok_str : fail_str, strerror( errno ) ); 83 | 84 | rc = file_exists( "nosuchfileondisk12345" ); 85 | errors += rc; // false is good 86 | fprintf( stderr, "%s file_exists() (non-existant file) test: %s\n", !rc ? ok_str : fail_str, strerror( errno ) ); 87 | 88 | errno = 0; 89 | rc = is_file( argv[1] ); 90 | errors += !rc; // true is good, so add 0 on good :) 91 | fprintf( stderr, "%s is_file() test: %s\n", rc ? ok_str : fail_str, strerror( errno ) ); 92 | 93 | if( cp_file( argv[1], argv[4], 0 ) ) { // test copy to dir1 given on command line 94 | char dfile[1024]; 95 | char sfile[1024]; 96 | char* cp; 97 | 98 | fprintf( stderr, "%s cp_file() %s->%s no unlink\n", ok_str, argv[1], argv[4] ); // indicate success 99 | 100 | cp = strrchr( argv[1], '/' ); // point at just filename 101 | if( cp == NULL ) { 102 | cp = argv[1]; 103 | } 104 | 105 | snprintf( sfile, 1024, "%s/%s", argv[4], cp ); // source is from the dir1 directory 106 | snprintf( dfile, 1024, "%s/copied_file", argv[4] ); // dest into same directory 107 | if( cp_file( sfile, dfile, 1 ) ) { // copy file to file and unlink src 108 | fprintf( stderr, "%s cp_file() %s->%s, with unlink\n", ok_str, sfile, dfile ); 109 | } else { 110 | fprintf( stderr, "%s file copy %s->%s with unlink (others skipped): %s\n", fail_str, sfile, dfile, strerror( errno ) ); 111 | errors += 1; 112 | } 113 | } else { 114 | errors += 1; 115 | fprintf( stderr, "%s file copy %s->%s (other copy tests skipped): %s\n", argv[1], argv[4], fail_str, strerror( errno ) ); 116 | } 117 | 118 | errno = 0; 119 | fname = argv[1]; 120 | rc = rm_file( fname, FALSE ); 121 | fprintf( stderr, "%s deleting file: %s %s\n", rc ? ok_str : fail_str, fname, strerror( errno ) ); 122 | errors += rc ? 0 : 1; 123 | 124 | errno = 0; 125 | fname = argv[2]; 126 | target = argv[3]; 127 | memset( wbuf, 0, sizeof( wbuf ) ); // keep valgrind happy by initialising all of the buffer 128 | snprintf( wbuf, sizeof( wbuf ), "%s/", target ); // ensure it's seen as a directory name 129 | rc = mv_file( fname, wbuf ); 130 | fprintf( stderr, "%s moving file: %s to %s %s\n", rc ? ok_str : fail_str, fname, target, strerror( errno ) ); 131 | errors += rc ? 0 : 1; 132 | 133 | 134 | errno = 0; 135 | fname = argv[5]; 136 | rc = rm_file( fname, TRUE ); 137 | fprintf( stderr, "%s backup file: %s %s\n", rc ? ok_str : fail_str, fname, strerror( errno ) ); 138 | errors += rc ? 0 : 1; 139 | 140 | 141 | 142 | exit( !!errors ); 143 | } 144 | -------------------------------------------------------------------------------- /doc/debugging/strip_issue.xfm: -------------------------------------------------------------------------------- 1 | 2 | 3 | .ll 6.5i 4 | .sf Helvetica 5 | .st 10p 6 | 7 | .if hfm 8 | .co bg white 9 | .co #000000 10 | .fi 11 | 12 | .dh 1 m=.5i e=no s=21 i=0 p=16 f=Helvetica-bold 13 | .dh 2 m=.5i s=21 i=0 p=14 f=Helvetica-bold 14 | .dh 3 m=.5i s=10 i=0 p=12 f=Helvetica-bold 15 | 16 | .hn off 17 | 18 | .im ../setup.im 19 | 20 | 21 | .dv sub_title VLAN ID Stripped When Strip Disabled 22 | .st 18p 23 | .sf Helvetica 24 | .gv date 25 | .if pfm 26 | .bc start 27 | Virtual Function Daemon -- VFd 28 | .br 29 | .st 14 30 | &sub_title 31 | .bc end 32 | .st &textsize 33 | .ei 34 | .im ../caution.im 35 | 36 | &bold(Virtual Function Daemon -- VFd) 37 | .sp 38 | &bold(&sub_title) 39 | .fi 40 | 41 | .** while it makes sense to leave spaces after opening and before closing of macro parens (e.g. &ital( word ) 42 | .** this actually causes issues for the space sensitive markdown world. Since we must support this beast 43 | .** of an output format, be warned that spaces will likely cause issues, as well as make it more difficult 44 | .** to spell check. 45 | 46 | .sp 2 47 | &h2(Overview) 48 | An odd &ital(failure case) has been observed in some environments and is documented here as, at least 49 | at the time of the writing, the unexpected behaviour is caused by the manner which the DPDK application 50 | configures the device via DPDK library calls. 51 | With the same application, and thus the same &ital(internal) device configuration, we have observed 52 | different results with regard to VLAN ID stripping on Rx packets. 53 | 54 | .sp 55 | It is the intent of this brief to describe what was observed, and what we believe is the correct behaviour. 56 | We will also indicate the application device settings that are related, and potential causes of 57 | unexpected behaviour. 58 | 59 | 60 | &h2(Symptom) 61 | The initial symptom of the problem was that in the VF configuration file the value of stag stripping 62 | was set to false, yet the VLAN ID was being removed from the packets received by the DPDK application. 63 | This symptom was not observed in all environments; in some, the VLAN IDs remained in the packet as 64 | was expected. 65 | .sp 66 | 67 | Further examination of the NIC registers indicated that indeed stripping was enabled, however 68 | VFd logs indicated that the option was being turned off when the VF was configured on the NIC. 69 | When the kernel driver (ixgbevf) was used in the guest, the packets arrived with the VLAN ID as 70 | was expected. 71 | 72 | 73 | &h2(Cause) 74 | The problem was observed in conjunction with the DPDK application (gobbler ¬e .sm ) 75 | &start_note( .5i ) 76 | Gobbler is available as a test tool in the VFd gadgets repo: 77 | &{http}github.com/att/vfd.gadgets.git 78 | &end_note 79 | and was directly related to setting the &ital(Rx offload) DEV_RX_OFFLOAD_VLAN_STRIP flag. 80 | When this offload flag was not set by the application, the expected behaviour in the "failing" 81 | environment was observed. 82 | 83 | 84 | &h2(Conclusions) 85 | It is logical to assume that if the DPDK application sets the strip offload that the VLAN ID should 86 | be stripped from Rx packets regardless of the setting pushed to the NIC by VFd as the result of the 87 | VF configuration file. 88 | We assert that this &ital(is) the correct behaviour, and the &ital(problem) that was observed really 89 | was not a problem. 90 | .sp 91 | 92 | However, it seems there are some environments (likely some versions of the Niantic NIC itself) where the 93 | strip offload setting by the DPDK application does not reach the NIC, and the VFd configuration setting 94 | always applies. 95 | We consider this to be incorrect behaviour, but is not something that is within VFd's control and it 96 | is up to the systems administration staff to ensure that the VF configuration provided to VFd reflects 97 | the desired strip stag setting based on the application's needs. 98 | 99 | .sp 100 | When troubleshooting VLAN ID stripping "bugs," it is likely that the unexpected behaviour is caused 101 | by one of the following and is not a VFd bug. 102 | .sp .5 103 | &beg_list 104 | &item The strip stag setting in the VF's configuration file is incorrect, and the application is not 105 | setting the offload properly or at all and the default is incorrect. 106 | 107 | &item The DPDK application is setting the strip related offload which is opposite to the value 108 | in VFd VF configuration file, and the expectation is that the value in the VFd configuration 109 | is enforced. 110 | 111 | &item The DPDK application is attempting to set the strip related offload, however the underlying 112 | device is not being updated with the setting and the setting expected is opposite of that 113 | configured in the VFd VF configuration. 114 | &end_list 115 | 116 | 117 | 118 | .** ----------------------------------------------------------------------------------------------- 119 | .if tfm 120 | &h1( Notes: ) 121 | .sp 2 122 | .cn showend 123 | &line 124 | .fi 125 | 126 | .** ----------------------------------------------------------------------------------------------- 127 | .gv remain 128 | .if &_iremain < 4 129 | .pa 130 | .ei 131 | .sp 5 132 | .fi 133 | 134 | .if tfm 135 | .sp 5 136 | .ln 137 | .im ../caution.im 138 | .fi 139 | 140 | .st 8p 141 | .gv version 142 | .gv Date 143 | &def_list( .75i &ditext ) 144 | &di(Source) vfd/doc/strip_issue.xfm 145 | &di(Original) 13 June 2018 146 | &di(Revised) &_date 147 | &di(Formatter) &_ver 148 | &end_dlist 149 | 150 | -------------------------------------------------------------------------------- /doc/debugging/figures/diag_mirror1.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 5 1 0 2 1 7 50 -1 -1 0.000 0 0 0 0 7207.500 2745.000 7200 2610 7335 2700 7200 2880 11 | 6 9810 1485 10260 2790 12 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 13 | 9810 1485 10260 1485 10260 2790 9810 2790 9810 1485 14 | 4 0 0 50 -1 4 10 1.5708 4 120 855 10080 2565 TO* Switch\001 15 | -6 16 | 6 7110 585 8100 1080 17 | 2 4 0 1 0 22 55 -1 30 0.000 0 0 7 0 0 5 18 | 8100 1080 7110 1080 7110 585 8100 585 8100 1080 19 | 4 0 0 50 -1 6 14 0.0000 4 180 450 7380 945 VFd\001 20 | -6 21 | 6 5715 720 6615 1080 22 | 2 4 0 1 0 19 55 -1 30 0.000 0 0 7 0 0 5 23 | 6615 1080 5715 1080 5715 720 6615 720 6615 1080 24 | 4 0 0 50 -1 4 10 0.0000 4 120 435 5940 945 Driver\001 25 | -6 26 | 6 1800 1125 4905 2790 27 | 6 1890 1530 3060 2430 28 | 2 2 0 1 0 7 53 -1 20 0.000 0 0 -1 0 0 5 29 | 1890 1530 3060 1530 3060 2430 1890 2430 1890 1530 30 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 31 | 1890 1935 3015 1935 32 | 4 0 0 50 -1 4 10 0.0000 4 150 915 2025 1800 Application\001 33 | 4 0 0 50 -1 4 10 0.0000 4 120 855 2070 2250 DPDK PMD\001 34 | -6 35 | 6 3645 1305 4005 2205 36 | 2 4 0 1 0 19 53 -1 30 0.000 0 0 7 0 0 5 37 | 4005 1305 4005 2205 3645 2205 3645 1305 4005 1305 38 | 4 0 0 50 -1 4 10 1.5708 4 120 435 3915 2025 Driver\001 39 | -6 40 | 2 2 0 1 0 7 52 -1 20 0.000 0 0 -1 0 0 5 41 | 4185 1395 4905 1395 4905 1665 4185 1665 4185 1395 42 | 2 2 0 1 0 7 52 -1 20 0.000 0 0 -1 0 0 5 43 | 4185 1800 4905 1800 4905 2070 4185 2070 4185 1800 44 | 2 2 0 1 0 17 55 -1 30 0.000 0 0 -1 0 0 5 45 | 1800 1125 4635 1125 4635 2790 1800 2790 1800 1125 46 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 47 | 1 1 1.00 60.00 120.00 48 | 1 1 1.00 60.00 120.00 49 | 3060 2115 3645 1845 50 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 51 | 3960 1485 4275 1485 52 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 53 | 3960 1890 4275 1890 54 | 4 0 0 50 -1 4 10 0.0000 4 120 375 4410 1575 vNIC\001 55 | 4 0 0 50 -1 4 10 0.0000 4 120 375 4365 1980 vNIC\001 56 | 4 0 0 50 -1 4 14 0.0000 4 180 675 1890 1350 Guest\001 57 | -6 58 | 6 3600 3375 3960 4275 59 | 2 4 0 1 0 19 53 -1 30 0.000 0 0 7 0 0 5 60 | 3960 3375 3960 4275 3600 4275 3600 3375 3960 3375 61 | 4 0 0 50 -1 4 10 1.5708 4 120 435 3870 4095 Driver\001 62 | -6 63 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 64 | 6525 1845 9405 1845 65 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 66 | 6525 2070 9405 2070 67 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 68 | 6525 2295 9405 2295 69 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 70 | 6525 2520 9405 2520 71 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 72 | 6525 2700 9405 2700 73 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 74 | 9360 2430 9855 2430 75 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 76 | 4905 1530 6525 1935 77 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 78 | 4905 1935 6525 2610 79 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 80 | 9360 1710 9855 1710 81 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 82 | 1 1 1.00 60.00 120.00 83 | 1 1 1.00 60.00 120.00 84 | 6840 1575 6165 1080 85 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 86 | 1 1 1.00 60.00 120.00 87 | 1 1 1.00 60.00 120.00 88 | 7110 810 6570 810 89 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 90 | 1 1 1.00 60.00 120.00 91 | 7290 945 7290 1530 92 | 2 2 0 1 0 31 60 -1 32 0.000 0 0 -1 0 0 5 93 | 1305 225 9225 225 9225 5040 1305 5040 1305 225 94 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 95 | 6525 2925 9405 2925 96 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 97 | 6525 3150 9405 3150 98 | 2 2 0 1 0 7 52 -1 20 0.000 0 0 -1 0 0 5 99 | 4140 3330 4860 3330 4860 3600 4140 3600 4140 3330 100 | 2 2 0 1 0 17 55 -1 30 0.000 0 0 -1 0 0 5 101 | 1755 3060 4590 3060 4590 4725 1755 4725 1755 3060 102 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 103 | 3915 3555 4230 3420 104 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 105 | 4860 3465 6525 2835 106 | 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 107 | 1 1 1.00 60.00 120.00 108 | 7200 2610 7605 2610 109 | 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 3 110 | 4905 2025 6255 2610 7200 2610 111 | 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 1 0 3 112 | 1 1 1.00 60.00 120.00 113 | 7200 2880 6255 2880 4860 3375 114 | 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 115 | 1 1 1.00 60.00 120.00 116 | 9540 2610 7740 2610 117 | 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 3 118 | 1 1 1.00 60.00 120.00 119 | 8145 2610 8010 2880 7335 2880 120 | 2 2 0 1 0 7 53 -1 20 0.000 0 0 -1 0 0 5 121 | 1845 3645 3015 3645 3015 4050 1845 4050 1845 3645 122 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 123 | 1 1 1.00 60.00 120.00 124 | 1 1 1.00 60.00 120.00 125 | 3015 3825 3600 3825 126 | 2 2 0 1 0 6 55 -1 30 0.000 0 0 -1 0 0 5 127 | 6525 1575 9495 1575 9495 3645 6525 3645 6525 1575 128 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 129 | 6525 3375 9405 3375 130 | 4 0 0 50 -1 4 10 0.0000 4 120 270 6660 1755 PF0\001 131 | 4 0 0 50 -1 4 10 0.0000 4 120 270 6615 2475 PF1\001 132 | 4 0 0 50 -1 4 10 0.0000 4 120 285 6660 2025 VF0\001 133 | 4 0 0 50 -1 4 10 0.0000 4 120 285 6615 2655 VF0\001 134 | 4 0 0 50 -1 4 10 0.0000 4 120 300 6660 2250 VFn\001 135 | 4 0 0 50 -1 4 10 6.0214 4 120 540 5535 1620 SR-IOV\001 136 | 4 0 0 50 -1 6 12 0.0000 4 195 1185 8280 1530 Physical NIC\001 137 | 4 0 0 50 -1 6 14 0.0000 4 225 1485 1440 495 Physical Host\001 138 | 4 0 0 45 -1 4 10 0.0000 4 120 285 6615 2880 VF1\001 139 | 4 0 0 45 -1 4 10 0.0000 4 120 285 6615 3105 VF2\001 140 | 4 0 0 45 -1 4 10 0.0000 4 120 285 6615 3330 VF3\001 141 | 4 0 0 50 -1 4 10 0.0000 4 120 375 4365 3510 vNIC\001 142 | 4 0 0 50 -1 4 14 0.0000 4 225 2325 1845 3285 Mirror Target (guest)\001 143 | 4 0 -1 50 -1 6 12 0.0000 4 150 810 8325 2655 Inbound\001 144 | 4 0 -1 50 -1 6 12 5.9341 4 150 990 5130 2385 Outbound\001 145 | 4 0 0 50 -1 4 10 0.0000 4 150 750 2025 3870 tcpdump\001 146 | 4 0 0 45 -1 4 10 0.0000 4 120 300 6615 3555 VFn\001 147 | -------------------------------------------------------------------------------- /doc/debugging/figures/diat_mirror1.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 5 1 0 2 1 7 50 -1 -1 0.000 0 0 0 0 7207.500 2745.000 7200 2610 7335 2700 7200 2880 11 | 6 9810 1485 10260 2790 12 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 13 | 9810 1485 10260 1485 10260 2790 9810 2790 9810 1485 14 | 4 0 0 50 -1 4 10 1.5708 4 120 855 10080 2565 TO* Switch\001 15 | -6 16 | 6 7110 585 8100 1080 17 | 2 4 0 1 0 22 55 -1 30 0.000 0 0 7 0 0 5 18 | 8100 1080 7110 1080 7110 585 8100 585 8100 1080 19 | 4 0 0 50 -1 6 14 0.0000 4 180 450 7380 945 VFd\001 20 | -6 21 | 6 5715 720 6615 1080 22 | 2 4 0 1 0 19 55 -1 30 0.000 0 0 7 0 0 5 23 | 6615 1080 5715 1080 5715 720 6615 720 6615 1080 24 | 4 0 0 50 -1 4 10 0.0000 4 120 435 5940 945 Driver\001 25 | -6 26 | 6 1800 1125 4905 2790 27 | 6 1890 1530 3060 2430 28 | 2 2 0 1 0 7 53 -1 20 0.000 0 0 -1 0 0 5 29 | 1890 1530 3060 1530 3060 2430 1890 2430 1890 1530 30 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 31 | 1890 1935 3015 1935 32 | 4 0 0 50 -1 4 10 0.0000 4 150 915 2025 1800 Application\001 33 | 4 0 0 50 -1 4 10 0.0000 4 120 855 2070 2250 DPDK PMD\001 34 | -6 35 | 6 3645 1305 4005 2205 36 | 2 4 0 1 0 19 53 -1 30 0.000 0 0 7 0 0 5 37 | 4005 1305 4005 2205 3645 2205 3645 1305 4005 1305 38 | 4 0 0 50 -1 4 10 1.5708 4 120 435 3915 2025 Driver\001 39 | -6 40 | 2 2 0 1 0 7 52 -1 20 0.000 0 0 -1 0 0 5 41 | 4185 1395 4905 1395 4905 1665 4185 1665 4185 1395 42 | 2 2 0 1 0 7 52 -1 20 0.000 0 0 -1 0 0 5 43 | 4185 1800 4905 1800 4905 2070 4185 2070 4185 1800 44 | 2 2 0 1 0 17 55 -1 30 0.000 0 0 -1 0 0 5 45 | 1800 1125 4635 1125 4635 2790 1800 2790 1800 1125 46 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 47 | 1 1 1.00 60.00 120.00 48 | 1 1 1.00 60.00 120.00 49 | 3060 2115 3645 1845 50 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 51 | 3960 1485 4275 1485 52 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 53 | 3960 1890 4275 1890 54 | 4 0 0 50 -1 4 10 0.0000 4 120 375 4410 1575 vNIC\001 55 | 4 0 0 50 -1 4 10 0.0000 4 120 375 4365 1980 vNIC\001 56 | 4 0 0 50 -1 4 14 0.0000 4 180 675 1890 1350 Guest\001 57 | -6 58 | 6 3600 3240 3960 4140 59 | 2 4 0 1 0 19 53 -1 30 0.000 0 0 7 0 0 5 60 | 3960 3240 3960 4140 3600 4140 3600 3240 3960 3240 61 | 4 0 0 50 -1 4 10 1.5708 4 120 435 3870 3960 Driver\001 62 | -6 63 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 64 | 6525 1845 9405 1845 65 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 66 | 6525 2070 9405 2070 67 | 2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 68 | 6525 2295 9405 2295 69 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 70 | 6525 2520 9405 2520 71 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 72 | 6525 2700 9405 2700 73 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 74 | 9360 2430 9855 2430 75 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 76 | 4905 1530 6525 1935 77 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 78 | 4905 1935 6525 2610 79 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 80 | 9360 1710 9855 1710 81 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 82 | 1 1 1.00 60.00 120.00 83 | 1 1 1.00 60.00 120.00 84 | 6840 1575 6165 1080 85 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 86 | 1 1 1.00 60.00 120.00 87 | 1 1 1.00 60.00 120.00 88 | 7110 810 6570 810 89 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 90 | 1 1 1.00 60.00 120.00 91 | 7290 945 7290 1530 92 | 2 2 0 1 0 31 60 -1 32 0.000 0 0 -1 0 0 5 93 | 1305 225 9225 225 9225 5040 1305 5040 1305 225 94 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 95 | 6525 2925 9405 2925 96 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 97 | 6525 3150 9405 3150 98 | 2 2 0 1 0 6 55 -1 30 0.000 0 0 -1 0 0 5 99 | 6525 1575 9450 1575 9450 3555 6525 3555 6525 1575 100 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 101 | 6525 3375 9405 3375 102 | 2 2 0 1 0 7 52 -1 20 0.000 0 0 -1 0 0 5 103 | 4140 3330 4860 3330 4860 3600 4140 3600 4140 3330 104 | 2 2 0 1 0 17 55 -1 30 0.000 0 0 -1 0 0 5 105 | 1755 3060 4590 3060 4590 4725 1755 4725 1755 3060 106 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 107 | 1 1 1.00 60.00 120.00 108 | 1 1 1.00 60.00 120.00 109 | 3015 3690 3600 3690 110 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 111 | 3915 3420 4230 3420 112 | 2 2 0 1 0 7 53 -1 20 0.000 0 0 -1 0 0 5 113 | 1845 3465 3015 3465 3015 3870 1845 3870 1845 3465 114 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 115 | 4860 3465 6525 2835 116 | 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 1 0 2 117 | 1 1 1.00 60.00 120.00 118 | 7200 2610 7605 2610 119 | 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 3 120 | 4905 2025 6255 2610 7200 2610 121 | 2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 1 0 3 122 | 1 1 1.00 60.00 120.00 123 | 7200 2880 6255 2880 4860 3375 124 | 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 125 | 1 1 1.00 60.00 120.00 126 | 9540 2610 7740 2610 127 | 2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 3 128 | 1 1 1.00 60.00 120.00 129 | 8145 2610 8010 2880 7335 2880 130 | 4 0 0 50 -1 4 10 0.0000 4 120 270 6660 1755 PF0\001 131 | 4 0 0 50 -1 4 10 0.0000 4 120 270 6615 2475 PF1\001 132 | 4 0 0 50 -1 4 10 0.0000 4 120 285 6660 2025 VF0\001 133 | 4 0 0 50 -1 4 10 0.0000 4 120 285 6615 2655 VF0\001 134 | 4 0 0 50 -1 4 10 0.0000 4 120 300 6660 2250 VFn\001 135 | 4 0 0 50 -1 4 10 6.0214 4 120 540 5535 1620 SR-IOV\001 136 | 4 0 0 50 -1 6 12 0.0000 4 195 1185 8280 1530 Physical NIC\001 137 | 4 0 0 50 -1 6 14 0.0000 4 225 1485 1440 495 Physical Host\001 138 | 4 0 0 45 -1 4 10 0.0000 4 120 285 6615 2880 VF1\001 139 | 4 0 0 45 -1 4 10 0.0000 4 120 300 6615 3510 VFn\001 140 | 4 0 0 45 -1 4 10 0.0000 4 120 285 6615 3105 VF2\001 141 | 4 0 0 45 -1 4 10 0.0000 4 120 285 6615 3330 VF3\001 142 | 4 0 0 50 -1 4 10 0.0000 4 120 375 4365 3510 vNIC\001 143 | 4 0 0 50 -1 4 14 0.0000 4 225 2325 1845 3285 Mirror Target (guest)\001 144 | 4 0 0 50 -1 4 10 0.0000 4 150 750 1980 3735 tcpdump\001 145 | 4 0 -1 50 -1 6 12 0.0000 4 150 810 8325 2655 Inbound\001 146 | 4 0 -1 50 -1 6 12 5.9341 4 150 990 5130 2385 Outbound\001 147 | -------------------------------------------------------------------------------- /src/package/mk_deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function clean_house 4 | { 5 | trap - EXIT 6 | echo "something failed or you aborted" 7 | rm -fr /tmp/PID$$.* 8 | exit 1 9 | } 10 | 11 | function clean_exit 12 | { 13 | trap - EXIT 14 | rm -fr /tmp/PID$$.* 15 | exit ${1:0} 16 | } 17 | 18 | function verbose 19 | { 20 | if (( chatty > 0 )) 21 | then 22 | echo "$@" >&2 23 | fi 24 | } 25 | 26 | function help 27 | { 28 | usage 29 | cat <'] [-v] [cleanup]" 39 | echo " cleanup causes a cleanup of the named version and no building" 40 | echo " -a arch allows the architecture to be specified amd64 is the default" 41 | echo " -p prompt; don't assume certain things" 42 | echo " -r n supplies the revsion number" 43 | echo " -v verbose mode" 44 | echo " -u str name and email address to be put into change (default: $who)" 45 | } 46 | 47 | function build_mail_str 48 | { 49 | typeset w="${WHOIAM:-$user <$user@att.com>}" # default 50 | 51 | if [[ -z $WHOIAM ]] # let user override, but pull from git if we can 52 | then 53 | git config --list| grep user|sed 's/=/ /;' |while read what data 54 | do 55 | case $what in 56 | user.email) ge="$data";; 57 | user.name) gn="$data";; 58 | esac 59 | done 60 | 61 | if [[ -n $gn && -n $ge ]] 62 | then 63 | w="$gn <$ge>" 64 | fi 65 | fi 66 | 67 | echo "$w" 68 | } 69 | 70 | user=${LOGNAME:-$USER} 71 | argv0=$0 72 | arch="amd64" 73 | confirm=0 74 | rev=1 # deb revision number 75 | chatty=0 76 | who=$( build_mail_str ) # sets who 77 | 78 | while [[ $1 == -* ]] 79 | do 80 | case $1 in 81 | -a) arch="$2"; shift;; 82 | -p) confirm=1;; 83 | -r) rev=$2; shift;; 84 | -u) who="$2"; shift;; 85 | -v) chatty=1;; 86 | -\?) help 87 | exit 0 88 | ;; 89 | *) echo "unrecognised option $1" 90 | usage 91 | exit 1 92 | esac 93 | 94 | shift 95 | done 96 | 97 | pkg_name="$1" 98 | full_pkg_name="attlr$1" 99 | ver=$2 100 | cleanup=$3 101 | 102 | if [[ -z $pkg_name || -z $ver ]] 103 | then 104 | echo "missing positional parameters [FAIL]" 105 | usage 106 | exit 1 107 | fi 108 | 109 | src_dir=$PWD 110 | if [[ ! -d ${pkg_name}_debian ]] 111 | then 112 | echo "cannot find debian files directory in $src_dir: ${pkg_name}_debian [FAIL]" 113 | exit 1 114 | fi 115 | 116 | bundle_dir=/tmp/$user/export/bundle 117 | if [[ ! -d $bundle_dir ]] 118 | then 119 | echo "cannot find bundle directory: /tmp/$user/export/bundle [FAIL]" 120 | exit 1 121 | fi 122 | 123 | set -e # lazy way out 124 | trap "clean_house" 1 2 3 15 EXIT # purge everything on failure or exit 125 | 126 | cd $bundle_dir 127 | rtar=$bundle_dir/${full_pkg_name}-${ver}.tar.gz # rtar? original script pulled it from a remote machine :) 128 | release=$bundle_dir/${full_pkg_name}_${ver} # where we'll build the directory to make the release 129 | 130 | if [[ -d $release ]] 131 | then 132 | set +e 133 | if ! rm -fr $release- $release 134 | then 135 | echo "unable to remove previous export directories: $release- $release" 136 | printf "try as root? [y|N]" 137 | read ans 138 | if [[ ${ans:-n} == "n"* ]] 139 | then 140 | clean_house 0 141 | fi 142 | fi 143 | 144 | set -e 145 | sudo rm -fr $release- $release 146 | fi 147 | 148 | if [[ $cleanup == "cleanup" ]] # only invoked to clean 149 | then 150 | trap - EXIT 151 | exit 0 152 | fi 153 | 154 | if [[ -e $rtar ]] 155 | then 156 | echo "using $rtar" 157 | else 158 | echo "cannot find: $rtar" 159 | clean_exit 1 160 | fi 161 | 162 | verbose "making release directory $release" 163 | mkdir -p $release 164 | cd $release 165 | rm -fr lib 166 | verbose "unpack tar" 167 | gzip -dc $rtar | tar -xf - 168 | 169 | find . -type f |xargs md5sum >/tmp/PID$$.md5 # capture md5sum before we add DEBIAN directory 170 | 171 | verbose "populate DEBIAN directory" 172 | ( 173 | mkdir -p DEBIAN 174 | ls $src_dir/${pkg_name}_debian/[a-z]* | while read f 175 | do 176 | if [[ ${f##*/} == "control" ]] 177 | then 178 | sed "s//$ver/" $f >DEBIAN/${f##*/} 179 | else 180 | cp $f DEBIAN/ 181 | fi 182 | done 183 | ) 184 | cp /tmp/PID$$.md5 DEBIAN/md5sums 185 | 186 | edit=1 187 | if [[ -f ../changelog.$pkg_name.$ver ]] # if one from a previous run, don't make them edit it again 188 | then 189 | cp ../changelog.$pkg_name.$ver DEBIAN/changelog 190 | 191 | if (( confirm )) 192 | then 193 | printf "previous change log used; edit it? [Yn]" 194 | read ans 195 | else 196 | ans=n 197 | fi 198 | if [[ $ans == "n" ]] 199 | then 200 | edit=0 201 | fi 202 | else 203 | # CAUTION -- the change log parser is way too sensitive -- leading spaces tabs seem to matter 204 | date=$(date -R) 205 | cat <DEBIAN/changelog 206 | ${full_pkg_name} (${ver}-1) UNRELEASED; urgency=low 207 | 208 | * Bug Fixes. (Closes: #xxx) 209 | 210 | -- $who $date 211 | endKat 212 | 213 | echo "" 214 | echo "a new change log was created, you must edit it" 215 | printf "press return to edit " 216 | read foo 217 | fi 218 | 219 | if (( edit )) 220 | then 221 | vi DEBIAN/changelog 222 | cp DEBIAN/changelog ../changelog.$pkg_name.$ver 223 | fi 224 | 225 | 226 | if (( confirm )) 227 | then 228 | printf "run debuild [yN]? " 229 | read ans 230 | else 231 | ans=y 232 | fi 233 | if [[ $ans == "y"* ]] 234 | then 235 | cd .. 236 | find $release | sudo xargs chown root:root # files in package must be owned by root 237 | deb_name=${full_pkg_name}_${ver}-${rev}_$arch.deb 238 | set -x 239 | dpkg-deb -b $release $deb_name 240 | set +x 241 | find $release | sudo xargs chown $user:users 242 | 243 | echo "deb file created: $bundle_dir/$deb_name" 244 | else 245 | echo "make any changes needed and then run 'dpkg-deb -b $release ${full_pkg_name}_${ver}_$arch.deb'" 246 | fi 247 | 248 | trap - EXIT 249 | exit 0 250 | -------------------------------------------------------------------------------- /src/lib/parm_file_test.cfg: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "comment": "test config file; log and config paths have lead spaces to test trim funciton", 4 | "log_dir": " /var/log/vfd", 5 | "log_keep": 9, 6 | "log_level": 3, 7 | "init_log_level": 3, 8 | "config_dir": " /var/lib/vfd/config", 9 | "fifo": "/var/lib/vfd/request", 10 | "cpu_mask": "0x01", 11 | "dpdk_log_level": 2, 12 | "dpdk_init_log_level": 8, 13 | "default_mtu": 9000, 14 | "enable_qos": true, 15 | 16 | "pciids": [ 17 | { "id": "0000:08:00.0", 18 | "promiscuous": false, 19 | "mtu": 9002, 20 | "hw_strip_crc": true, 21 | "enable_loopback": false, 22 | "pf_driver": "pci-stub", 23 | "vf_driver": "pci-stub", 24 | "vf_oversubscription", true, 25 | 26 | "tc_comment": "traffic classes define human readable name, tc number (priority) and other parms", 27 | "tclasses": [ 28 | { 29 | "name": "best effort", 30 | "pri": 0, 31 | "llatency": true, 32 | "lsp": false, 33 | "bsp": true, 34 | "max_bw": 100, 35 | "min_bw": 2 36 | }, 37 | { 38 | "name": "realtime", 39 | "pri": 1, 40 | "llatency": false, 41 | "lsp": false, 42 | "bsp": false, 43 | "max_bw": 30, 44 | "min_bw": 5 45 | }, 46 | { 47 | "name": "voice", 48 | "pri": 2, 49 | "llatency": false, 50 | "lsp": false, 51 | "bsp": false, 52 | "max_bw": 90, 53 | "min_bw": 13 54 | }, 55 | { 56 | "name": "control", 57 | "pri": 3, 58 | "llatency": false, 59 | "lsp": false, 60 | "bsp": false, 61 | "max_bw": 80, 62 | "min_bw": 30 63 | } 64 | ], 65 | 66 | "bwg_comment": "groups traffic classes together, min derived from TC values", 67 | "bw_grps": 68 | { 69 | "bwg0": [0], 70 | "bwg1": [1, 2], 71 | "bwg2": [3] 72 | } 73 | }, 74 | 75 | { "id": "0000:08:00.1", 76 | "promiscuous": true, 77 | "mtu": 9004, 78 | "enable_loopback": false, 79 | "pf_driver": "pci-stub", 80 | "vf_driver": "pci-stub", 81 | "vf_oversubscription", false, 82 | 83 | "tc_comment": "this tests the ability to handle a missing tc", 84 | "tclasses": [ 85 | { 86 | "rem": "test max/min limit checks", 87 | "name": "2_best effort", 88 | "pri": 0, 89 | "llatency": true, 90 | "lsp": false, 91 | "bsp": true, 92 | "max_bw": 500, 93 | "min_bw": -2 94 | }, 95 | { 96 | "name": "2_voice", 97 | "pri": 2, 98 | "llatency": false, 99 | "lsp": false, 100 | "bsp": false, 101 | "max_bw": 90, 102 | "min_bw": 13 103 | }, 104 | { 105 | "name": "2_control", 106 | "pri": 3, 107 | "llatency": false, 108 | "lsp": false, 109 | "bsp": false, 110 | "max_bw": 80, 111 | "min_bw": 30 112 | } 113 | ], 114 | 115 | "bwg_comment": "groups traffic classes together, min derived from TC values", 116 | "bw_grps": { 117 | "bwg0": [0], 118 | "bwg1": [1, 2], 119 | "bwg2": [3] 120 | } 121 | }, 122 | 123 | { "id": "0000:08:00.2", 124 | "mtu": 9006, 125 | "enable_loopback": false, 126 | "pf_driver": "pci-stub", 127 | "vf_driver": "pci-stub", 128 | 129 | "tc_comment": "test the ability to handle 8 classes", 130 | "tclasses": [ 131 | { 132 | "name": "8_best effort", 133 | "pri": 0, 134 | "llatency": true, 135 | "lsp": false, 136 | "bsp": true, 137 | "max_bw": 100, 138 | "min_bw": 2 139 | }, 140 | { 141 | "name": "8_realtime", 142 | "pri": 1, 143 | "llatency": false, 144 | "lsp": false, 145 | "bsp": false, 146 | "max_bw": 30, 147 | "min_bw": 5 148 | }, 149 | { 150 | "name": "8_voice", 151 | "pri": 2, 152 | "llatency": false, 153 | "lsp": false, 154 | "bsp": false, 155 | "max_bw": 90, 156 | "min_bw": 13 157 | }, 158 | { 159 | "name": "8_control", 160 | "pri": 3, 161 | "llatency": false, 162 | "lsp": false, 163 | "bsp": false, 164 | "max_bw": 80, 165 | "min_bw": 30 166 | }, 167 | { 168 | "name": "8_extra", 169 | "pri": 4, 170 | "llatency": true, 171 | "lsp": false, 172 | "bsp": true, 173 | "max_bw": 100, 174 | "min_bw": 2 175 | }, 176 | { 177 | "name": "8_extra2", 178 | "pri": 5, 179 | "llatency": false, 180 | "lsp": false, 181 | "bsp": false, 182 | "max_bw": 30, 183 | "min_bw": 5 184 | }, 185 | { 186 | "name": "8_extra3", 187 | "pri": 6, 188 | "llatency": false, 189 | "lsp": false, 190 | "bsp": false, 191 | "max_bw": 90, 192 | "min_bw": 13 193 | }, 194 | { 195 | "rem-tc8": "test unnamed support" 196 | "pri": 7, 197 | "llatency": false, 198 | "lsp": false, 199 | "bsp": false, 200 | "max_bw": 80, 201 | "min_bw": 30 202 | } 203 | 204 | ], 205 | 206 | "bwg_comment": "groups traffic classes together, min derived from TC values", 207 | "bw_grps": 208 | { 209 | "bwg0": [0], 210 | "bwg1": [1, 2], 211 | "bwg2": [3] 212 | "bwg3": [4,5] 213 | "bwg4": [6] 214 | "bwg5": [7] 215 | } 216 | }, 217 | { 218 | "rem-pc4": "test without any traffic classes", 219 | "id": "0000:08:00.3", 220 | "mtu": 9008, 221 | "hw_strip_crc": false, 222 | "enable_loopback": false, 223 | "pf_driver": "pci-stub", 224 | "vf_driver": "pci-stub", 225 | } 226 | 227 | ] 228 | } 229 | 230 | --------------------------------------------------------------------------------