diff --git a/go.mod b/go.mod index 10eb646..f66ec95 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/google/gofuzz v1.1.0 github.com/google/uuid v1.3.0 + github.com/intel/afxdp-plugins-for-kubernetes/pkg/goclient v0.0.0 github.com/intel/afxdp-plugins-for-kubernetes/pkg/subfunctions v0.0.0 github.com/pkg/errors v0.9.1 github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1 @@ -22,3 +23,4 @@ require ( ) replace github.com/intel/afxdp-plugins-for-kubernetes/pkg/subfunctions => ./pkg/subfunctions +replace github.com/intel/afxdp-plugins-for-kubernetes/pkg/goclient => ./pkg/goclient diff --git a/pkg/cclient/README.md b/pkg/cclient/README.md new file mode 100644 index 0000000..4f1b9bc --- /dev/null +++ b/pkg/cclient/README.md @@ -0,0 +1,46 @@ +# Compiling the C Library + +## Creating the shared library and header files: + +```cmd +go build -o lib_udsclient.so -buildmode=c-shared cclient.go +``` +- this creates the header and shared library files from the cclient.go file. + +## Creating the the static library and header files: + +```cmd +go build -o lib_udsclient.a -buildmode=c-archive ./cclient.go +``` +- this creates the shared library and header files + +## Usage + +After creating the library and header files as described in the previous steps, +this is how to use the functions generated by cgo + +```c +char* GetUdsClientVersion() +``` +This returns the version of the handshake on your local machine/client. + +```c +char* GetUdsServerVersion() +``` +This returns the version of the handshake on the server/host. + +```c +int RequestXskMapFd(char* device) +``` +This requests an xskmap Fd for a specified device. + +```c +int RequestBusyPoll(int busyTimeout, int busyBudget, int fd) +``` +This requests a busy poll for a specific device by using it's fd, and specifying a timeout and a budget. + +```c +void CleanUpConnection() +``` +After all the other functions are called, this needs to be called after all the work you need to do is done, +so that the connection to the UDS can be cleaned up. \ No newline at end of file diff --git a/pkg/cclient/cclient.go b/pkg/cclient/cclient.go new file mode 100644 index 0000000..f3f5ea5 --- /dev/null +++ b/pkg/cclient/cclient.go @@ -0,0 +1,94 @@ +package main + +import ( + "C" + "fmt" + "os" + + "github.com/intel/afxdp-plugins-for-kubernetes/internal/uds" + "github.com/intel/afxdp-plugins-for-kubernetes/pkg/goclient" +) + +func main() { + // Needed for cgo to generate the .h +} + +var cleaner uds.CleanupFunc + +/* +GetClientVersion is an exported version for c of the goclient GetClientVersion() +*/ +//export GetUdsClientVersion +func GetUdsClientVersion() *C.char { + return C.CString(goclient.GetClientVersion()) +} + +/* +ServerVersion is an exported version for c of the goclient GetServerVersion() +*/ +//export GetUdsServerVersion +func GetUdsServerVersion() *C.char { + response, function, err := goclient.GetServerVersion() + if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + function() + return C.CString("-1") + } + + cleaner = function + + return C.CString(response) +} + +/* +GetXskMapFd is an exported version for c of the goclient XskMapFd() +*/ +//export RequestXskMapFd +func RequestXskMapFd(device *C.char) (fd C.int) { + if device != nil { + fdVal, function, err := goclient.RequestXSKmapFD(C.GoString(device)) + fd = C.int(fdVal) + if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + function() + return -1 + } + + cleaner = function + return fd + } + + return -1 +} + +/* +RequestBusyPoll is an exported version for c of the goclient RequestBusyPoll() +*/ +//export RequestBusyPoll +func RequestBusyPoll(busyTimeout, busyBudget, fd C.int) C.int { + timeout, budget, fdInt := int(busyTimeout), int(busyBudget), int(fd) + if timeout > -1 && budget > -1 && fdInt > -1 { + function, err := goclient.RequestBusyPoll(timeout, budget, fdInt) + if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + function() + return -1 + } + cleaner = function + return 0 + } + return -1 +} + +/* +CleanUpConnection an explicit exported cgo function to cleanup a connection after calling any of the other functions. +Pass in one of the available function names to clean up the connection after use. +*/ +//export CleanUpConnection +func CleanUpConnection() { + if cleaner == nil { + fmt.Println("No cleanup function available to call") + } else { + cleaner() + } +}