Merge tag 'trace-v5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux-2.6-microblaze.git] / net / mptcp / protocol.h
index e21a5bc..edc0128 100644 (file)
 #define OPTION_MPTCP_MPJ_SYNACK        BIT(4)
 #define OPTION_MPTCP_MPJ_ACK   BIT(5)
 #define OPTION_MPTCP_ADD_ADDR  BIT(6)
-#define OPTION_MPTCP_ADD_ADDR6 BIT(7)
-#define OPTION_MPTCP_RM_ADDR   BIT(8)
-#define OPTION_MPTCP_FASTCLOSE BIT(9)
-#define OPTION_MPTCP_PRIO      BIT(10)
+#define OPTION_MPTCP_RM_ADDR   BIT(7)
+#define OPTION_MPTCP_FASTCLOSE BIT(8)
+#define OPTION_MPTCP_PRIO      BIT(9)
+#define OPTION_MPTCP_RST       BIT(10)
 
 /* MPTCP option subtypes */
 #define MPTCPOPT_MP_CAPABLE    0
@@ -36,6 +36,7 @@
 #define MPTCPOPT_MP_PRIO       5
 #define MPTCPOPT_MP_FAIL       6
 #define MPTCPOPT_MP_FASTCLOSE  7
+#define MPTCPOPT_RST           8
 
 /* MPTCP suboption lengths */
 #define TCPOLEN_MPTCP_MPC_SYN          4
 #define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT      22
 #define TCPOLEN_MPTCP_PORT_LEN         2
 #define TCPOLEN_MPTCP_PORT_ALIGN       2
-#define TCPOLEN_MPTCP_RM_ADDR_BASE     4
+#define TCPOLEN_MPTCP_RM_ADDR_BASE     3
 #define TCPOLEN_MPTCP_PRIO             3
 #define TCPOLEN_MPTCP_PRIO_ALIGN       4
 #define TCPOLEN_MPTCP_FASTCLOSE                12
+#define TCPOLEN_MPTCP_RST              4
 
 /* MPTCP MP_JOIN flags */
 #define MPTCPOPT_BACKUP                BIT(0)
 
 /* MPTCP ADD_ADDR flags */
 #define MPTCP_ADDR_ECHO                BIT(0)
-#define MPTCP_ADDR_IPVERSION_4 4
-#define MPTCP_ADDR_IPVERSION_6 6
 
 /* MPTCP MP_PRIO flags */
 #define MPTCP_PRIO_BKUP                BIT(0)
 
+/* MPTCP TCPRST flags */
+#define MPTCP_RST_TRANSIENT    BIT(0)
+
 /* MPTCP socket flags */
 #define MPTCP_DATA_READY       0
 #define MPTCP_NOSPACE          1
 #define MPTCP_PUSH_PENDING     6
 #define MPTCP_CLEAN_UNA                7
 #define MPTCP_ERROR_REPORT     8
+#define MPTCP_RETRANSMIT       9
+#define MPTCP_WORK_SYNC_SETSOCKOPT 10
 
 static inline bool before64(__u64 seq1, __u64 seq2)
 {
@@ -122,11 +127,11 @@ struct mptcp_options_received {
        u16     mp_capable : 1,
                mp_join : 1,
                fastclose : 1,
+               reset : 1,
                dss : 1,
                add_addr : 1,
                rm_addr : 1,
                mp_prio : 1,
-               family : 4,
                echo : 1,
                backup : 1;
        u32     token;
@@ -141,16 +146,11 @@ struct mptcp_options_received {
                ack64:1,
                mpc_map:1,
                __unused:2;
-       u8      addr_id;
-       u8      rm_id;
-       union {
-               struct in_addr  addr;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-               struct in6_addr addr6;
-#endif
-       };
+       struct mptcp_addr_info addr;
+       struct mptcp_rm_list rm_list;
        u64     ahmac;
-       u16     port;
+       u8      reset_reason:4;
+       u8      reset_transient:1;
 };
 
 static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
@@ -159,20 +159,6 @@ static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
                     ((nib & 0xF) << 8) | field);
 }
 
-struct mptcp_addr_info {
-       sa_family_t             family;
-       __be16                  port;
-       u8                      id;
-       u8                      flags;
-       int                     ifindex;
-       union {
-               struct in_addr addr;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-               struct in6_addr addr6;
-#endif
-       };
-};
-
 enum mptcp_pm_status {
        MPTCP_PM_ADD_ADDR_RECEIVED,
        MPTCP_PM_ADD_ADDR_SEND_ACK,
@@ -207,7 +193,8 @@ struct mptcp_pm_data {
        u8              local_addr_used;
        u8              subflows;
        u8              status;
-       u8              rm_id;
+       struct mptcp_rm_list rm_list_tx;
+       struct mptcp_rm_list rm_list_rx;
 };
 
 struct mptcp_data_frag {
@@ -269,6 +256,8 @@ struct mptcp_sock {
                u64     time;   /* start time of measurement window */
                u64     rtt_us; /* last maximum rtt of subflows */
        } rcvq_space;
+
+       u32 setsockopt_seq;
 };
 
 #define mptcp_lock_sock(___sk, cb) do {                                        \
@@ -420,10 +409,15 @@ struct mptcp_subflow_context {
        u8      hmac[MPTCPOPT_HMAC_LEN];
        u8      local_id;
        u8      remote_id;
+       u8      reset_seen:1;
+       u8      reset_transient:1;
+       u8      reset_reason:4;
 
        long    delegated_status;
        struct  list_head delegated_node;   /* link into delegated_action, protected by local BH */
 
+       u32 setsockopt_seq;
+
        struct  sock *tcp_sock;     /* tcp sk backpointer */
        struct  sock *conn;         /* parent mptcp_sock */
        const   struct inet_connection_sock_af_ops *icsk_af_ops;
@@ -543,12 +537,25 @@ 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);
+                           const struct mptcp_addr_info *remote,
+                           u8 flags, int ifindex);
 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)
+{
+       struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+
+       /* can't send if JOIN hasn't completed yet (i.e. is usable for mptcp) */
+       if (subflow->request_join && !subflow->fully_established)
+               return false;
+
+       /* only send if our side has not closed yet */
+       return ((1 << ssk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT));
+}
+
 static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
                                              struct mptcp_subflow_context *ctx)
 {
@@ -581,6 +588,11 @@ void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk);
 void mptcp_data_ready(struct sock *sk, struct sock *ssk);
 bool mptcp_finish_join(struct sock *sk);
 bool mptcp_schedule_work(struct sock *sk);
+int mptcp_setsockopt(struct sock *sk, int level, int optname,
+                    sockptr_t optval, unsigned int optlen);
+int mptcp_getsockopt(struct sock *sk, int level, int optname,
+                    char __user *optval, int __user *option);
+
 void __mptcp_check_push(struct sock *sk, struct sock *ssk);
 void __mptcp_data_acked(struct sock *sk);
 void __mptcp_error_report(struct sock *sk);
@@ -641,13 +653,16 @@ void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int
 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);
 void mptcp_pm_connection_closed(struct mptcp_sock *msk);
-void mptcp_pm_subflow_established(struct mptcp_sock *msk,
-                                 struct mptcp_subflow_context *subflow);
+void mptcp_pm_subflow_established(struct mptcp_sock *msk);
 void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id);
 void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
                                const struct mptcp_addr_info *addr);
+void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk,
+                             struct mptcp_addr_info *addr);
 void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk);
-void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id);
+void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk);
+void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
+                              const struct mptcp_rm_list *rm_list);
 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,
@@ -657,12 +672,15 @@ bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk);
 struct mptcp_pm_add_entry *
 mptcp_pm_del_add_timer(struct mptcp_sock *msk,
                       struct mptcp_addr_info *addr);
+struct mptcp_pm_add_entry *
+mptcp_lookup_anno_list_by_saddr(struct mptcp_sock *msk,
+                               struct mptcp_addr_info *addr);
 
 int mptcp_pm_announce_addr(struct mptcp_sock *msk,
                           const struct mptcp_addr_info *addr,
-                          bool echo, bool port);
-int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id);
-int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 local_id);
+                          bool echo);
+int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
+int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
 
 void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
                 const struct sock *ssk, gfp_t gfp);
@@ -709,23 +727,38 @@ static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
        return len;
 }
 
+static inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
+{
+       if (rm_list->nr == 0 || rm_list->nr > MPTCP_RM_IDS_MAX)
+               return -EINVAL;
+
+       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_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
-                            u8 *rm_id);
+                            struct mptcp_rm_list *rm_list);
 int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
 
 void __init mptcp_pm_nl_init(void);
 void mptcp_pm_nl_data_init(struct mptcp_sock *msk);
 void mptcp_pm_nl_work(struct mptcp_sock *msk);
-void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, u8 rm_id);
+void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
+                                    const struct mptcp_rm_list *rm_list);
 int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
 unsigned int mptcp_pm_get_add_addr_signal_max(struct mptcp_sock *msk);
 unsigned int mptcp_pm_get_add_addr_accept_max(struct mptcp_sock *msk);
 unsigned int mptcp_pm_get_subflows_max(struct mptcp_sock *msk);
 unsigned int mptcp_pm_get_local_addr_max(struct mptcp_sock *msk);
 
-static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)
+int mptcp_setsockopt(struct sock *sk, int level, int optname,
+                    sockptr_t optval, unsigned int optlen);
+
+void mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk);
+void mptcp_sockopt_sync_all(struct mptcp_sock *msk);
+
+static inline struct mptcp_ext *mptcp_get_ext(const struct sk_buff *skb)
 {
        return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP);
 }