Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405/* SPDX-License-Identifier: GPL-2.0+ *//* * Copyright (c) 2021 Taehee Yoo <ap420073@gmail.com> */#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_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 16struct 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 sock __rcu *sk; 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_ */