18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci=========================
48c2ecf20Sopenharmony_ciStream Parser (strparser)
58c2ecf20Sopenharmony_ci=========================
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciIntroduction
88c2ecf20Sopenharmony_ci============
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciThe stream parser (strparser) is a utility that parses messages of an
118c2ecf20Sopenharmony_ciapplication layer protocol running over a data stream. The stream
128c2ecf20Sopenharmony_ciparser works in conjunction with an upper layer in the kernel to provide
138c2ecf20Sopenharmony_cikernel support for application layer messages. For instance, Kernel
148c2ecf20Sopenharmony_ciConnection Multiplexor (KCM) uses the Stream Parser to parse messages
158c2ecf20Sopenharmony_ciusing a BPF program.
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciThe strparser works in one of two modes: receive callback or general
188c2ecf20Sopenharmony_cimode.
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciIn receive callback mode, the strparser is called from the data_ready
218c2ecf20Sopenharmony_cicallback of a TCP socket. Messages are parsed and delivered as they are
228c2ecf20Sopenharmony_cireceived on the socket.
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciIn general mode, a sequence of skbs are fed to strparser from an
258c2ecf20Sopenharmony_cioutside source. Message are parsed and delivered as the sequence is
268c2ecf20Sopenharmony_ciprocessed. This modes allows strparser to be applied to arbitrary
278c2ecf20Sopenharmony_cistreams of data.
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ciInterface
308c2ecf20Sopenharmony_ci=========
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ciThe API includes a context structure, a set of callbacks, utility
338c2ecf20Sopenharmony_cifunctions, and a data_ready function for receive callback mode. The
348c2ecf20Sopenharmony_cicallbacks include a parse_msg function that is called to perform
358c2ecf20Sopenharmony_ciparsing (e.g.  BPF parsing in case of KCM), and a rcv_msg function
368c2ecf20Sopenharmony_cithat is called when a full message has been completed.
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ciFunctions
398c2ecf20Sopenharmony_ci=========
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci     ::
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	strp_init(struct strparser *strp, struct sock *sk,
448c2ecf20Sopenharmony_ci		const struct strp_callbacks *cb)
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci     Called to initialize a stream parser. strp is a struct of type
478c2ecf20Sopenharmony_ci     strparser that is allocated by the upper layer. sk is the TCP
488c2ecf20Sopenharmony_ci     socket associated with the stream parser for use with receive
498c2ecf20Sopenharmony_ci     callback mode; in general mode this is set to NULL. Callbacks
508c2ecf20Sopenharmony_ci     are called by the stream parser (the callbacks are listed below).
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci     ::
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	void strp_pause(struct strparser *strp)
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci     Temporarily pause a stream parser. Message parsing is suspended
578c2ecf20Sopenharmony_ci     and no new messages are delivered to the upper layer.
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci     ::
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	void strp_unpause(struct strparser *strp)
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci     Unpause a paused stream parser.
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci     ::
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	void strp_stop(struct strparser *strp);
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci     strp_stop is called to completely stop stream parser operations.
708c2ecf20Sopenharmony_ci     This is called internally when the stream parser encounters an
718c2ecf20Sopenharmony_ci     error, and it is called from the upper layer to stop parsing
728c2ecf20Sopenharmony_ci     operations.
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci     ::
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	void strp_done(struct strparser *strp);
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci     strp_done is called to release any resources held by the stream
798c2ecf20Sopenharmony_ci     parser instance. This must be called after the stream processor
808c2ecf20Sopenharmony_ci     has been stopped.
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci     ::
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	int strp_process(struct strparser *strp, struct sk_buff *orig_skb,
858c2ecf20Sopenharmony_ci			 unsigned int orig_offset, size_t orig_len,
868c2ecf20Sopenharmony_ci			 size_t max_msg_size, long timeo)
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci    strp_process is called in general mode for a stream parser to
898c2ecf20Sopenharmony_ci    parse an sk_buff. The number of bytes processed or a negative
908c2ecf20Sopenharmony_ci    error number is returned. Note that strp_process does not
918c2ecf20Sopenharmony_ci    consume the sk_buff. max_msg_size is maximum size the stream
928c2ecf20Sopenharmony_ci    parser will parse. timeo is timeout for completing a message.
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci    ::
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	void strp_data_ready(struct strparser *strp);
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci    The upper layer calls strp_tcp_data_ready when data is ready on
998c2ecf20Sopenharmony_ci    the lower socket for strparser to process. This should be called
1008c2ecf20Sopenharmony_ci    from a data_ready callback that is set on the socket. Note that
1018c2ecf20Sopenharmony_ci    maximum messages size is the limit of the receive socket
1028c2ecf20Sopenharmony_ci    buffer and message timeout is the receive timeout for the socket.
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci    ::
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	void strp_check_rcv(struct strparser *strp);
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci    strp_check_rcv is called to check for new messages on the socket.
1098c2ecf20Sopenharmony_ci    This is normally called at initialization of a stream parser
1108c2ecf20Sopenharmony_ci    instance or after strp_unpause.
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ciCallbacks
1138c2ecf20Sopenharmony_ci=========
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ciThere are six callbacks:
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci    ::
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	int (*parse_msg)(struct strparser *strp, struct sk_buff *skb);
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci    parse_msg is called to determine the length of the next message
1228c2ecf20Sopenharmony_ci    in the stream. The upper layer must implement this function. It
1238c2ecf20Sopenharmony_ci    should parse the sk_buff as containing the headers for the
1248c2ecf20Sopenharmony_ci    next application layer message in the stream.
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci    The skb->cb in the input skb is a struct strp_msg. Only
1278c2ecf20Sopenharmony_ci    the offset field is relevant in parse_msg and gives the offset
1288c2ecf20Sopenharmony_ci    where the message starts in the skb.
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci    The return values of this function are:
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci    =========    ===========================================================
1338c2ecf20Sopenharmony_ci    >0           indicates length of successfully parsed message
1348c2ecf20Sopenharmony_ci    0            indicates more data must be received to parse the message
1358c2ecf20Sopenharmony_ci    -ESTRPIPE    current message should not be processed by the
1368c2ecf20Sopenharmony_ci		 kernel, return control of the socket to userspace which
1378c2ecf20Sopenharmony_ci		 can proceed to read the messages itself
1388c2ecf20Sopenharmony_ci    other < 0    Error in parsing, give control back to userspace
1398c2ecf20Sopenharmony_ci		 assuming that synchronization is lost and the stream
1408c2ecf20Sopenharmony_ci		 is unrecoverable (application expected to close TCP socket)
1418c2ecf20Sopenharmony_ci    =========    ===========================================================
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci    In the case that an error is returned (return value is less than
1448c2ecf20Sopenharmony_ci    zero) and the parser is in receive callback mode, then it will set
1458c2ecf20Sopenharmony_ci    the error on TCP socket and wake it up. If parse_msg returned
1468c2ecf20Sopenharmony_ci    -ESTRPIPE and the stream parser had previously read some bytes for
1478c2ecf20Sopenharmony_ci    the current message, then the error set on the attached socket is
1488c2ecf20Sopenharmony_ci    ENODATA since the stream is unrecoverable in that case.
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci    ::
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	void (*lock)(struct strparser *strp)
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci    The lock callback is called to lock the strp structure when
1558c2ecf20Sopenharmony_ci    the strparser is performing an asynchronous operation (such as
1568c2ecf20Sopenharmony_ci    processing a timeout). In receive callback mode the default
1578c2ecf20Sopenharmony_ci    function is to lock_sock for the associated socket. In general
1588c2ecf20Sopenharmony_ci    mode the callback must be set appropriately.
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci    ::
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	void (*unlock)(struct strparser *strp)
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci    The unlock callback is called to release the lock obtained
1658c2ecf20Sopenharmony_ci    by the lock callback. In receive callback mode the default
1668c2ecf20Sopenharmony_ci    function is release_sock for the associated socket. In general
1678c2ecf20Sopenharmony_ci    mode the callback must be set appropriately.
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci    ::
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci	void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb);
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci    rcv_msg is called when a full message has been received and
1748c2ecf20Sopenharmony_ci    is queued. The callee must consume the sk_buff; it can
1758c2ecf20Sopenharmony_ci    call strp_pause to prevent any further messages from being
1768c2ecf20Sopenharmony_ci    received in rcv_msg (see strp_pause above). This callback
1778c2ecf20Sopenharmony_ci    must be set.
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci    The skb->cb in the input skb is a struct strp_msg. This
1808c2ecf20Sopenharmony_ci    struct contains two fields: offset and full_len. Offset is
1818c2ecf20Sopenharmony_ci    where the message starts in the skb, and full_len is the
1828c2ecf20Sopenharmony_ci    the length of the message. skb->len - offset may be greater
1838c2ecf20Sopenharmony_ci    then full_len since strparser does not trim the skb.
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci    ::
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	int (*read_sock_done)(struct strparser *strp, int err);
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci     read_sock_done is called when the stream parser is done reading
1908c2ecf20Sopenharmony_ci     the TCP socket in receive callback mode. The stream parser may
1918c2ecf20Sopenharmony_ci     read multiple messages in a loop and this function allows cleanup
1928c2ecf20Sopenharmony_ci     to occur when exiting the loop. If the callback is not set (NULL
1938c2ecf20Sopenharmony_ci     in strp_init) a default function is used.
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci     ::
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	void (*abort_parser)(struct strparser *strp, int err);
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci     This function is called when stream parser encounters an error
2008c2ecf20Sopenharmony_ci     in parsing. The default function stops the stream parser and
2018c2ecf20Sopenharmony_ci     sets the error in the socket if the parser is in receive callback
2028c2ecf20Sopenharmony_ci     mode. The default function can be changed by setting the callback
2038c2ecf20Sopenharmony_ci     to non-NULL in strp_init.
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ciStatistics
2068c2ecf20Sopenharmony_ci==========
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ciVarious counters are kept for each stream parser instance. These are in
2098c2ecf20Sopenharmony_cithe strp_stats structure. strp_aggr_stats is a convenience structure for
2108c2ecf20Sopenharmony_ciaccumulating statistics for multiple stream parser instances.
2118c2ecf20Sopenharmony_cisave_strp_stats and aggregate_strp_stats are helper functions to save
2128c2ecf20Sopenharmony_ciand aggregate statistics.
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ciMessage assembly limits
2158c2ecf20Sopenharmony_ci=======================
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ciThe stream parser provide mechanisms to limit the resources consumed by
2188c2ecf20Sopenharmony_cimessage assembly.
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ciA timer is set when assembly starts for a new message. In receive
2218c2ecf20Sopenharmony_cicallback mode the message timeout is taken from rcvtime for the
2228c2ecf20Sopenharmony_ciassociated TCP socket. In general mode, the timeout is passed as an
2238c2ecf20Sopenharmony_ciargument in strp_process. If the timer fires before assembly completes
2248c2ecf20Sopenharmony_cithe stream parser is aborted and the ETIMEDOUT error is set on the TCP
2258c2ecf20Sopenharmony_cisocket if in receive callback mode.
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ciIn receive callback mode, message length is limited to the receive
2288c2ecf20Sopenharmony_cibuffer size of the associated TCP socket. If the length returned by
2298c2ecf20Sopenharmony_ciparse_msg is greater than the socket buffer size then the stream parser
2308c2ecf20Sopenharmony_ciis aborted with EMSGSIZE error set on the TCP socket. Note that this
2318c2ecf20Sopenharmony_cimakes the maximum size of receive skbuffs for a socket with a stream
2328c2ecf20Sopenharmony_ciparser to be 2*sk_rcvbuf of the TCP socket.
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ciIn general mode the message length limit is passed in as an argument
2358c2ecf20Sopenharmony_cito strp_process.
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ciAuthor
2388c2ecf20Sopenharmony_ci======
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ciTom Herbert (tom@quantonium.net)
241