summaryrefslogtreecommitdiff
path: root/include/net/tcp.h
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2025-01-08 14:19:22 -0600
committerTom Rini <trini@konsulko.com>2025-01-08 14:19:22 -0600
commit3bfd12008bef1a8353e7ceaca2cb06cf388527ed (patch)
treeac25e8db2f18bcba9f48518249fc020a05cb576c /include/net/tcp.h
parent6d41f0a39d6423c8e57e92ebbe9f8c0333a63f72 (diff)
parentd6da3dbaef57fc1d319b6b552efa009e2489d7d9 (diff)
Merge branch 'next'
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r--include/net/tcp.h257
1 files changed, 238 insertions, 19 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index c29d4ce24a7..5022fa9dc1b 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -265,6 +265,7 @@ union tcp_build_pkt {
* @TCP_CLOSING: Rec FIN, sent FIN, ACK waiting for ACK
* @TCP_FIN_WAIT_1: Sent FIN waiting for response
* @TCP_FIN_WAIT_2: Rec ACK from FIN sent, waiting for FIN
+ * @TCP_LAST_ACK: Waiting for ACK of the connection termination
*/
enum tcp_state {
TCP_CLOSED,
@@ -274,30 +275,248 @@ enum tcp_state {
TCP_CLOSE_WAIT,
TCP_CLOSING,
TCP_FIN_WAIT_1,
- TCP_FIN_WAIT_2
+ TCP_FIN_WAIT_2,
+ TCP_LAST_ACK,
};
-enum tcp_state tcp_get_tcp_state(void);
-void tcp_set_tcp_state(enum tcp_state new_state);
-int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len,
- u8 action, u32 tcp_seq_num, u32 tcp_ack_num);
+/**
+ * enum tcp_status - TCP stream status for connection
+ * @TCP_ERR_OK: no rx/tx errors
+ * @TCP_ERR_TOUT: rx/tx timeout happened
+ * @TCP_ERR_RST: connection was reset
+ * @TCP_ERR_IO: input/output error
+ */
+enum tcp_status {
+ TCP_ERR_OK = 0,
+ TCP_ERR_TOUT,
+ TCP_ERR_RST,
+ TCP_ERR_IO
+};
/**
- * rxhand_tcp() - An incoming packet handler.
- * @pkt: pointer to the application packet
- * @dport: destination TCP port
- * @sip: source IP address
- * @sport: source TCP port
- * @tcp_seq_num: TCP sequential number
- * @tcp_ack_num: TCP acknowledgment number
- * @action: TCP action (SYN, ACK, FIN, etc)
- * @len: packet length
+ * struct tcp_stream - TCP data stream structure
+ * @rhost: Remote host, network byte order
+ * @rport: Remote port, host byte order
+ * @lport: Local port, host byte order
+ *
+ * @priv: User private data (not used by tcp module)
+ *
+ * @max_retry_count: Maximum retransmit attempts (default 3)
+ * @initial_timeout: Timeout from initial TX to reTX (default 2 sec)
+ * @rx_inactiv_timeout: Maximum time from last rx till connection drop
+ * (default 30 sec)
+ *
+ * @on_closed: User callback, called just before destroying TCP stream
+ * @on_established: User callback, called when TCP stream enters
+ * TCP_ESTABLISHED state
+ * @on_rcv_nxt_update: User callback, called when all data in the segment
+ * [0..rx_bytes - 1] was received
+ * @on_snd_una_update: User callback, called when all data in the segment
+ * [0..tx_bytes - 1] were transferred and acknowledged
+ * @rx: User callback, called on receive of segment
+ * [rx_offs..rx_offs+len-1]. If NULL -- all incoming data
+ * will be ignored. User SHOULD store the segment and
+ * return the number of accepted bytes or negative value
+ * on error.
+ * WARNING: Previous segmengs may not be received yet
+ * @tx: User callback, called on transmit/retransmit of segment
+ * [tx_offs..tx_offs+maxlen-1]. If NULL -- no data will
+ * be transmitted. User SHOULD fill provided buffer and
+ * return the number of bytes in the buffer or negative
+ * value on error.
+ * WARNING: do not use tcp_stream_close() from this
+ * callback (it will break stream). Better use
+ * on_snd_una_update() callback for such purposes.
+ *
+ * @time_last_rx: Arrival time of last valid incoming package (ticks)
+ * @time_start: Timeout start time (ticks)
+ * @time_delta: Timeout duration (ticks)
+ * @time_handler Timeout handler for a stream
+ *
+ * @state: TCP connection state
+ * @status: TCP stream status (OK or ERR)
+ * @rx_packets: total number of received packets
+ * @tx_packets: total number of transmitted packets
+ *
+ * @fin_rx: Non-zero if TCP_FIN was received
+ * @fin_rx_seq: TCP sequence of rx FIN bit
+ * @fin_tx: Non-zero if TCP_FIN was sent (or planned to send)
+ * @fin_tx_seq: TCP sequence of tx FIN bit
+ *
+ * @iss: Initial send sequence number
+ * @snd_una: Send unacknowledged
+ * @snd_nxt: Send next
+ * @snd_wnd: Send window (in bytes)
+ * @snd_wl1: Segment sequence number used for last window update
+ * @snd_wl2: Segment acknowledgment number used for last window update
+ *
+ * @irs: Initial receive sequence number
+ * @rcv_nxt: Receive next
+ * @rcv_wnd: Receive window (in bytes)
+ *
+ * @loc_timestamp: Local timestamp
+ * @rmt_timestamp: Remote timestamp
+ *
+ * @rmt_win_scale: Remote window scale factor
+ *
+ * @lost: Used for SACK
+ *
+ * @retry_cnt: Number of retry attempts remaining. Only SYN, FIN
+ * or DATA segments are tried to retransmit.
+ * @retry_timeout: Current retry timeout (ms)
+ * @retry_action: TCP flags used for sending
+ * @retry_seq_num: TCP sequence for retransmit
+ * retry_tx_len: Number of data to transmit
+ * @retry_tx_offs: Position in the TX stream
*/
-typedef void rxhand_tcp(uchar *pkt, u16 dport,
- struct in_addr sip, u16 sport,
- u32 tcp_seq_num, u32 tcp_ack_num,
- u8 action, unsigned int len);
-void tcp_set_tcp_handler(rxhand_tcp *f);
+struct tcp_stream {
+ struct in_addr rhost;
+ u16 rport;
+ u16 lport;
+
+ void *priv;
+
+ int max_retry_count;
+ int initial_timeout;
+ int rx_inactiv_timeout;
+
+ void (*on_closed)(struct tcp_stream *tcp);
+ void (*on_established)(struct tcp_stream *tcp);
+ void (*on_rcv_nxt_update)(struct tcp_stream *tcp, u32 rx_bytes);
+ void (*on_snd_una_update)(struct tcp_stream *tcp, u32 tx_bytes);
+ int (*rx)(struct tcp_stream *tcp, u32 rx_offs, void *buf, int len);
+ int (*tx)(struct tcp_stream *tcp, u32 tx_offs, void *buf, int maxlen);
+
+ ulong time_last_rx;
+ ulong time_start;
+ ulong time_delta;
+ void (*time_handler)(struct tcp_stream *tcp);
+
+ enum tcp_state state;
+ enum tcp_status status;
+ u32 rx_packets;
+ u32 tx_packets;
+
+ int fin_rx;
+ u32 fin_rx_seq;
+
+ int fin_tx;
+ u32 fin_tx_seq;
+
+ u32 iss;
+ u32 snd_una;
+ u32 snd_nxt;
+ u32 snd_wnd;
+ u32 snd_wl1;
+ u32 snd_wl2;
+
+ u32 irs;
+ u32 rcv_nxt;
+ u32 rcv_wnd;
+
+ /* TCP option timestamp */
+ u32 loc_timestamp;
+ u32 rmt_timestamp;
+
+ /* TCP window scale */
+ u8 rmt_win_scale;
+
+ /* TCP sliding window control used to request re-TX */
+ struct tcp_sack_v lost;
+
+ /* used for data retransmission */
+ int retry_cnt;
+ int retry_timeout;
+ u8 retry_action;
+ u32 retry_seq_num;
+ u32 retry_tx_len;
+ u32 retry_tx_offs;
+};
+
+void tcp_init(void);
+
+/*
+ * This function sets user callback called on TCP stream creation.
+ * Callback should:
+ * + Check TCP stream endpoint and make connection verdict
+ * - return non-zero value to accept connection
+ * - return zero to drop connection
+ * + Setup TCP stream callbacks like: on_closed(), on_established(),
+ * n_rcv_nxt_update(), on_snd_una_update(), rx() and tx().
+ * + Setup other stream related data
+ *
+ * WARNING: User MUST setup TCP stream on_create handler. Without it
+ * no connection (including outgoung) will be created.
+ */
+void tcp_stream_set_on_create_handler(int (*on_create)(struct tcp_stream *));
+
+/*
+ * tcp_stream_get -- Get or create TCP stream
+ * @is_new: if non-zero and no stream found, then create a new one
+ * @rhost: Remote host, network byte order
+ * @rport: Remote port, host byte order
+ * @lport: Local port, host byte order
+ *
+ * Returns: TCP stream structure or NULL (if not found/created)
+ */
+struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost,
+ u16 rport, u16 lport);
+
+/*
+ * tcp_stream_connect -- Create new TCP stream for remote connection.
+ * @rhost: Remote host, network byte order
+ * @rport: Remote port, host byte order
+ *
+ * Returns: TCP new stream structure or NULL (if not created).
+ * Random local port will be used.
+ */
+struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport);
+
+/*
+ * tcp_stream_put -- Return stream to a TCP subsystem. Subsystem will
+ * check stream and destroy it (if stream was already
+ * closed). Otherwize no stream change will happen.
+ * @tcp: TCP stream to put
+ */
+void tcp_stream_put(struct tcp_stream *tcp);
+
+/*
+ * tcp_stream_restart_rx_timer -- Restart RX inactivity timer. Usually there
+ * is no needs to call this function. Timer
+ * will be restarted on receiving of any valid
+ * tcp packet belonging to a stream.
+ *
+ * This function may be used to prevent connection
+ * break in the following case:
+ * - u-boot is busy with very long data processing
+ * - remote side waits for u-boot reply
+ *
+ * @tcp: TCP stream to put
+ */
+void tcp_stream_restart_rx_timer(struct tcp_stream *tcp);
+
+enum tcp_state tcp_stream_get_state(struct tcp_stream *tcp);
+enum tcp_status tcp_stream_get_status(struct tcp_stream *tcp);
+
+/*
+ * tcp_stream_rx_offs(),
+ * tcp_stream_tx_offs() -- Returns offset of first unacknowledged byte
+ * in receive/transmit stream correspondingly.
+ * The result is NOT affected by sin/fin flags.
+ * @tcp: TCP stream
+ */
+u32 tcp_stream_rx_offs(struct tcp_stream *tcp);
+u32 tcp_stream_tx_offs(struct tcp_stream *tcp);
+
+/* reset tcp stream */
+void tcp_stream_reset(struct tcp_stream *tcp);
+/* force TCP stream closing, do NOT use from tcp->tx callback */
+void tcp_stream_close(struct tcp_stream *tcp);
+
+void tcp_streams_poll(void);
+
+int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len,
+ u8 action, u32 tcp_seq_num, u32 tcp_ack_num);
void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int len);