core: Add TX/RX API that exposes message tag and tag owner
MCTP received packets can carry a message tag and tag owner bit
which is set by a remote MCTP endpoint. This can be used by the
remote MCTP endpoint to track the responses. Thus, libmctp should
provide a mechanism for the upper layer MCTP applications to
respond with the same message tag.
This patchset extends TX and RX API with message tag and
tag owner bits.
Signed-off-by: Sumanth Bhat <sumanth.bhat@linux.intel.com>
Change-Id: I6d07eafa86c653abdd4313ab7cc77e5a93124477
diff --git a/core.c b/core.c
index 11d4777..c3ee659 100644
--- a/core.c
+++ b/core.c
@@ -88,7 +88,8 @@
#endif
static int mctp_message_tx_on_bus(struct mctp_bus *bus, mctp_eid_t src,
- mctp_eid_t dest, void *msg, size_t msg_len);
+ mctp_eid_t dest, bool tag_owner,
+ uint8_t msg_tag, void *msg, size_t msg_len);
struct mctp_pktbuf *mctp_pktbuf_alloc(struct mctp_binding *binding, size_t len)
{
@@ -436,7 +437,8 @@
}
static bool mctp_ctrl_handle_msg(struct mctp_bus *bus, mctp_eid_t src,
- void *buffer, size_t length)
+ uint8_t msg_tag, bool tag_owner, void *buffer,
+ size_t length)
{
struct mctp_ctrl_msg_hdr *msg_hdr = buffer;
@@ -450,7 +452,7 @@
if (mctp_ctrl_cmd_is_transport(msg_hdr)) {
if (bus->binding->control_rx != NULL) {
/* MCTP bus binding handler */
- bus->binding->control_rx(src,
+ bus->binding->control_rx(src, msg_tag, tag_owner,
bus->binding->control_rx_data,
buffer, length);
return true;
@@ -482,7 +484,8 @@
* 'buf' is not NULL.
*/
static void mctp_rx(struct mctp *mctp, struct mctp_bus *bus, mctp_eid_t src,
- mctp_eid_t dest, void *buf, size_t len)
+ mctp_eid_t dest, bool tag_owner, uint8_t msg_tag, void *buf,
+ size_t len)
{
assert(buf != NULL);
@@ -498,14 +501,16 @@
*/
if (mctp_ctrl_cmd_is_request(msg_hdr)) {
bool handled;
- handled = mctp_ctrl_handle_msg(bus, src, buf,
- len);
+ handled = mctp_ctrl_handle_msg(
+ bus, src, msg_tag, tag_owner, buf, len);
if (handled)
return;
}
}
+
if (mctp->message_rx)
- mctp->message_rx(src, mctp->message_rx_data, buf, len);
+ mctp->message_rx(src, tag_owner, msg_tag,
+ mctp->message_rx_data, buf, len);
}
if (mctp->route_policy == ROUTE_BRIDGE) {
@@ -516,7 +521,8 @@
if (dest_bus == bus)
continue;
- mctp_message_tx_on_bus(dest_bus, src, dest, buf, len);
+ mctp_message_tx_on_bus(dest_bus, src, dest, tag_owner,
+ msg_tag, buf, len);
}
}
@@ -529,6 +535,7 @@
uint8_t flags, exp_seq, seq, tag;
struct mctp_msg_ctx *ctx;
struct mctp_hdr *hdr;
+ bool tag_owner;
size_t len;
void *p;
int rc;
@@ -552,6 +559,8 @@
flags = hdr->flags_seq_tag & (MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM);
tag = (hdr->flags_seq_tag >> MCTP_HDR_TAG_SHIFT) & MCTP_HDR_TAG_MASK;
seq = (hdr->flags_seq_tag >> MCTP_HDR_SEQ_SHIFT) & MCTP_HDR_SEQ_MASK;
+ tag_owner =
+ (hdr->flags_seq_tag >> MCTP_HDR_TO_SHIFT) & MCTP_HDR_TO_MASK;
switch (flags) {
case MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM:
@@ -559,7 +568,7 @@
* no need to create a message context */
len = pkt->end - pkt->mctp_hdr_off - sizeof(struct mctp_hdr);
p = pkt->data + pkt->mctp_hdr_off + sizeof(struct mctp_hdr);
- mctp_rx(mctp, bus, hdr->src, hdr->dest, p, len);
+ mctp_rx(mctp, bus, hdr->src, hdr->dest, tag_owner, tag, p, len);
break;
case MCTP_HDR_FLAG_SOM:
@@ -620,8 +629,8 @@
rc = mctp_msg_ctx_add_pkt(ctx, pkt, mctp->max_message_size);
if (!rc)
- mctp_rx(mctp, bus, ctx->src, ctx->dest,
- ctx->buf, ctx->buf_size);
+ mctp_rx(mctp, bus, ctx->src, ctx->dest, tag_owner, tag,
+ ctx->buf, ctx->buf_size);
mctp_msg_ctx_drop(ctx);
break;
@@ -735,7 +744,8 @@
}
static int mctp_message_tx_on_bus(struct mctp_bus *bus, mctp_eid_t src,
- mctp_eid_t dest, void *msg, size_t msg_len)
+ mctp_eid_t dest, bool tag_owner,
+ uint8_t msg_tag, void *msg, size_t msg_len)
{
size_t max_payload_len, payload_len, p;
struct mctp_pktbuf *pkt;
@@ -745,6 +755,9 @@
if (bus->state == mctp_bus_state_constructed)
return -ENXIO;
+ if ((msg_tag & MCTP_HDR_TAG_MASK) != msg_tag)
+ return -EINVAL;
+
max_payload_len = MCTP_BODY_SIZE(bus->binding->pkt_size);
{
@@ -767,12 +780,11 @@
payload_len + sizeof(*hdr));
hdr = mctp_pktbuf_hdr(pkt);
- /* todo: tags */
hdr->ver = bus->binding->version & 0xf;
hdr->dest = dest;
hdr->src = src;
- hdr->flags_seq_tag = MCTP_HDR_FLAG_TO |
- (0 << MCTP_HDR_TAG_SHIFT);
+ hdr->flags_seq_tag = (tag_owner << MCTP_HDR_TO_SHIFT) |
+ (msg_tag << MCTP_HDR_TAG_SHIFT);
if (i == 0)
hdr->flags_seq_tag |= MCTP_HDR_FLAG_SOM;
@@ -800,14 +812,22 @@
return 0;
}
-int mctp_message_tx(struct mctp *mctp, mctp_eid_t eid,
- void *msg, size_t msg_len)
+int mctp_message_tx(struct mctp *mctp, mctp_eid_t eid, bool tag_owner,
+ uint8_t msg_tag, void *msg, size_t msg_len)
{
struct mctp_bus *bus;
+ /* TODO: Protect against same tag being used across
+ * different callers */
+ if ((msg_tag & MCTP_HDR_TAG_MASK) != msg_tag) {
+ mctp_prerr("Incorrect message tag %u passed.", msg_tag);
+ return -EINVAL;
+ }
+
bus = find_bus_for_eid(mctp, eid);
if (!bus)
return 0;
- return mctp_message_tx_on_bus(bus, bus->eid, eid, msg, msg_len);
+ return mctp_message_tx_on_bus(bus, bus->eid, eid, tag_owner, msg_tag,
+ msg, msg_len);
}