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        struct mptcp_rm_list rm_list;
  62        u8 join_id;
  63        u8 backup;
  64        u8 reset_reason:4,
  65           reset_transient:1,
  66           csum_reqd:1,
  67           allow_join_id0:1;
  68        union {
  69                struct {
  70                        u64 sndr_key;
  71                        u64 rcvr_key;
  72                        u64 data_seq;
  73                        u32 subflow_seq;
  74                        u16 data_len;
  75                        __sum16 csum;
  76                };
  77                struct {
  78                        struct mptcp_addr_info addr;
  79                        u64 ahmac;
  80                };
  81                struct {
  82                        struct mptcp_ext ext_copy;
  83                        u64 fail_seq;
  84                };
  85                struct {
  86                        u32 nonce;
  87                        u32 token;
  88                        u64 thmac;
  89                        u8 hmac[20];
  90                };
  91        };
  92#endif
  93};
  94
  95#ifdef CONFIG_MPTCP
  96extern struct request_sock_ops mptcp_subflow_request_sock_ops;
  97
  98void mptcp_init(void);
  99
 100static inline bool sk_is_mptcp(const struct sock *sk)
 101{
 102        return tcp_sk(sk)->is_mptcp;
 103}
 104
 105static inline bool rsk_is_mptcp(const struct request_sock *req)
 106{
 107        return tcp_rsk(req)->is_mptcp;
 108}
 109
 110static inline bool rsk_drop_req(const struct request_sock *req)
 111{
 112        return tcp_rsk(req)->is_mptcp && tcp_rsk(req)->drop_req;
 113}
 114
 115void mptcp_space(const struct sock *ssk, int *space, int *full_space);
 116bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
 117                       unsigned int *size, struct mptcp_out_options *opts);
 118bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
 119                          struct mptcp_out_options *opts);
 120bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
 121                               unsigned int *size, unsigned int remaining,
 122                               struct mptcp_out_options *opts);
 123bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb);
 124
 125void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
 126                         struct mptcp_out_options *opts);
 127
 128/* move the skb extension owership, with the assumption that 'to' is
 129 * newly allocated
 130 */
 131static inline void mptcp_skb_ext_move(struct sk_buff *to,
 132                                      struct sk_buff *from)
 133{
 134        if (!skb_ext_exist(from, SKB_EXT_MPTCP))
 135                return;
 136
 137        if (WARN_ON_ONCE(to->active_extensions))
 138                skb_ext_put(to);
 139
 140        to->active_extensions = from->active_extensions;
 141        to->extensions = from->extensions;
 142        from->active_extensions = 0;
 143}
 144
 145static inline void mptcp_skb_ext_copy(struct sk_buff *to,
 146                                      struct sk_buff *from)
 147{
 148        struct mptcp_ext *from_ext;
 149
 150        from_ext = skb_ext_find(from, SKB_EXT_MPTCP);
 151        if (!from_ext)
 152                return;
 153
 154        from_ext->frozen = 1;
 155        skb_ext_copy(to, from);
 156}
 157
 158static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext,
 159                                     const struct mptcp_ext *from_ext)
 160{
 161        /* MPTCP always clears the ext when adding it to the skb, so
 162         * holes do not bother us here
 163         */
 164        return !from_ext ||
 165               (to_ext && from_ext &&
 166                !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext)));
 167}
 168
 169/* check if skbs can be collapsed.
 170 * MPTCP collapse is allowed if neither @to or @from carry an mptcp data
 171 * mapping, or if the extension of @to is the same as @from.
 172 * Collapsing is not possible if @to lacks an extension, but @from carries one.
 173 */
 174static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
 175                                          const struct sk_buff *from)
 176{
 177        return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP),
 178                                 skb_ext_find(from, SKB_EXT_MPTCP));
 179}
 180
 181void mptcp_seq_show(struct seq_file *seq);
 182int mptcp_subflow_init_cookie_req(struct request_sock *req,
 183                                  const struct sock *sk_listener,
 184                                  struct sk_buff *skb);
 185
 186__be32 mptcp_get_reset_option(const struct sk_buff *skb);
 187
 188static inline __be32 mptcp_reset_option(const struct sk_buff *skb)
 189{
 190        if (skb_ext_exist(skb, SKB_EXT_MPTCP))
 191                return mptcp_get_reset_option(skb);
 192
 193        return htonl(0u);
 194}
 195#else
 196
 197static inline void mptcp_init(void)
 198{
 199}
 200
 201static inline bool sk_is_mptcp(const struct sock *sk)
 202{
 203        return false;
 204}
 205
 206static inline bool rsk_is_mptcp(const struct request_sock *req)
 207{
 208        return false;
 209}
 210
 211static inline bool rsk_drop_req(const struct request_sock *req)
 212{
 213        return false;
 214}
 215
 216static inline void mptcp_parse_option(const struct sk_buff *skb,
 217                                      const unsigned char *ptr, int opsize,
 218                                      struct tcp_options_received *opt_rx)
 219{
 220}
 221
 222static inline bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
 223                                     unsigned int *size,
 224                                     struct mptcp_out_options *opts)
 225{
 226        return false;
 227}
 228
 229static inline bool mptcp_synack_options(const struct request_sock *req,
 230                                        unsigned int *size,
 231                                        struct mptcp_out_options *opts)
 232{
 233        return false;
 234}
 235
 236static inline bool mptcp_established_options(struct sock *sk,
 237                                             struct sk_buff *skb,
 238                                             unsigned int *size,
 239                                             unsigned int remaining,
 240                                             struct mptcp_out_options *opts)
 241{
 242        return false;
 243}
 244
 245static inline bool mptcp_incoming_options(struct sock *sk,
 246                                          struct sk_buff *skb)
 247{
 248        return true;
 249}
 250
 251static inline void mptcp_skb_ext_move(struct sk_buff *to,
 252                                      const struct sk_buff *from)
 253{
 254}
 255
 256static inline void mptcp_skb_ext_copy(struct sk_buff *to,
 257                                      struct sk_buff *from)
 258{
 259}
 260
 261static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
 262                                          const struct sk_buff *from)
 263{
 264        return true;
 265}
 266
 267static inline void mptcp_space(const struct sock *ssk, int *s, int *fs) { }
 268static inline void mptcp_seq_show(struct seq_file *seq) { }
 269
 270static inline int mptcp_subflow_init_cookie_req(struct request_sock *req,
 271                                                const struct sock *sk_listener,
 272                                                struct sk_buff *skb)
 273{
 274        return 0; /* TCP fallback */
 275}
 276
 277static inline __be32 mptcp_reset_option(const struct sk_buff *skb)  { return htonl(0u); }
 278#endif /* CONFIG_MPTCP */
 279
 280#if IS_ENABLED(CONFIG_MPTCP_IPV6)
 281int mptcpv6_init(void);
 282void mptcpv6_handle_mapped(struct sock *sk, bool mapped);
 283#elif IS_ENABLED(CONFIG_IPV6)
 284static inline int mptcpv6_init(void) { return 0; }
 285static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { }
 286#endif
 287
 288#endif /* __NET_MPTCP_H */
 289