amt.h (8062B)
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_TEARDOWN, 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_ */