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