Merge tag 'char-misc-5.15-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / net / mptcp / protocol.h
index 0f0c026..d3e6fd1 100644 (file)
 #define OPTION_MPTCP_FASTCLOSE BIT(8)
 #define OPTION_MPTCP_PRIO      BIT(9)
 #define OPTION_MPTCP_RST       BIT(10)
+#define OPTION_MPTCP_DSS       BIT(11)
+#define OPTION_MPTCP_FAIL      BIT(12)
+
+#define OPTION_MPTCP_CSUMREQD  BIT(13)
+
+#define OPTIONS_MPTCP_MPC      (OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_SYNACK | \
+                                OPTION_MPTCP_MPC_ACK)
+#define OPTIONS_MPTCP_MPJ      (OPTION_MPTCP_MPJ_SYN | OPTION_MPTCP_MPJ_SYNACK | \
+                                OPTION_MPTCP_MPJ_ACK)
 
 /* MPTCP option subtypes */
 #define MPTCPOPT_MP_CAPABLE    0
@@ -67,6 +76,7 @@
 #define TCPOLEN_MPTCP_PRIO_ALIGN       4
 #define TCPOLEN_MPTCP_FASTCLOSE                12
 #define TCPOLEN_MPTCP_RST              4
+#define TCPOLEN_MPTCP_FAIL             12
 
 #define TCPOLEN_MPTCP_MPC_ACK_DATA_CSUM        (TCPOLEN_MPTCP_DSS_CHECKSUM + TCPOLEN_MPTCP_MPC_ACK_DATA)
 
@@ -129,35 +139,28 @@ struct mptcp_options_received {
        u32     subflow_seq;
        u16     data_len;
        __sum16 csum;
-       u16     mp_capable : 1,
-               mp_join : 1,
-               fastclose : 1,
-               reset : 1,
-               dss : 1,
-               add_addr : 1,
-               rm_addr : 1,
-               mp_prio : 1,
-               echo : 1,
-               csum_reqd : 1,
-               backup : 1,
-               deny_join_id0 : 1;
+       u16     suboptions;
        u32     token;
        u32     nonce;
-       u64     thmac;
-       u8      hmac[MPTCPOPT_HMAC_LEN];
-       u8      join_id;
-       u8      use_map:1,
+       u16     use_map:1,
                dsn64:1,
                data_fin:1,
                use_ack:1,
                ack64:1,
                mpc_map:1,
+               reset_reason:4,
+               reset_transient:1,
+               echo:1,
+               backup:1,
+               deny_join_id0:1,
                __unused:2;
+       u8      join_id;
+       u64     thmac;
+       u8      hmac[MPTCPOPT_HMAC_LEN];
        struct mptcp_addr_info addr;
        struct mptcp_rm_list rm_list;
        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)
@@ -178,8 +181,6 @@ enum mptcp_pm_status {
 enum mptcp_addr_signal_status {
        MPTCP_ADD_ADDR_SIGNAL,
        MPTCP_ADD_ADDR_ECHO,
-       MPTCP_ADD_ADDR_IPV6,
-       MPTCP_ADD_ADDR_PORT,
        MPTCP_RM_ADDR_SIGNAL,
 };
 
@@ -230,12 +231,17 @@ struct mptcp_sock {
        struct sock     *last_snd;
        int             snd_burst;
        int             old_wspace;
+       u64             recovery_snd_nxt;       /* in recovery mode accept up to this seq;
+                                                * recovery related fields are under data_lock
+                                                * protection
+                                                */
        u64             snd_una;
        u64             wnd_end;
        unsigned long   timer_ival;
        u32             token;
        int             rmem_released;
        unsigned long   flags;
+       bool            recovery;               /* closing subflow write queue reinjected */
        bool            can_ack;
        bool            fully_established;
        bool            rcv_data_fin;
@@ -425,9 +431,11 @@ struct mptcp_subflow_context {
                mpc_map : 1,
                backup : 1,
                send_mp_prio : 1,
+               send_mp_fail : 1,
                rx_eof : 1,
                can_ack : 1,        /* only after processing the remote a key */
-               disposable : 1;     /* ctx can be free at ulp release time */
+               disposable : 1,     /* ctx can be free at ulp release time */
+               stale : 1;          /* unable to snd/rcv data, do not use for xmit */
        enum mptcp_data_avail data_avail;
        u32     remote_nonce;
        u64     thmac;
@@ -439,11 +447,13 @@ struct mptcp_subflow_context {
        u8      reset_seen:1;
        u8      reset_transient:1;
        u8      reset_reason:4;
+       u8      stale_count;
 
        long    delegated_status;
        struct  list_head delegated_node;   /* link into delegated_action, protected by local BH */
 
-       u32 setsockopt_seq;
+       u32     setsockopt_seq;
+       u32     stale_rcv_tstamp;
 
        struct  sock *tcp_sock;     /* tcp sk backpointer */
        struct  sock *conn;         /* parent mptcp_sock */
@@ -549,31 +559,34 @@ static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *su
        clear_bit(MPTCP_DELEGATE_SEND, &subflow->delegated_status);
 }
 
-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);
-int mptcp_allow_join_id0(struct net *net);
+int mptcp_is_enabled(const struct net *net);
+unsigned int mptcp_get_add_addr_timeout(const struct net *net);
+int mptcp_is_checksum_enabled(const struct net *net);
+int mptcp_allow_join_id0(const struct net *net);
+unsigned int mptcp_stale_loss_cnt(const struct net *net);
 void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
                                     struct mptcp_options_received *mp_opt);
+bool __mptcp_retransmit_pending_data(struct sock *sk);
+void __mptcp_push_pending(struct sock *sk, unsigned int flags);
 bool mptcp_subflow_data_available(struct sock *sk);
 void __init mptcp_subflow_init(void);
 void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
 void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
                     struct mptcp_subflow_context *subflow);
+void mptcp_subflow_send_ack(struct sock *ssk);
 void mptcp_subflow_reset(struct sock *ssk);
 void mptcp_sock_graft(struct sock *sk, struct socket *parent);
 struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
 
 /* called with sk socket lock held */
 int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
-                           const struct mptcp_addr_info *remote,
-                           u8 flags, int ifindex);
+                           const struct mptcp_addr_info *remote);
 int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock);
 void mptcp_info2sockaddr(const struct mptcp_addr_info *info,
                         struct sockaddr_storage *addr,
                         unsigned short family);
 
-static inline bool mptcp_subflow_active(struct mptcp_subflow_context *subflow)
+static inline bool __mptcp_subflow_active(struct mptcp_subflow_context *subflow)
 {
        struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
 
@@ -585,6 +598,10 @@ static inline bool mptcp_subflow_active(struct mptcp_subflow_context *subflow)
        return ((1 << ssk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT));
 }
 
+void mptcp_subflow_set_active(struct mptcp_subflow_context *subflow);
+
+bool mptcp_subflow_active(struct mptcp_subflow_context *subflow);
+
 static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
                                              struct mptcp_subflow_context *ctx)
 {
@@ -596,6 +613,19 @@ static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
        inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops;
 }
 
+static inline bool mptcp_has_another_subflow(struct sock *ssk)
+{
+       struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk), *tmp;
+       struct mptcp_sock *msk = mptcp_sk(subflow->conn);
+
+       mptcp_for_each_subflow(msk, tmp) {
+               if (tmp != subflow)
+                       return true;
+       }
+
+       return false;
+}
+
 void __init mptcp_proto_init(void);
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
 int __init mptcp_proto_v6_init(void);
@@ -690,6 +720,8 @@ void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac);
 
 void __init mptcp_pm_init(void);
 void mptcp_pm_data_init(struct mptcp_sock *msk);
+void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk);
+void mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk);
 void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side);
 void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk, gfp_t gfp);
 bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk);
@@ -708,6 +740,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 *
@@ -716,6 +749,8 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 struct mptcp_pm_add_entry *
 mptcp_lookup_anno_list_by_saddr(struct mptcp_sock *msk,
                                struct mptcp_addr_info *addr);
+int mptcp_pm_get_flags_and_ifindex_by_id(struct net *net, unsigned int id,
+                                        u8 *flags, int *ifindex);
 
 int mptcp_pm_announce_addr(struct mptcp_sock *msk,
                           const struct mptcp_addr_info *addr,
@@ -730,22 +765,18 @@ void mptcp_event_addr_removed(const struct mptcp_sock *msk, u8 id);
 
 static inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
 {
-       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_SIGNAL);
+       return READ_ONCE(msk->pm.addr_signal) &
+               (BIT(MPTCP_ADD_ADDR_SIGNAL) | BIT(MPTCP_ADD_ADDR_ECHO));
 }
 
-static inline bool mptcp_pm_should_add_signal_echo(struct mptcp_sock *msk)
-{
-       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_ECHO);
-}
-
-static inline bool mptcp_pm_should_add_signal_ipv6(struct mptcp_sock *msk)
+static inline bool mptcp_pm_should_add_signal_addr(struct mptcp_sock *msk)
 {
-       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_IPV6);
+       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_SIGNAL);
 }
 
-static inline bool mptcp_pm_should_add_signal_port(struct mptcp_sock *msk)
+static inline bool mptcp_pm_should_add_signal_echo(struct mptcp_sock *msk)
 {
-       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_PORT);
+       return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_ECHO);
 }
 
 static inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
@@ -776,8 +807,10 @@ static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
        return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
 }
 
-bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
-                             struct mptcp_addr_info *saddr, bool *echo, bool *port);
+bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
+                             unsigned int opt_size, unsigned int remaining,
+                             struct mptcp_addr_info *addr, bool *echo,
+                             bool *port, bool *drop_other_suboptions);
 bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
                             struct mptcp_rm_list *rm_list);
 int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);