1
2
3
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
26 AMT_OPS_INT,
27
28 AMT_OPS_UNI,
29
30 AMT_OPS_SUB,
31
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
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
253
254
255
256
257
258
259enum amt_source_status {
260 AMT_SOURCE_STATUS_NONE,
261
262 AMT_SOURCE_STATUS_FWD,
263
264 AMT_SOURCE_STATUS_D_FWD,
265};
266
267
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
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
300 spinlock_t lock;
301
302 struct list_head tunnel_list;
303 struct gro_cells gro_cells;
304
305
306 struct delayed_work discovery_wq;
307
308 struct delayed_work req_wq;
309
310 struct delayed_work secret_wq;
311
312 enum amt_status status;
313
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
321 u32 max_tunnels;
322
323 u32 nr_tunnels;
324
325 u32 mode;
326
327 __be16 relay_port;
328
329 __be16 gw_port;
330
331 __be32 local_ip;
332
333 __be32 remote_ip;
334
335 __be32 discovery_ip;
336
337 __be32 nonce;
338
339 bool ready4;
340 bool ready6;
341 u8 req_cnt;
342 u8 qi;
343 u64 qrv;
344 u64 qri;
345
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
386