Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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
 14enum 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
 27enum 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
 41enum 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
 55enum 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
 67enum 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 */
 85enum 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
 93struct 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
105struct 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
120struct 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
136struct 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
155struct 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
176struct 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
193struct 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
207struct 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
218struct 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
226struct 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
234struct amt_skb_cb {
235	struct amt_tunnel_list *tunnel;
236};
237
238struct 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
257union 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 */
271enum 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 */
280struct 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 */
293struct 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
308struct amt_events {
309	enum amt_event event;
310	struct sk_buff *skb;
311};
312
313struct 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
398static 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
403static 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_ */