mctp(7)
โจ mctp โ Management Component Transport Protocol โจ
okay bestie, welcome to the group chat for mctp, from the Linux man-pages posse ๐ this one lives in the Miscellaneous Information Manual and it's all about the Management Component Transport Protocol. sit down, grab a boba, we're doing inter-device messaging ๐ง
๐ธ NAME ๐ธ
mctp โ Management Component Transport Protocol
๐ SYNOPSIS ๐
#include <linux/mctp.h> /* MCTP address type and protocol constants */
#include <sys/socket.h>
mctp_socket = socket(AF_MCTP, SOCK_DGRAM, 0);
no cap, that's the whole vibe right there โ๏ธ
๐ DESCRIPTION ๐
So Linux implements the Management Component Transport Protocol, aka MCTP, which is specified by DMTF spec DSP0236 โ and it's currently sitting at version 1 fr fr.
It's a connectionless protocol, typically used between devices inside a server system. Now listen: message reliability and ordering are not guaranteed ๐ญ but message boundaries are preserved. So your messages stay whole, they just might show up in a different order or... not at all. iconic behavior honestly.
The API for MCTP messaging uses a standard sockets interface, using the sendto(2) and recvfrom(2) classes of system calls to transfer messages. Messages may get fragmented into packets before transmission and reassembled at the remote endpoint โ but this fragmentation and reassembly is transparent to user space, so you don't have to think about it even once. you're welcome ๐ซถ
๐ Address format ๐
MCTP addresses (also called EIDs, or Endpoint Identifiers) are single-byte values, typed as mctp_eid_t. Packets between a local and a remote endpoint are identified by the source and destination EIDs, plus a three-bit tag value.
Addressing data gets passed in socket system calls through a sockaddr_mctp structure, and it's defined like this:
typedef uint8_t mctp_eid_t;
struct mctp_addr {
mctp_eid_t s_addr;
};
struct sockaddr_mctp {
unsigned short smctp_family; /* = AF_MCTP */
uint16_t __smctp_pad0;
int smctp_network; /* local network identifier */
struct mctp_addr smctp_addr; /* EID */
uint8_t smctp_type; /* message type byte */
uint8_t smctp_tag; /* tag value & owner */
uint8_t __smctp_pad1;
};
study that struct, it's the blueprint ๐โจ
๐ Sending messages ๐
Messages can be transmitted using the sendto(2) and sendmsg(2) system calls, by providing a sockaddr_mctp structure describing the addressing parameters. like so:
ssize_t n;
const char *buf;
struct sockaddr_mctp addr;
/* unused fields must be zero */
memset(&addr, 0, sizeof(addr));
/* set message destination */
addr.smctp_family = AF_MCTP;
addr.smctp_network = 0;
addr.smctp_addr.s_addr = 8; /* remote EID */
addr.smctp_tag = MCTP_TAG_OWNER;
addr.smctp_type = MYPROGRAM_MCTP_TYPE_ECHO; /* example type */
buf = "hello, world!"
n = sendto(sd, buf, 13, 0,
(struct sockaddr *) &addr, sizeof(addr));
okay so here's the tea: the sender owns the message tag, so MCTP_TAG_OWNER is used as the tag data. The kernel will allocate a specific tag value for this message. But โ and this is the plot twist โ if no tag is available, sendto(2) will return an error, with errno set to EBUSY ๐ญ
That allocated tag stays associated with the socket, so any replies to the sent message will be received by the same socket. cute, right? it remembers ๐ฅน
โ ๏ธ Sending a MCTP message requires the CAP_NET_RAW capability. no cap on the cap requirement.
๐ฆ Receiving messages ๐ฆ
Messages can be received using the recvfrom(2) and recvmsg(2) system calls.
char buf[13];
socklen_t addrlen;
struct sockaddr_mctp addr;
addrlen = sizeof(addr);
n = recvfrom(sd, buf, sizeof(buf), 0,
(struct sockaddr *) &addr, &addrlen);
In order to receive an incoming message, the receiver will need to either have previously sent a message to the same endpoint, or performed a bind(2) to receive all messages of a certain type:
struct sockaddr_mctp addr;
addr.smctp_family = AF_MCTP;
addr.smctp_network = MCTP_NET_ANY;
addr.smctp_addr.s_addr = MCTP_ADDR_ANY;
addr.smctp_type = MYPROGRAM_MCTP_TYPE_ECHO; /* our 'echo' type */
int rc = bind(sd, (struct sockaddr *) &addr, sizeof(addr));
This call requires the CAP_NET_BIND_SERVICE capability, and will result in the socket receiving all messages sent to locally-assigned EIDs, for the specified message type. main character energy, taking all the messages ๐
After a recvfrom(2) or recvmsg(2) returns a success condition, the provided address argument will be populated with the sender's network and EID, as well as the tag value used for the message. Any reply to this message should pass the same address and tag value (with the TO bit cleared) to indicate that it is directed to the same remote endpoint. slay, threaded conversation ๐
๐ SEE ALSO ๐
socket(7)linux.git/Documentation/networking/mctp.rst- The DSP0236 specification.
aaaand that's the whole page bestie, go forth and socket ๐ซถโจ
this masterpiece came to you courtesy of Linux man-pages 6.20, dated 2026-02-08, and it's filed under mctp(7). periodt ๐
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-copyleft
- Copyright 2021-2025, Jeremy Kerr <jk@codeconstruct.com.au>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms