From: Noa Osherovich <noaos@xxxxxxxxxxxx> GID class represents ibv_gid and exposes the GID value. It can be used to query a GID as follows: import pyverbs.device as d ctx = d.Context(name='mlx5_0') gid = ctx.query_gid(port_num=1, index=0) print(gid) fe80:0000:0000:0000:7cfe:9003:00af:7970 Signed-off-by: Noa Osherovich <noaos@xxxxxxxxxxxx> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> --- pyverbs/addr.pxd | 9 +++++++ pyverbs/addr.pyx | 53 ++++++++++++++++++++++++++++++++++++++++++ pyverbs/device.pyx | 9 +++++++ pyverbs/libibverbs.pxd | 10 ++++++++ 4 files changed, 81 insertions(+) create mode 100644 pyverbs/addr.pxd create mode 100644 pyverbs/addr.pyx diff --git a/pyverbs/addr.pxd b/pyverbs/addr.pxd new file mode 100644 index 00000000..39039379 --- /dev/null +++ b/pyverbs/addr.pxd @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. See COPYING file + +from .base cimport PyverbsObject +from pyverbs cimport libibverbs as v + + +cdef class Gid(PyverbsObject): + cdef v.ibv_gid gid diff --git a/pyverbs/addr.pyx b/pyverbs/addr.pyx new file mode 100644 index 00000000..1869f364 --- /dev/null +++ b/pyverbs/addr.pyx @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. See COPYING file + +import sys +from libc.stdint cimport uint8_t +from .pyverbs_error import PyverbsUserError + +cdef extern from 'Python.h': + object PyBytes_FromStringAndSize(char *str, Py_ssize_t len) + +cdef extern from 'endian.h': + unsigned long be64toh(unsigned long host_64bits) + + +cdef class Gid(PyverbsObject): + """ + GID class represents ibv_gid. It enables user to query for GIDs values. + """ + property gid: + def __get__(self): + """ + Expose the inner GID + :return: A GID string in an 8 words format: + 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx' + """ + return self.__str__() + def __set__(self, val): + """ + Sets the inner GID + :param val: A GID string in an 8 words format: + 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx' + :return: None + """ + val = val.split(':') + if len(val) != 8: + raise PyverbsUserError("Invalid GID value ({val})".format(val=val)) + if any([len(v) != 4 for v in val]): + raise PyverbsUserError("Invalid GID value ({val})".format(val=val)) + val_int = int("".join(val), 16) + vals = [] + for i in range(8): + vals.append(val[i][0:2]) + vals.append(val[i][2:4]) + + for i in range(16): + self.gid.raw[i] = <uint8_t>int(vals[i],16) + + def __str__(self): + hex_values = '%016x%016x' % (be64toh(self.gid._global.subnet_prefix), + be64toh(self.gid._global.interface_id)) + return ':'.join([hex_values[0:4], hex_values[4:8], hex_values[8:12], + hex_values[12:16], hex_values[16:20], hex_values[20:24], + hex_values[24:28],hex_values[28:32]]) diff --git a/pyverbs/device.pyx b/pyverbs/device.pyx index 8432fc90..696459f7 100644 --- a/pyverbs/device.pyx +++ b/pyverbs/device.pyx @@ -10,6 +10,7 @@ from .pyverbs_error import PyverbsRDMAError from .pyverbs_error import PyverbsUserError from pyverbs.base import PyverbsRDMAErrno cimport pyverbs.libibverbs as v +from pyverbs.addr cimport Gid cdef extern from 'errno.h': int errno @@ -132,6 +133,14 @@ cdef class Context(PyverbsObject): format(name=self.name), errno) return dev_attr + def query_gid(self, unsigned int port_num, int index): + gid = Gid() + rc = v.ibv_query_gid(self.context, port_num, index, &gid.gid) + if rc != 0: + raise PyverbsRDMAError('Failed to query gid {idx} of port {port}'. + format(idx=index, port=port_num)) + return gid + cdef class DeviceAttr(PyverbsObject): """ diff --git a/pyverbs/libibverbs.pxd b/pyverbs/libibverbs.pxd index 20f855c2..f212078f 100644 --- a/pyverbs/libibverbs.pxd +++ b/pyverbs/libibverbs.pxd @@ -6,6 +6,14 @@ from libc.stdint cimport uint8_t, uint64_t cdef extern from 'infiniband/verbs.h': + cdef struct anon: + unsigned long subnet_prefix + unsigned long interface_id + + cdef union ibv_gid: + anon _global "global" + uint8_t raw[16] + cdef struct ibv_device: char *name int node_type @@ -62,3 +70,5 @@ cdef extern from 'infiniband/verbs.h': int ibv_close_device(ibv_context *context) int ibv_query_device(ibv_context *context, ibv_device_attr *device_attr) unsigned long ibv_get_device_guid(ibv_device *device) + int ibv_query_gid(ibv_context *context, unsigned int port_num, + int index, ibv_gid *gid) -- 2.19.1