* [MPTCP][PATCH mptcp-next 0/6] DSS checksum support @ 2021-03-22 11:37 Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled Geliang Tang 0 siblings, 1 reply; 21+ messages in thread From: Geliang Tang @ 2021-03-22 11:37 UTC (permalink / raw) To: mptcp, mptcp; +Cc: Geliang Tang apply: export/20210320T065116 + "refactor mptcp_addr_info and cleanups" Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/134 Geliang Tang (6): mptcp: add a new sysctl checksum_enabled mptcp: add csum_enabled in mptcp_out_options mptcp: add the csum_reqd fields mptcp: add the DSS checksum sending mptcp: add the DSS checksum receiving mptcp: add trace event for DSS checksum Documentation/networking/mptcp-sysctl.rst | 8 +++ include/net/mptcp.h | 4 +- include/trace/events/mptcp.h | 51 +++++++++++++++ net/mptcp/ctrl.c | 14 +++++ net/mptcp/options.c | 76 ++++++++++++++++++++--- net/mptcp/protocol.c | 4 ++ net/mptcp/protocol.h | 14 ++++- net/mptcp/subflow.c | 46 ++++++++++++++ 8 files changed, 205 insertions(+), 12 deletions(-) create mode 100644 include/trace/events/mptcp.h -- 2.30.2 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled 2021-03-22 11:37 [MPTCP][PATCH mptcp-next 0/6] DSS checksum support Geliang Tang @ 2021-03-22 11:37 ` Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options Geliang Tang 2021-03-22 22:22 ` [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled Mat Martineau 0 siblings, 2 replies; 21+ messages in thread From: Geliang Tang @ 2021-03-22 11:37 UTC (permalink / raw) To: mptcp, mptcp; +Cc: Geliang Tang This patch added a new sysctl, named checksum_enabled, to control whether DSS checksum can be enabled. Signed-off-by: Geliang Tang <geliangtang@gmail.com> --- Documentation/networking/mptcp-sysctl.rst | 8 ++++++++ net/mptcp/ctrl.c | 14 ++++++++++++++ net/mptcp/protocol.h | 1 + 3 files changed, 23 insertions(+) diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst index 6af0196c4297..1128e09d6c4d 100644 --- a/Documentation/networking/mptcp-sysctl.rst +++ b/Documentation/networking/mptcp-sysctl.rst @@ -24,3 +24,11 @@ add_addr_timeout - INTEGER (seconds) sysctl. Default: 120 + +checksum_enabled - INTEGER + Control whether DSS checksum can be enabled. + + DSS checksum can be enabled if the value is nonzero. This is a + per-namespace sysctl. + + Default: 1 diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index 96ba616f59bf..115cebc8c02a 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -19,6 +19,7 @@ struct mptcp_pernet { int mptcp_enabled; unsigned int add_addr_timeout; + int checksum_enabled; }; static struct mptcp_pernet *mptcp_get_pernet(struct net *net) @@ -36,6 +37,11 @@ unsigned int mptcp_get_add_addr_timeout(struct net *net) return mptcp_get_pernet(net)->add_addr_timeout; } +int mptcp_is_checksum_enabled(struct net *net) +{ + return mptcp_get_pernet(net)->checksum_enabled; +} + static struct ctl_table mptcp_sysctl_table[] = { { .procname = "enabled", @@ -52,6 +58,12 @@ static struct ctl_table mptcp_sysctl_table[] = { .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, + { + .procname = "checksum_enabled", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, {} }; @@ -59,6 +71,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) { pernet->mptcp_enabled = 1; pernet->add_addr_timeout = TCP_RTO_MAX; + pernet->checksum_enabled = 1; } static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) @@ -75,6 +88,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) table[0].data = &pernet->mptcp_enabled; table[1].data = &pernet->add_addr_timeout; + table[2].data = &pernet->checksum_enabled; hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table); if (!hdr) diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 14f0114be17a..fd36239d8905 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -519,6 +519,7 @@ static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *su int mptcp_is_enabled(struct net *net); unsigned int mptcp_get_add_addr_timeout(struct net *net); +int mptcp_is_checksum_enabled(struct net *net); void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow, struct mptcp_options_received *mp_opt); bool mptcp_subflow_data_available(struct sock *sk); -- 2.30.2 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled Geliang Tang @ 2021-03-22 11:37 ` Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Geliang Tang 2021-03-23 10:41 ` [MPTCP] [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options Paolo Abeni 2021-03-22 22:22 ` [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled Mat Martineau 1 sibling, 2 replies; 21+ messages in thread From: Geliang Tang @ 2021-03-22 11:37 UTC (permalink / raw) To: mptcp, mptcp; +Cc: Geliang Tang This patch add a new member csum_enabled in struct mptcp_out_options. In mptcp_write_options, if this csum_enabled field is enabled, send out the MP_CAPABLE suboption with the MPTCP_CAP_CHECKSUM_REQD flag. Signed-off-by: Geliang Tang <geliangtang@gmail.com> --- include/net/mptcp.h | 3 ++- net/mptcp/options.c | 10 ++++++++-- net/mptcp/protocol.h | 3 ++- net/mptcp/subflow.c | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 83f23774b908..36fb6907aa6f 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -64,7 +64,8 @@ struct mptcp_out_options { u8 join_id; u8 backup; u8 reset_reason:4; - u8 reset_transient:1; + u8 reset_transient:1, + csum_enabled:1; u32 nonce; u64 thmac; u32 token; diff --git a/net/mptcp/options.c b/net/mptcp/options.c index e3fcd2b0ffd7..f45bebb923dc 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -379,6 +379,7 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, subflow->snd_isn = TCP_SKB_CB(skb)->end_seq; if (subflow->request_mptcp) { opts->suboptions = OPTION_MPTCP_MPC_SYN; + opts->csum_enabled = mptcp_is_checksum_enabled(sock_net(sk)); *size = TCPOLEN_MPTCP_MPC_SYN; return true; } else if (subflow->request_join) { @@ -464,6 +465,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb, opts->suboptions = OPTION_MPTCP_MPC_ACK; opts->sndr_key = subflow->local_key; opts->rcvr_key = subflow->remote_key; + opts->csum_enabled = mptcp_is_checksum_enabled(sock_net(sk)); /* Section 3.1. * The MP_CAPABLE option is carried on the SYN, SYN/ACK, and ACK @@ -786,6 +788,7 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, if (subflow_req->mp_capable) { opts->suboptions = OPTION_MPTCP_MPC_SYNACK; opts->sndr_key = subflow_req->local_key; + opts->csum_enabled = subflow_req->csum_enabled; *size = TCPOLEN_MPTCP_MPC_SYNACK; pr_debug("subflow_req=%p, local_key=%llu", subflow_req, subflow_req->local_key); @@ -1116,7 +1119,7 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, { if ((OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_SYNACK | OPTION_MPTCP_MPC_ACK) & opts->suboptions) { - u8 len; + u8 len, flag = MPTCP_CAP_HMAC_SHA256; if (OPTION_MPTCP_MPC_SYN & opts->suboptions) len = TCPOLEN_MPTCP_MPC_SYN; @@ -1127,9 +1130,12 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, else len = TCPOLEN_MPTCP_MPC_ACK; + if (opts->csum_enabled) + flag |= MPTCP_CAP_CHECKSUM_REQD; + *ptr++ = mptcp_option(MPTCPOPT_MP_CAPABLE, len, MPTCP_SUPPORTED_VERSION, - MPTCP_CAP_HMAC_SHA256); + flag); if (!((OPTION_MPTCP_MPC_SYNACK | OPTION_MPTCP_MPC_ACK) & opts->suboptions)) diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index fd36239d8905..14f1e2fd3c08 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -335,7 +335,8 @@ struct mptcp_subflow_request_sock { struct tcp_request_sock sk; u16 mp_capable : 1, mp_join : 1, - backup : 1; + backup : 1, + csum_enabled : 1; u8 local_id; u8 remote_id; u64 local_key; diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 5fc3cada11dd..e2e9cc34713d 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -106,6 +106,7 @@ static void subflow_init_req(struct request_sock *req, const struct sock *sk_lis subflow_req->mp_capable = 0; subflow_req->mp_join = 0; + subflow_req->csum_enabled = mptcp_is_checksum_enabled(sock_net(sk_listener)); subflow_req->msk = NULL; mptcp_token_init_request(req); } -- 2.30.2 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options Geliang Tang @ 2021-03-22 11:37 ` Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Geliang Tang ` (2 more replies) 2021-03-23 10:41 ` [MPTCP] [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options Paolo Abeni 1 sibling, 3 replies; 21+ messages in thread From: Geliang Tang @ 2021-03-22 11:37 UTC (permalink / raw) To: mptcp, mptcp; +Cc: Geliang Tang This patch added a new flag csum_reqd in struct mptcp_options_received, if the flag MPTCP_CAP_CHECKSUM_REQD is set in the receiving MP_CAPABLE suboption, set this csum_reqd flag. It also added another new csum_reqd member in struct mptcp_sock too, if the csum_reqd flag in mptcp_options_received is set, set this member to true. Signed-off-by: Geliang Tang <geliangtang@gmail.com> --- net/mptcp/options.c | 8 +++++--- net/mptcp/protocol.c | 1 + net/mptcp/protocol.h | 2 ++ net/mptcp/subflow.c | 4 ++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index f45bebb923dc..bdced173edff 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -69,11 +69,9 @@ static void mptcp_parse_option(const struct sk_buff *skb, * "If a checksum is not present when its use has been * negotiated, the receiver MUST close the subflow with a RST as * it is considered broken." - * - * We don't implement DSS checksum - fall back to TCP. */ if (flags & MPTCP_CAP_CHECKSUM_REQD) - break; + mp_opt->csum_reqd = 1; mp_opt->mp_capable = 1; if (opsize >= TCPOLEN_MPTCP_MPC_SYNACK) { @@ -340,6 +338,7 @@ void mptcp_get_options(const struct sk_buff *skb, mp_opt->dss = 0; mp_opt->mp_prio = 0; mp_opt->reset = 0; + mp_opt->csum_reqd = 0; length = (th->doff * 4) - sizeof(struct tcphdr); ptr = (const unsigned char *)(th + 1); @@ -1013,6 +1012,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) mptcp_schedule_work((struct sock *)msk); } + if (mp_opt.csum_reqd) + WRITE_ONCE(msk->csum_reqd, true); + if (mp_opt.add_addr && add_addr_hmac_valid(msk, &mp_opt)) { if (!mp_opt.echo) { mptcp_pm_add_addr_received(msk, &mp_opt.addr); diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 9d7e7e13fba8..94c3568c7a60 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2364,6 +2364,7 @@ static int __mptcp_init_sock(struct sock *sk) msk->ack_hint = NULL; msk->first = NULL; inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss; + WRITE_ONCE(msk->csum_reqd, mptcp_is_checksum_enabled(sock_net(sk))); mptcp_pm_data_init(msk); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 14f1e2fd3c08..4fc4871595ef 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -132,6 +132,7 @@ struct mptcp_options_received { rm_addr : 1, mp_prio : 1, echo : 1, + csum_reqd : 1, backup : 1; u32 token; u32 nonce; @@ -233,6 +234,7 @@ struct mptcp_sock { bool snd_data_fin_enable; bool rcv_fastclose; bool use_64bit_ack; /* Set when we received a 64-bit DSN */ + bool csum_reqd; spinlock_t join_list_lock; struct sock *ack_hint; struct work_struct work; diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index e2e9cc34713d..9fec1a273100 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -403,6 +403,8 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) goto fallback; } + if (mp_opt.csum_reqd) + WRITE_ONCE(mptcp_sk(parent)->csum_reqd, true); subflow->mp_capable = 1; subflow->can_ack = 1; subflow->remote_key = mp_opt.sndr_key; @@ -643,6 +645,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req); if (!new_msk) fallback = true; + else if (mp_opt.csum_reqd) + WRITE_ONCE(mptcp_sk(new_msk)->csum_reqd, true); } else if (subflow_req->mp_join) { mptcp_get_options(skb, &mp_opt); if (!mp_opt.mp_join || !subflow_hmac_valid(req, &mp_opt) || -- 2.30.2 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Geliang Tang @ 2021-03-22 11:37 ` Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Geliang Tang ` (2 more replies) 2021-03-22 22:52 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Mat Martineau 2021-03-23 10:12 ` [MPTCP] " Paolo Abeni 2 siblings, 3 replies; 21+ messages in thread From: Geliang Tang @ 2021-03-22 11:37 UTC (permalink / raw) To: mptcp, mptcp; +Cc: Geliang Tang In mptcp_established_options_dss, use the new function mptcp_generate_dss_csum to generate the DSS checksum value. In mptcp_write_options, send out DSS with the checksum value. Signed-off-by: Geliang Tang <geliangtang@gmail.com> --- include/net/mptcp.h | 1 + net/mptcp/options.c | 41 ++++++++++++++++++++++++++++++++++++++--- net/mptcp/protocol.h | 7 +++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 36fb6907aa6f..869a6d98a72e 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -32,6 +32,7 @@ struct mptcp_ext { frozen:1, reset_transient:1; u8 reset_reason:4; + u16 csum; }; #define MPTCP_RM_IDS_MAX 8 diff --git a/net/mptcp/options.c b/net/mptcp/options.c index bdced173edff..69eb15ef9385 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -521,6 +521,30 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow, } } +static u16 mptcp_generate_dss_csum(struct sk_buff *skb) +{ + struct csum_pseudo_header header; + struct mptcp_ext *mpext; + __wsum csum; + + if (!skb) + return 0; + + mpext = mptcp_get_ext(skb); + if (!mpext || !mpext->use_map) + return 0; + + header.data_seq = mpext->data_seq; + header.subflow_seq = mpext->subflow_seq; + header.data_len = mpext->data_len; + header.csum = 0; + + csum = skb_checksum(skb, 0, skb->len, 0); + csum = csum_partial(&header, sizeof(header), csum); + + return csum_fold(csum); +} + static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, bool snd_data_fin_enable, unsigned int *size, @@ -544,8 +568,11 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, remaining -= map_size; dss_size = map_size; - if (mpext) + if (mpext) { + if (msk->csum_reqd) + mpext->csum = mptcp_generate_dss_csum(skb); opts->ext_copy = *mpext; + } if (skb && snd_data_fin_enable) mptcp_write_data_fin(subflow, skb, &opts->ext_copy); @@ -1304,6 +1331,9 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64; if (mpext->data_fin) flags |= MPTCP_DSS_DATA_FIN; + + if (mpext->csum) + len += TCPOLEN_MPTCP_DSS_CHECKSUM; } *ptr++ = mptcp_option(MPTCPOPT_DSS, len, 0, flags); @@ -1323,8 +1353,13 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, ptr += 2; put_unaligned_be32(mpext->subflow_seq, ptr); ptr += 1; - put_unaligned_be32(mpext->data_len << 16 | - TCPOPT_NOP << 8 | TCPOPT_NOP, ptr); + if (mpext->csum) { + put_unaligned_be32(mpext->data_len << 16 | + mpext->csum, ptr); + } else { + put_unaligned_be32(mpext->data_len << 16 | + TCPOPT_NOP << 8 | TCPOPT_NOP, ptr); + } } } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 4fc4871595ef..f62cea8635f0 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -333,6 +333,13 @@ static inline struct mptcp_data_frag *mptcp_rtx_head(const struct sock *sk) return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list); } +struct csum_pseudo_header { + u64 data_seq; + u32 subflow_seq; + u16 data_len; + u16 csum; +}; + struct mptcp_subflow_request_sock { struct tcp_request_sock sk; u16 mp_capable : 1, -- 2.30.2 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Geliang Tang @ 2021-03-22 11:37 ` Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 6/6] mptcp: add trace event for DSS checksum Geliang Tang ` (2 more replies) 2021-03-22 23:10 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Mat Martineau 2021-03-23 17:07 ` [MPTCP] " Paolo Abeni 2 siblings, 3 replies; 21+ messages in thread From: Geliang Tang @ 2021-03-22 11:37 UTC (permalink / raw) To: mptcp, mptcp; +Cc: Geliang Tang This patch added a new member csum in struct mptcp_options_received. In mptcp_parse_option, parse the checksum value from the receiving DSS, and save it in mp_opt->csum. In mptcp_incoming_options, pass it to mpext->csum. In validate_mapping, use the new function validate_dss_csum to validata the DSS checksum. In validate_dss_csum, if the data has been split in different packets, skip validating. Signed-off-by: Geliang Tang <geliangtang@gmail.com> --- net/mptcp/options.c | 13 +++++++++++-- net/mptcp/protocol.h | 1 + net/mptcp/subflow.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 69eb15ef9385..ed89f6c2ed49 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -206,9 +206,14 @@ static void mptcp_parse_option(const struct sk_buff *skb, mp_opt->data_len = get_unaligned_be16(ptr); ptr += 2; - pr_debug("data_seq=%llu subflow_seq=%u data_len=%u", + if (opsize == expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM) { + mp_opt->csum = get_unaligned_be16(ptr); + ptr += 2; + } + + pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%u", mp_opt->data_seq, mp_opt->subflow_seq, - mp_opt->data_len); + mp_opt->data_len, mp_opt->csum); } break; @@ -339,6 +344,7 @@ void mptcp_get_options(const struct sk_buff *skb, mp_opt->mp_prio = 0; mp_opt->reset = 0; mp_opt->csum_reqd = 0; + mp_opt->csum = 0; length = (th->doff * 4) - sizeof(struct tcphdr); ptr = (const unsigned char *)(th + 1); @@ -1124,6 +1130,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) } mpext->data_len = mp_opt.data_len; mpext->use_map = 1; + + if (READ_ONCE(msk->csum_reqd)) + mpext->csum = mp_opt.csum; } } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index f62cea8635f0..51ef3173a2e5 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -123,6 +123,7 @@ struct mptcp_options_received { u64 data_seq; u32 subflow_seq; u16 data_len; + u16 csum; u16 mp_capable : 1, mp_join : 1, fastclose : 1, diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 9fec1a273100..2eeea7d527f0 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -799,10 +799,45 @@ static bool skb_is_fully_mapped(struct sock *ssk, struct sk_buff *skb) mptcp_subflow_get_map_offset(subflow); } +static bool validate_dss_csum(struct sock *ssk, struct sk_buff *skb) +{ + struct csum_pseudo_header header; + struct mptcp_ext *mpext; + __wsum csum; + + if (!skb) + goto out; + + mpext = mptcp_get_ext(skb); + if (!mpext || !mpext->use_map || !mpext->csum || + mpext->data_len != skb->len) + goto out; + + header.data_seq = mpext->data_seq; + header.subflow_seq = mpext->subflow_seq; + header.data_len = mpext->data_len; + header.csum = mpext->csum; + + csum = skb_checksum(skb, 0, skb->len, 0); + csum = csum_partial(&header, sizeof(header), csum); + + if (csum_fold(csum)) { + pr_err("DSS checksum error! data_seq=%llu subflow_seq=%u data_len=%u csum=%u %u", + header.data_seq, header.subflow_seq, header.data_len, + header.csum, csum_fold(csum)); + + return false; + } + +out: + return true; +} + static bool validate_mapping(struct sock *ssk, struct sk_buff *skb) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); u32 ssn = tcp_sk(ssk)->copied_seq - subflow->ssn_offset; + struct mptcp_sock *msk = mptcp_sk(subflow->conn); if (unlikely(before(ssn, subflow->map_subflow_seq))) { /* Mapping covers data later in the subflow stream, @@ -817,6 +852,8 @@ static bool validate_mapping(struct sock *ssk, struct sk_buff *skb) warn_bad_map(subflow, ssn + skb->len); return false; } + if (READ_ONCE(msk->csum_reqd)) + validate_dss_csum(ssk, skb); return true; } -- 2.30.2 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [MPTCP][PATCH mptcp-next 6/6] mptcp: add trace event for DSS checksum 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Geliang Tang @ 2021-03-22 11:37 ` Geliang Tang 2021-03-22 23:40 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Mat Martineau 2021-03-23 10:37 ` [MPTCP] " Paolo Abeni 2 siblings, 0 replies; 21+ messages in thread From: Geliang Tang @ 2021-03-22 11:37 UTC (permalink / raw) To: mptcp, mptcp; +Cc: Geliang Tang This patch added the trace event for DSS checksum. Add a tracepoint in mptcp_generate_dss_csum and a tracepoint in validate_dss_csum. Signed-off-by: Geliang Tang <geliangtang@gmail.com> --- include/trace/events/mptcp.h | 51 ++++++++++++++++++++++++++++++++++++ net/mptcp/options.c | 4 +++ net/mptcp/protocol.c | 3 +++ net/mptcp/subflow.c | 4 +++ 4 files changed, 62 insertions(+) create mode 100644 include/trace/events/mptcp.h diff --git a/include/trace/events/mptcp.h b/include/trace/events/mptcp.h new file mode 100644 index 000000000000..a5b87e304303 --- /dev/null +++ b/include/trace/events/mptcp.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mptcp + +#if !defined(_TRACE_MPTCP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MPTCP_H + +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(mptcp_event_dss_csum, + + TP_PROTO(struct csum_pseudo_header *header, __u16 csum), + + TP_ARGS(header, csum), + + TP_STRUCT__entry( + __field(__u64, data_seq) + __field(__u32, subflow_seq) + __field(__u16, data_len) + __field(__u16, dss_csum) + __field(__u16, csum) + ), + + TP_fast_assign( + __entry->data_seq = header->data_seq; + __entry->subflow_seq = header->subflow_seq; + __entry->data_len = header->data_len; + __entry->dss_csum = header->csum; + __entry->csum = csum; + ), + + TP_printk("data_seq=%llu subflow_seq=%u data_len=%u csum=%u", + __entry->data_seq, __entry->subflow_seq, __entry->data_len, + __entry->csum) +); + +DEFINE_EVENT(mptcp_event_dss_csum, mptcp_generate_dss_csum, + TP_PROTO(struct csum_pseudo_header *header, __u16 csum), + TP_ARGS(header, csum)); + +DEFINE_EVENT_PRINT(mptcp_event_dss_csum, validate_dss_csum, + TP_PROTO(struct csum_pseudo_header *header, __u16 csum), + TP_ARGS(header, csum), + TP_printk("data_seq=%llu subflow_seq=%u data_len=%u csum=%u, DSS checksum %s!", + __entry->data_seq, __entry->subflow_seq, __entry->data_len, + __entry->dss_csum, __entry->csum ? "error" : "done")); + +#endif /* _TRACE_MPTCP_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/net/mptcp/options.c b/net/mptcp/options.c index ed89f6c2ed49..8ec41bf56c3b 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -13,6 +13,8 @@ #include "protocol.h" #include "mib.h" +#include <trace/events/mptcp.h> + static bool mptcp_cap_flag_sha256(u8 flags) { return (flags & MPTCP_CAP_FLAG_MASK) == MPTCP_CAP_HMAC_SHA256; @@ -548,6 +550,8 @@ static u16 mptcp_generate_dss_csum(struct sk_buff *skb) csum = skb_checksum(skb, 0, skb->len, 0); csum = csum_partial(&header, sizeof(header), csum); + trace_mptcp_generate_dss_csum(&header, csum_fold(csum)); + return csum_fold(csum); } diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 94c3568c7a60..1f767612c917 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -25,6 +25,9 @@ #include "protocol.h" #include "mib.h" +#define CREATE_TRACE_POINTS +#include <trace/events/mptcp.h> + #if IS_ENABLED(CONFIG_MPTCP_IPV6) struct mptcp6_sock { struct mptcp_sock msk; diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 2eeea7d527f0..7e63d902a3de 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -27,6 +27,8 @@ static void mptcp_subflow_ops_undo_override(struct sock *ssk); +#include <trace/events/mptcp.h> + static void SUBFLOW_REQ_INC_STATS(struct request_sock *req, enum linux_mptcp_mib_field field) { @@ -821,6 +823,8 @@ static bool validate_dss_csum(struct sock *ssk, struct sk_buff *skb) csum = skb_checksum(skb, 0, skb->len, 0); csum = csum_partial(&header, sizeof(header), csum); + trace_validate_dss_csum(&header, csum_fold(csum)); + if (csum_fold(csum)) { pr_err("DSS checksum error! data_seq=%llu subflow_seq=%u data_len=%u csum=%u %u", header.data_seq, header.subflow_seq, header.data_len, -- 2.30.2 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 6/6] mptcp: add trace event for DSS checksum Geliang Tang @ 2021-03-22 23:40 ` Mat Martineau 2021-03-23 12:55 ` Geliang Tang 2021-03-23 10:37 ` [MPTCP] " Paolo Abeni 2 siblings, 1 reply; 21+ messages in thread From: Mat Martineau @ 2021-03-22 23:40 UTC (permalink / raw) To: Geliang Tang; +Cc: mptcp, mptcp On Mon, 22 Mar 2021, Geliang Tang wrote: > This patch added a new member csum in struct mptcp_options_received. In > mptcp_parse_option, parse the checksum value from the receiving DSS, and > save it in mp_opt->csum. In mptcp_incoming_options, pass it to > mpext->csum. > > In validate_mapping, use the new function validate_dss_csum to validata > the DSS checksum. > > In validate_dss_csum, if the data has been split in different packets, > skip validating. > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > --- > net/mptcp/options.c | 13 +++++++++++-- > net/mptcp/protocol.h | 1 + > net/mptcp/subflow.c | 37 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 49 insertions(+), 2 deletions(-) > > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > index 69eb15ef9385..ed89f6c2ed49 100644 > --- a/net/mptcp/options.c > +++ b/net/mptcp/options.c > @@ -206,9 +206,14 @@ static void mptcp_parse_option(const struct sk_buff *skb, > mp_opt->data_len = get_unaligned_be16(ptr); > ptr += 2; > > - pr_debug("data_seq=%llu subflow_seq=%u data_len=%u", > + if (opsize == expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM) { Now that more of the checksum code has been added, I think that expected_opsize should be set to the exact value that is needed - either expect the checksum, or don't expect the checksum. RFC 6824 said: "If a checksum is present, but its use had not been negotiated in the MP_CAPABLE handshake, the checksum field MUST be ignored." RFC 8684 says: "If a checksum is present but its use had not been negotiated in the MP_CAPABLE handshake, the receiver MUST close the subflow with a RST, as it is not behaving as negotiated. If a checksum is not present when its use has been negotiated, the receiver MUST close the subflow with a RST, as it is considered broken." There's some old RFC 6824-based code earlier in the function: if (opsize != expected_opsize && opsize != expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM) break; That needs to be changed to: if (opsize != expected_opsize) break; and expected_opsize should include TCPOLEN_MPTCP_DSS_CHECKSUM only if the checksum is enabled. > + mp_opt->csum = get_unaligned_be16(ptr); > + ptr += 2; > + } > + > + pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%u", > mp_opt->data_seq, mp_opt->subflow_seq, > - mp_opt->data_len); > + mp_opt->data_len, mp_opt->csum); > } > > break; > @@ -339,6 +344,7 @@ void mptcp_get_options(const struct sk_buff *skb, > mp_opt->mp_prio = 0; > mp_opt->reset = 0; > mp_opt->csum_reqd = 0; > + mp_opt->csum = 0; > > length = (th->doff * 4) - sizeof(struct tcphdr); > ptr = (const unsigned char *)(th + 1); > @@ -1124,6 +1130,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) > } > mpext->data_len = mp_opt.data_len; > mpext->use_map = 1; > + > + if (READ_ONCE(msk->csum_reqd)) > + mpext->csum = mp_opt.csum; > } > } > > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > index f62cea8635f0..51ef3173a2e5 100644 > --- a/net/mptcp/protocol.h > +++ b/net/mptcp/protocol.h > @@ -123,6 +123,7 @@ struct mptcp_options_received { > u64 data_seq; > u32 subflow_seq; > u16 data_len; > + u16 csum; > u16 mp_capable : 1, > mp_join : 1, > fastclose : 1, > diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c > index 9fec1a273100..2eeea7d527f0 100644 > --- a/net/mptcp/subflow.c > +++ b/net/mptcp/subflow.c > @@ -799,10 +799,45 @@ static bool skb_is_fully_mapped(struct sock *ssk, struct sk_buff *skb) > mptcp_subflow_get_map_offset(subflow); > } > > +static bool validate_dss_csum(struct sock *ssk, struct sk_buff *skb) > +{ > + struct csum_pseudo_header header; > + struct mptcp_ext *mpext; > + __wsum csum; > + > + if (!skb) > + goto out; > + > + mpext = mptcp_get_ext(skb); > + if (!mpext || !mpext->use_map || !mpext->csum || > + mpext->data_len != skb->len) > + goto out; > + > + header.data_seq = mpext->data_seq; > + header.subflow_seq = mpext->subflow_seq; > + header.data_len = mpext->data_len; > + header.csum = mpext->csum; > + > + csum = skb_checksum(skb, 0, skb->len, 0); The checksum isn't calculated using the data from a single skb, it requires the complete reassembled data for the current mapping. If we're lucky, GRO has placed everything in one skb. But that can't be assumed. The checksum can be calculated incrementally as skbs arrive, but checksum verification will require changes to data reassembly and MPTCP-level acknowledgements, and will delay movement of data to the msk until the checksum is verified. Also review my comments on the MP_FAIL RFC patch: https://lists.01.org/hyperkitty/list/mptcp@lists.01.org/message/KSEEB5Q4ND3GKOW7S3FZ32PHCWWON5QC/ Thanks for the patch set! Mat > + csum = csum_partial(&header, sizeof(header), csum); > + > + if (csum_fold(csum)) { > + pr_err("DSS checksum error! data_seq=%llu subflow_seq=%u data_len=%u csum=%u %u", > + header.data_seq, header.subflow_seq, header.data_len, > + header.csum, csum_fold(csum)); > + > + return false; > + } > + > +out: > + return true; > +} > + > static bool validate_mapping(struct sock *ssk, struct sk_buff *skb) > { > struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); > u32 ssn = tcp_sk(ssk)->copied_seq - subflow->ssn_offset; > + struct mptcp_sock *msk = mptcp_sk(subflow->conn); > > if (unlikely(before(ssn, subflow->map_subflow_seq))) { > /* Mapping covers data later in the subflow stream, > @@ -817,6 +852,8 @@ static bool validate_mapping(struct sock *ssk, struct sk_buff *skb) > warn_bad_map(subflow, ssn + skb->len); > return false; > } > + if (READ_ONCE(msk->csum_reqd)) > + validate_dss_csum(ssk, skb); > return true; > } > > -- > 2.30.2 -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving 2021-03-22 23:40 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Mat Martineau @ 2021-03-23 12:55 ` Geliang Tang 2021-03-24 0:52 ` Mat Martineau 0 siblings, 1 reply; 21+ messages in thread From: Geliang Tang @ 2021-03-23 12:55 UTC (permalink / raw) To: Mat Martineau; +Cc: mptcp, mptcp Hi Mat, Mat Martineau <mathew.j.martineau@linux.intel.com> 于2021年3月23日周二 上午7:40写道: > > On Mon, 22 Mar 2021, Geliang Tang wrote: > > > This patch added a new member csum in struct mptcp_options_received. In > > mptcp_parse_option, parse the checksum value from the receiving DSS, and > > save it in mp_opt->csum. In mptcp_incoming_options, pass it to > > mpext->csum. > > > > In validate_mapping, use the new function validate_dss_csum to validata > > the DSS checksum. > > > > In validate_dss_csum, if the data has been split in different packets, > > skip validating. > > > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > > --- > > net/mptcp/options.c | 13 +++++++++++-- > > net/mptcp/protocol.h | 1 + > > net/mptcp/subflow.c | 37 +++++++++++++++++++++++++++++++++++++ > > 3 files changed, 49 insertions(+), 2 deletions(-) > > > > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > > index 69eb15ef9385..ed89f6c2ed49 100644 > > --- a/net/mptcp/options.c > > +++ b/net/mptcp/options.c > > @@ -206,9 +206,14 @@ static void mptcp_parse_option(const struct sk_buff *skb, > > mp_opt->data_len = get_unaligned_be16(ptr); > > ptr += 2; > > > > - pr_debug("data_seq=%llu subflow_seq=%u data_len=%u", > > + if (opsize == expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM) { > > Now that more of the checksum code has been added, I think that > expected_opsize should be set to the exact value that is needed - either > expect the checksum, or don't expect the checksum. > > RFC 6824 said: "If a checksum is present, but its use had not been > negotiated in the MP_CAPABLE handshake, the checksum field MUST be > ignored." > > RFC 8684 says: "If a checksum is present but its use had > not been negotiated in the MP_CAPABLE handshake, the receiver MUST > close the subflow with a RST, as it is not behaving as negotiated. > If a checksum is not present when its use has been negotiated, the > receiver MUST close the subflow with a RST, as it is considered > broken." > > There's some old RFC 6824-based code earlier in the function: > > if (opsize != expected_opsize && > opsize != expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM) > break; > > That needs to be changed to: > > if (opsize != expected_opsize) > break; > > and expected_opsize should include TCPOLEN_MPTCP_DSS_CHECKSUM only if the > checksum is enabled. > > > + mp_opt->csum = get_unaligned_be16(ptr); > > + ptr += 2; > > + } > > + > > + pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%u", > > mp_opt->data_seq, mp_opt->subflow_seq, > > - mp_opt->data_len); > > + mp_opt->data_len, mp_opt->csum); > > } > > > > break; > > @@ -339,6 +344,7 @@ void mptcp_get_options(const struct sk_buff *skb, > > mp_opt->mp_prio = 0; > > mp_opt->reset = 0; > > mp_opt->csum_reqd = 0; > > + mp_opt->csum = 0; > > > > length = (th->doff * 4) - sizeof(struct tcphdr); > > ptr = (const unsigned char *)(th + 1); > > @@ -1124,6 +1130,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) > > } > > mpext->data_len = mp_opt.data_len; > > mpext->use_map = 1; > > + > > + if (READ_ONCE(msk->csum_reqd)) > > + mpext->csum = mp_opt.csum; > > } > > } > > > > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > > index f62cea8635f0..51ef3173a2e5 100644 > > --- a/net/mptcp/protocol.h > > +++ b/net/mptcp/protocol.h > > @@ -123,6 +123,7 @@ struct mptcp_options_received { > > u64 data_seq; > > u32 subflow_seq; > > u16 data_len; > > + u16 csum; > > u16 mp_capable : 1, > > mp_join : 1, > > fastclose : 1, > > diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c > > index 9fec1a273100..2eeea7d527f0 100644 > > --- a/net/mptcp/subflow.c > > +++ b/net/mptcp/subflow.c > > @@ -799,10 +799,45 @@ static bool skb_is_fully_mapped(struct sock *ssk, struct sk_buff *skb) > > mptcp_subflow_get_map_offset(subflow); > > } > > > > +static bool validate_dss_csum(struct sock *ssk, struct sk_buff *skb) > > +{ > > + struct csum_pseudo_header header; > > + struct mptcp_ext *mpext; > > + __wsum csum; > > + > > + if (!skb) > > + goto out; > > + > > + mpext = mptcp_get_ext(skb); > > + if (!mpext || !mpext->use_map || !mpext->csum || > > + mpext->data_len != skb->len) > > + goto out; > > + > > + header.data_seq = mpext->data_seq; > > + header.subflow_seq = mpext->subflow_seq; > > + header.data_len = mpext->data_len; > > + header.csum = mpext->csum; > > + > > + csum = skb_checksum(skb, 0, skb->len, 0); > > The checksum isn't calculated using the data from a single skb, it > requires the complete reassembled data for the current mapping. If we're > lucky, GRO has placed everything in one skb. But that can't be assumed. > > The checksum can be calculated incrementally as skbs arrive, but checksum > verification will require changes to data reassembly and MPTCP-level > acknowledgements, and will delay movement of data to the msk until the > checksum is verified. Also review my comments on the MP_FAIL RFC patch: I need some help here. How can I get the reassembled data for the current mapping? And in which function to calculate the skbs checksum and where to verify them? Could you please give me more detail? Thanks. -Geliang > > https://lists.01.org/hyperkitty/list/mptcp@lists.01.org/message/KSEEB5Q4ND3GKOW7S3FZ32PHCWWON5QC/ > > > Thanks for the patch set! > > Mat > > > > + csum = csum_partial(&header, sizeof(header), csum); > > + > > + if (csum_fold(csum)) { > > + pr_err("DSS checksum error! data_seq=%llu subflow_seq=%u data_len=%u csum=%u %u", > > + header.data_seq, header.subflow_seq, header.data_len, > > + header.csum, csum_fold(csum)); > > + > > + return false; > > + } > > + > > +out: > > + return true; > > +} > > + > > static bool validate_mapping(struct sock *ssk, struct sk_buff *skb) > > { > > struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); > > u32 ssn = tcp_sk(ssk)->copied_seq - subflow->ssn_offset; > > + struct mptcp_sock *msk = mptcp_sk(subflow->conn); > > > > if (unlikely(before(ssn, subflow->map_subflow_seq))) { > > /* Mapping covers data later in the subflow stream, > > @@ -817,6 +852,8 @@ static bool validate_mapping(struct sock *ssk, struct sk_buff *skb) > > warn_bad_map(subflow, ssn + skb->len); > > return false; > > } > > + if (READ_ONCE(msk->csum_reqd)) > > + validate_dss_csum(ssk, skb); > > return true; > > } > > > > -- > > 2.30.2 > > -- > Mat Martineau > Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving 2021-03-23 12:55 ` Geliang Tang @ 2021-03-24 0:52 ` Mat Martineau 0 siblings, 0 replies; 21+ messages in thread From: Mat Martineau @ 2021-03-24 0:52 UTC (permalink / raw) To: Geliang Tang; +Cc: mptcp, mptcp [-- Attachment #1: Type: text/plain, Size: 8386 bytes --] On Tue, 23 Mar 2021, Geliang Tang wrote: > Hi Mat, > > Mat Martineau <mathew.j.martineau@linux.intel.com> 于2021年3月23日周二 上午7:40写道: >> >> On Mon, 22 Mar 2021, Geliang Tang wrote: >> >>> This patch added a new member csum in struct mptcp_options_received. In >>> mptcp_parse_option, parse the checksum value from the receiving DSS, and >>> save it in mp_opt->csum. In mptcp_incoming_options, pass it to >>> mpext->csum. >>> >>> In validate_mapping, use the new function validate_dss_csum to validata >>> the DSS checksum. >>> >>> In validate_dss_csum, if the data has been split in different packets, >>> skip validating. >>> >>> Signed-off-by: Geliang Tang <geliangtang@gmail.com> >>> --- >>> net/mptcp/options.c | 13 +++++++++++-- >>> net/mptcp/protocol.h | 1 + >>> net/mptcp/subflow.c | 37 +++++++++++++++++++++++++++++++++++++ >>> 3 files changed, 49 insertions(+), 2 deletions(-) >>> >>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c >>> index 69eb15ef9385..ed89f6c2ed49 100644 >>> --- a/net/mptcp/options.c >>> +++ b/net/mptcp/options.c >>> @@ -206,9 +206,14 @@ static void mptcp_parse_option(const struct sk_buff *skb, >>> mp_opt->data_len = get_unaligned_be16(ptr); >>> ptr += 2; >>> >>> - pr_debug("data_seq=%llu subflow_seq=%u data_len=%u", >>> + if (opsize == expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM) { >> >> Now that more of the checksum code has been added, I think that >> expected_opsize should be set to the exact value that is needed - either >> expect the checksum, or don't expect the checksum. >> >> RFC 6824 said: "If a checksum is present, but its use had not been >> negotiated in the MP_CAPABLE handshake, the checksum field MUST be >> ignored." >> >> RFC 8684 says: "If a checksum is present but its use had >> not been negotiated in the MP_CAPABLE handshake, the receiver MUST >> close the subflow with a RST, as it is not behaving as negotiated. >> If a checksum is not present when its use has been negotiated, the >> receiver MUST close the subflow with a RST, as it is considered >> broken." >> >> There's some old RFC 6824-based code earlier in the function: >> >> if (opsize != expected_opsize && >> opsize != expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM) >> break; >> >> That needs to be changed to: >> >> if (opsize != expected_opsize) >> break; >> >> and expected_opsize should include TCPOLEN_MPTCP_DSS_CHECKSUM only if the >> checksum is enabled. >> >>> + mp_opt->csum = get_unaligned_be16(ptr); >>> + ptr += 2; >>> + } >>> + >>> + pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%u", >>> mp_opt->data_seq, mp_opt->subflow_seq, >>> - mp_opt->data_len); >>> + mp_opt->data_len, mp_opt->csum); >>> } >>> >>> break; >>> @@ -339,6 +344,7 @@ void mptcp_get_options(const struct sk_buff *skb, >>> mp_opt->mp_prio = 0; >>> mp_opt->reset = 0; >>> mp_opt->csum_reqd = 0; >>> + mp_opt->csum = 0; >>> >>> length = (th->doff * 4) - sizeof(struct tcphdr); >>> ptr = (const unsigned char *)(th + 1); >>> @@ -1124,6 +1130,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) >>> } >>> mpext->data_len = mp_opt.data_len; >>> mpext->use_map = 1; >>> + >>> + if (READ_ONCE(msk->csum_reqd)) >>> + mpext->csum = mp_opt.csum; >>> } >>> } >>> >>> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h >>> index f62cea8635f0..51ef3173a2e5 100644 >>> --- a/net/mptcp/protocol.h >>> +++ b/net/mptcp/protocol.h >>> @@ -123,6 +123,7 @@ struct mptcp_options_received { >>> u64 data_seq; >>> u32 subflow_seq; >>> u16 data_len; >>> + u16 csum; >>> u16 mp_capable : 1, >>> mp_join : 1, >>> fastclose : 1, >>> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c >>> index 9fec1a273100..2eeea7d527f0 100644 >>> --- a/net/mptcp/subflow.c >>> +++ b/net/mptcp/subflow.c >>> @@ -799,10 +799,45 @@ static bool skb_is_fully_mapped(struct sock *ssk, struct sk_buff *skb) >>> mptcp_subflow_get_map_offset(subflow); >>> } >>> >>> +static bool validate_dss_csum(struct sock *ssk, struct sk_buff *skb) >>> +{ >>> + struct csum_pseudo_header header; >>> + struct mptcp_ext *mpext; >>> + __wsum csum; >>> + >>> + if (!skb) >>> + goto out; >>> + >>> + mpext = mptcp_get_ext(skb); >>> + if (!mpext || !mpext->use_map || !mpext->csum || >>> + mpext->data_len != skb->len) >>> + goto out; >>> + >>> + header.data_seq = mpext->data_seq; >>> + header.subflow_seq = mpext->subflow_seq; >>> + header.data_len = mpext->data_len; >>> + header.csum = mpext->csum; >>> + >>> + csum = skb_checksum(skb, 0, skb->len, 0); >> >> The checksum isn't calculated using the data from a single skb, it >> requires the complete reassembled data for the current mapping. If we're >> lucky, GRO has placed everything in one skb. But that can't be assumed. >> >> The checksum can be calculated incrementally as skbs arrive, but checksum >> verification will require changes to data reassembly and MPTCP-level >> acknowledgements, and will delay movement of data to the msk until the >> checksum is verified. Also review my comments on the MP_FAIL RFC patch: > > I need some help here. > > How can I get the reassembled data for the current mapping? And in which > function to calculate the skbs checksum and where to verify them? Could > you please give me more detail? > Look at __mptcp_mvoe_skbs_from_subflow() - the skbs will arrive in ssk->sk_receive_queue. The way the rx code works now, it is fairly aggressive about moving data to the msk as quickly as possible. There will need to be a check to see if checksums are enabled, delaying the call to __mptcp_move_skb() until enough data is available in ssk->sk_receive_queue for the full mapping (ssk->map_data_len), then validating the checksum for the pseudoheader and the full mapping, and finally moving the skbs covered by that mapping. The data covered by the checksum might not align with the skbs, so the code will have to make sure it is only using the data with sequence numbers in the range required by the mapping. Delaying __mptcp_move_skb() will also delay changes to msk->ack_seq, which is a good thing: that will mean the data is not acked until the checksum is validated. Does that give a good place to start? The exact place to calculate the checksum isn't immediately obvious - might be up the call stack from where __mptcp_move_skb() is called. Mat > >> >> https://lists.01.org/hyperkitty/list/mptcp@lists.01.org/message/KSEEB5Q4ND3GKOW7S3FZ32PHCWWON5QC/ >> >> >> Thanks for the patch set! >> >> Mat >> >> >>> + csum = csum_partial(&header, sizeof(header), csum); >>> + >>> + if (csum_fold(csum)) { >>> + pr_err("DSS checksum error! data_seq=%llu subflow_seq=%u data_len=%u csum=%u %u", >>> + header.data_seq, header.subflow_seq, header.data_len, >>> + header.csum, csum_fold(csum)); >>> + >>> + return false; >>> + } >>> + >>> +out: >>> + return true; >>> +} >>> + >>> static bool validate_mapping(struct sock *ssk, struct sk_buff *skb) >>> { >>> struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); >>> u32 ssn = tcp_sk(ssk)->copied_seq - subflow->ssn_offset; >>> + struct mptcp_sock *msk = mptcp_sk(subflow->conn); >>> >>> if (unlikely(before(ssn, subflow->map_subflow_seq))) { >>> /* Mapping covers data later in the subflow stream, >>> @@ -817,6 +852,8 @@ static bool validate_mapping(struct sock *ssk, struct sk_buff *skb) >>> warn_bad_map(subflow, ssn + skb->len); >>> return false; >>> } >>> + if (READ_ONCE(msk->csum_reqd)) >>> + validate_dss_csum(ssk, skb); >>> return true; >>> } >>> >>> -- >>> 2.30.2 >> >> -- >> Mat Martineau >> Intel > -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP] [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 6/6] mptcp: add trace event for DSS checksum Geliang Tang 2021-03-22 23:40 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Mat Martineau @ 2021-03-23 10:37 ` Paolo Abeni 2 siblings, 0 replies; 21+ messages in thread From: Paolo Abeni @ 2021-03-23 10:37 UTC (permalink / raw) To: Geliang Tang, mptcp, mptcp On Mon, 2021-03-22 at 19:37 +0800, Geliang Tang wrote: > This patch added a new member csum in struct mptcp_options_received. In > mptcp_parse_option, parse the checksum value from the receiving DSS, and > save it in mp_opt->csum. In mptcp_incoming_options, pass it to > mpext->csum. > > In validate_mapping, use the new function validate_dss_csum to validata > the DSS checksum. > > In validate_dss_csum, if the data has been split in different packets, > skip validating. > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > --- > net/mptcp/options.c | 13 +++++++++++-- > net/mptcp/protocol.h | 1 + > net/mptcp/subflow.c | 37 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 49 insertions(+), 2 deletions(-) > > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > index 69eb15ef9385..ed89f6c2ed49 100644 > --- a/net/mptcp/options.c > +++ b/net/mptcp/options.c > @@ -206,9 +206,14 @@ static void mptcp_parse_option(const struct sk_buff *skb, > mp_opt->data_len = get_unaligned_be16(ptr); > ptr += 2; > > - pr_debug("data_seq=%llu subflow_seq=%u data_len=%u", > + if (opsize == expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM) { > + mp_opt->csum = get_unaligned_be16(ptr); > + ptr += 2; > + } > + > + pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%u", > mp_opt->data_seq, mp_opt->subflow_seq, > - mp_opt->data_len); > + mp_opt->data_len, mp_opt->csum); > } > > break; > @@ -339,6 +344,7 @@ void mptcp_get_options(const struct sk_buff *skb, > mp_opt->mp_prio = 0; > mp_opt->reset = 0; > mp_opt->csum_reqd = 0; > + mp_opt->csum = 0; > > length = (th->doff * 4) - sizeof(struct tcphdr); > ptr = (const unsigned char *)(th + 1); > @@ -1124,6 +1130,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) > } > mpext->data_len = mp_opt.data_len; > mpext->use_map = 1; > + > + if (READ_ONCE(msk->csum_reqd)) > + mpext->csum = mp_opt.csum; > } > } > > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > index f62cea8635f0..51ef3173a2e5 100644 > --- a/net/mptcp/protocol.h > +++ b/net/mptcp/protocol.h > @@ -123,6 +123,7 @@ struct mptcp_options_received { > u64 data_seq; > u32 subflow_seq; > u16 data_len; > + u16 csum; > u16 mp_capable : 1, > mp_join : 1, > fastclose : 1, > diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c > index 9fec1a273100..2eeea7d527f0 100644 > --- a/net/mptcp/subflow.c > +++ b/net/mptcp/subflow.c > @@ -799,10 +799,45 @@ static bool skb_is_fully_mapped(struct sock *ssk, struct sk_buff *skb) > mptcp_subflow_get_map_offset(subflow); > } > > +static bool validate_dss_csum(struct sock *ssk, struct sk_buff *skb) > +{ > + struct csum_pseudo_header header; > + struct mptcp_ext *mpext; > + __wsum csum; > + > + if (!skb) > + goto out; > + > + mpext = mptcp_get_ext(skb); > + if (!mpext || !mpext->use_map || !mpext->csum || > + mpext->data_len != skb->len) > + goto out; > + > + header.data_seq = mpext->data_seq; > + header.subflow_seq = mpext->subflow_seq; > + header.data_len = mpext->data_len; > + header.csum = mpext->csum; > + > + csum = skb_checksum(skb, 0, skb->len, 0); > + csum = csum_partial(&header, sizeof(header), csum); > + > + if (csum_fold(csum)) { > + pr_err("DSS checksum error! data_seq=%llu subflow_seq=%u data_len=%u csum=%u %u", > + header.data_seq, header.subflow_seq, header.data_len, > + header.csum, csum_fold(csum)); Here we likely need to increment a new mib counter, and avoid any printk, otherwise an evil peer could easily DoS a server. /P ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Geliang Tang @ 2021-03-22 23:10 ` Mat Martineau 2021-03-23 10:22 ` [MPTCP] " Paolo Abeni 2021-03-23 17:07 ` [MPTCP] " Paolo Abeni 2 siblings, 1 reply; 21+ messages in thread From: Mat Martineau @ 2021-03-22 23:10 UTC (permalink / raw) To: Geliang Tang; +Cc: mptcp, mptcp On Mon, 22 Mar 2021, Geliang Tang wrote: > In mptcp_established_options_dss, use the new function > mptcp_generate_dss_csum to generate the DSS checksum value. > > In mptcp_write_options, send out DSS with the checksum value. > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > --- > include/net/mptcp.h | 1 + > net/mptcp/options.c | 41 ++++++++++++++++++++++++++++++++++++++--- > net/mptcp/protocol.h | 7 +++++++ > 3 files changed, 46 insertions(+), 3 deletions(-) > > diff --git a/include/net/mptcp.h b/include/net/mptcp.h > index 36fb6907aa6f..869a6d98a72e 100644 > --- a/include/net/mptcp.h > +++ b/include/net/mptcp.h > @@ -32,6 +32,7 @@ struct mptcp_ext { > frozen:1, > reset_transient:1; > u8 reset_reason:4; > + u16 csum; > }; > > #define MPTCP_RM_IDS_MAX 8 > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > index bdced173edff..69eb15ef9385 100644 > --- a/net/mptcp/options.c > +++ b/net/mptcp/options.c > @@ -521,6 +521,30 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow, > } > } > > +static u16 mptcp_generate_dss_csum(struct sk_buff *skb) > +{ > + struct csum_pseudo_header header; > + struct mptcp_ext *mpext; > + __wsum csum; > + > + if (!skb) > + return 0; > + > + mpext = mptcp_get_ext(skb); > + if (!mpext || !mpext->use_map) > + return 0; > + > + header.data_seq = mpext->data_seq; > + header.subflow_seq = mpext->subflow_seq; > + header.data_len = mpext->data_len; > + header.csum = 0; > + > + csum = skb_checksum(skb, 0, skb->len, 0); > + csum = csum_partial(&header, sizeof(header), csum); > + > + return csum_fold(csum); > +} > + > static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, > bool snd_data_fin_enable, > unsigned int *size, > @@ -544,8 +568,11 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, > > remaining -= map_size; > dss_size = map_size; > - if (mpext) > + if (mpext) { > + if (msk->csum_reqd) > + mpext->csum = mptcp_generate_dss_csum(skb); > opts->ext_copy = *mpext; > + } > > if (skb && snd_data_fin_enable) > mptcp_write_data_fin(subflow, skb, &opts->ext_copy); > @@ -1304,6 +1331,9 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, > flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64; > if (mpext->data_fin) > flags |= MPTCP_DSS_DATA_FIN; > + > + if (mpext->csum) Instead of relying on a non-zero mpext->csum, what about using opts->csum_enabled instead? (Would have to make sure that flag is set in mptcp_out_options for data packets too) This would be more compatible with hardware offload if that gets added later. > + len += TCPOLEN_MPTCP_DSS_CHECKSUM; > } > > *ptr++ = mptcp_option(MPTCPOPT_DSS, len, 0, flags); > @@ -1323,8 +1353,13 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, > ptr += 2; > put_unaligned_be32(mpext->subflow_seq, ptr); > ptr += 1; > - put_unaligned_be32(mpext->data_len << 16 | > - TCPOPT_NOP << 8 | TCPOPT_NOP, ptr); > + if (mpext->csum) { Same as above, want to test the same opts->csum_enabled value. > + put_unaligned_be32(mpext->data_len << 16 | > + mpext->csum, ptr); > + } else { > + put_unaligned_be32(mpext->data_len << 16 | > + TCPOPT_NOP << 8 | TCPOPT_NOP, ptr); > + } > } > } > > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > index 4fc4871595ef..f62cea8635f0 100644 > --- a/net/mptcp/protocol.h > +++ b/net/mptcp/protocol.h > @@ -333,6 +333,13 @@ static inline struct mptcp_data_frag *mptcp_rtx_head(const struct sock *sk) > return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list); > } > > +struct csum_pseudo_header { > + u64 data_seq; > + u32 subflow_seq; > + u16 data_len; > + u16 csum; > +}; > + > struct mptcp_subflow_request_sock { > struct tcp_request_sock sk; > u16 mp_capable : 1, > -- > 2.30.2 -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP] Re: [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending 2021-03-22 23:10 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Mat Martineau @ 2021-03-23 10:22 ` Paolo Abeni 2021-03-24 1:07 ` Mat Martineau 0 siblings, 1 reply; 21+ messages in thread From: Paolo Abeni @ 2021-03-23 10:22 UTC (permalink / raw) To: Mat Martineau, Geliang Tang; +Cc: mptcp, mptcp On Mon, 2021-03-22 at 16:10 -0700, Mat Martineau wrote: > On Mon, 22 Mar 2021, Geliang Tang wrote: > > > In mptcp_established_options_dss, use the new function > > mptcp_generate_dss_csum to generate the DSS checksum value. > > > > In mptcp_write_options, send out DSS with the checksum value. > > > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > > --- > > include/net/mptcp.h | 1 + > > net/mptcp/options.c | 41 ++++++++++++++++++++++++++++++++++++++--- > > net/mptcp/protocol.h | 7 +++++++ > > 3 files changed, 46 insertions(+), 3 deletions(-) > > > > diff --git a/include/net/mptcp.h b/include/net/mptcp.h > > index 36fb6907aa6f..869a6d98a72e 100644 > > --- a/include/net/mptcp.h > > +++ b/include/net/mptcp.h > > @@ -32,6 +32,7 @@ struct mptcp_ext { > > frozen:1, > > reset_transient:1; > > u8 reset_reason:4; > > + u16 csum; > > }; > > > > #define MPTCP_RM_IDS_MAX 8 > > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > > index bdced173edff..69eb15ef9385 100644 > > --- a/net/mptcp/options.c > > +++ b/net/mptcp/options.c > > @@ -521,6 +521,30 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow, > > } > > } > > > > +static u16 mptcp_generate_dss_csum(struct sk_buff *skb) > > +{ > > + struct csum_pseudo_header header; > > + struct mptcp_ext *mpext; > > + __wsum csum; > > + > > + if (!skb) > > + return 0; > > + > > + mpext = mptcp_get_ext(skb); > > + if (!mpext || !mpext->use_map) > > + return 0; > > + > > + header.data_seq = mpext->data_seq; > > + header.subflow_seq = mpext->subflow_seq; > > + header.data_len = mpext->data_len; > > + header.csum = 0; > > + > > + csum = skb_checksum(skb, 0, skb->len, 0); > > + csum = csum_partial(&header, sizeof(header), csum); > > + > > + return csum_fold(csum); > > +} > > + > > static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, > > bool snd_data_fin_enable, > > unsigned int *size, > > @@ -544,8 +568,11 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, > > > > remaining -= map_size; > > dss_size = map_size; > > - if (mpext) > > + if (mpext) { > > + if (msk->csum_reqd) > > + mpext->csum = mptcp_generate_dss_csum(skb); > > opts->ext_copy = *mpext; > > + } > > > > if (skb && snd_data_fin_enable) > > mptcp_write_data_fin(subflow, skb, &opts->ext_copy); > > @@ -1304,6 +1331,9 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, > > flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64; > > if (mpext->data_fin) > > flags |= MPTCP_DSS_DATA_FIN; > > + > > + if (mpext->csum) > > Instead of relying on a non-zero mpext->csum, what about using > opts->csum_enabled instead? (Would have to make sure that flag is set in > mptcp_out_options for data packets too) > > This would be more compatible with hardware offload if that gets added > later. Side note, not sure if already discussed in the last mtgs, xmit csum offload looks doable, togethar with TSO !?! The nic have all the pieces in place/available to compute it... /P ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP] Re: [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending 2021-03-23 10:22 ` [MPTCP] " Paolo Abeni @ 2021-03-24 1:07 ` Mat Martineau 0 siblings, 0 replies; 21+ messages in thread From: Mat Martineau @ 2021-03-24 1:07 UTC (permalink / raw) To: Paolo Abeni; +Cc: Geliang Tang, mptcp, mptcp On Tue, 23 Mar 2021, Paolo Abeni wrote: > On Mon, 2021-03-22 at 16:10 -0700, Mat Martineau wrote: >> On Mon, 22 Mar 2021, Geliang Tang wrote: >> >>> In mptcp_established_options_dss, use the new function >>> mptcp_generate_dss_csum to generate the DSS checksum value. >>> >>> In mptcp_write_options, send out DSS with the checksum value. >>> >>> Signed-off-by: Geliang Tang <geliangtang@gmail.com> >>> --- >>> include/net/mptcp.h | 1 + >>> net/mptcp/options.c | 41 ++++++++++++++++++++++++++++++++++++++--- >>> net/mptcp/protocol.h | 7 +++++++ >>> 3 files changed, 46 insertions(+), 3 deletions(-) >>> >>> diff --git a/include/net/mptcp.h b/include/net/mptcp.h >>> index 36fb6907aa6f..869a6d98a72e 100644 >>> --- a/include/net/mptcp.h >>> +++ b/include/net/mptcp.h >>> @@ -32,6 +32,7 @@ struct mptcp_ext { >>> frozen:1, >>> reset_transient:1; >>> u8 reset_reason:4; >>> + u16 csum; >>> }; >>> >>> #define MPTCP_RM_IDS_MAX 8 >>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c >>> index bdced173edff..69eb15ef9385 100644 >>> --- a/net/mptcp/options.c >>> +++ b/net/mptcp/options.c >>> @@ -521,6 +521,30 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow, >>> } >>> } >>> >>> +static u16 mptcp_generate_dss_csum(struct sk_buff *skb) >>> +{ >>> + struct csum_pseudo_header header; >>> + struct mptcp_ext *mpext; >>> + __wsum csum; >>> + >>> + if (!skb) >>> + return 0; >>> + >>> + mpext = mptcp_get_ext(skb); >>> + if (!mpext || !mpext->use_map) >>> + return 0; >>> + >>> + header.data_seq = mpext->data_seq; >>> + header.subflow_seq = mpext->subflow_seq; >>> + header.data_len = mpext->data_len; >>> + header.csum = 0; >>> + >>> + csum = skb_checksum(skb, 0, skb->len, 0); >>> + csum = csum_partial(&header, sizeof(header), csum); >>> + >>> + return csum_fold(csum); >>> +} >>> + >>> static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, >>> bool snd_data_fin_enable, >>> unsigned int *size, >>> @@ -544,8 +568,11 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, >>> >>> remaining -= map_size; >>> dss_size = map_size; >>> - if (mpext) >>> + if (mpext) { >>> + if (msk->csum_reqd) >>> + mpext->csum = mptcp_generate_dss_csum(skb); >>> opts->ext_copy = *mpext; >>> + } >>> >>> if (skb && snd_data_fin_enable) >>> mptcp_write_data_fin(subflow, skb, &opts->ext_copy); >>> @@ -1304,6 +1331,9 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, >>> flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64; >>> if (mpext->data_fin) >>> flags |= MPTCP_DSS_DATA_FIN; >>> + >>> + if (mpext->csum) >> >> Instead of relying on a non-zero mpext->csum, what about using >> opts->csum_enabled instead? (Would have to make sure that flag is set in >> mptcp_out_options for data packets too) >> >> This would be more compatible with hardware offload if that gets added >> later. > > Side note, not sure if already discussed in the last mtgs, xmit csum > offload looks doable, togethar with TSO !?! The nic have all the pieces > in place/available to compute it... > Yes, I did talk about this with one of the NIC maintainers and the tx side seemed doable. See notes near the end of https://lore.kernel.org/mptcp/e308928e-872d-a7b3-2b0b-751572915de2@tessares.net/ -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP] [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Geliang Tang 2021-03-22 23:10 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Mat Martineau @ 2021-03-23 17:07 ` Paolo Abeni 2 siblings, 0 replies; 21+ messages in thread From: Paolo Abeni @ 2021-03-23 17:07 UTC (permalink / raw) To: Geliang Tang, mptcp, mptcp On Mon, 2021-03-22 at 19:37 +0800, Geliang Tang wrote: > In mptcp_established_options_dss, use the new function > mptcp_generate_dss_csum to generate the DSS checksum value. > > In mptcp_write_options, send out DSS with the checksum value. > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > --- > include/net/mptcp.h | 1 + > net/mptcp/options.c | 41 ++++++++++++++++++++++++++++++++++++++--- > net/mptcp/protocol.h | 7 +++++++ > 3 files changed, 46 insertions(+), 3 deletions(-) > > diff --git a/include/net/mptcp.h b/include/net/mptcp.h > index 36fb6907aa6f..869a6d98a72e 100644 > --- a/include/net/mptcp.h > +++ b/include/net/mptcp.h > @@ -32,6 +32,7 @@ struct mptcp_ext { > frozen:1, > reset_transient:1; > u8 reset_reason:4; > + u16 csum; > }; > > #define MPTCP_RM_IDS_MAX 8 > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > index bdced173edff..69eb15ef9385 100644 > --- a/net/mptcp/options.c > +++ b/net/mptcp/options.c > @@ -521,6 +521,30 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow, > } > } > > +static u16 mptcp_generate_dss_csum(struct sk_buff *skb) > +{ > + struct csum_pseudo_header header; > + struct mptcp_ext *mpext; > + __wsum csum; > + > + if (!skb) > + return 0; > + > + mpext = mptcp_get_ext(skb); > + if (!mpext || !mpext->use_map) > + return 0; > + > + header.data_seq = mpext->data_seq; > + header.subflow_seq = mpext->subflow_seq; > + header.data_len = mpext->data_len; > + header.csum = 0; > + > + csum = skb_checksum(skb, 0, skb->len, 0); > + csum = csum_partial(&header, sizeof(header), csum); > + > + return csum_fold(csum); > +} > + > static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, > bool snd_data_fin_enable, > unsigned int *size, > @@ -544,8 +568,11 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, > > remaining -= map_size; > dss_size = map_size; > - if (mpext) > + if (mpext) { > + if (msk->csum_reqd) > + mpext->csum = mptcp_generate_dss_csum(skb); > opts->ext_copy = *mpext; > + } > > if (skb && snd_data_fin_enable) > mptcp_write_data_fin(subflow, skb, &opts->ext_copy); > @@ -1304,6 +1331,9 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, > flags |= MPTCP_DSS_HAS_MAP | MPTCP_DSS_DSN64; > if (mpext->data_fin) > flags |= MPTCP_DSS_DATA_FIN; > + > + if (mpext->csum) > + len += TCPOLEN_MPTCP_DSS_CHECKSUM; > } > > *ptr++ = mptcp_option(MPTCPOPT_DSS, len, 0, flags); If csum is enabled, we additionally need to insert the csum even in the MPC+data packets. In a similar way, we need to extract the csum value from MPC+data packets in the input path, when csum is enabled (in the next patch) /P ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Geliang Tang @ 2021-03-22 22:52 ` Mat Martineau 2021-03-23 10:12 ` [MPTCP] " Paolo Abeni 2 siblings, 0 replies; 21+ messages in thread From: Mat Martineau @ 2021-03-22 22:52 UTC (permalink / raw) To: Geliang Tang; +Cc: mptcp, mptcp On Mon, 22 Mar 2021, Geliang Tang wrote: > This patch added a new flag csum_reqd in struct mptcp_options_received, if > the flag MPTCP_CAP_CHECKSUM_REQD is set in the receiving MP_CAPABLE > suboption, set this csum_reqd flag. > > It also added another new csum_reqd member in struct mptcp_sock too, if the > csum_reqd flag in mptcp_options_received is set, set this member to true. > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > --- > net/mptcp/options.c | 8 +++++--- > net/mptcp/protocol.c | 1 + > net/mptcp/protocol.h | 2 ++ > net/mptcp/subflow.c | 4 ++++ > 4 files changed, 12 insertions(+), 3 deletions(-) > > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > index f45bebb923dc..bdced173edff 100644 > --- a/net/mptcp/options.c > +++ b/net/mptcp/options.c > @@ -69,11 +69,9 @@ static void mptcp_parse_option(const struct sk_buff *skb, > * "If a checksum is not present when its use has been > * negotiated, the receiver MUST close the subflow with a RST as > * it is considered broken." > - * > - * We don't implement DSS checksum - fall back to TCP. > */ > if (flags & MPTCP_CAP_CHECKSUM_REQD) > - break; > + mp_opt->csum_reqd = 1; > > mp_opt->mp_capable = 1; > if (opsize >= TCPOLEN_MPTCP_MPC_SYNACK) { > @@ -340,6 +338,7 @@ void mptcp_get_options(const struct sk_buff *skb, > mp_opt->dss = 0; > mp_opt->mp_prio = 0; > mp_opt->reset = 0; > + mp_opt->csum_reqd = 0; > > length = (th->doff * 4) - sizeof(struct tcphdr); > ptr = (const unsigned char *)(th + 1); > @@ -1013,6 +1012,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) > mptcp_schedule_work((struct sock *)msk); > } > > + if (mp_opt.csum_reqd) > + WRITE_ONCE(msk->csum_reqd, true); > + Is this assignment needed here? It looks like setting msk->csum_reqd in subflow_finish_connect() and subflow_syn_recv_sock() should cover both outgoing and incoming connections. Thanks, Mat > if (mp_opt.add_addr && add_addr_hmac_valid(msk, &mp_opt)) { > if (!mp_opt.echo) { > mptcp_pm_add_addr_received(msk, &mp_opt.addr); > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c > index 9d7e7e13fba8..94c3568c7a60 100644 > --- a/net/mptcp/protocol.c > +++ b/net/mptcp/protocol.c > @@ -2364,6 +2364,7 @@ static int __mptcp_init_sock(struct sock *sk) > msk->ack_hint = NULL; > msk->first = NULL; > inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss; > + WRITE_ONCE(msk->csum_reqd, mptcp_is_checksum_enabled(sock_net(sk))); > > mptcp_pm_data_init(msk); > > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > index 14f1e2fd3c08..4fc4871595ef 100644 > --- a/net/mptcp/protocol.h > +++ b/net/mptcp/protocol.h > @@ -132,6 +132,7 @@ struct mptcp_options_received { > rm_addr : 1, > mp_prio : 1, > echo : 1, > + csum_reqd : 1, > backup : 1; > u32 token; > u32 nonce; > @@ -233,6 +234,7 @@ struct mptcp_sock { > bool snd_data_fin_enable; > bool rcv_fastclose; > bool use_64bit_ack; /* Set when we received a 64-bit DSN */ > + bool csum_reqd; > spinlock_t join_list_lock; > struct sock *ack_hint; > struct work_struct work; > diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c > index e2e9cc34713d..9fec1a273100 100644 > --- a/net/mptcp/subflow.c > +++ b/net/mptcp/subflow.c > @@ -403,6 +403,8 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) > goto fallback; > } > > + if (mp_opt.csum_reqd) > + WRITE_ONCE(mptcp_sk(parent)->csum_reqd, true); > subflow->mp_capable = 1; > subflow->can_ack = 1; > subflow->remote_key = mp_opt.sndr_key; > @@ -643,6 +645,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, > new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req); > if (!new_msk) > fallback = true; > + else if (mp_opt.csum_reqd) > + WRITE_ONCE(mptcp_sk(new_msk)->csum_reqd, true); > } else if (subflow_req->mp_join) { > mptcp_get_options(skb, &mp_opt); > if (!mp_opt.mp_join || !subflow_hmac_valid(req, &mp_opt) || > -- > 2.30.2 -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP] [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Geliang Tang 2021-03-22 22:52 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Mat Martineau @ 2021-03-23 10:12 ` Paolo Abeni 2021-03-24 1:05 ` Mat Martineau 2 siblings, 1 reply; 21+ messages in thread From: Paolo Abeni @ 2021-03-23 10:12 UTC (permalink / raw) To: Geliang Tang, mptcp, mptcp, Florian Westphal On Mon, 2021-03-22 at 19:37 +0800, Geliang Tang wrote: > This patch added a new flag csum_reqd in struct mptcp_options_received, if > the flag MPTCP_CAP_CHECKSUM_REQD is set in the receiving MP_CAPABLE > suboption, set this csum_reqd flag. > > It also added another new csum_reqd member in struct mptcp_sock too, if the > csum_reqd flag in mptcp_options_received is set, set this member to true. > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > --- > net/mptcp/options.c | 8 +++++--- > net/mptcp/protocol.c | 1 + > net/mptcp/protocol.h | 2 ++ > net/mptcp/subflow.c | 4 ++++ > 4 files changed, 12 insertions(+), 3 deletions(-) > > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > index f45bebb923dc..bdced173edff 100644 > --- a/net/mptcp/options.c > +++ b/net/mptcp/options.c > @@ -69,11 +69,9 @@ static void mptcp_parse_option(const struct sk_buff *skb, > * "If a checksum is not present when its use has been > * negotiated, the receiver MUST close the subflow with a RST as > * it is considered broken." > - * > - * We don't implement DSS checksum - fall back to TCP. > */ > if (flags & MPTCP_CAP_CHECKSUM_REQD) > - break; > + mp_opt->csum_reqd = 1; > > mp_opt->mp_capable = 1; > if (opsize >= TCPOLEN_MPTCP_MPC_SYNACK) { > @@ -340,6 +338,7 @@ void mptcp_get_options(const struct sk_buff *skb, > mp_opt->dss = 0; > mp_opt->mp_prio = 0; > mp_opt->reset = 0; > + mp_opt->csum_reqd = 0; > > length = (th->doff * 4) - sizeof(struct tcphdr); > ptr = (const unsigned char *)(th + 1); > @@ -1013,6 +1012,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) > mptcp_schedule_work((struct sock *)msk); > } > > + if (mp_opt.csum_reqd) > + WRITE_ONCE(msk->csum_reqd, true); > + > if (mp_opt.add_addr && add_addr_hmac_valid(msk, &mp_opt)) { > if (!mp_opt.echo) { > mptcp_pm_add_addr_received(msk, &mp_opt.addr); > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c > index 9d7e7e13fba8..94c3568c7a60 100644 > --- a/net/mptcp/protocol.c > +++ b/net/mptcp/protocol.c > @@ -2364,6 +2364,7 @@ static int __mptcp_init_sock(struct sock *sk) > msk->ack_hint = NULL; > msk->first = NULL; > inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss; > + WRITE_ONCE(msk->csum_reqd, mptcp_is_checksum_enabled(sock_net(sk))); > > mptcp_pm_data_init(msk); > > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > index 14f1e2fd3c08..4fc4871595ef 100644 > --- a/net/mptcp/protocol.h > +++ b/net/mptcp/protocol.h > @@ -132,6 +132,7 @@ struct mptcp_options_received { > rm_addr : 1, > mp_prio : 1, > echo : 1, > + csum_reqd : 1, > backup : 1; > u32 token; > u32 nonce; > @@ -233,6 +234,7 @@ struct mptcp_sock { > bool snd_data_fin_enable; > bool rcv_fastclose; > bool use_64bit_ack; /* Set when we received a 64-bit DSN */ > + bool csum_reqd; > spinlock_t join_list_lock; > struct sock *ack_hint; > struct work_struct work; > diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c > index e2e9cc34713d..9fec1a273100 100644 > --- a/net/mptcp/subflow.c > +++ b/net/mptcp/subflow.c > @@ -403,6 +403,8 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) > goto fallback; > } > > + if (mp_opt.csum_reqd) > + WRITE_ONCE(mptcp_sk(parent)->csum_reqd, true); > subflow->mp_capable = 1; > subflow->can_ack = 1; > subflow->remote_key = mp_opt.sndr_key; > @@ -643,6 +645,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, > new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req); > if (!new_msk) > fallback = true; > + else if (mp_opt.csum_reqd) > + WRITE_ONCE(mptcp_sk(new_msk)->csum_reqd, true); I think this chunk would be better located inside mptcp_sk_clone(). @Mat, @Florian, slighly related: if we do the assignment there, the WRITE_ONCE will not be required, right? - since that functions runs under msk lock. We already have a few WRITE_ONCE there which are likely not really needed... /P ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP] [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields 2021-03-23 10:12 ` [MPTCP] " Paolo Abeni @ 2021-03-24 1:05 ` Mat Martineau 0 siblings, 0 replies; 21+ messages in thread From: Mat Martineau @ 2021-03-24 1:05 UTC (permalink / raw) To: Paolo Abeni; +Cc: Geliang Tang, mptcp, mptcp, Florian Westphal On Tue, 23 Mar 2021, Paolo Abeni wrote: > On Mon, 2021-03-22 at 19:37 +0800, Geliang Tang wrote: >> This patch added a new flag csum_reqd in struct mptcp_options_received, if >> the flag MPTCP_CAP_CHECKSUM_REQD is set in the receiving MP_CAPABLE >> suboption, set this csum_reqd flag. >> >> It also added another new csum_reqd member in struct mptcp_sock too, if the >> csum_reqd flag in mptcp_options_received is set, set this member to true. >> >> Signed-off-by: Geliang Tang <geliangtang@gmail.com> >> --- >> net/mptcp/options.c | 8 +++++--- >> net/mptcp/protocol.c | 1 + >> net/mptcp/protocol.h | 2 ++ >> net/mptcp/subflow.c | 4 ++++ >> 4 files changed, 12 insertions(+), 3 deletions(-) >> >> diff --git a/net/mptcp/options.c b/net/mptcp/options.c >> index f45bebb923dc..bdced173edff 100644 >> --- a/net/mptcp/options.c >> +++ b/net/mptcp/options.c >> @@ -69,11 +69,9 @@ static void mptcp_parse_option(const struct sk_buff *skb, >> * "If a checksum is not present when its use has been >> * negotiated, the receiver MUST close the subflow with a RST as >> * it is considered broken." >> - * >> - * We don't implement DSS checksum - fall back to TCP. >> */ >> if (flags & MPTCP_CAP_CHECKSUM_REQD) >> - break; >> + mp_opt->csum_reqd = 1; >> >> mp_opt->mp_capable = 1; >> if (opsize >= TCPOLEN_MPTCP_MPC_SYNACK) { >> @@ -340,6 +338,7 @@ void mptcp_get_options(const struct sk_buff *skb, >> mp_opt->dss = 0; >> mp_opt->mp_prio = 0; >> mp_opt->reset = 0; >> + mp_opt->csum_reqd = 0; >> >> length = (th->doff * 4) - sizeof(struct tcphdr); >> ptr = (const unsigned char *)(th + 1); >> @@ -1013,6 +1012,9 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) >> mptcp_schedule_work((struct sock *)msk); >> } >> >> + if (mp_opt.csum_reqd) >> + WRITE_ONCE(msk->csum_reqd, true); >> + >> if (mp_opt.add_addr && add_addr_hmac_valid(msk, &mp_opt)) { >> if (!mp_opt.echo) { >> mptcp_pm_add_addr_received(msk, &mp_opt.addr); >> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c >> index 9d7e7e13fba8..94c3568c7a60 100644 >> --- a/net/mptcp/protocol.c >> +++ b/net/mptcp/protocol.c >> @@ -2364,6 +2364,7 @@ static int __mptcp_init_sock(struct sock *sk) >> msk->ack_hint = NULL; >> msk->first = NULL; >> inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss; >> + WRITE_ONCE(msk->csum_reqd, mptcp_is_checksum_enabled(sock_net(sk))); >> >> mptcp_pm_data_init(msk); >> >> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h >> index 14f1e2fd3c08..4fc4871595ef 100644 >> --- a/net/mptcp/protocol.h >> +++ b/net/mptcp/protocol.h >> @@ -132,6 +132,7 @@ struct mptcp_options_received { >> rm_addr : 1, >> mp_prio : 1, >> echo : 1, >> + csum_reqd : 1, >> backup : 1; >> u32 token; >> u32 nonce; >> @@ -233,6 +234,7 @@ struct mptcp_sock { >> bool snd_data_fin_enable; >> bool rcv_fastclose; >> bool use_64bit_ack; /* Set when we received a 64-bit DSN */ >> + bool csum_reqd; >> spinlock_t join_list_lock; >> struct sock *ack_hint; >> struct work_struct work; >> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c >> index e2e9cc34713d..9fec1a273100 100644 >> --- a/net/mptcp/subflow.c >> +++ b/net/mptcp/subflow.c >> @@ -403,6 +403,8 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) >> goto fallback; >> } >> >> + if (mp_opt.csum_reqd) >> + WRITE_ONCE(mptcp_sk(parent)->csum_reqd, true); >> subflow->mp_capable = 1; >> subflow->can_ack = 1; >> subflow->remote_key = mp_opt.sndr_key; >> @@ -643,6 +645,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, >> new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req); >> if (!new_msk) >> fallback = true; >> + else if (mp_opt.csum_reqd) >> + WRITE_ONCE(mptcp_sk(new_msk)->csum_reqd, true); > > I think this chunk would be better located inside mptcp_sk_clone(). > > @Mat, @Florian, slighly related: if we do the assignment there, the > WRITE_ONCE will not be required, right? - since that functions runs > under msk lock. We already have a few WRITE_ONCE there which are likely > not really needed... Yeah, I think it would fit well in mptcp_sk_clone(). Given that csum_reqd doesn't change after the connection starts I'm not sure WRITE_ONCE/READ_ONCE are really needed for the value, and I think the need for WRITE_ONCE is determined by the lockless readers rather than whether the writer is under msk lock (there's a recent LWN article I really should read to confirm my understanding). -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP] [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Geliang Tang @ 2021-03-23 10:41 ` Paolo Abeni 1 sibling, 0 replies; 21+ messages in thread From: Paolo Abeni @ 2021-03-23 10:41 UTC (permalink / raw) To: Geliang Tang, mptcp, mptcp On Mon, 2021-03-22 at 19:37 +0800, Geliang Tang wrote: > This patch add a new member csum_enabled in struct mptcp_out_options. > In mptcp_write_options, if this csum_enabled field is enabled, send out > the MP_CAPABLE suboption with the MPTCP_CAP_CHECKSUM_REQD flag. > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > --- > include/net/mptcp.h | 3 ++- > net/mptcp/options.c | 10 ++++++++-- > net/mptcp/protocol.h | 3 ++- > net/mptcp/subflow.c | 1 + > 4 files changed, 13 insertions(+), 4 deletions(-) > > diff --git a/include/net/mptcp.h b/include/net/mptcp.h > index 83f23774b908..36fb6907aa6f 100644 > --- a/include/net/mptcp.h > +++ b/include/net/mptcp.h > @@ -64,7 +64,8 @@ struct mptcp_out_options { > u8 join_id; > u8 backup; > u8 reset_reason:4; > - u8 reset_transient:1; > + u8 reset_transient:1, > + csum_enabled:1; > u32 nonce; > u64 thmac; > u32 token; > diff --git a/net/mptcp/options.c b/net/mptcp/options.c > index e3fcd2b0ffd7..f45bebb923dc 100644 > --- a/net/mptcp/options.c > +++ b/net/mptcp/options.c > @@ -379,6 +379,7 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, > subflow->snd_isn = TCP_SKB_CB(skb)->end_seq; > if (subflow->request_mptcp) { > opts->suboptions = OPTION_MPTCP_MPC_SYN; > + opts->csum_enabled = mptcp_is_checksum_enabled(sock_net(sk)); > *size = TCPOLEN_MPTCP_MPC_SYN; > return true; > } else if (subflow->request_join) { > @@ -464,6 +465,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb, > opts->suboptions = OPTION_MPTCP_MPC_ACK; > opts->sndr_key = subflow->local_key; > opts->rcvr_key = subflow->remote_key; > + opts->csum_enabled = mptcp_is_checksum_enabled(sock_net(sk)); Note that 'mptcp_is_checksum_enabled(sock_net(sk))' can change its value between SYN and 3rd ack, depending on user-space actions. I think it would be better 'cache' the mptcp_is_checksum_enabled(sock_net(sk)) value inside some new msk field at msk creation time (for outgoing socket), so that this will always be consistent and we could expose the 'csum requested' info to user-space via diag in a reliable way. For incoming socket, I think we could copy the 'subflow_req- >csum_enabled' into the msk. Cheers, Paolo ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options Geliang Tang @ 2021-03-22 22:22 ` Mat Martineau 2021-03-22 23:46 ` Mat Martineau 1 sibling, 1 reply; 21+ messages in thread From: Mat Martineau @ 2021-03-22 22:22 UTC (permalink / raw) To: Geliang Tang; +Cc: mptcp, mptcp On Mon, 22 Mar 2021, Geliang Tang wrote: > This patch added a new sysctl, named checksum_enabled, to control > whether DSS checksum can be enabled. > > Signed-off-by: Geliang Tang <geliangtang@gmail.com> > --- > Documentation/networking/mptcp-sysctl.rst | 8 ++++++++ > net/mptcp/ctrl.c | 14 ++++++++++++++ > net/mptcp/protocol.h | 1 + > 3 files changed, 23 insertions(+) > > diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst > index 6af0196c4297..1128e09d6c4d 100644 > --- a/Documentation/networking/mptcp-sysctl.rst > +++ b/Documentation/networking/mptcp-sysctl.rst > @@ -24,3 +24,11 @@ add_addr_timeout - INTEGER (seconds) > sysctl. > > Default: 120 > + > +checksum_enabled - INTEGER > + Control whether DSS checksum can be enabled. > + > + DSS checksum can be enabled if the value is nonzero. This is a > + per-namespace sysctl. > + > + Default: 1 In my opinion, this should default to 0 for compatibility with previous upstream kernel versions and because it sounds like checksums aren't used as much in practice. But I'm not totally committed to that - what do those of you with more MPTCP deployment experience think? Mat > diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c > index 96ba616f59bf..115cebc8c02a 100644 > --- a/net/mptcp/ctrl.c > +++ b/net/mptcp/ctrl.c > @@ -19,6 +19,7 @@ struct mptcp_pernet { > > int mptcp_enabled; > unsigned int add_addr_timeout; > + int checksum_enabled; > }; > > static struct mptcp_pernet *mptcp_get_pernet(struct net *net) > @@ -36,6 +37,11 @@ unsigned int mptcp_get_add_addr_timeout(struct net *net) > return mptcp_get_pernet(net)->add_addr_timeout; > } > > +int mptcp_is_checksum_enabled(struct net *net) > +{ > + return mptcp_get_pernet(net)->checksum_enabled; > +} > + > static struct ctl_table mptcp_sysctl_table[] = { > { > .procname = "enabled", > @@ -52,6 +58,12 @@ static struct ctl_table mptcp_sysctl_table[] = { > .mode = 0644, > .proc_handler = proc_dointvec_jiffies, > }, > + { > + .procname = "checksum_enabled", > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = proc_dointvec, > + }, > {} > }; > > @@ -59,6 +71,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) > { > pernet->mptcp_enabled = 1; > pernet->add_addr_timeout = TCP_RTO_MAX; > + pernet->checksum_enabled = 1; > } > > static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) > @@ -75,6 +88,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) > > table[0].data = &pernet->mptcp_enabled; > table[1].data = &pernet->add_addr_timeout; > + table[2].data = &pernet->checksum_enabled; > > hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table); > if (!hdr) > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > index 14f0114be17a..fd36239d8905 100644 > --- a/net/mptcp/protocol.h > +++ b/net/mptcp/protocol.h > @@ -519,6 +519,7 @@ static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *su > > int mptcp_is_enabled(struct net *net); > unsigned int mptcp_get_add_addr_timeout(struct net *net); > +int mptcp_is_checksum_enabled(struct net *net); > void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow, > struct mptcp_options_received *mp_opt); > bool mptcp_subflow_data_available(struct sock *sk); > -- > 2.30.2 -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled 2021-03-22 22:22 ` [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled Mat Martineau @ 2021-03-22 23:46 ` Mat Martineau 0 siblings, 0 replies; 21+ messages in thread From: Mat Martineau @ 2021-03-22 23:46 UTC (permalink / raw) To: Geliang Tang; +Cc: mptcp, mptcp On Mon, 22 Mar 2021, Mat Martineau wrote: > > On Mon, 22 Mar 2021, Geliang Tang wrote: > >> This patch added a new sysctl, named checksum_enabled, to control >> whether DSS checksum can be enabled. >> >> Signed-off-by: Geliang Tang <geliangtang@gmail.com> >> --- >> Documentation/networking/mptcp-sysctl.rst | 8 ++++++++ >> net/mptcp/ctrl.c | 14 ++++++++++++++ >> net/mptcp/protocol.h | 1 + >> 3 files changed, 23 insertions(+) >> >> diff --git a/Documentation/networking/mptcp-sysctl.rst >> b/Documentation/networking/mptcp-sysctl.rst >> index 6af0196c4297..1128e09d6c4d 100644 >> --- a/Documentation/networking/mptcp-sysctl.rst >> +++ b/Documentation/networking/mptcp-sysctl.rst >> @@ -24,3 +24,11 @@ add_addr_timeout - INTEGER (seconds) >> sysctl. >> >> Default: 120 >> + >> +checksum_enabled - INTEGER >> + Control whether DSS checksum can be enabled. >> + >> + DSS checksum can be enabled if the value is nonzero. This is a >> + per-namespace sysctl. >> + >> + Default: 1 > > In my opinion, this should default to 0 for compatibility with previous > upstream kernel versions and because it sounds like checksums aren't used as > much in practice. But I'm not totally committed to that - what do those of > you with more MPTCP deployment experience think? > > Mat > > >> diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c >> index 96ba616f59bf..115cebc8c02a 100644 >> --- a/net/mptcp/ctrl.c >> +++ b/net/mptcp/ctrl.c >> @@ -19,6 +19,7 @@ struct mptcp_pernet { >> >> int mptcp_enabled; >> unsigned int add_addr_timeout; >> + int checksum_enabled; >> }; >> >> static struct mptcp_pernet *mptcp_get_pernet(struct net *net) >> @@ -36,6 +37,11 @@ unsigned int mptcp_get_add_addr_timeout(struct net *net) >> return mptcp_get_pernet(net)->add_addr_timeout; >> } >> >> +int mptcp_is_checksum_enabled(struct net *net) >> +{ >> + return mptcp_get_pernet(net)->checksum_enabled; >> +} >> + One more thing, it would be good to have the checksum functionality forced off until all the code is in place. It would be more git-bisect-compatible if mptcp_is_checksum_enabled() always returns false and the incoming checksum flag is rejected until the last patch in the series. Mat >> static struct ctl_table mptcp_sysctl_table[] = { >> { >> .procname = "enabled", >> @@ -52,6 +58,12 @@ static struct ctl_table mptcp_sysctl_table[] = { >> .mode = 0644, >> .proc_handler = proc_dointvec_jiffies, >> }, >> + { >> + .procname = "checksum_enabled", >> + .maxlen = sizeof(int), >> + .mode = 0644, >> + .proc_handler = proc_dointvec, >> + }, >> {} >> }; >> >> @@ -59,6 +71,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet >> *pernet) >> { >> pernet->mptcp_enabled = 1; >> pernet->add_addr_timeout = TCP_RTO_MAX; >> + pernet->checksum_enabled = 1; >> } >> >> static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet >> *pernet) >> @@ -75,6 +88,7 @@ static int mptcp_pernet_new_table(struct net *net, struct >> mptcp_pernet *pernet) >> >> table[0].data = &pernet->mptcp_enabled; >> table[1].data = &pernet->add_addr_timeout; >> + table[2].data = &pernet->checksum_enabled; >> >> hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table); >> if (!hdr) >> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h >> index 14f0114be17a..fd36239d8905 100644 >> --- a/net/mptcp/protocol.h >> +++ b/net/mptcp/protocol.h >> @@ -519,6 +519,7 @@ static inline void mptcp_subflow_delegated_done(struct >> mptcp_subflow_context *su >> >> int mptcp_is_enabled(struct net *net); >> unsigned int mptcp_get_add_addr_timeout(struct net *net); >> +int mptcp_is_checksum_enabled(struct net *net); >> void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow, >> struct mptcp_options_received *mp_opt); >> bool mptcp_subflow_data_available(struct sock *sk); >> -- >> 2.30.2 -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2021-03-24 1:07 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-03-22 11:37 [MPTCP][PATCH mptcp-next 0/6] DSS checksum support Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Geliang Tang 2021-03-22 11:37 ` [MPTCP][PATCH mptcp-next 6/6] mptcp: add trace event for DSS checksum Geliang Tang 2021-03-22 23:40 ` [MPTCP][PATCH mptcp-next 5/6] mptcp: add the DSS checksum receiving Mat Martineau 2021-03-23 12:55 ` Geliang Tang 2021-03-24 0:52 ` Mat Martineau 2021-03-23 10:37 ` [MPTCP] " Paolo Abeni 2021-03-22 23:10 ` [MPTCP][PATCH mptcp-next 4/6] mptcp: add the DSS checksum sending Mat Martineau 2021-03-23 10:22 ` [MPTCP] " Paolo Abeni 2021-03-24 1:07 ` Mat Martineau 2021-03-23 17:07 ` [MPTCP] " Paolo Abeni 2021-03-22 22:52 ` [MPTCP][PATCH mptcp-next 3/6] mptcp: add the csum_reqd fields Mat Martineau 2021-03-23 10:12 ` [MPTCP] " Paolo Abeni 2021-03-24 1:05 ` Mat Martineau 2021-03-23 10:41 ` [MPTCP] [MPTCP][PATCH mptcp-next 2/6] mptcp: add csum_enabled in mptcp_out_options Paolo Abeni 2021-03-22 22:22 ` [MPTCP][PATCH mptcp-next 1/6] mptcp: add a new sysctl checksum_enabled Mat Martineau 2021-03-22 23:46 ` Mat Martineau
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.