Skip to content

Commit

Permalink
Merge branch 'MCTP-tag-control-interface'
Browse files Browse the repository at this point in the history
Jeremy Kerr says:

====================
MCTP tag control interface

This series implements a small interface for userspace-controlled
message tag allocation for the MCTP protocol. Rather than leaving the
kernel to allocate per-message tag values, userspace can explicitly
allocate (and release) message tags through two new ioctls:
SIOCMCTPALLOCTAG and SIOCMCTPDROPTAG.

In order to do this, we first introduce some minor changes to the tag
handling, including a couple of new tests for the route input paths.

As always, any comments/queries/etc are most welcome.

v2:
 - make mctp_lookup_prealloc_tag static
 - minor checkpatch formatting fixes
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 9, 2022
2 parents aa4725c + 63ed1aa commit b4f029f
Show file tree
Hide file tree
Showing 7 changed files with 489 additions and 68 deletions.
48 changes: 48 additions & 0 deletions Documentation/networking/mctp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,54 @@ remote address is already known, or the message does not require a reply.
Like the send calls, sockets will only receive responses to requests they have
sent (TO=1) and may only respond (TO=0) to requests they have received.

``ioctl(SIOCMCTPALLOCTAG)`` and ``ioctl(SIOCMCTPDROPTAG)``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

These tags give applications more control over MCTP message tags, by allocating
(and dropping) tag values explicitly, rather than the kernel automatically
allocating a per-message tag at ``sendmsg()`` time.

In general, you will only need to use these ioctls if your MCTP protocol does
not fit the usual request/response model. For example, if you need to persist
tags across multiple requests, or a request may generate more than one response.
In these cases, the ioctls allow you to decouple the tag allocation (and
release) from individual message send and receive operations.

Both ioctls are passed a pointer to a ``struct mctp_ioc_tag_ctl``:

.. code-block:: C
struct mctp_ioc_tag_ctl {
mctp_eid_t peer_addr;
__u8 tag;
__u16 flags;
};
``SIOCMCTPALLOCTAG`` allocates a tag for a specific peer, which an application
can use in future ``sendmsg()`` calls. The application populates the
``peer_addr`` member with the remote EID. Other fields must be zero.

On return, the ``tag`` member will be populated with the allocated tag value.
The allocated tag will have the following tag bits set:

- ``MCTP_TAG_OWNER``: it only makes sense to allocate tags if you're the tag
owner

- ``MCTP_TAG_PREALLOC``: to indicate to ``sendmsg()`` that this is a
preallocated tag.

- ... and the actual tag value, within the least-significant three bits
(``MCTP_TAG_MASK``). Note that zero is a valid tag value.

The tag value should be used as-is for the ``smctp_tag`` member of ``struct
sockaddr_mctp``.

``SIOCMCTPDROPTAG`` releases a tag that has been previously allocated by a
``SIOCMCTPALLOCTAG`` ioctl. The ``peer_addr`` must be the same as used for the
allocation, and the ``tag`` value must match exactly the tag returned from the
allocation (including the ``MCTP_TAG_OWNER`` and ``MCTP_TAG_PREALLOC`` bits).
The ``flags`` field must be zero.

Kernel internals
================

Expand Down
16 changes: 15 additions & 1 deletion include/net/mctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ static inline bool mctp_address_ok(mctp_eid_t eid)
return eid >= 8 && eid < 255;
}

static inline bool mctp_address_matches(mctp_eid_t match, mctp_eid_t eid)
{
return match == eid || match == MCTP_ADDR_ANY;
}

static inline struct mctp_hdr *mctp_hdr(struct sk_buff *skb)
{
return (struct mctp_hdr *)skb_network_header(skb);
Expand Down Expand Up @@ -121,7 +126,7 @@ struct mctp_sock {
*/
struct mctp_sk_key {
mctp_eid_t peer_addr;
mctp_eid_t local_addr;
mctp_eid_t local_addr; /* MCTP_ADDR_ANY for local owned tags */
__u8 tag; /* incoming tag match; invert TO for local */

/* we hold a ref to sk when set */
Expand Down Expand Up @@ -158,6 +163,12 @@ struct mctp_sk_key {
*/
unsigned long dev_flow_state;
struct mctp_dev *dev;

/* a tag allocated with SIOCMCTPALLOCTAG ioctl will not expire
* automatically on timeout or response, instead SIOCMCTPDROPTAG
* is used.
*/
bool manual_alloc;
};

struct mctp_skb_cb {
Expand Down Expand Up @@ -234,6 +245,9 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt,
struct sk_buff *skb, mctp_eid_t daddr, u8 req_tag);

void mctp_key_unref(struct mctp_sk_key *key);
struct mctp_sk_key *mctp_alloc_local_tag(struct mctp_sock *msk,
mctp_eid_t daddr, mctp_eid_t saddr,
bool manual, u8 *tagp);

/* routing <--> device interface */
unsigned int mctp_default_net(struct net *net);
Expand Down
5 changes: 4 additions & 1 deletion include/trace/events/mctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ enum {
MCTP_TRACE_KEY_REPLIED,
MCTP_TRACE_KEY_INVALIDATED,
MCTP_TRACE_KEY_CLOSED,
MCTP_TRACE_KEY_DROPPED,
};
#endif /* __TRACE_MCTP_ENUMS */

TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_TIMEOUT);
TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_REPLIED);
TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_INVALIDATED);
TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_CLOSED);
TRACE_DEFINE_ENUM(MCTP_TRACE_KEY_DROPPED);

TRACE_EVENT(mctp_key_acquire,
TP_PROTO(const struct mctp_sk_key *key),
Expand Down Expand Up @@ -66,7 +68,8 @@ TRACE_EVENT(mctp_key_release,
{ MCTP_TRACE_KEY_TIMEOUT, "timeout" },
{ MCTP_TRACE_KEY_REPLIED, "replied" },
{ MCTP_TRACE_KEY_INVALIDATED, "invalidated" },
{ MCTP_TRACE_KEY_CLOSED, "closed" })
{ MCTP_TRACE_KEY_CLOSED, "closed" },
{ MCTP_TRACE_KEY_DROPPED, "dropped" })
)
);

Expand Down
18 changes: 18 additions & 0 deletions include/uapi/linux/mctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,25 @@ struct sockaddr_mctp_ext {

#define MCTP_TAG_MASK 0x07
#define MCTP_TAG_OWNER 0x08
#define MCTP_TAG_PREALLOC 0x10

#define MCTP_OPT_ADDR_EXT 1

#define SIOCMCTPALLOCTAG (SIOCPROTOPRIVATE + 0)
#define SIOCMCTPDROPTAG (SIOCPROTOPRIVATE + 1)

struct mctp_ioc_tag_ctl {
mctp_eid_t peer_addr;

/* For SIOCMCTPALLOCTAG: must be passed as zero, kernel will
* populate with the allocated tag value. Returned tag value will
* always have TO and PREALLOC set.
*
* For SIOCMCTPDROPTAG: userspace provides tag value to drop, from
* a prior SIOCMCTPALLOCTAG call (and so must have TO and PREALLOC set).
*/
__u8 tag;
__u16 flags;
};

#endif /* __UAPI_MCTP_H */
Loading

0 comments on commit b4f029f

Please sign in to comment.