xref: /openbmc/linux/include/net/amt.h (revision 5c7587f6)
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