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>
                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;
        }
        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);
                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;
 
        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,
 
                add_addr : 1,
                rm_addr : 1,
                mp_prio : 1,
+               mp_fail : 1,
                echo : 1,
                csum_reqd : 1,
                backup : 1,
        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)
 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 *