linux/include/net/mptcp.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Multipath TCP
   4 *
   5 * Copyright (c) 2017 - 2019, Intel Corporation.
   6 */
   7
   8#ifndef __NET_MPTCP_H
   9#define __NET_MPTCP_H
  10
  11#include <linux/skbuff.h>
  12#include <linux/tcp.h>
  13#include <linux/types.h>
  14
  15struct seq_file;
  16
  17/* MPTCP sk_buff extension data */
  18struct mptcp_ext {
  19        union {
  20                u64     data_ack;
  21                u32     data_ack32;
  22        };
  23        u64             data_seq;
  24        u32             subflow_seq;
  25        u16             data_len;
  26        __sum16         csum;
  27        u8              use_map:1,
  28                        dsn64:1,
  29                        data_fin:1,
  30                        use_ack:1,
  31                        ack64:1,
  32                        mpc_map:1,
  33                        frozen:1,
  34                        reset_transient:1;
  35        u8              reset_reason:4,
  36                        csum_reqd:1;
  37};
  38
  39#define MPTCP_RM_IDS_MAX        8
  40
  41struct mptcp_rm_list {
  42        u8 ids[MPTCP_RM_IDS_MAX];
  43        u8 nr;
  44};
  45
  46struct mptcp_addr_info {
  47        u8                      id;
  48        sa_family_t             family;
  49        __be16                  port;
  50        union {
  51                struct in_addr  addr;
  52#if IS_ENABLED(CONFIG_MPTCP_IPV6)
  53                struct in6_addr addr6;
  54#endif
  55        };
  56};
  57
  58struct mptcp_out_options {
  59#if IS_ENABLED(CONFIG_MPTCP)
  60        u16 suboptions;
  61        u64 sndr_key;
  62        u64 rcvr_key;
  63        u64 ahmac;
  64        struct mptcp_addr_info addr;
  65        struct mptcp_rm_list rm_list;
  66        u8 join_id;
  67        u8 backup;
  68        u8 reset_reason:4,
  69           reset_transient:1,
  70           csum_reqd:1,
  71           allow_join_id0:1;
  72        u32 nonce;
  73        u64 thmac;
  74        u32 token;
  75        u8 hmac[20];
  76        struct mptcp_ext ext_copy;
  77#endif
  78};
  79
  80#ifdef CONFIG_MPTCP
  81extern struct request_sock_ops mptcp_subflow_request_sock_ops;
  82
  83void mptcp_init(void);
  84
  85static inline bool sk_is_mptcp(const struct sock *sk)
  86{
  87        return tcp_sk(sk)->is_mptcp;
  88}
  89
  90static inline bool rsk_is_mptcp(const struct request_sock *req)
  91{
  92        return tcp_rsk(req)->is_mptcp;
  93}
  94
  95static inline bool rsk_drop_req(const struct request_sock *req)
  96{
  97        return tcp_rsk(req)->is_mptcp && tcp_rsk(req)->drop_req;
  98}
  99
 100void mptcp_space(const struct sock *ssk, int *space, int *full_space);
 101bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
 102                       unsigned int *size, struct mptcp_out_options *opts);
 103bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
 104                          struct mptcp_out_options *opts);
 105bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
 106                               unsigned int *size, unsigned int remaining,
 107                               struct mptcp_out_options *opts);
 108bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb);
 109
 110void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 111                         struct mptcp_out_options *opts);
 112
 113/* move the skb extension owership, with the assumption that 'to' is
 114 * newly allocated
 115 */
 116static inline void mptcp_skb_ext_move(struct sk_buff *to,
 117                                      struct sk_buff *from)
 118{
 119        if (!skb_ext_exist(from, SKB_EXT_MPTCP))
 120                return;
 121
 122        if (WARN_ON_ONCE(to->active_extensions))
 123                skb_ext_put(to);
 124
 125        to->active_extensions = from->active_extensions;
 126        to->extensions = from->extensions;
 127        from->active_extensions = 0;
 128}
 129
 130static inline void mptcp_skb_ext_copy(struct sk_buff *to,
 131                                      struct sk_buff *from)
 132{
 133        struct mptcp_ext *from_ext;
 134
 135        from_ext = skb_ext_find(from, SKB_EXT_MPTCP);
 136        if (!from_ext)
 137                return;
 138
 139        from_ext->frozen = 1;
 140        skb_ext_copy(to, from);
 141}
 142
 143static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext,
 144                                     const struct mptcp_ext *from_ext)
 145{
 146        /* MPTCP always clears the ext when adding it to the skb, so
 147         * holes do not bother us here
 148         */
 149        return !from_ext ||
 150               (to_ext && from_ext &&
 151                !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext)));
 152}
 153
 154/* check if skbs can be collapsed.
 155 * MPTCP collapse is allowed if neither @to or @from carry an mptcp data
 156 * mapping, or if the extension of @to is the same as @from.
 157 * Collapsing is not possible if @to lacks an extension, but @from carries one.
 158 */
 159static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
 160                                          const struct sk_buff *from)
 161{
 162        return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP),
 163                                 skb_ext_find(from, SKB_EXT_MPTCP));
 164}
 165
 166void mptcp_seq_show(struct seq_file *seq);
 167int mptcp_subflow_init_cookie_req(struct request_sock *req,
 168                                  const struct sock *sk_listener,
 169                                  struct sk_buff *skb);
 170
 171__be32 mptcp_get_reset_option(const struct sk_buff *skb);
 172
 173static inline __be32 mptcp_reset_option(const struct sk_buff *skb)
 174{
 175        if (skb_ext_exist(skb, SKB_EXT_MPTCP))
 176                return mptcp_get_reset_option(skb);
 177
 178        return htonl(0u);
 179}
 180#else
 181
 182static inline void mptcp_init(void)
 183{
 184}
 185
 186static inline bool sk_is_mptcp(const struct sock *sk)
 187{
 188        return false;
 189}
 190
 191static inline bool rsk_is_mptcp(const struct request_sock *req)
 192{
 193        return false;
 194}
 195
 196static inline bool rsk_drop_req(const struct request_sock *req)
 197{
 198        return false;
 199}
 200
 201static inline void mptcp_parse_option(const struct sk_buff *skb,
 202                                      const unsigned char *ptr, int opsize,
 203                                      struct tcp_options_received *opt_rx)
 204{
 205}
 206
 207static inline bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
 208                                     unsigned int *size,
 209                                     struct mptcp_out_options *opts)
 210{
 211        return false;
 212}
 213
 214static inline bool mptcp_synack_options(const struct request_sock *req,
 215                                        unsigned int *size,
 216                                        struct mptcp_out_options *opts)
 217{
 218        return false;
 219}
 220
 221static inline bool mptcp_established_options(struct sock *sk,
 222                                             struct sk_buff *skb,
 223                                             unsigned int *size,
 224                                             unsigned int remaining,
 225                                             struct mptcp_out_options *opts)
 226{
 227        return false;
 228}
 229
 230static inline bool mptcp_incoming_options(struct sock *sk,
 231                                          struct sk_buff *skb)
 232{
 233        return true;
 234}
 235
 236static inline void mptcp_skb_ext_move(struct sk_buff *to,
 237                                      const struct sk_buff *from)
 238{
 239}
 240
 241static inline void mptcp_skb_ext_copy(struct sk_buff *to,
 242                                      struct sk_buff *from)
 243{
 244}
 245
 246static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
 247                                          const struct sk_buff *from)
 248{
 249        return true;
 250}
 251
 252static inline void mptcp_space(const struct sock *ssk, int *s, int *fs) { }
 253static inline void mptcp_seq_show(struct seq_file *seq) { }
 254
 255static inline int mptcp_subflow_init_cookie_req(struct request_sock *req,
 256                                                const struct sock *sk_listener,
 257                                                struct sk_buff *skb)
 258{
 259        return 0; /* TCP fallback */
 260}
 261
 262static inline __be32 mptcp_reset_option(const struct sk_buff *skb)  { return htonl(0u); }
 263#endif /* CONFIG_MPTCP */
 264
 265#if IS_ENABLED(CONFIG_MPTCP_IPV6)
 266int mptcpv6_init(void);
 267void mptcpv6_handle_mapped(struct sock *sk, bool mapped);
 268#elif IS_ENABLED(CONFIG_IPV6)
 269static inline int mptcpv6_init(void) { return 0; }
 270static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { }
 271#endif
 272
 273#endif /* __NET_MPTCP_H */
 274