162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci==============================================
462306a36Sopenharmony_ciManagement Component Transport Protocol (MCTP)
562306a36Sopenharmony_ci==============================================
662306a36Sopenharmony_ci
762306a36Sopenharmony_cinet/mctp/ contains protocol support for MCTP, as defined by DMTF standard
862306a36Sopenharmony_ciDSP0236. Physical interface drivers ("bindings" in the specification) are
962306a36Sopenharmony_ciprovided in drivers/net/mctp/.
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciThe core code provides a socket-based interface to send and receive MCTP
1262306a36Sopenharmony_cimessages, through an AF_MCTP, SOCK_DGRAM socket.
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ciStructure: interfaces & networks
1562306a36Sopenharmony_ci================================
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciThe kernel models the local MCTP topology through two items: interfaces and
1862306a36Sopenharmony_cinetworks.
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciAn interface (or "link") is an instance of an MCTP physical transport binding
2162306a36Sopenharmony_ci(as defined by DSP0236, section 3.2.47), likely connected to a specific hardware
2262306a36Sopenharmony_cidevice. This is represented as a ``struct netdevice``.
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciA network defines a unique address space for MCTP endpoints by endpoint-ID
2562306a36Sopenharmony_ci(described by DSP0236, section 3.2.31). A network has a user-visible identifier
2662306a36Sopenharmony_cito allow references from userspace. Route definitions are specific to one
2762306a36Sopenharmony_cinetwork.
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciInterfaces are associated with one network. A network may be associated with one
3062306a36Sopenharmony_cior more interfaces.
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciIf multiple networks are present, each may contain endpoint IDs (EIDs) that are
3362306a36Sopenharmony_cialso present on other networks.
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ciSockets API
3662306a36Sopenharmony_ci===========
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciProtocol definitions
3962306a36Sopenharmony_ci--------------------
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciMCTP uses ``AF_MCTP`` / ``PF_MCTP`` for the address- and protocol- families.
4262306a36Sopenharmony_ciSince MCTP is message-based, only ``SOCK_DGRAM`` sockets are supported.
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci.. code-block:: C
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci    int sd = socket(AF_MCTP, SOCK_DGRAM, 0);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ciThe only (current) value for the ``protocol`` argument is 0.
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciAs with all socket address families, source and destination addresses are
5162306a36Sopenharmony_cispecified with a ``sockaddr`` type, with a single-byte endpoint address:
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci.. code-block:: C
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci    typedef __u8		mctp_eid_t;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci    struct mctp_addr {
5862306a36Sopenharmony_ci            mctp_eid_t		s_addr;
5962306a36Sopenharmony_ci    };
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci    struct sockaddr_mctp {
6262306a36Sopenharmony_ci            __kernel_sa_family_t smctp_family;
6362306a36Sopenharmony_ci            unsigned int         smctp_network;
6462306a36Sopenharmony_ci            struct mctp_addr     smctp_addr;
6562306a36Sopenharmony_ci            __u8                 smctp_type;
6662306a36Sopenharmony_ci            __u8                 smctp_tag;
6762306a36Sopenharmony_ci    };
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci    #define MCTP_NET_ANY	0x0
7062306a36Sopenharmony_ci    #define MCTP_ADDR_ANY	0xff
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciSyscall behaviour
7462306a36Sopenharmony_ci-----------------
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ciThe following sections describe the MCTP-specific behaviours of the standard
7762306a36Sopenharmony_cisocket system calls. These behaviours have been chosen to map closely to the
7862306a36Sopenharmony_ciexisting sockets APIs.
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci``bind()`` : set local socket address
8162306a36Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciSockets that receive incoming request packets will bind to a local address,
8462306a36Sopenharmony_ciusing the ``bind()`` syscall.
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci.. code-block:: C
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci    struct sockaddr_mctp addr;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci    addr.smctp_family = AF_MCTP;
9162306a36Sopenharmony_ci    addr.smctp_network = MCTP_NET_ANY;
9262306a36Sopenharmony_ci    addr.smctp_addr.s_addr = MCTP_ADDR_ANY;
9362306a36Sopenharmony_ci    addr.smctp_type = MCTP_TYPE_PLDM;
9462306a36Sopenharmony_ci    addr.smctp_tag = MCTP_TAG_OWNER;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci    int rc = bind(sd, (struct sockaddr *)&addr, sizeof(addr));
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ciThis establishes the local address of the socket. Incoming MCTP messages that
9962306a36Sopenharmony_cimatch the network, address, and message type will be received by this socket.
10062306a36Sopenharmony_ciThe reference to 'incoming' is important here; a bound socket will only receive
10162306a36Sopenharmony_cimessages with the TO bit set, to indicate an incoming request message, rather
10262306a36Sopenharmony_cithan a response.
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ciThe ``smctp_tag`` value will configure the tags accepted from the remote side of
10562306a36Sopenharmony_cithis socket. Given the above, the only valid value is ``MCTP_TAG_OWNER``, which
10662306a36Sopenharmony_ciwill result in remotely "owned" tags being routed to this socket. Since
10762306a36Sopenharmony_ci``MCTP_TAG_OWNER`` is set, the 3 least-significant bits of ``smctp_tag`` are not
10862306a36Sopenharmony_ciused; callers must set them to zero.
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ciA ``smctp_network`` value of ``MCTP_NET_ANY`` will configure the socket to
11162306a36Sopenharmony_cireceive incoming packets from any locally-connected network. A specific network
11262306a36Sopenharmony_civalue will cause the socket to only receive incoming messages from that network.
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ciThe ``smctp_addr`` field specifies a local address to bind to. A value of
11562306a36Sopenharmony_ci``MCTP_ADDR_ANY`` configures the socket to receive messages addressed to any
11662306a36Sopenharmony_cilocal destination EID.
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ciThe ``smctp_type`` field specifies which message types to receive. Only the
11962306a36Sopenharmony_cilower 7 bits of the type is matched on incoming messages (ie., the
12062306a36Sopenharmony_cimost-significant IC bit is not part of the match). This results in the socket
12162306a36Sopenharmony_cireceiving packets with and without a message integrity check footer.
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci``sendto()``, ``sendmsg()``, ``send()`` : transmit an MCTP message
12462306a36Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ciAn MCTP message is transmitted using one of the ``sendto()``, ``sendmsg()`` or
12762306a36Sopenharmony_ci``send()`` syscalls. Using ``sendto()`` as the primary example:
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci.. code-block:: C
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci    struct sockaddr_mctp addr;
13262306a36Sopenharmony_ci    char buf[14];
13362306a36Sopenharmony_ci    ssize_t len;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci    /* set message destination */
13662306a36Sopenharmony_ci    addr.smctp_family = AF_MCTP;
13762306a36Sopenharmony_ci    addr.smctp_network = 0;
13862306a36Sopenharmony_ci    addr.smctp_addr.s_addr = 8;
13962306a36Sopenharmony_ci    addr.smctp_tag = MCTP_TAG_OWNER;
14062306a36Sopenharmony_ci    addr.smctp_type = MCTP_TYPE_ECHO;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci    /* arbitrary message to send, with message-type header */
14362306a36Sopenharmony_ci    buf[0] = MCTP_TYPE_ECHO;
14462306a36Sopenharmony_ci    memcpy(buf + 1, "hello, world!", sizeof(buf) - 1);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci    len = sendto(sd, buf, sizeof(buf), 0,
14762306a36Sopenharmony_ci                    (struct sockaddr_mctp *)&addr, sizeof(addr));
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ciThe network and address fields of ``addr`` define the remote address to send to.
15062306a36Sopenharmony_ciIf ``smctp_tag`` has the ``MCTP_TAG_OWNER``, the kernel will ignore any bits set
15162306a36Sopenharmony_ciin ``MCTP_TAG_VALUE``, and generate a tag value suitable for the destination
15262306a36Sopenharmony_ciEID. If ``MCTP_TAG_OWNER`` is not set, the message will be sent with the tag
15362306a36Sopenharmony_civalue as specified. If a tag value cannot be allocated, the system call will
15462306a36Sopenharmony_cireport an errno of ``EAGAIN``.
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ciThe application must provide the message type byte as the first byte of the
15762306a36Sopenharmony_cimessage buffer passed to ``sendto()``. If a message integrity check is to be
15862306a36Sopenharmony_ciincluded in the transmitted message, it must also be provided in the message
15962306a36Sopenharmony_cibuffer, and the most-significant bit of the message type byte must be 1.
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ciThe ``sendmsg()`` system call allows a more compact argument interface, and the
16262306a36Sopenharmony_cimessage buffer to be specified as a scatter-gather list. At present no ancillary
16362306a36Sopenharmony_cimessage types (used for the ``msg_control`` data passed to ``sendmsg()``) are
16462306a36Sopenharmony_cidefined.
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ciTransmitting a message on an unconnected socket with ``MCTP_TAG_OWNER``
16762306a36Sopenharmony_cispecified will cause an allocation of a tag, if no valid tag is already
16862306a36Sopenharmony_ciallocated for that destination. The (destination-eid,tag) tuple acts as an
16962306a36Sopenharmony_ciimplicit local socket address, to allow the socket to receive responses to this
17062306a36Sopenharmony_cioutgoing message. If any previous allocation has been performed (to for a
17162306a36Sopenharmony_cidifferent remote EID), that allocation is lost.
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ciSockets will only receive responses to requests they have sent (with TO=1) and
17462306a36Sopenharmony_cimay only respond (with TO=0) to requests they have received.
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci``recvfrom()``, ``recvmsg()``, ``recv()`` : receive an MCTP message
17762306a36Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ciAn MCTP message can be received by an application using one of the
18062306a36Sopenharmony_ci``recvfrom()``, ``recvmsg()``, or ``recv()`` system calls. Using ``recvfrom()``
18162306a36Sopenharmony_cias the primary example:
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci.. code-block:: C
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci    struct sockaddr_mctp addr;
18662306a36Sopenharmony_ci    socklen_t addrlen;
18762306a36Sopenharmony_ci    char buf[14];
18862306a36Sopenharmony_ci    ssize_t len;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci    addrlen = sizeof(addr);
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci    len = recvfrom(sd, buf, sizeof(buf), 0,
19362306a36Sopenharmony_ci                    (struct sockaddr_mctp *)&addr, &addrlen);
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci    /* We can expect addr to describe an MCTP address */
19662306a36Sopenharmony_ci    assert(addrlen >= sizeof(buf));
19762306a36Sopenharmony_ci    assert(addr.smctp_family == AF_MCTP);
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci    printf("received %zd bytes from remote EID %d\n", rc, addr.smctp_addr);
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ciThe address argument to ``recvfrom`` and ``recvmsg`` is populated with the
20262306a36Sopenharmony_ciremote address of the incoming message, including tag value (this will be needed
20362306a36Sopenharmony_ciin order to reply to the message).
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ciThe first byte of the message buffer will contain the message type byte. If an
20662306a36Sopenharmony_ciintegrity check follows the message, it will be included in the received buffer.
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ciThe ``recv()`` system call behaves in a similar way, but does not provide a
20962306a36Sopenharmony_ciremote address to the application. Therefore, these are only useful if the
21062306a36Sopenharmony_ciremote address is already known, or the message does not require a reply.
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ciLike the send calls, sockets will only receive responses to requests they have
21362306a36Sopenharmony_cisent (TO=1) and may only respond (TO=0) to requests they have received.
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci``ioctl(SIOCMCTPALLOCTAG)`` and ``ioctl(SIOCMCTPDROPTAG)``
21662306a36Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ciThese tags give applications more control over MCTP message tags, by allocating
21962306a36Sopenharmony_ci(and dropping) tag values explicitly, rather than the kernel automatically
22062306a36Sopenharmony_ciallocating a per-message tag at ``sendmsg()`` time.
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ciIn general, you will only need to use these ioctls if your MCTP protocol does
22362306a36Sopenharmony_cinot fit the usual request/response model. For example, if you need to persist
22462306a36Sopenharmony_citags across multiple requests, or a request may generate more than one response.
22562306a36Sopenharmony_ciIn these cases, the ioctls allow you to decouple the tag allocation (and
22662306a36Sopenharmony_cirelease) from individual message send and receive operations.
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ciBoth ioctls are passed a pointer to a ``struct mctp_ioc_tag_ctl``:
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci.. code-block:: C
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci    struct mctp_ioc_tag_ctl {
23362306a36Sopenharmony_ci        mctp_eid_t      peer_addr;
23462306a36Sopenharmony_ci        __u8		tag;
23562306a36Sopenharmony_ci        __u16   	flags;
23662306a36Sopenharmony_ci    };
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci``SIOCMCTPALLOCTAG`` allocates a tag for a specific peer, which an application
23962306a36Sopenharmony_cican use in future ``sendmsg()`` calls. The application populates the
24062306a36Sopenharmony_ci``peer_addr`` member with the remote EID. Other fields must be zero.
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ciOn return, the ``tag`` member will be populated with the allocated tag value.
24362306a36Sopenharmony_ciThe allocated tag will have the following tag bits set:
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci - ``MCTP_TAG_OWNER``: it only makes sense to allocate tags if you're the tag
24662306a36Sopenharmony_ci   owner
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci - ``MCTP_TAG_PREALLOC``: to indicate to ``sendmsg()`` that this is a
24962306a36Sopenharmony_ci   preallocated tag.
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci - ... and the actual tag value, within the least-significant three bits
25262306a36Sopenharmony_ci   (``MCTP_TAG_MASK``). Note that zero is a valid tag value.
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ciThe tag value should be used as-is for the ``smctp_tag`` member of ``struct
25562306a36Sopenharmony_cisockaddr_mctp``.
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci``SIOCMCTPDROPTAG`` releases a tag that has been previously allocated by a
25862306a36Sopenharmony_ci``SIOCMCTPALLOCTAG`` ioctl. The ``peer_addr`` must be the same as used for the
25962306a36Sopenharmony_ciallocation, and the ``tag`` value must match exactly the tag returned from the
26062306a36Sopenharmony_ciallocation (including the ``MCTP_TAG_OWNER`` and ``MCTP_TAG_PREALLOC`` bits).
26162306a36Sopenharmony_ciThe ``flags`` field must be zero.
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ciKernel internals
26462306a36Sopenharmony_ci================
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ciThere are a few possible packet flows in the MCTP stack:
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci1. local TX to remote endpoint, message <= MTU::
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	sendmsg()
27162306a36Sopenharmony_ci	 -> mctp_local_output()
27262306a36Sopenharmony_ci	    : route lookup
27362306a36Sopenharmony_ci	    -> rt->output() (== mctp_route_output)
27462306a36Sopenharmony_ci	       -> dev_queue_xmit()
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci2. local TX to remote endpoint, message > MTU::
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	sendmsg()
27962306a36Sopenharmony_ci	-> mctp_local_output()
28062306a36Sopenharmony_ci	    -> mctp_do_fragment_route()
28162306a36Sopenharmony_ci	       : creates packet-sized skbs. For each new skb:
28262306a36Sopenharmony_ci	       -> rt->output() (== mctp_route_output)
28362306a36Sopenharmony_ci	          -> dev_queue_xmit()
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci3. remote TX to local endpoint, single-packet message::
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	mctp_pkttype_receive()
28862306a36Sopenharmony_ci	: route lookup
28962306a36Sopenharmony_ci	-> rt->output() (== mctp_route_input)
29062306a36Sopenharmony_ci	   : sk_key lookup
29162306a36Sopenharmony_ci	   -> sock_queue_rcv_skb()
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci4. remote TX to local endpoint, multiple-packet message::
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	mctp_pkttype_receive()
29662306a36Sopenharmony_ci	: route lookup
29762306a36Sopenharmony_ci	-> rt->output() (== mctp_route_input)
29862306a36Sopenharmony_ci	   : sk_key lookup
29962306a36Sopenharmony_ci	   : stores skb in struct sk_key->reasm_head
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	mctp_pkttype_receive()
30262306a36Sopenharmony_ci	: route lookup
30362306a36Sopenharmony_ci	-> rt->output() (== mctp_route_input)
30462306a36Sopenharmony_ci	   : sk_key lookup
30562306a36Sopenharmony_ci	   : finds existing reassembly in sk_key->reasm_head
30662306a36Sopenharmony_ci	   : appends new fragment
30762306a36Sopenharmony_ci	   -> sock_queue_rcv_skb()
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ciKey refcounts
31062306a36Sopenharmony_ci-------------
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci * keys are refed by:
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci   - a skb: during route output, stored in ``skb->cb``.
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci   - netns and sock lists.
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci * keys can be associated with a device, in which case they hold a
31962306a36Sopenharmony_ci   reference to the dev (set through ``key->dev``, counted through
32062306a36Sopenharmony_ci   ``dev->key_count``). Multiple keys can reference the device.
321