Skip to content

Commit

Permalink
Merge pull request #487 from intel-go/develop
Browse files Browse the repository at this point in the history
Release v0.6.0
  • Loading branch information
aregm authored Oct 4, 2018
2 parents 1fbebd4 + 24d9c83 commit e30524b
Show file tree
Hide file tree
Showing 100 changed files with 3,803 additions and 4,829 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ script:
- docker exec -i test-nff-go make
# Build standalone examples
- docker exec -i test-nff-go bash -c "cd examples && make gopacketParserExample && cd .."
- docker exec -i test-nff-go bash -c "cd test/localTesting && make && cd -"
- docker exec -i test-nff-go bash -c "cd examples && make nffPktgen && cd -"
- docker exec -i test-nff-go make -C examples/dpi
# Run unit tests
- docker exec -i test-nff-go sysctl -w vm.nr_hugepages=1024
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ TESTING_TARGETS = $(CI_TESTING_TARGETS) test/stability

all: $(SUBDIRS)

debug:
$(MAKE) all NFF_GO_DEBUG=y

dpdk: nff-go-base

test: dpdk
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ Use Go version 1.9 or higher. To check the version of Go, do:
cd $GOPATH/src/github.com/intel-go/nff-go
make -j8

## Building NFF-GO in debug mode

make debug -j8

# Running NFF-GO

## Documentation
Expand Down Expand Up @@ -202,7 +206,7 @@ downloaded automatically.

If you want to contribute to NFF-Go, check our [Contributing
guide](https://github.com/intel-go/yanff/blob/master/CONTRIBUTING.md). We also
recommend checking the 'janitorial' bugs in our list of open issues; these bugs
recommend checking the bugs with 'help-wanted' or 'easyfix' in our list of open issues; these bugs
can be solved without an extensive knowledge of NFF-Go. We would love to help
you start contributing.

Expand Down
19 changes: 13 additions & 6 deletions common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,18 @@ const (
IPNumber = 0x04
TCPNumber = 0x06
UDPNumber = 0x11
NoNextHeader = 0x3B
ICMPv6Number = 0x3a
NoNextHeader = 0x3b
)

// Supported ICMP Types
const (
ICMPTypeEchoRequest uint8 = 8
ICMPTypeEchoResponse uint8 = 0
ICMPTypeEchoRequest uint8 = 8
ICMPTypeEchoResponse uint8 = 0
ICMPv6TypeEchoRequest uint8 = 128
ICMPv6TypeEchoResponse uint8 = 129
ICMPv6NeighborSolicitation uint8 = 135
ICMPv6NeighborAdvertisement uint8 = 136
)

// These constants keep length of supported headers in bytes.
Expand Down Expand Up @@ -92,11 +97,11 @@ const (
// No - no output even after fatal errors
No LogType = 1 << iota
// Initialization - output during system initialization
Initialization
Initialization = 2
// Debug - output during execution one time per time period (scheduler ticks)
Debug
Debug = 4
// Verbose - output during execution as soon as something happens. Can influence performance
Verbose
Verbose = 8
)

// TCPFlags contains set TCP flags.
Expand Down Expand Up @@ -147,6 +152,8 @@ const (
MultipleReceivePort
MultipleKNIPort
WrongPort
FailToInitDPDK
FailToCreateKNI
)

// NFError is error type returned by nff-go functions
Expand Down
75 changes: 75 additions & 0 deletions devices/bind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2018 Intel Corporation.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package devices helps to query DPDK compatibles devices and to bind/unbind drivers
package devices

// Device is a DPDK compatible device and should be able to bind, unbind and
// probe.
type Device interface {
// Binds a driver to the device
Bind(driver string) error
// Unbinds the current driver from the device
Unbind() error
// Returns the name of the driver that is currently bound
CurrentDriver() (string, error)
// Probes the currently bound driver and checks if there is an error
Probe() error
// Returns the ID of the device
ID() string
}

// New returns a corresponding device by given input
func New(input string) (Device, error) {
switch {
case IsPciID.Match([]byte(input)):
return NewDeviceByPciID(input)
case IsUUID.Match([]byte(input)):
return NewDeviceByVmbusID(input)
default:
return NewDeviceByNicName(input)
}
}

// NewDeviceByPciID returns a PCI device by given PCI ID
func NewDeviceByPciID(pciID string) (Device, error) {
device, err := GetPciDeviceByPciID(pciID)
if err != nil {
return nil, err
}

return device, nil
}

// NewDeviceByVmbusID returns a VMBus device by given UUID
func NewDeviceByVmbusID(uuid string) (Device, error) {
device, err := GetVmbusDeviceByUUID(uuid)
if err != nil {
return nil, err
}

return device, nil
}

// NewDeviceByNicName returns a device by given NIC name, e.g. eth0.
func NewDeviceByNicName(nicName string) (Device, error) {
devID, err := GetDeviceID(nicName)
if err != nil {
return nil, err
}

device, err := newDevice(devID)
if err != nil {
return nil, err
}

return device, nil
}

func newDevice(id string) (Device, error) {
if IsPciID.Match([]byte(id)) {
return GetPciDeviceByPciID(id)
}
return GetVmbusDeviceByUUID(id)
}
112 changes: 112 additions & 0 deletions devices/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2018 Intel Corporation.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package devices helps to query DPDK compatibles devices and to bind/unbind drivers
package devices

import (
"fmt"
"regexp"
)

// Driver names
const (
DriverHvNetvcs = "hv_netvcs"
DriverUioPciGeneric = "uio_pci_generic"
DriverIgUio = "ig_uio"
DriverVfioPci = "vfio-pci"
DriverUioHvGeneric = "uio_hv_generic"
)

// Path to PCI
const (
PathSysPciDevices = "/sys/bus/pci/devices"
PathSysPciDrivers = "/sys/bus/pci/drivers"
PathSysPciDriverProbe = "/sys/bus/pci/drivers_probe"
)

// Path to VMBus
const (
PathSysVmbusDevices = "/sys/bus/vmbus/devices"
PathSysVmbusDrivers = "/sys/bus/vmbus/drivers"
)

// Path to net
const (
PathSysClassNet = "/sys/class/net"
)

// Regular expressions for PCI-ID and UUID
var (
IsPciID *regexp.Regexp
IsUUID *regexp.Regexp
)

// DPDK related drivers
var (
DefaultDpdkDriver = DriverUioPciGeneric
DpdkDrivers = [...]string{DriverUioPciGeneric, DriverIgUio, DriverVfioPci, DriverUioHvGeneric}
DpdkPciDrivers = [...]string{DriverUioPciGeneric, DriverIgUio, DriverVfioPci}
DpdkVmbusDrivers = [...]string{DriverUioHvGeneric}
)

type stringBuilder string

func (s stringBuilder) With(args ...interface{}) string {
return fmt.Sprintf(string(s), args...)
}

var (
pathSysPciDevicesBind stringBuilder = PathSysPciDevices + "/%s/driver/bind"
pathSysPciDevicesUnbind stringBuilder = PathSysPciDevices + "/%s/driver/unbind"
pathSysPciDevicesOverrideDriver stringBuilder = PathSysPciDevices + "/%s/driver_override"

pathSysPciDriversBind stringBuilder = PathSysPciDrivers + "/%s/bind"
pathSysPciDriversUnbind stringBuilder = PathSysPciDrivers + "/%s/unbind"
pathSysPciDriversNewID stringBuilder = PathSysPciDrivers + "/%s/new_id"
)

var (
pathSysVmbusDriversBind stringBuilder = PathSysVmbusDrivers + "/%s/bind"
pathSysVmbusDriversUnbind stringBuilder = PathSysVmbusDrivers + "/%s/unbind"
pathSysVmbusDriversNewID stringBuilder = PathSysVmbusDrivers + "/%s/new_id"
)

var (
pathSysClassNetDeviceDriver stringBuilder = PathSysClassNet + "/%s/device/driver"
pathSysClassNetDevice stringBuilder = PathSysClassNet + "/%s/device"
)

var (
vmbusDeviceStringer stringBuilder = "ID: %s\nClass:\t%s\nDriver:\t%s"
pciDeviceStringer stringBuilder = "ID: %s\nClass:\t%s\nVendor:\t%s\nDevice:\t%s\nDriver:\t%s"
)

var (
// for ethtool output
rPciIDForEthtool *regexp.Regexp

// for lspci output
rPciClass *regexp.Regexp
rPciVendor *regexp.Regexp
rPciDevice *regexp.Regexp
rPciDriver *regexp.Regexp

// for find output
rVmbusDriver *regexp.Regexp
)

func init() {
rPciIDForEthtool = regexp.MustCompile("bus-info:\\s([0-9:.]+)")

rPciClass = regexp.MustCompile("[Cc]lass:\\s([0-9a-zA-Z]{4})")
rPciVendor = regexp.MustCompile("[Vv]endor:\\s([0-9a-zA-Z]{4})")
rPciDevice = regexp.MustCompile("[Dd]evice:\\s([0-9a-zA-Z]{4})")
rPciDriver = regexp.MustCompile("[Dd]river:\\s(\\S+)")

rVmbusDriver = regexp.MustCompile("/sys/bus/vmbus/drivers/(\\S+)/")

IsPciID = regexp.MustCompile("^\\d{4}:\\d{2}:\\d{2}.\\d$")
IsUUID = regexp.MustCompile("^[[:xdigit:]]{8}-[[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}$")
}
21 changes: 21 additions & 0 deletions devices/errno.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2018 Intel Corporation.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package devices helps to query DPDK compatibles devices and to bind/unbind drivers
package devices

import (
"errors"
)

// Errors of devices package
var (
ErrNoBoundDriver = errors.New("no driver is bound to the device")
ErrAlreadyBoundDriver = errors.New("device has already bound the selected driver")
ErrBind = errors.New("fail to bind the driver")
ErrUnbind = errors.New("fail to unbind the driver")
ErrUnsupportedDriver = errors.New("unsupported DPDK driver")
ErrNotProbe = errors.New("device doesn't support 'drive_probe'")
ErrKernelModuleNotLoaded = errors.New("kernel module is not loaded")
)
98 changes: 98 additions & 0 deletions devices/misc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2018 Intel Corporation.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package devices helps to query DPDK compatibles devices and to bind/unbind drivers
package devices

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
)

var defaultTimeoutLimitation = 5 * time.Second

// FindDefaultDpdkDriver returns a default DPDK driver that the given NIC can
// use.
func FindDefaultDpdkDriver(nicName string) string {
driver, err := readlinkBaseCmd(pathSysClassNetDeviceDriver.With(nicName))
if err != nil {
return DefaultDpdkDriver
}
switch driver {
case DriverHvNetvcs:
return DriverUioHvGeneric
default:
return DefaultDpdkDriver
}
}

// GetDeviceID returns the device ID of given NIC name.
func GetDeviceID(nicName string) (string, error) {
// DEV_ID=$(basename $(readlink /sys/class/net/<nicName>/device))
return readlinkBaseCmd(pathSysClassNetDevice.With(nicName))
}

// IsModuleLoaded checks if the kernel has already loaded the driver or not.
func IsModuleLoaded(driver string) bool {
output, err := cmdOutputWithTimeout(defaultTimeoutLimitation, "lsmod")
if err != nil {
// Can't run lsmod, return false
return false
}
lines := strings.Split(string(output), "\n")
for _, line := range lines {
if checkModuleLine(line, driver) {
return true
}
}
return false
}

func writeToTargetWithData(sysfs string, flag int, mode os.FileMode, data string) error {
writer, err := os.OpenFile(sysfs, flag, mode)
if err != nil {
return fmt.Errorf("OpenFile failed: %s", err.Error())
}
defer writer.Close()

_, err = writer.Write([]byte(data))
if err != nil {
return fmt.Errorf("WriteFile failed: %s", err.Error())
}

return nil
}

func readlinkBaseCmd(path string) (string, error) {
output, err := cmdOutputWithTimeout(defaultTimeoutLimitation, "readlink", path)
if err != nil {
return "", fmt.Errorf("Cmd Execute readlink failed: %s", err.Error())
}
outputStr := strings.Trim(string(output), "\n")
result := filepath.Base(outputStr)
return result, nil
}

func checkModuleLine(line, driver string) bool {
if !strings.Contains(line, driver) {
return false
}
elements := strings.Split(line, " ")
return elements[0] == driver
}

func cmdOutputWithTimeout(duration time.Duration, cmd string, parameters ...string) ([]byte, error) {
ctx, cancel := context.WithTimeout(context.Background(), duration)
defer cancel()
output, err := exec.CommandContext(ctx, cmd, parameters...).Output()
if err != nil {
return nil, err
}
return output, nil
}
Loading

0 comments on commit e30524b

Please sign in to comment.