123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- /* SPDX-License-Identifier: GPL-2.0+ */
- /*
- * Copyright (c) 2021 Taehee Yoo <[email protected]>
- */
- #ifndef _NET_AMT_H_
- #define _NET_AMT_H_
- #include <linux/siphash.h>
- #include <linux/jhash.h>
- #include <linux/netdevice.h>
- #include <net/gro_cells.h>
- #include <net/rtnetlink.h>
- enum amt_msg_type {
- AMT_MSG_DISCOVERY = 1,
- AMT_MSG_ADVERTISEMENT,
- AMT_MSG_REQUEST,
- AMT_MSG_MEMBERSHIP_QUERY,
- AMT_MSG_MEMBERSHIP_UPDATE,
- AMT_MSG_MULTICAST_DATA,
- AMT_MSG_TEARDOWN,
- __AMT_MSG_MAX,
- };
- #define AMT_MSG_MAX (__AMT_MSG_MAX - 1)
- enum amt_ops {
- /* A*B */
- AMT_OPS_INT,
- /* A+B */
- AMT_OPS_UNI,
- /* A-B */
- AMT_OPS_SUB,
- /* B-A */
- AMT_OPS_SUB_REV,
- __AMT_OPS_MAX,
- };
- #define AMT_OPS_MAX (__AMT_OPS_MAX - 1)
- enum amt_filter {
- AMT_FILTER_FWD,
- AMT_FILTER_D_FWD,
- AMT_FILTER_FWD_NEW,
- AMT_FILTER_D_FWD_NEW,
- AMT_FILTER_ALL,
- AMT_FILTER_NONE_NEW,
- AMT_FILTER_BOTH,
- AMT_FILTER_BOTH_NEW,
- __AMT_FILTER_MAX,
- };
- #define AMT_FILTER_MAX (__AMT_FILTER_MAX - 1)
- enum amt_act {
- AMT_ACT_GMI,
- AMT_ACT_GMI_ZERO,
- AMT_ACT_GT,
- AMT_ACT_STATUS_FWD_NEW,
- AMT_ACT_STATUS_D_FWD_NEW,
- AMT_ACT_STATUS_NONE_NEW,
- __AMT_ACT_MAX,
- };
- #define AMT_ACT_MAX (__AMT_ACT_MAX - 1)
- enum amt_status {
- AMT_STATUS_INIT,
- AMT_STATUS_SENT_DISCOVERY,
- AMT_STATUS_RECEIVED_DISCOVERY,
- AMT_STATUS_SENT_ADVERTISEMENT,
- AMT_STATUS_RECEIVED_ADVERTISEMENT,
- AMT_STATUS_SENT_REQUEST,
- AMT_STATUS_RECEIVED_REQUEST,
- AMT_STATUS_SENT_QUERY,
- AMT_STATUS_RECEIVED_QUERY,
- AMT_STATUS_SENT_UPDATE,
- AMT_STATUS_RECEIVED_UPDATE,
- __AMT_STATUS_MAX,
- };
- #define AMT_STATUS_MAX (__AMT_STATUS_MAX - 1)
- /* Gateway events only */
- enum amt_event {
- AMT_EVENT_NONE,
- AMT_EVENT_RECEIVE,
- AMT_EVENT_SEND_DISCOVERY,
- AMT_EVENT_SEND_REQUEST,
- __AMT_EVENT_MAX,
- };
- struct amt_header {
- #if defined(__LITTLE_ENDIAN_BITFIELD)
- u8 type:4,
- version:4;
- #elif defined(__BIG_ENDIAN_BITFIELD)
- u8 version:4,
- type:4;
- #else
- #error "Please fix <asm/byteorder.h>"
- #endif
- } __packed;
- struct amt_header_discovery {
- #if defined(__LITTLE_ENDIAN_BITFIELD)
- u32 type:4,
- version:4,
- reserved:24;
- #elif defined(__BIG_ENDIAN_BITFIELD)
- u32 version:4,
- type:4,
- reserved:24;
- #else
- #error "Please fix <asm/byteorder.h>"
- #endif
- __be32 nonce;
- } __packed;
- struct amt_header_advertisement {
- #if defined(__LITTLE_ENDIAN_BITFIELD)
- u32 type:4,
- version:4,
- reserved:24;
- #elif defined(__BIG_ENDIAN_BITFIELD)
- u32 version:4,
- type:4,
- reserved:24;
- #else
- #error "Please fix <asm/byteorder.h>"
- #endif
- __be32 nonce;
- __be32 ip4;
- } __packed;
- struct amt_header_request {
- #if defined(__LITTLE_ENDIAN_BITFIELD)
- u32 type:4,
- version:4,
- reserved1:7,
- p:1,
- reserved2:16;
- #elif defined(__BIG_ENDIAN_BITFIELD)
- u32 version:4,
- type:4,
- p:1,
- reserved1:7,
- reserved2:16;
- #else
- #error "Please fix <asm/byteorder.h>"
- #endif
- __be32 nonce;
- } __packed;
- struct amt_header_membership_query {
- #if defined(__LITTLE_ENDIAN_BITFIELD)
- u64 type:4,
- version:4,
- reserved:6,
- l:1,
- g:1,
- response_mac:48;
- #elif defined(__BIG_ENDIAN_BITFIELD)
- u64 version:4,
- type:4,
- g:1,
- l:1,
- reserved:6,
- response_mac:48;
- #else
- #error "Please fix <asm/byteorder.h>"
- #endif
- __be32 nonce;
- } __packed;
- struct amt_header_membership_update {
- #if defined(__LITTLE_ENDIAN_BITFIELD)
- u64 type:4,
- version:4,
- reserved:8,
- response_mac:48;
- #elif defined(__BIG_ENDIAN_BITFIELD)
- u64 version:4,
- type:4,
- reserved:8,
- response_mac:48;
- #else
- #error "Please fix <asm/byteorder.h>"
- #endif
- __be32 nonce;
- } __packed;
- struct amt_header_mcast_data {
- #if defined(__LITTLE_ENDIAN_BITFIELD)
- u16 type:4,
- version:4,
- reserved:8;
- #elif defined(__BIG_ENDIAN_BITFIELD)
- u16 version:4,
- type:4,
- reserved:8;
- #else
- #error "Please fix <asm/byteorder.h>"
- #endif
- } __packed;
- struct amt_headers {
- union {
- struct amt_header_discovery discovery;
- struct amt_header_advertisement advertisement;
- struct amt_header_request request;
- struct amt_header_membership_query query;
- struct amt_header_membership_update update;
- struct amt_header_mcast_data data;
- };
- } __packed;
- struct amt_gw_headers {
- union {
- struct amt_header_discovery discovery;
- struct amt_header_request request;
- struct amt_header_membership_update update;
- };
- } __packed;
- struct amt_relay_headers {
- union {
- struct amt_header_advertisement advertisement;
- struct amt_header_membership_query query;
- struct amt_header_mcast_data data;
- };
- } __packed;
- struct amt_skb_cb {
- struct amt_tunnel_list *tunnel;
- };
- struct amt_tunnel_list {
- struct list_head list;
- /* Protect All resources under an amt_tunne_list */
- spinlock_t lock;
- struct amt_dev *amt;
- u32 nr_groups;
- u32 nr_sources;
- enum amt_status status;
- struct delayed_work gc_wq;
- __be16 source_port;
- __be32 ip4;
- __be32 nonce;
- siphash_key_t key;
- u64 mac:48,
- reserved:16;
- struct rcu_head rcu;
- struct hlist_head groups[];
- };
- union amt_addr {
- __be32 ip4;
- #if IS_ENABLED(CONFIG_IPV6)
- struct in6_addr ip6;
- #endif
- };
- /* RFC 3810
- *
- * When the router is in EXCLUDE mode, the router state is represented
- * by the notation EXCLUDE (X,Y), where X is called the "Requested List"
- * and Y is called the "Exclude List". All sources, except those from
- * the Exclude List, will be forwarded by the router
- */
- enum amt_source_status {
- AMT_SOURCE_STATUS_NONE,
- /* Node of Requested List */
- AMT_SOURCE_STATUS_FWD,
- /* Node of Exclude List */
- AMT_SOURCE_STATUS_D_FWD,
- };
- /* protected by gnode->lock */
- struct amt_source_node {
- struct hlist_node node;
- struct amt_group_node *gnode;
- struct delayed_work source_timer;
- union amt_addr source_addr;
- enum amt_source_status status;
- #define AMT_SOURCE_OLD 0
- #define AMT_SOURCE_NEW 1
- u8 flags;
- struct rcu_head rcu;
- };
- /* Protected by amt_tunnel_list->lock */
- struct amt_group_node {
- struct amt_dev *amt;
- union amt_addr group_addr;
- union amt_addr host_addr;
- bool v6;
- u8 filter_mode;
- u32 nr_sources;
- struct amt_tunnel_list *tunnel_list;
- struct hlist_node node;
- struct delayed_work group_timer;
- struct rcu_head rcu;
- struct hlist_head sources[];
- };
- #define AMT_MAX_EVENTS 16
- struct amt_events {
- enum amt_event event;
- struct sk_buff *skb;
- };
- struct amt_dev {
- struct net_device *dev;
- struct net_device *stream_dev;
- struct net *net;
- /* Global lock for amt device */
- spinlock_t lock;
- /* Used only in relay mode */
- struct list_head tunnel_list;
- struct gro_cells gro_cells;
- /* Protected by RTNL */
- struct delayed_work discovery_wq;
- /* Protected by RTNL */
- struct delayed_work req_wq;
- /* Protected by RTNL */
- struct delayed_work secret_wq;
- struct work_struct event_wq;
- /* AMT status */
- enum amt_status status;
- /* Generated key */
- siphash_key_t key;
- struct socket __rcu *sock;
- u32 max_groups;
- u32 max_sources;
- u32 hash_buckets;
- u32 hash_seed;
- /* Default 128 */
- u32 max_tunnels;
- /* Default 128 */
- u32 nr_tunnels;
- /* Gateway or Relay mode */
- u32 mode;
- /* Default 2268 */
- __be16 relay_port;
- /* Default 2268 */
- __be16 gw_port;
- /* Outer local ip */
- __be32 local_ip;
- /* Outer remote ip */
- __be32 remote_ip;
- /* Outer discovery ip */
- __be32 discovery_ip;
- /* Only used in gateway mode */
- __be32 nonce;
- /* Gateway sent request and received query */
- bool ready4;
- bool ready6;
- u8 req_cnt;
- u8 qi;
- u64 qrv;
- u64 qri;
- /* Used only in gateway mode */
- u64 mac:48,
- reserved:16;
- /* AMT gateway side message handler queue */
- struct amt_events events[AMT_MAX_EVENTS];
- u8 event_idx;
- u8 nr_events;
- };
- #define AMT_TOS 0xc0
- #define AMT_IPHDR_OPTS 4
- #define AMT_IP6HDR_OPTS 8
- #define AMT_GC_INTERVAL (30 * 1000)
- #define AMT_MAX_GROUP 32
- #define AMT_MAX_SOURCE 128
- #define AMT_HSIZE_SHIFT 8
- #define AMT_HSIZE (1 << AMT_HSIZE_SHIFT)
- #define AMT_DISCOVERY_TIMEOUT 5000
- #define AMT_INIT_REQ_TIMEOUT 1
- #define AMT_INIT_QUERY_INTERVAL 125
- #define AMT_MAX_REQ_TIMEOUT 120
- #define AMT_MAX_REQ_COUNT 3
- #define AMT_SECRET_TIMEOUT 60000
- #define IANA_AMT_UDP_PORT 2268
- #define AMT_MAX_TUNNELS 128
- #define AMT_MAX_REQS 128
- #define AMT_GW_HLEN (sizeof(struct iphdr) + \
- sizeof(struct udphdr) + \
- sizeof(struct amt_gw_headers))
- #define AMT_RELAY_HLEN (sizeof(struct iphdr) + \
- sizeof(struct udphdr) + \
- sizeof(struct amt_relay_headers))
- static inline bool netif_is_amt(const struct net_device *dev)
- {
- return dev->rtnl_link_ops && !strcmp(dev->rtnl_link_ops->kind, "amt");
- }
- static inline u64 amt_gmi(const struct amt_dev *amt)
- {
- return ((amt->qrv * amt->qi) + amt->qri) * 1000;
- }
- #endif /* _NET_AMT_H_ */
|