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