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