mptcp: MP_FAIL suboption receiving
authorGeliang Tang <geliangtang@xiaomi.com>
Tue, 24 Aug 2021 23:26:16 +0000 (16:26 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 25 Aug 2021 10:02:34 +0000 (11:02 +0100)
This patch added handling for receiving MP_FAIL suboption.

Add a new members mp_fail and fail_seq in struct mptcp_options_received.
When MP_FAIL suboption is received, set mp_fail to 1 and save the sequence
number to fail_seq.

Then invoke mptcp_pm_mp_fail_received to deal with the MP_FAIL suboption.

Signed-off-by: Geliang Tang <geliangtang@xiaomi.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/options.c
net/mptcp/pm.c
net/mptcp/protocol.h

index f2ebdd55d3ccd1ef17e6b921440d5cfe5cf392ca..fa287a49dc847e3602526a0c031934cd5beca041 100644 (file)
@@ -336,6 +336,16 @@ static void mptcp_parse_option(const struct sk_buff *skb,
                mp_opt->reset_reason = *ptr;
                break;
 
+       case MPTCPOPT_MP_FAIL:
+               if (opsize != TCPOLEN_MPTCP_FAIL)
+                       break;
+
+               ptr += 2;
+               mp_opt->mp_fail = 1;
+               mp_opt->fail_seq = get_unaligned_be64(ptr);
+               pr_debug("MP_FAIL: data_seq=%llu", mp_opt->fail_seq);
+               break;
+
        default:
                break;
        }
@@ -364,6 +374,7 @@ void mptcp_get_options(const struct sock *sk,
        mp_opt->reset = 0;
        mp_opt->csum_reqd = READ_ONCE(msk->csum_enabled);
        mp_opt->deny_join_id0 = 0;
+       mp_opt->mp_fail = 0;
 
        length = (th->doff * 4) - sizeof(struct tcphdr);
        ptr = (const unsigned char *)(th + 1);
@@ -1145,6 +1156,11 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
                mp_opt.mp_prio = 0;
        }
 
+       if (mp_opt.mp_fail) {
+               mptcp_pm_mp_fail_received(sk, mp_opt.fail_seq);
+               mp_opt.mp_fail = 0;
+       }
+
        if (mp_opt.reset) {
                subflow->reset_seen = 1;
                subflow->reset_reason = mp_opt.reset_reason;
index da0c4c925350e6f7a0e68620059962e4890f2a78..6ab386ff32944eb3ec4049ae2ca66166169e4e4c 100644 (file)
@@ -249,6 +249,11 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
        mptcp_event(MPTCP_EVENT_SUB_PRIORITY, mptcp_sk(subflow->conn), sk, GFP_ATOMIC);
 }
 
+void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
+{
+       pr_debug("fail_seq=%llu", fail_seq);
+}
+
 /* path manager helpers */
 
 bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
index 3e4a79cf520ab5da96fc8e4717f825fabaaef9a9..9ee5676e70c6c36da344a6d6a63d9c592e30ac70 100644 (file)
@@ -140,6 +140,7 @@ struct mptcp_options_received {
                add_addr : 1,
                rm_addr : 1,
                mp_prio : 1,
+               mp_fail : 1,
                echo : 1,
                csum_reqd : 1,
                backup : 1,
@@ -161,6 +162,7 @@ struct mptcp_options_received {
        u64     ahmac;
        u8      reset_reason:4;
        u8      reset_transient:1;
+       u64     fail_seq;
 };
 
 static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
@@ -726,6 +728,7 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);
 int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
                                 struct mptcp_addr_info *addr,
                                 u8 bkup);
+void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq);
 void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
 bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk);
 struct mptcp_pm_add_entry *