@@ -64,3 +64,6 @@ cdef class DM(PyverbsCM):
cdef class PortAttr(PyverbsObject):
cdef v.ibv_port_attr attr
+
+cdef class GIDEntry(PyverbsObject):
+ cdef v.ibv_gid_entry entry
@@ -26,6 +26,8 @@ from libc.stdlib cimport free, malloc
from libc.string cimport memset
from libc.stdint cimport uint64_t
from libc.stdint cimport uint16_t
+from libc.stdint cimport uint32_t
+from pyverbs.utils import gid_str
cdef extern from 'endian.h':
unsigned long be64toh(unsigned long host_64bits);
@@ -240,6 +242,53 @@ cdef class Context(PyverbsCM):
format(p=port_num), rc)
return port_attrs
+ def query_gid_table(self, size_t max_entries, uint32_t flags=0):
+ """
+ Queries the GID tables of the device for at most <max_entries> entries
+ and returns them.
+ :param max_entries: Maximum number of GID entries to retrieve
+ :param flags: Specifies new extra members of struct ibv_gid_entry to
+ query
+ :return: List of GIDEntry objects on success
+ """
+ cdef v.ibv_gid_entry *entries
+ cdef v.ibv_gid_entry entry
+
+ entries = <v.ibv_gid_entry *>malloc(max_entries *
+ sizeof(v.ibv_gid_entry))
+ rc = v.ibv_query_gid_table(self.context, entries, max_entries, flags)
+ if rc < 0:
+ raise PyverbsRDMAError('Failed to query gid tables of the device',
+ rc)
+ gid_entries = []
+ for i in range(rc):
+ entry = entries[i]
+ gid_entries.append(GIDEntry(entry.gid._global.subnet_prefix,
+ entry.gid._global.interface_id, entry.gid_index,
+ entry.port_num, entry.gid_type,
+ entry.ndev_ifindex))
+ free(entries)
+ return gid_entries
+
+ def query_gid_ex(self, uint32_t port_num, uint32_t gid_index,
+ uint32_t flags=0):
+ """
+ Queries the GID table of port <port_num> in index <gid_index>, and
+ returns the GID entry.
+ :param port_num: The port number to query
+ :param gid_index: The index in the GID table to query
+ :param flags: Specifies new extra members of struct ibv_gid_entry to
+ query
+ :return: GIDEntry object on success
+ """
+ entry = GIDEntry()
+ rc = v.ibv_query_gid_ex(self.context, port_num, gid_index,
+ &entry.entry, flags)
+ if rc != 0:
+ raise PyverbsRDMAError(f'Failed to query gid table of port '\
+ f'{port_num} in index {gid_index}', rc)
+ return entry
+
cdef add_ref(self, obj):
if isinstance(obj, PD):
self.pds.add(obj)
@@ -816,6 +865,63 @@ cdef class PortAttr(PyverbsObject):
print_format.format('Flags', self.attr.flags)
+cdef class GIDEntry(PyverbsObject):
+ def __init__(self, subnet_prefix=0, interface_id=0, gid_index=0,
+ port_num=0, gid_type=0, ndev_ifindex=0):
+ super().__init__()
+ self.entry.gid._global.subnet_prefix = subnet_prefix
+ self.entry.gid._global.interface_id = interface_id
+ self.entry.gid_index = gid_index
+ self.entry.port_num = port_num
+ self.entry.gid_type = gid_type
+ self.entry.ndev_ifindex = ndev_ifindex
+
+ @property
+ def gid_subnet_prefix(self):
+ return self.entry.gid._global.subnet_prefix
+
+ @property
+ def gid_interface_id(self):
+ return self.entry.gid._global.interface_id
+
+ @property
+ def gid_index(self):
+ return self.entry.gid_index
+
+ @property
+ def port_num(self):
+ return self.entry.port_num
+
+ @property
+ def gid_type(self):
+ return self.entry.gid_type
+
+ @property
+ def ndev_ifindex(self):
+ return self.entry.ndev_ifindex
+
+ def gid_str(self):
+ return gid_str(self.gid_subnet_prefix, self.gid_interface_id)
+
+ def __str__(self):
+ print_format = '{:<24}: {:<20}\n'
+ return print_format.format('GID', self.gid_str()) +\
+ print_format.format('GID Index', self.gid_index) +\
+ print_format.format('Port number', self.port_num) +\
+ print_format.format('GID type', translate_gid_type(
+ self.gid_type)) +\
+ print_format.format('Ndev ifindex', self.ndev_ifindex)
+
+
+def translate_gid_type(gid_type):
+ types = {e.IBV_GID_TYPE_IB: 'IB', e.IBV_GID_TYPE_ROCE_V1: 'RoCEv1',
+ e.IBV_GID_TYPE_ROCE_V2: 'RoCEv2'}
+ try:
+ return types[gid_type]
+ except KeyError:
+ return f'Unknown gid_type ({gid_type})'
+
+
def guid_format(num):
"""
Get GUID representation of the given number, including change of endianness.
@@ -483,6 +483,13 @@ cdef extern from 'infiniband/verbs.h':
uint32_t options
uint32_t comp_mask
+ cdef struct ibv_gid_entry:
+ ibv_gid gid
+ uint32_t gid_index
+ uint32_t port_num
+ uint32_t gid_type
+ uint32_t ndev_ifindex
+
ibv_device **ibv_get_device_list(int *n)
int ibv_get_device_index(ibv_device *device);
void ibv_free_device_list(ibv_device **list)
@@ -613,6 +620,12 @@ cdef extern from 'infiniband/verbs.h':
void ibv_unimport_mr(ibv_mr *mr)
ibv_pd *ibv_import_pd(ibv_context *context, uint32_t handle)
void ibv_unimport_pd(ibv_pd *pd)
+ int ibv_query_gid_ex(ibv_context *context, uint32_t port_num,
+ uint32_t gid_index, ibv_gid_entry *entry,
+ uint32_t flags)
+ ssize_t ibv_query_gid_table(ibv_context *context,
+ ibv_gid_entry *entries, size_t max_entries,
+ uint32_t flags)
cdef extern from 'infiniband/driver.h':
@@ -427,6 +427,11 @@ cdef extern from '<infiniband/verbs.h>':
cdef void *IBV_ALLOCATOR_USE_DEFAULT
+ cpdef enum ibv_gid_type:
+ IBV_GID_TYPE_IB
+ IBV_GID_TYPE_ROCE_V1
+ IBV_GID_TYPE_ROCE_V2
+
cdef extern from "<infiniband/verbs_api.h>":
cdef unsigned long long IBV_ADVISE_MR_ADVICE_PREFETCH