vpp_device: fix vpp device kernel driver binding
[csit.git] / resources / libraries / bash / function / device.sh
index 0eda008..729a837 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
@@ -98,15 +98,11 @@ function bind_interfaces_to_driver () {
 
     pci_path="/sys/bus/pci/devices/${ADDR}"
     drv_path="/sys/bus/pci/drivers/${DRIVER}"
-    vd=$(cat ${pci_path}/vendor ${pci_path}/device) || {
-        die "Failed to retrieve interface details!"
-    }
-    set +e
-    echo ${vd} | sudo tee ${drv_path}/new_id
-    set -e
-    echo ${ADDR} | sudo tee ${pci_path}/driver/unbind || {
-        die "Failed to unbind interface ${ADDR}!"
-    }
+    if [ -d "${pci_path}/driver" ]; then
+        echo ${ADDR} | sudo tee ${pci_path}/driver/unbind || {
+            die "Failed to unbind interface ${ADDR}!"
+        }
+    fi
     echo ${ADDR} | sudo tee ${drv_path}/bind || {
         die "Failed to bind interface ${ADDR}!"
     }
@@ -270,87 +266,99 @@ function get_available_interfaces () {
             tg_netdev=(enp24)
             dut1_netdev=(enp59)
             ;;
-        "1n_vbox")
+       "1n_tx2")
+            # Add Intel Corporation XL710/X710 Virtual Function to the
+            # whitelist.
+            pci_id="0x154c"
+            tg_netdev=(enp5s2 enp5s3 enp5s4 enp5s5
+                       enp5s6 enp5s7 enp5s8 enp5s9)
+            tg_netdev+=(enp5s10 enp5s11 enp5s12 enp5s13
+                        enp5s14 enp5s15 enp5s16 enp5s17)
+            dut1_netdev=(enp145s2 enp145s3 enp145s4 enp145s5
+                         enp145s6 enp145s7 enp145s8 enp145s9)
+            dut1_netdev+=(enp145s10 enp145s11 enp145s12 enp145s13
+                          enp145s14 enp145s15 enp145s16 enp145s17)
+            ;;
+       "1n_vbox")
             # Add Intel Corporation 82545EM Gigabit Ethernet Controller to the
             # whitelist.
             pci_id="0x100f"
-            tg_netdev=(enpTGa enpTGb)
-            dut1_netdev=(enpSUTa enpSUTb)
+            tg_netdev=(enp0s8 enp0s9)
+            dut1_netdev=(enp0s16 enp0s17)
             ;;
         *)
             die "Unknown specification: ${case_text}!"
     esac
 
-    net_path="/sys/bus/pci/devices/*/net/*"
+    device_count=2
 
     # TG side of connections.
     TG_NETDEVS=()
     TG_PCIDEVS=()
     TG_NETMACS=()
     TG_DRIVERS=()
+    TG_VLANS=()
     # DUT1 side of connections.
     DUT1_NETDEVS=()
     DUT1_PCIDEVS=()
     DUT1_NETMACS=()
     DUT1_DRIVERS=()
+    DUT1_VLANS=()
 
-    # Following code is filtering available VFs represented by network device
-    # name. Only allowed VFs PCI IDs are used.
-    for netdev in \
-        $(find ${net_path} -type d -name . -o -prune -exec basename '{}' ';');
+    # Find the first ${device_count} number of available TG Linux network
+    # VF device names. Only allowed VF PCI IDs are filtered.
+    for netdev in ${tg_netdev[@]}
     do
-        if grep -q "${pci_id}" "/sys/class/net/${netdev}/device/device"; then
-            # We will filter to TG/DUT1 side of connection (this can be in
-            # future overriden by more advanced conditions for mapping).
-            for sub in ${tg_netdev[@]}; do
-                if [[ "${netdev#*$sub}" != "${netdev}" ]]; then
-                    tg_side+=(${netdev})
-                fi
-            done
-            for sub in ${dut1_netdev[@]}; do
-                if [[ "${netdev#*$sub}" != "${netdev}" ]]; then
-                    dut1_side+=(${netdev})
-                fi
-            done
+        for netdev_path in $(grep -l "${pci_id}" \
+                             /sys/class/net/${netdev}*/device/device \
+                             2> /dev/null)
+        do
+            if [[ ${#TG_NETDEVS[@]} -lt ${device_count} ]]; then
+                tg_netdev_name=$(dirname ${netdev_path})
+                tg_netdev_name=$(dirname ${tg_netdev_name})
+                TG_NETDEVS+=($(basename ${tg_netdev_name}))
+            else
+                break
+            fi
+        done
+        if [[ ${#TG_NETDEVS[@]} -eq ${device_count} ]]; then
+            break
         fi
     done
 
-    case "${case_text}" in
-        "1n_skx")
-            # Pick up first two DUT1 interfaces binded to i40evf.
-            for netdev in "${dut1_side[@]::2}"; do
-                DUT1_NETDEVS+=(${netdev})
-            done
-            # Corresponding TG interfaces will be same ID.SUB_ID, but on
-            # opposite linked device.
-            for netdev in "${DUT1_NETDEVS[@]}"; do
-                TG_NETDEVS+=(${netdev/$dut1_netdev/$tg_netdev})
-            done
-            ;;
-        *)
-            for netdev in "${tg_side[@]::2}"; do
-                TG_NETDEVS+=(${netdev})
-            done
-            for netdev in "${dut1_side[@]::2}"; do
-                DUT1_NETDEVS+=(${netdev})
-            done
-    esac
+    i=0
+    for netdev in "${TG_NETDEVS[@]}"; do
+        # Find the index of selected tg netdev among tg_netdevs
+        # e.g. enp8s5f7 is a vf of netdev enp8s5 with index 11
+        # and the corresponding dut1 netdev is enp133s13.
+        while [[ "${netdev}" != "${tg_netdev[$i]}"* ]]; do
+            ((i++))
+        done
+        # Rename tg netdev to dut1 netdev
+        # e.g. enp8s5f7 -> enp133s13f7
+        DUT1_NETDEVS+=(${netdev/${tg_netdev[$i]}/${dut1_netdev[$i]}})
+        # Don't need to reset i, all netdevs are sorted.
+    done
 
     for NETDEV in "${TG_NETDEVS[@]}"; do
         get_pci_addr
         get_mac_addr
         get_krn_driver
+        get_vlan_filter
         TG_PCIDEVS+=(${PCI_ADDR})
         TG_NETMACS+=(${MAC_ADDR})
         TG_DRIVERS+=(${KRN_DRIVER})
+        TG_VLANS+=(${VLAN_ID})
     done
     for NETDEV in "${DUT1_NETDEVS[@]}"; do
         get_pci_addr
         get_mac_addr
         get_krn_driver
+        get_vlan_filter
         DUT1_PCIDEVS+=(${PCI_ADDR})
         DUT1_NETMACS+=(${MAC_ADDR})
         DUT1_DRIVERS+=(${KRN_DRIVER})
+        DUT1_VLANS+=(${VLAN_ID})
     done
 
     # We need at least two interfaces for TG/DUT1 for building topology.
@@ -423,6 +431,24 @@ function get_pci_addr () {
 }
 
 
+function get_vlan_filter () {
+
+    # Get VLAN stripping filter from PF searched by mac adress.
+    #
+    # Variables read:
+    # - MAC_ADDR - MAC address of VF.
+    # Variables set:
+    # - VLAN_ID - VLAN ids.
+
+    set -exuo pipefail
+
+    # Sed regular expression pattern.
+    exp="s/^.*vlan ([[:digit:]]+).*$/\1/"
+    VLAN_ID=$(ip link | grep vlan | grep ${MAC_ADDR} | sed -re "${exp}") || true
+    VLAN_ID="${VLAN_ID:-0}"
+}
+
+
 function installed () {
 
     # Check if the given utility is installed. Fail if not installed.
@@ -471,12 +497,16 @@ function read_env_variables () {
     DCR_UUIDS+=([dut1]="${CSIT_DUT1_UUID}")
     TG_PCIDEVS=("${CSIT_TG_INTERFACES_PORT1_PCI}")
     TG_DRIVERS=("${CSIT_TG_INTERFACES_PORT1_DRV}")
+    TG_VLANS+=("${CSIT_TG_INTERFACES_PORT1_VLAN}")
     TG_PCIDEVS+=("${CSIT_TG_INTERFACES_PORT2_PCI}")
     TG_DRIVERS+=("${CSIT_TG_INTERFACES_PORT2_DRV}")
+    TG_VLANS+=("${CSIT_TG_INTERFACES_PORT2_VLAN}")
     DUT1_PCIDEVS=("${CSIT_DUT1_INTERFACES_PORT1_PCI}")
     DUT1_DRIVERS=("${CSIT_DUT1_INTERFACES_PORT1_DRV}")
+    DUT1_VLANS+=("${CSIT_DUT1_INTERFACES_PORT1_VLAN}")
     DUT1_PCIDEVS+=("${CSIT_DUT1_INTERFACES_PORT2_PCI}")
     DUT1_DRIVERS+=("${CSIT_DUT1_INTERFACES_PORT2_DRV}")
+    DUT1_VLANS+=("${CSIT_DUT1_INTERFACES_PORT2_VLAN}")
 }
 
 
@@ -517,15 +547,19 @@ function set_env_variables () {
     CSIT_TG_INTERFACES_PORT1_MAC="${TG_NETMACS[0]}"
     CSIT_TG_INTERFACES_PORT1_PCI="${TG_PCIDEVS[0]}"
     CSIT_TG_INTERFACES_PORT1_DRV="${TG_DRIVERS[0]}"
+    CSIT_TG_INTERFACES_PORT1_VLAN="${TG_VLANS[0]}"
     CSIT_TG_INTERFACES_PORT2_MAC="${TG_NETMACS[1]}"
     CSIT_TG_INTERFACES_PORT2_PCI="${TG_PCIDEVS[1]}"
     CSIT_TG_INTERFACES_PORT2_DRV="${TG_DRIVERS[1]}"
+    CSIT_TG_INTERFACES_PORT2_VLAN="${TG_VLANS[1]}"
     CSIT_DUT1_INTERFACES_PORT1_MAC="${DUT1_NETMACS[0]}"
     CSIT_DUT1_INTERFACES_PORT1_PCI="${DUT1_PCIDEVS[0]}"
     CSIT_DUT1_INTERFACES_PORT1_DRV="${DUT1_DRIVERS[0]}"
+    CSIT_DUT1_INTERFACES_PORT1_VLAN="${DUT1_VLANS[0]}"
     CSIT_DUT1_INTERFACES_PORT2_MAC="${DUT1_NETMACS[1]}"
     CSIT_DUT1_INTERFACES_PORT2_PCI="${DUT1_PCIDEVS[1]}"
     CSIT_DUT1_INTERFACES_PORT2_DRV="${DUT1_DRIVERS[1]}"
+    CSIT_DUT1_INTERFACES_PORT2_VLAN="${DUT1_VLANS[1]}"
     set +a
 }
 
@@ -564,13 +598,18 @@ function start_topology_containers () {
     # Override access to PCI bus by attaching a filesystem mount to the
     # container.
     dcr_stc_params+="--mount type=tmpfs,destination=/sys/bus/pci/devices "
-    # Mount vfio to be able to bind to see binded interfaces. We cannot use
-    # --device=/dev/vfio as this does not see newly binded interfaces.
+    # Mount vfio to be able to bind to see bound interfaces. We cannot use
+    # --device=/dev/vfio as this does not see newly bound interfaces.
     dcr_stc_params+="--volume /dev/vfio:/dev/vfio "
-    # Mount nested_vm image to be able to run VM tests.
-    dcr_stc_params+="--volume /var/lib/vm/vhost-nested.img:/var/lib/vm/vhost-nested.img "
     # Mount docker.sock to be able to use docker deamon of the host.
     dcr_stc_params+="--volume /var/run/docker.sock:/var/run/docker.sock "
+    # Mount /opt/boot/ where VM kernel and initrd are located.
+    dcr_stc_params+="--volume /opt/boot/:/opt/boot/ "
+    # Mount host hugepages for VMs.
+    dcr_stc_params+="--volume /dev/hugepages/:/dev/hugepages/ "
+    # Disable IPv6.
+    dcr_stc_params+="--sysctl net.ipv6.conf.all.disable_ipv6=1 "
+    dcr_stc_params+="--sysctl net.ipv6.conf.default.disable_ipv6=1 "
 
     # Docker Container UUIDs.
     declare -gA DCR_UUIDS