#! /usr/bin/env python
#
#   BSD LICENSE
#
#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
#   All rights reserved.
#
#   Redistribution and use in source and binary forms, with or without
#   modification, are permitted provided that the following conditions
#   are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in
#       the documentation and/or other materials provided with the
#       distribution.
#     * Neither the name of Intel Corporation nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

import sys
import os
import getopt
import subprocess
from os.path import exists, abspath, dirname, basename

# The PCI base class for NETWORK devices
NETWORK_BASE_CLASS = "02"
CRYPTO_BASE_CLASS = "0b"

# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
devices = {}
# list of supported DPDK drivers
dpdk_drivers = ["igb_uio", "vfio-pci", "uio_pci_generic"]

# command-line arg flags
b_flag = None
status_flag = False
force_flag = False
args = []


def usage():
    '''Print usage information for the program'''
    argv0 = basename(sys.argv[0])
    print("""
Usage:
------

     %(argv0)s [options] DEVICE1 DEVICE2 ....

where DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax
or "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may
also be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc.

Options:
    --help, --usage:
        Display usage information and quit

    -s, --status:
        Print the current status of all known network and crypto devices.
        For each device, it displays the PCI domain, bus, slot and function,
        along with a text description of the device. Depending upon whether the
        device is being used by a kernel driver, the igb_uio driver, or no
        driver, other relevant information will be displayed:
        * the Linux interface name e.g. if=eth0
        * the driver being used e.g. drv=igb_uio
        * any suitable drivers not currently using that device
            e.g. unused=igb_uio
        NOTE: if this flag is passed along with a bind/unbind option, the
        status display will always occur after the other operations have taken
        place.

    -b driver, --bind=driver:
        Select the driver to use or \"none\" to unbind the device

    -u, --unbind:
        Unbind a device (Equivalent to \"-b none\")

    --force:
        By default, network devices which are used by Linux - as indicated by having
        routes in the routing table - cannot be modified. Using the --force
        flag overrides this behavior, allowing active links to be forcibly
        unbound.
        WARNING: This can lead to loss of network connection and should be used
        with caution.

Examples:
---------

To display current device status:
        %(argv0)s --status

To bind eth1 from the current driver and move to use igb_uio
        %(argv0)s --bind=igb_uio eth1

To unbind 0000:01:00.0 from using any driver
        %(argv0)s -u 0000:01:00.0

To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver
        %(argv0)s -b ixgbe 02:00.0 02:00.1

    """ % locals())  # replace items from local variables


# This is roughly compatible with check_output function in subprocess module
# which is only available in python 2.7.
def check_output(args, stderr=None):
    '''Run a command and capture its output'''
    return subprocess.Popen(args, stdout=subprocess.PIPE,
                            stderr=stderr).communicate()[0]


def find_module(mod):
    '''find the .ko file for kernel module named mod.
    Searches the $RTE_SDK/$RTE_TARGET directory, the kernel
    modules directory and finally under the parent directory of
    the script '''
    # check $RTE_SDK/$RTE_TARGET directory
    if 'RTE_SDK' in os.environ and 'RTE_TARGET' in os.environ:
        path = "%s/%s/kmod/%s.ko" % (os.environ['RTE_SDK'],
                                     os.environ['RTE_TARGET'], mod)
        if exists(path):
            return path

    # check using depmod
    try:
        depmod_out = check_output(["modinfo", "-n", mod],
                                  stderr=subprocess.STDOUT).lower()
        if "error" not in depmod_out:
            path = depmod_out.strip()
            if exists(path):
                return path
    except:  # if modinfo can't find module, it fails, so continue
        pass

    # check for a copy based off current path
    tools_dir = dirname(abspath(sys.argv[0]))
    if (tools_dir.endswith("tools")):
        base_dir = dirname(tools_dir)
        find_out = check_output(["find", base_dir, "-name", mod + ".ko"])
        if len(find_out) > 0:  # something matched
            path = find_out.splitlines()[0]
            if exists(path):
                return path


def check_modules():
    '''Checks that igb_uio is loaded'''
    global dpdk_drivers

    # list of supported modules
    mods = [{"Name": driver, "Found": False} for driver in dpdk_drivers]

    # first check if module is loaded
    try:
        # Get list of sysfs modules (both built-in and dynamically loaded)
        sysfs_path = '/sys/module/'

        # Get the list of directories in sysfs_path
        sysfs_mods = [os.path.join(sysfs_path, o) for o
                      in os.listdir(sysfs_path)
                      if os.path.isdir(os.path.join(sysfs_path, o))]

        # Extract the last element of '/sys/module/abc' in the array
        sysfs_mods = [a.split('/')[-1] for a in sysfs_mods]

        # special case for vfio_pci (module is named vfio-pci,
        # but its .ko is named vfio_pci)
        sysfs_mods = map(lambda a:
                         a if a != 'vfio_pci' else 'vfio-pci', sysfs_mods)

        for mod in mods:
            if mod["Name"] in sysfs_mods:
                mod["Found"] = True
    except:
        pass

    # check if we have at least one loaded module
    if True not in [mod["Found"] for mod in mods] and b_flag is not None:
        if b_flag in dpdk_drivers:
            print("Error - no supported modules(DPDK driver) are loaded")
            sys.exit(1)
        else:
            print("Warning - no supported modules(DPDK driver) are loaded")

    # change DPDK driver list to only contain drivers that are loaded
    dpdk_drivers = [mod["Name"] for mod in mods if mod["Found"]]


def has_driver(dev_id):
    '''return true if a device is assigned to a driver. False otherwise'''
    return "Driver_str" in devices[dev_id]


def get_pci_device_details(dev_id):
    '''This function gets additional details for a PCI device'''
    device = {}

    extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines()

    # parse lspci details
    for line in extra_info:
        if len(line) == 0:
            continue
        name, value = line.decode().split("\t", 1)
        name = name.strip(":") + "_str"
        device[name] = value
    # check for a unix interface name
    device["Interface"] = ""
    for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id):
        if "net" in dirs:
            device["Interface"] = \
                ",".join(os.listdir(os.path.join(base, "net")))
            break
    # check if a port is used for ssh connection
    device["Ssh_if"] = False
    device["Active"] = ""

    return device


def get_nic_details():
    '''This function populates the "devices" dictionary. The keys used are
    the pci addresses (domain:bus:slot.func). The values are themselves
    dictionaries - one for each NIC.'''
    global devices
    global dpdk_drivers

    # clear any old data
    devices = {}
    # first loop through and read details for all devices
    # request machine readable format, with numeric IDs
    dev = {}
    dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
    for dev_line in dev_lines:
        if (len(dev_line) == 0):
            if dev["Class"][0:2] == NETWORK_BASE_CLASS:
                # convert device and vendor ids to numbers, then add to global
                dev["Vendor"] = int(dev["Vendor"], 16)
                dev["Device"] = int(dev["Device"], 16)
                # use dict to make copy of dev
                devices[dev["Slot"]] = dict(dev)
        else:
            name, value = dev_line.decode().split("\t", 1)
            dev[name.rstrip(":")] = value

    # check what is the interface if any for an ssh connection if
    # any to this host, so we can mark it later.
    ssh_if = []
    route = check_output(["ip", "-o", "route"])
    # filter out all lines for 169.254 routes
    route = "\n".join(filter(lambda ln: not ln.startswith("169.254"),
                             route.decode().splitlines()))
    rt_info = route.split()
    for i in range(len(rt_info) - 1):
        if rt_info[i] == "dev":
            ssh_if.append(rt_info[i+1])

    # based on the basic info, get extended text details
    for d in devices.keys():
        # get additional info and add it to existing data
        devices[d] = devices[d].copy()
        devices[d].update(get_pci_device_details(d).items())

        for _if in ssh_if:
            if _if in devices[d]["Interface"].split(","):
                devices[d]["Ssh_if"] = True
                devices[d]["Active"] = "*Active*"
                break

        # add igb_uio to list of supporting modules if needed
        if "Module_str" in devices[d]:
            for driver in dpdk_drivers:
                if driver not in devices[d]["Module_str"]:
                    devices[d]["Module_str"] = \
                        devices[d]["Module_str"] + ",%s" % driver
        else:
            devices[d]["Module_str"] = ",".join(dpdk_drivers)

        # make sure the driver and module strings do not have any duplicates
        if has_driver(d):
            modules = devices[d]["Module_str"].split(",")
            if devices[d]["Driver_str"] in modules:
                modules.remove(devices[d]["Driver_str"])
                devices[d]["Module_str"] = ",".join(modules)


def get_crypto_details():
    '''This function populates the "devices" dictionary. The keys used are
    the pci addresses (domain:bus:slot.func). The values are themselves
    dictionaries - one for each NIC.'''
    global devices
    global dpdk_drivers

    # clear any old data
    # devices = {}
    # first loop through and read details for all devices
    # request machine readable format, with numeric IDs
    dev = {}
    dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
    for dev_line in dev_lines:
        if (len(dev_line) == 0):
            if (dev["Class"][0:2] == CRYPTO_BASE_CLASS):
                # convert device and vendor ids to numbers, then add to global
                dev["Vendor"] = int(dev["Vendor"], 16)
                dev["Device"] = int(dev["Device"], 16)
                # use dict to make copy of dev
                devices[dev["Slot"]] = dict(dev)
        else:
            name, value = dev_line.decode().split("\t", 1)
            dev[name.rstrip(":")] = value

    # based on the basic info, get extended text details
    for d in devices.keys():
        # get additional info and add it to existing data
        devices[d] = devices[d].copy()
        devices[d].update(get_pci_device_details(d).items())

        # add igb_uio to list of supporting modules if needed
        if "Module_str" in devices[d]:
            for driver in dpdk_drivers:
                if driver not in devices[d]["Module_str"]:
                    devices[d]["Module_str"] = \
                        devices[d]["Module_str"] + ",%s" % driver
        else:
            devices[d]["Module_str"] = ",".join(dpdk_drivers)

        # make sure the driver and module strings do not have any duplicates
        if has_driver(d):
            modules = devices[d]["Module_str"].split(",")
            if devices[d]["Driver_str"] in modules:
                modules.remove(devices[d]["Driver_str"])
                devices[d]["Module_str"] = ",".join(modules)


def dev_id_from_dev_name(dev_name):
    '''Take a device "name" - a string passed in by user to identify a NIC
    device, and determine the device id - i.e. the domain:bus:slot.func - for
    it, which can then be used to index into the devices array'''

    # check if it's already a suitable index
    if dev_name in devices:
        return dev_name
    # check if it's an index just missing the domain part
    elif "0000:" + dev_name in devices:
        return "0000:" + dev_name
    else:
        # check if it's an interface name, e.g. eth1
        for d in devices.keys():
            if dev_name in devices[d]["Interface"].split(","):
                return devices[d]["Slot"]
    # if nothing else matches - error
    print("Unknown device: %s. "
          "Please specify device in \"bus:slot.func\" format" % dev_name)
    sys.exit(1)


def unbind_one(dev_id, force):
    '''Unbind the device identified by "dev_id" from its current driver'''
    dev = devices[dev_id]
    if not has_driver(dev_id):
        print("%s %s %s is not currently managed by any driver\n" %
              (dev["Slot"], dev["Device_str"], dev["Interface"]))
        return

    # prevent us disconnecting ourselves
    if dev["Ssh_if"] and not force:
        print("Routing table indicates that interface %s is active. "
              "Skipping unbind" % (dev_id))
        return

    # write to /sys to unbind
    filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"]
    try:
        f = open(filename, "a")
    except:
        print("Error: unbind failed for %s - Cannot open %s"
              % (dev_id, filename))
        sys.exit(1)
    f.write(dev_id)
    f.close()


def bind_one(dev_id, driver, force):
    '''Bind the device given by "dev_id" to the driver "driver". If the device
    is already bound to a different driver, it will be unbound first'''
    dev = devices[dev_id]
    saved_driver = None  # used to rollback any unbind in case of failure

    # prevent disconnection of our ssh session
    if dev["Ssh_if"] and not force:
        print("Routing table indicates that interface %s is active. "
              "Not modifying" % (dev_id))
        return

    # unbind any existing drivers we don't want
    if has_driver(dev_id):
        if dev["Driver_str"] == driver:
            print("%s already bound to driver %s, skipping\n"
                  % (dev_id, driver))
            return
        else:
            saved_driver = dev["Driver_str"]
            unbind_one(dev_id, force)
            dev["Driver_str"] = ""  # clear driver string

    # if we are binding to one of DPDK drivers, add PCI id's to that driver
    if driver in dpdk_drivers:
        filename = "/sys/bus/pci/drivers/%s/new_id" % driver
        try:
            f = open(filename, "w")
        except:
            print("Error: bind failed for %s - Cannot open %s"
                  % (dev_id, filename))
            return
        try:
            f.write("%04x %04x" % (dev["Vendor"], dev["Device"]))
            f.close()
        except:
            print("Error: bind failed for %s - Cannot write new PCI ID to "
                  "driver %s" % (dev_id, driver))
            return

    # do the bind by writing to /sys
    filename = "/sys/bus/pci/drivers/%s/bind" % driver
    try:
        f = open(filename, "a")
    except:
        print("Error: bind failed for %s - Cannot open %s"
              % (dev_id, filename))
        if saved_driver is not None:  # restore any previous driver
            bind_one(dev_id, saved_driver, force)
        return
    try:
        f.write(dev_id)
        f.close()
    except:
        # for some reason, closing dev_id after adding a new PCI ID to new_id
        # results in IOError. however, if the device was successfully bound,
        # we don't care for any errors and can safely ignore IOError
        tmp = get_pci_device_details(dev_id)
        if "Driver_str" in tmp and tmp["Driver_str"] == driver:
            return
        print("Error: bind failed for %s - Cannot bind to driver %s"
              % (dev_id, driver))
        if saved_driver is not None:  # restore any previous driver
            bind_one(dev_id, saved_driver, force)
        return


def unbind_all(dev_list, force=False):
    """Unbind method, takes a list of device locations"""
    dev_list = map(dev_id_from_dev_name, dev_list)
    for d in dev_list:
        unbind_one(d, force)


def bind_all(dev_list, driver, force=False):
    """Bind method, takes a list of device locations"""
    global devices

    dev_list = map(dev_id_from_dev_name, dev_list)

    for d in dev_list:
        bind_one(d, driver, force)

    # when binding devices to a generic driver (i.e. one that doesn't have a
    # PCI ID table), some devices that are not bound to any other driver could
    # be bound even if no one has asked them to. hence, we check the list of
    # drivers again, and see if some of the previously-unbound devices were
    # erroneously bound.
    for d in devices.keys():
        # skip devices that were already bound or that we know should be bound
        if "Driver_str" in devices[d] or d in dev_list:
            continue

        # update information about this device
        devices[d] = dict(devices[d].items() +
                          get_pci_device_details(d).items())

        # check if updated information indicates that the device was bound
        if "Driver_str" in devices[d]:
            unbind_one(d, force)


def display_devices(title, dev_list, extra_params=None):
    '''Displays to the user the details of a list of devices given in
    "dev_list". The "extra_params" parameter, if given, should contain a string
     with %()s fields in it for replacement by the named fields in each
     device's dictionary.'''
    strings = []  # this holds the strings to print. We sort before printing
    print("\n%s" % title)
    print("="*len(title))
    if len(dev_list) == 0:
        strings.append("<none>")
    else:
        for dev in dev_list:
            if extra_params is not None:
                strings.append("%s '%s' %s" % (dev["Slot"],
                               dev["Device_str"], extra_params % dev))
            else:
                strings.append("%s '%s'" % (dev["Slot"], dev["Device_str"]))
    # sort before printing, so that the entries appear in PCI order
    strings.sort()
    print("\n".join(strings))  # print one per line


def show_status():
    '''Function called when the script is passed the "--status" option.
    Displays to the user what devices are bound to the igb_uio driver, the
    kernel driver or to no driver'''
    global dpdk_drivers
    kernel_drv = []
    dpdk_drv = []
    no_drv = []

    # split our list of network devices into the three categories above
    for d in devices.keys():
        if (NETWORK_BASE_CLASS in devices[d]["Class"]):
            if not has_driver(d):
                no_drv.append(devices[d])
                continue
            if devices[d]["Driver_str"] in dpdk_drivers:
                dpdk_drv.append(devices[d])
            else:
                kernel_drv.append(devices[d])

    # print each category separately, so we can clearly see what's used by DPDK
    display_devices("Network devices using DPDK-compatible driver", dpdk_drv,
                    "drv=%(Driver_str)s unused=%(Module_str)s")
    display_devices("Network devices using kernel driver", kernel_drv,
                    "if=%(Interface)s drv=%(Driver_str)s "
                    "unused=%(Module_str)s %(Active)s")
    display_devices("Other network devices", no_drv, "unused=%(Module_str)s")

    # split our list of crypto devices into the three categories above
    kernel_drv = []
    dpdk_drv = []
    no_drv = []

    for d in devices.keys():
        if (CRYPTO_BASE_CLASS in devices[d]["Class"]):
            if not has_driver(d):
                no_drv.append(devices[d])
                continue
            if devices[d]["Driver_str"] in dpdk_drivers:
                dpdk_drv.append(devices[d])
            else:
                kernel_drv.append(devices[d])

    display_devices("Crypto devices using DPDK-compatible driver", dpdk_drv,
                    "drv=%(Driver_str)s unused=%(Module_str)s")
    display_devices("Crypto devices using kernel driver", kernel_drv,
                    "drv=%(Driver_str)s "
                    "unused=%(Module_str)s")
    display_devices("Other crypto devices", no_drv, "unused=%(Module_str)s")


def parse_args():
    '''Parses the command-line arguments given by the user and takes the
    appropriate action for each'''
    global b_flag
    global status_flag
    global force_flag
    global args
    if len(sys.argv) <= 1:
        usage()
        sys.exit(0)

    try:
        opts, args = getopt.getopt(sys.argv[1:], "b:us",
                                   ["help", "usage", "status", "force",
                                    "bind=", "unbind"])
    except getopt.GetoptError as error:
        print(str(error))
        print("Run '%s --usage' for further information" % sys.argv[0])
        sys.exit(1)

    for opt, arg in opts:
        if opt == "--help" or opt == "--usage":
            usage()
            sys.exit(0)
        if opt == "--status" or opt == "-s":
            status_flag = True
        if opt == "--force":
            force_flag = True
        if opt == "-b" or opt == "-u" or opt == "--bind" or opt == "--unbind":
            if b_flag is not None:
                print("Error - Only one bind or unbind may be specified\n")
                sys.exit(1)
            if opt == "-u" or opt == "--unbind":
                b_flag = "none"
            else:
                b_flag = arg


def do_arg_actions():
    '''do the actual action requested by the user'''
    global b_flag
    global status_flag
    global force_flag
    global args

    if b_flag is None and not status_flag:
        print("Error: No action specified for devices."
              "Please give a -b or -u option")
        print("Run '%s --usage' for further information" % sys.argv[0])
        sys.exit(1)

    if b_flag is not None and len(args) == 0:
        print("Error: No devices specified.")
        print("Run '%s --usage' for further information" % sys.argv[0])
        sys.exit(1)

    if b_flag == "none" or b_flag == "None":
        unbind_all(args, force_flag)
    elif b_flag is not None:
        bind_all(args, b_flag, force_flag)
    if status_flag:
        if b_flag is not None:
            get_nic_details()  # refresh if we have changed anything
            get_crypto_details()  # refresh if we have changed anything
        show_status()


def main():
    '''program main function'''
    parse_args()
    check_modules()
    get_nic_details()
    get_crypto_details()
    do_arg_actions()


if __name__ == "__main__":
    main()
