Add a new call to libibumad that allows a user to register for snooping MADs. Snooped MADs are returned to the user through the umad_recv routine.
A user can specify a filter for snooped MADs through the new API. To support possible future extensions to the filter, the size of the structure is also provided. Signed-off-by: Sean Hefty <[email protected]> --- libibumad/Makefile.am | 1 + libibumad/include/infiniband/umad.h | 10 ++++++ libibumad/man/umad_register_snoop.3 | 52 ++++++++++++++++++++++++++++++++++ libibumad/src/libibumad.map | 1 + libibumad/src/umad.c | 54 ++++++++++++++++++++++++++++++++++- 5 files changed, 117 insertions(+), 1 deletions(-) mode change 100644 => 100755 libibumad/include/infiniband/umad.h create mode 100755 libibumad/man/umad_register_snoop.3 mode change 100644 => 100755 libibumad/src/umad.c diff --git a/libibumad/Makefile.am b/libibumad/Makefile.am index 6e3f518..9c84f0c 100644 --- a/libibumad/Makefile.am +++ b/libibumad/Makefile.am @@ -14,6 +14,7 @@ man_MANS = man/umad_debug.3 man/umad_get_ca.3 \ man/umad_set_addr_net.3 man/umad_set_addr.3 man/umad_set_pkey.3 \ man/umad_get_pkey.3 \ man/umad_register.3 man/umad_register_oui.3 man/umad_unregister.3 \ + man/umad_register_snoop.3 \ man/umad_send.3 man/umad_recv.3 man/umad_poll.3 \ man/umad_get_issm_path.3 diff --git a/libibumad/include/infiniband/umad.h b/libibumad/include/infiniband/umad.h old mode 100644 new mode 100755 index 7ad5e4a..153c5f1 --- a/libibumad/include/infiniband/umad.h +++ b/libibumad/include/infiniband/umad.h @@ -148,6 +148,14 @@ typedef struct umad_ca { umad_port_t *ports[UMAD_CA_MAX_PORTS]; } umad_ca_t; +typedef struct umad_filter { + uint8_t mgmt_class; + uint8_t mgmt_version; + uint16_t attr_id; + uint8_t errors; + uint8_t oui[3]; +} umad_filter_t; + int umad_init(void); int umad_done(void); @@ -186,6 +194,8 @@ int umad_register(int portid, int mgmt_class, int mgmt_version, uint8_t rmpp_version, long method_mask[16 / sizeof(long)]); int umad_register_oui(int portid, int mgmt_class, uint8_t rmpp_version, uint8_t oui[3], long method_mask[16 / sizeof(long)]); +int umad_register_snoop(int portid, umad_filter_t *filter, + size_t filter_length); int umad_unregister(int portid, int agentid); int umad_debug(int level); diff --git a/libibumad/man/umad_register_snoop.3 b/libibumad/man/umad_register_snoop.3 new file mode 100755 index 0000000..00b361d --- /dev/null +++ b/libibumad/man/umad_register_snoop.3 @@ -0,0 +1,52 @@ +.\" -*- nroff -*- +.\" +.TH UMAD_REGISTER_SNOOP 3 "October 15, 2010" "OpenIB" "OpenIB Programmer\'s Manual" +.SH "NAME" +umad_register_snoop \- register to capture sent and received MADs +.SH "SYNOPSIS" +.nf +.B #include <infiniband/umad.h> +.sp +.BI "int umad_register_snoop(int " "portid" ", umad_filter_t " "filter" ", size_t " "filter_length"); +.fi +.SH "DESCRIPTION" +.B umad_register_snoop() +Registers to snoop MADs that meet the specified filter. +MAD snooping occurs after RMPP segmentation has occurred on sent MADs, +and before RMPP reassembly occurs on received MADs. Snooped MADs +are returned to the user through the umad_recv interface. +.SH "FILTER" +Users specify a filter through the umad_filter_t routine. +Only MADs which pass all indicated filtering restrictions are reported +to the user. The definition for the umad_filter_t fields are: +.IP mgmt_class +Only MADs for the specified management class are reported to the user. +If mgmt_class is set to 0, then MADs for all management classes +sent or received on the GSI interface (QP1) are reported. +.IP mgmt_version +Restricts reported MADs to the specified management class version. +A user may set mgmt_version to 0 to report MADs of all versions. +This field is ignored if mgmt_class is set to 0. +.IP attr_id +Restricts MADs to those containing the specified attribute identifier. +A user may set attr_id to 0 to report MADs referencing any attribute ID. +This field is ignored if mgmt_class is set to 0. +.IP errors +If non-zero, only reports sent MADs that complete in error or MADs +containing a non-zero status value. Sent MADs which complete as successful +or canceled are not reported. +.IP oui +If non-zero, only reports MADs that contain the specified OUI. +This field is ignored if the mgmt_class is not in the vendor +class 2 range. +.SH "RETURN VALUE" +.B umad_register_snoop() +returns non-negative agent id number on success, and a negative value on error as follows: + -EINVAL invalid port handle, filter, or filter_length + -EPERM registration failed +.SH "SEE ALSO" +.BR umad_register(3), +.BR umad_unregister(3) +.SH "AUTHOR" +.TP +Sean Hefty <[email protected]> diff --git a/libibumad/src/libibumad.map b/libibumad/src/libibumad.map index 0154b7f..b4b0b4b 100644 --- a/libibumad/src/libibumad.map +++ b/libibumad/src/libibumad.map @@ -30,5 +30,6 @@ IBUMAD_1.0 { umad_debug; umad_addr_dump; umad_dump; + umad_register_snoop; local: *; }; diff --git a/libibumad/src/umad.c b/libibumad/src/umad.c old mode 100644 new mode 100755 index d16e750..6eb476d --- a/libibumad/src/umad.c +++ b/libibumad/src/umad.c @@ -67,9 +67,24 @@ # define VALGRIND_MAKE_MEM_DEFINED(addr,len) #endif +struct ib_user_mad_snoop_filter { + uint16_t attr_id; + uint8_t errors; + uint8_t reserved[13]; +}; + +enum { + UMAD_SNOOP_QP = 0x80, + UMAD_SNOOP_QP0 = 0x80, + UMAD_SNOOP_QP1 = 0x81 +}; + typedef struct ib_user_mad_reg_req { uint32_t id; - uint32_t method_mask[4]; + union { + uint32_t method_mask[4]; + struct ib_user_mad_snoop_filter filter; + }; uint8_t qpn; uint8_t mgmt_class; uint8_t mgmt_class_version; @@ -879,6 +894,43 @@ int umad_get_fd(int fd) return fd; } +int umad_register_snoop(int fd, umad_filter_t *filter, + size_t filter_length) +{ + struct ib_user_mad_reg_req req; + + if (filter_length != sizeof(struct umad_filter)) + return -EINVAL; + + TRACE("fd %d mgmt_class %u mgmt_version %d oui 0x%x%x%x attr_id %d errors %d", + fd, filter->mgmt_class, filter->mgmt_version, + (int) filter->oui[0], (int) filter->oui[1], (int) filter->oui[2], + filter->attr_id, filter->errors); + + memset(&req, 0, sizeof req); + req.qpn = (filter->mgmt_class == 0x1 || filter->mgmt_class == 0x81) ? + UMAD_SNOOP_QP0 : UMAD_SNOOP_QP1; + req.mgmt_class = filter->mgmt_class; + req.mgmt_class_version = filter->mgmt_version; + memcpy(req.oui, filter->oui, sizeof req.oui); + req.filter.attr_id = filter->attr_id; + req.filter.errors = filter->errors; + + VALGRIND_MAKE_MEM_DEFINED(&req, sizeof req); + + if (!ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (void *)&req)) { + DEBUG("fd %d registered to use agent %d qp %d class 0x%x oui 0x%x%x%x", + fd, req.id, req.qpn & ~UMAD_SNOOP_QP, req.mgmt_class, + (int) filter->oui[0], (int) filter->oui[1], (int) filter->oui[2]); + return req.id; /* return agentid */ + } + + DEBUG("fd %d registering qp %d class 0x%x oui 0x%x%x%x failed: %m", + fd, req.qpn & ~UMAD_SNOOP_QP, req.mgmt_class, + (int) filter->oui[0], (int) filter->oui[1], (int) filter->oui[2]); + return -EPERM; +} + int umad_register_oui(int fd, int mgmt_class, uint8_t rmpp_version, uint8_t oui[3], long method_mask[]) { -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
