linux/include/net/amt.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * Copyright (c) 2021 Taehee Yoo <ap420073@gmail.com>
   4 */
   5#ifndef _NET_AMT_H_
   6#define _NET_AMT_H_
   7
   8#include <linux/siphash.h>
   9#include <linux/jhash.h>
  10
  11enum amt_msg_type {
  12        AMT_MSG_DISCOVERY = 1,
  13        AMT_MSG_ADVERTISEMENT,
  14        AMT_MSG_REQUEST,
  15        AMT_MSG_MEMBERSHIP_QUERY,
  16        AMT_MSG_MEMBERSHIP_UPDATE,
  17        AMT_MSG_MULTICAST_DATA,
  18        AMT_MSG_TEARDOWM,
  19        __AMT_MSG_MAX,
  20};
  21
  22#define AMT_MSG_MAX (__AMT_MSG_MAX - 1)
  23
  24enum amt_ops {
  25        /* A*B */
  26        AMT_OPS_INT,
  27        /* A+B */
  28        AMT_OPS_UNI,
  29        /* A-B */
  30        AMT_OPS_SUB,
  31        /* B-A */
  32        AMT_OPS_SUB_REV,
  33        __AMT_OPS_MAX,
  34};
  35
  36#define AMT_OPS_MAX (__AMT_OPS_MAX - 1)
  37
  38enum amt_filter {
  39        AMT_FILTER_FWD,
  40        AMT_FILTER_D_FWD,
  41        AMT_FILTER_FWD_NEW,
  42        AMT_FILTER_D_FWD_NEW,
  43        AMT_FILTER_ALL,
  44        AMT_FILTER_NONE_NEW,
  45        AMT_FILTER_BOTH,
  46        AMT_FILTER_BOTH_NEW,
  47        __AMT_FILTER_MAX,
  48};
  49
  50#define AMT_FILTER_MAX (__AMT_FILTER_MAX - 1)
  51
  52enum amt_act {
  53        AMT_ACT_GMI,
  54        AMT_ACT_GMI_ZERO,
  55        AMT_ACT_GT,
  56        AMT_ACT_STATUS_FWD_NEW,
  57        AMT_ACT_STATUS_D_FWD_NEW,
  58        AMT_ACT_STATUS_NONE_NEW,
  59        __AMT_ACT_MAX,
  60};
  61
  62#define AMT_ACT_MAX (__AMT_ACT_MAX - 1)
  63
  64enum amt_status {
  65        AMT_STATUS_INIT,
  66        AMT_STATUS_SENT_DISCOVERY,
  67        AMT_STATUS_RECEIVED_DISCOVERY,
  68        AMT_STATUS_SENT_ADVERTISEMENT,
  69        AMT_STATUS_RECEIVED_ADVERTISEMENT,
  70        AMT_STATUS_SENT_REQUEST,
  71        AMT_STATUS_RECEIVED_REQUEST,
  72        AMT_STATUS_SENT_QUERY,
  73        AMT_STATUS_RECEIVED_QUERY,
  74        AMT_STATUS_SENT_UPDATE,
  75        AMT_STATUS_RECEIVED_UPDATE,
  76        __AMT_STATUS_MAX,
  77};
  78
  79#define AMT_STATUS_MAX (__AMT_STATUS_MAX - 1)
  80
  81struct amt_header {
  82#if defined(__LITTLE_ENDIAN_BITFIELD)
  83        u8 type:4,
  84           version:4;
  85#elif defined(__BIG_ENDIAN_BITFIELD)
  86        u8 version:4,
  87           type:4;
  88#else
  89#error  "Please fix <asm/byteorder.h>"
  90#endif
  91} __packed;
  92
  93struct amt_header_discovery {
  94#if defined(__LITTLE_ENDIAN_BITFIELD)
  95        u32     type:4,
  96                version:4,
  97                reserved:24;
  98#elif defined(__BIG_ENDIAN_BITFIELD)
  99        u32     version:4,
 100                type:4,
 101                reserved:24;
 102#else
 103#error  "Please fix <asm/byteorder.h>"
 104#endif
 105        __be32  nonce;
 106} __packed;
 107
 108struct amt_header_advertisement {
 109#if defined(__LITTLE_ENDIAN_BITFIELD)
 110        u32     type:4,
 111                version:4,
 112                reserved:24;
 113#elif defined(__BIG_ENDIAN_BITFIELD)
 114        u32     version:4,
 115                type:4,
 116                reserved:24;
 117#else
 118#error  "Please fix <asm/byteorder.h>"
 119#endif
 120        __be32  nonce;
 121        __be32  ip4;
 122} __packed;
 123
 124struct amt_header_request {
 125#if defined(__LITTLE_ENDIAN_BITFIELD)
 126        u32     type:4,
 127                version:4,
 128                reserved1:7,
 129                p:1,
 130                reserved2:16;
 131#elif defined(__BIG_ENDIAN_BITFIELD)
 132        u32     version:4,
 133                type:4,
 134                p:1,
 135                reserved1:7,
 136                reserved2:16;
 137#else
 138#error  "Please fix <asm/byteorder.h>"
 139#endif
 140        __be32  nonce;
 141} __packed;
 142
 143struct amt_header_membership_query {
 144#if defined(__LITTLE_ENDIAN_BITFIELD)
 145        u64     type:4,
 146                version:4,
 147                reserved:6,
 148                l:1,
 149                g:1,
 150                response_mac:48;
 151#elif defined(__BIG_ENDIAN_BITFIELD)
 152        u64     version:4,
 153                type:4,
 154                g:1,
 155                l:1,
 156                reserved:6,
 157                response_mac:48;
 158#else
 159#error  "Please fix <asm/byteorder.h>"
 160#endif
 161        __be32  nonce;
 162} __packed;
 163
 164struct amt_header_membership_update {
 165#if defined(__LITTLE_ENDIAN_BITFIELD)
 166        u64     type:4,
 167                version:4,
 168                reserved:8,
 169                response_mac:48;
 170#elif defined(__BIG_ENDIAN_BITFIELD)
 171        u64     version:4,
 172                type:4,
 173                reserved:8,
 174                response_mac:48;
 175#else
 176#error  "Please fix <asm/byteorder.h>"
 177#endif
 178        __be32  nonce;
 179} __packed;
 180
 181struct amt_header_mcast_data {
 182#if defined(__LITTLE_ENDIAN_BITFIELD)
 183        u16     type:4,
 184                version:4,
 185                reserved:8;
 186#elif defined(__BIG_ENDIAN_BITFIELD)
 187        u16     version:4,
 188                type:4,
 189                reserved:8;
 190#else
 191#error  "Please fix <asm/byteorder.h>"
 192#endif
 193} __packed;
 194
 195struct amt_headers {
 196        union {
 197                struct amt_header_discovery discovery;
 198                struct amt_header_advertisement advertisement;
 199                struct amt_header_request request;
 200                struct amt_header_membership_query query;
 201                struct amt_header_membership_update update;
 202                struct amt_header_mcast_data data;
 203        };
 204} __packed;
 205
 206struct amt_gw_headers {
 207        union {
 208                struct amt_header_discovery discovery;
 209                struct amt_header_request request;
 210                struct amt_header_membership_update update;
 211        };
 212} __packed;
 213
 214struct amt_relay_headers {
 215        union {
 216                struct amt_header_advertisement advertisement;
 217                struct amt_header_membership_query query;
 218                struct amt_header_mcast_data data;
 219        };
 220} __packed;
 221
 222struct amt_skb_cb {
 223        struct amt_tunnel_list *tunnel;
 224};
 225
 226struct amt_tunnel_list {
 227        struct list_head        list;
 228        /* Protect All resources under an amt_tunne_list */
 229        spinlock_t              lock;
 230        struct amt_dev          *amt;
 231        u32                     nr_groups;
 232        u32                     nr_sources;
 233        enum amt_status         status;
 234        struct delayed_work     gc_wq;
 235        __be16                  source_port;
 236        __be32                  ip4;
 237        __be32                  nonce;
 238        siphash_key_t           key;
 239        u64                     mac:48,
 240                                reserved:16;
 241        struct rcu_head         rcu;
 242        struct hlist_head       groups[];
 243};
 244
 245union amt_addr {
 246        __be32                  ip4;
 247#if IS_ENABLED(CONFIG_IPV6)
 248        struct in6_addr         ip6;
 249#endif
 250};
 251
 252/* RFC 3810
 253 *
 254 * When the router is in EXCLUDE mode, the router state is represented
 255 * by the notation EXCLUDE (X,Y), where X is called the "Requested List"
 256 * and Y is called the "Exclude List".  All sources, except those from
 257 * the Exclude List, will be forwarded by the router
 258 */
 259enum amt_source_status {
 260        AMT_SOURCE_STATUS_NONE,
 261        /* Node of Requested List */
 262        AMT_SOURCE_STATUS_FWD,
 263        /* Node of Exclude List */
 264        AMT_SOURCE_STATUS_D_FWD,
 265};
 266
 267/* protected by gnode->lock */
 268struct amt_source_node {
 269        struct hlist_node       node;
 270        struct amt_group_node   *gnode;
 271        struct delayed_work     source_timer;
 272        union amt_addr          source_addr;
 273        enum amt_source_status  status;
 274#define AMT_SOURCE_OLD  0
 275#define AMT_SOURCE_NEW  1
 276        u8                      flags;
 277        struct rcu_head         rcu;
 278};
 279
 280/* Protected by amt_tunnel_list->lock */
 281struct amt_group_node {
 282        struct amt_dev          *amt;
 283        union amt_addr          group_addr;
 284        union amt_addr          host_addr;
 285        bool                    v6;
 286        u8                      filter_mode;
 287        u32                     nr_sources;
 288        struct amt_tunnel_list  *tunnel_list;
 289        struct hlist_node       node;
 290        struct delayed_work     group_timer;
 291        struct rcu_head         rcu;
 292        struct hlist_head       sources[];
 293};
 294
 295struct amt_dev {
 296        struct net_device       *dev;
 297        struct net_device       *stream_dev;
 298        struct net              *net;
 299        /* Global lock for amt device */
 300        spinlock_t              lock;
 301        /* Used only in relay mode */
 302        struct list_head        tunnel_list;
 303        struct gro_cells        gro_cells;
 304
 305        /* Protected by RTNL */
 306        struct delayed_work     discovery_wq;
 307        /* Protected by RTNL */
 308        struct delayed_work     req_wq;
 309        /* Protected by RTNL */
 310        struct delayed_work     secret_wq;
 311        /* AMT status */
 312        enum amt_status         status;
 313        /* Generated key */
 314        siphash_key_t           key;
 315        struct socket     __rcu *sock;
 316        u32                     max_groups;
 317        u32                     max_sources;
 318        u32                     hash_buckets;
 319        u32                     hash_seed;
 320        /* Default 128 */
 321        u32                     max_tunnels;
 322        /* Default 128 */
 323        u32                     nr_tunnels;
 324        /* Gateway or Relay mode */
 325        u32                     mode;
 326        /* Default 2268 */
 327        __be16                  relay_port;
 328        /* Default 2268 */
 329        __be16                  gw_port;
 330        /* Outer local ip */
 331        __be32                  local_ip;
 332        /* Outer remote ip */
 333        __be32                  remote_ip;
 334        /* Outer discovery ip */
 335        __be32                  discovery_ip;
 336        /* Only used in gateway mode */
 337        __be32                  nonce;
 338        /* Gateway sent request and received query */
 339        bool                    ready4;
 340        bool                    ready6;
 341        u8                      req_cnt;
 342        u8                      qi;
 343        u64                     qrv;
 344        u64                     qri;
 345        /* Used only in gateway mode */
 346        u64                     mac:48,
 347                                reserved:16;
 348};
 349
 350#define AMT_TOS                 0xc0
 351#define AMT_IPHDR_OPTS          4
 352#define AMT_IP6HDR_OPTS         8
 353#define AMT_GC_INTERVAL         (30 * 1000)
 354#define AMT_MAX_GROUP           32
 355#define AMT_MAX_SOURCE          128
 356#define AMT_HSIZE_SHIFT         8
 357#define AMT_HSIZE               (1 << AMT_HSIZE_SHIFT)
 358
 359#define AMT_DISCOVERY_TIMEOUT   5000
 360#define AMT_INIT_REQ_TIMEOUT    1
 361#define AMT_INIT_QUERY_INTERVAL 125
 362#define AMT_MAX_REQ_TIMEOUT     120
 363#define AMT_MAX_REQ_COUNT       3
 364#define AMT_SECRET_TIMEOUT      60000
 365#define IANA_AMT_UDP_PORT       2268
 366#define AMT_MAX_TUNNELS         128
 367#define AMT_MAX_REQS            128
 368#define AMT_GW_HLEN (sizeof(struct iphdr) + \
 369                     sizeof(struct udphdr) + \
 370                     sizeof(struct amt_gw_headers))
 371#define AMT_RELAY_HLEN (sizeof(struct iphdr) + \
 372                     sizeof(struct udphdr) + \
 373                     sizeof(struct amt_relay_headers))
 374
 375static inline bool netif_is_amt(const struct net_device *dev)
 376{
 377        return dev->rtnl_link_ops && !strcmp(dev->rtnl_link_ops->kind, "amt");
 378}
 379
 380static inline u64 amt_gmi(const struct amt_dev *amt)
 381{
 382        return ((amt->qrv * amt->qi) + amt->qri) * 1000;
 383}
 384
 385#endif /* _NET_AMT_H_ */
 386