Skip to content

Commit

Permalink
Merge branch 'mptcp-dss-checksums'
Browse files Browse the repository at this point in the history
Mat Martineau says:

====================
mptcp: DSS checksum support

RFC 8684 defines a DSS checksum feature that allows MPTCP to detect
middlebox interference with the MPTCP DSS header and the portion of the
data stream associated with that header. So far, the MPTCP
implementation in the Linux kernel has not supported this feature.

This patch series adds DSS checksum support. By default, the kernel will
not request checksums when sending SYN or SYN/ACK packets for MPTCP
connections. Outgoing checksum requests can be enabled with a
per-namespace net.mptcp.checksum_enabled sysctl. MPTCP connections will
now proceed with DSS checksums when the peer requests them, whether the
sysctl is enabled or not.

Patches 1-5 add checksum bits to the outgoing SYN, SYN/ACK, and data
packet headers. This includes calculating the checksum using a range of
data and the MPTCP DSS mapping for that data.

Patches 6-10 handle the checksum request in the SYN or SYN/ACK, and
receiving and verifying the DSS checksum on data packets.

Patch 11 adjusts the MPTCP-level retransmission process for checksum
compatibility.

Patches 12-14 add checksum-related MIBs, the net.mptcp.checksum_enabled
sysctl, and a checksum field to debug trace output.

Patches 15 & 16 add selftests.

The series is slightly longer than the preferred 15-patch limit that
patchwork warns about. I do try to stay below that whenever possible -
this series does implement one feature and is, I think, cohesive enough
to justify keeping it together. If it's at all problematic please let me
know!

A trivial merge conflict with net/master is introduced in patch 15: a
commit in net/master removes a couple of nearby lines of code.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 18, 2021
2 parents e7f3863 + af66d3e commit a778e93
Show file tree
Hide file tree
Showing 14 changed files with 431 additions and 69 deletions.
8 changes: 8 additions & 0 deletions Documentation/networking/mptcp-sysctl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,11 @@ add_addr_timeout - INTEGER (seconds)
sysctl.

Default: 120

checksum_enabled - BOOLEAN
Control whether DSS checksum can be enabled.

DSS checksum can be enabled if the value is nonzero. This is a
per-namespace sysctl.

Default: 0
9 changes: 6 additions & 3 deletions include/net/mptcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct mptcp_ext {
u64 data_seq;
u32 subflow_seq;
u16 data_len;
__sum16 csum;
u8 use_map:1,
dsn64:1,
data_fin:1,
Expand All @@ -31,7 +32,8 @@ struct mptcp_ext {
mpc_map:1,
frozen:1,
reset_transient:1;
u8 reset_reason:4;
u8 reset_reason:4,
csum_reqd:1;
};

#define MPTCP_RM_IDS_MAX 8
Expand Down Expand Up @@ -63,8 +65,9 @@ struct mptcp_out_options {
struct mptcp_rm_list rm_list;
u8 join_id;
u8 backup;
u8 reset_reason:4;
u8 reset_transient:1;
u8 reset_reason:4,
reset_transient:1,
csum_reqd:1;
u32 nonce;
u64 thmac;
u32 token;
Expand Down
17 changes: 11 additions & 6 deletions include/trace/events/mptcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ DECLARE_EVENT_CLASS(mptcp_dump_mpext,
__field(u64, data_seq)
__field(u32, subflow_seq)
__field(u16, data_len)
__field(u16, csum)
__field(u8, use_map)
__field(u8, dsn64)
__field(u8, data_fin)
Expand All @@ -82,13 +83,15 @@ DECLARE_EVENT_CLASS(mptcp_dump_mpext,
__field(u8, frozen)
__field(u8, reset_transient)
__field(u8, reset_reason)
__field(u8, csum_reqd)
),

TP_fast_assign(
__entry->data_ack = mpext->ack64 ? mpext->data_ack : mpext->data_ack32;
__entry->data_seq = mpext->data_seq;
__entry->subflow_seq = mpext->subflow_seq;
__entry->data_len = mpext->data_len;
__entry->csum = (__force u16)mpext->csum;
__entry->use_map = mpext->use_map;
__entry->dsn64 = mpext->dsn64;
__entry->data_fin = mpext->data_fin;
Expand All @@ -98,16 +101,18 @@ DECLARE_EVENT_CLASS(mptcp_dump_mpext,
__entry->frozen = mpext->frozen;
__entry->reset_transient = mpext->reset_transient;
__entry->reset_reason = mpext->reset_reason;
__entry->csum_reqd = mpext->csum_reqd;
),

TP_printk("data_ack=%llu data_seq=%llu subflow_seq=%u data_len=%u use_map=%u dsn64=%u data_fin=%u use_ack=%u ack64=%u mpc_map=%u frozen=%u reset_transient=%u reset_reason=%u",
TP_printk("data_ack=%llu data_seq=%llu subflow_seq=%u data_len=%u csum=%x use_map=%u dsn64=%u data_fin=%u use_ack=%u ack64=%u mpc_map=%u frozen=%u reset_transient=%u reset_reason=%u csum_reqd=%u",
__entry->data_ack, __entry->data_seq,
__entry->subflow_seq, __entry->data_len,
__entry->use_map, __entry->dsn64,
__entry->data_fin, __entry->use_ack,
__entry->ack64, __entry->mpc_map,
__entry->frozen, __entry->reset_transient,
__entry->reset_reason)
__entry->csum, __entry->use_map,
__entry->dsn64, __entry->data_fin,
__entry->use_ack, __entry->ack64,
__entry->mpc_map, __entry->frozen,
__entry->reset_transient, __entry->reset_reason,
__entry->csum_reqd)
);

DEFINE_EVENT(mptcp_dump_mpext, get_mapping_status,
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/mptcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ struct mptcp_info {
__u64 mptcpi_rcv_nxt;
__u8 mptcpi_local_addr_used;
__u8 mptcpi_local_addr_max;
__u8 mptcpi_csum_enabled;
};

/*
Expand Down
16 changes: 16 additions & 0 deletions net/mptcp/ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct mptcp_pernet {

u8 mptcp_enabled;
unsigned int add_addr_timeout;
u8 checksum_enabled;
};

static struct mptcp_pernet *mptcp_get_pernet(struct net *net)
Expand All @@ -40,10 +41,16 @@ 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 void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
{
pernet->mptcp_enabled = 1;
pernet->add_addr_timeout = TCP_RTO_MAX;
pernet->checksum_enabled = 0;
}

#ifdef CONFIG_SYSCTL
Expand All @@ -65,6 +72,14 @@ static struct ctl_table mptcp_sysctl_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
{
.procname = "checksum_enabled",
.maxlen = sizeof(u8),
.mode = 0644,
.proc_handler = proc_dou8vec_minmax,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE
},
{}
};

Expand All @@ -82,6 +97,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)
Expand Down
1 change: 1 addition & 0 deletions net/mptcp/mib.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
SNMP_MIB_ITEM("DataCsumErr", MPTCP_MIB_DATACSUMERR),
SNMP_MIB_ITEM("OFOQueueTail", MPTCP_MIB_OFOQUEUETAIL),
SNMP_MIB_ITEM("OFOQueue", MPTCP_MIB_OFOQUEUE),
SNMP_MIB_ITEM("OFOMerge", MPTCP_MIB_OFOMERGE),
Expand Down
1 change: 1 addition & 0 deletions net/mptcp/mib.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum linux_mptcp_mib_field {
MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */
MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */
MPTCP_MIB_DATACSUMERR, /* The data checksum fail */
MPTCP_MIB_OFOQUEUETAIL, /* Segments inserted into OoO queue tail */
MPTCP_MIB_OFOQUEUE, /* Segments inserted into OoO queue */
MPTCP_MIB_OFOMERGE, /* Segments merged in OoO queue */
Expand Down
1 change: 1 addition & 0 deletions net/mptcp/mptcp_diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ static void mptcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
info->mptcpi_write_seq = READ_ONCE(msk->write_seq);
info->mptcpi_snd_una = READ_ONCE(msk->snd_una);
info->mptcpi_rcv_nxt = READ_ONCE(msk->ack_seq);
info->mptcpi_csum_enabled = READ_ONCE(msk->csum_enabled);
unlock_sock_fast(sk, slow);
}

Expand Down
Loading

0 comments on commit a778e93

Please sign in to comment.