1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2013-2018 Universita` di Pisa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *   1. Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *   2. Redistributions in binary form must reproduce the above copyright
13 *      notice, this list of conditions and the following disclaimer in the
14 *      documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28#ifndef _NET_NETMAP_BDG_H_
29#define _NET_NETMAP_BDG_H_
30
31#if defined(__FreeBSD__)
32#define BDG_RWLOCK_T		struct rwlock // struct rwlock
33
34#define	BDG_RWINIT(b)		\
35	rw_init_flags(&(b)->bdg_lock, "bdg lock", RW_NOWITNESS)
36#define BDG_WLOCK(b)		rw_wlock(&(b)->bdg_lock)
37#define BDG_WUNLOCK(b)		rw_wunlock(&(b)->bdg_lock)
38#define BDG_RLOCK(b)		rw_rlock(&(b)->bdg_lock)
39#define BDG_RTRYLOCK(b)		rw_try_rlock(&(b)->bdg_lock)
40#define BDG_RUNLOCK(b)		rw_runlock(&(b)->bdg_lock)
41#define BDG_RWDESTROY(b)	rw_destroy(&(b)->bdg_lock)
42
43#endif /* __FreeBSD__ */
44
45/*
46 * The following bridge-related functions are used by other
47 * kernel modules.
48 *
49 * VALE only supports unicast or broadcast. The lookup
50 * function can return 0 .. NM_BDG_MAXPORTS-1 for regular ports,
51 * NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 to indicate
52 * drop.
53 */
54typedef uint32_t (*bdg_lookup_fn_t)(struct nm_bdg_fwd *ft, uint8_t *ring_nr,
55		struct netmap_vp_adapter *, void *private_data);
56typedef int (*bdg_config_fn_t)(struct nm_ifreq *);
57typedef void (*bdg_dtor_fn_t)(const struct netmap_vp_adapter *);
58typedef void *(*bdg_update_private_data_fn_t)(void *private_data, void *callback_data, int *error);
59typedef int (*bdg_vp_create_fn_t)(struct nmreq_header *hdr,
60		if_t ifp, struct netmap_mem_d *nmd,
61		struct netmap_vp_adapter **ret);
62typedef int (*bdg_bwrap_attach_fn_t)(const char *nr_name, struct netmap_adapter *hwna);
63struct netmap_bdg_ops {
64	bdg_lookup_fn_t lookup;
65	bdg_config_fn_t config;
66	bdg_dtor_fn_t	dtor;
67	bdg_vp_create_fn_t	vp_create;
68	bdg_bwrap_attach_fn_t	bwrap_attach;
69	char name[IFNAMSIZ];
70};
71int netmap_bwrap_attach(const char *name, struct netmap_adapter *, struct netmap_bdg_ops *);
72int netmap_bdg_regops(const char *name, struct netmap_bdg_ops *bdg_ops, void *private_data, void *auth_token);
73
74#define	NM_BRIDGES		8	/* number of bridges */
75#define	NM_BDG_MAXPORTS		254	/* up to 254 */
76#define	NM_BDG_BROADCAST	NM_BDG_MAXPORTS
77#define	NM_BDG_NOPORT		(NM_BDG_MAXPORTS+1)
78
79/* XXX Should go away after fixing find_bridge() - Michio */
80#define NM_BDG_HASH		1024	/* forwarding table entries */
81
82/* XXX revise this */
83struct nm_hash_ent {
84	uint64_t	mac;	/* the top 2 bytes are the epoch */
85	uint64_t	ports;
86};
87
88/* Default size for the Maximum Frame Size. */
89#define NM_BDG_MFS_DEFAULT	1514
90
91/*
92 * nm_bridge is a descriptor for a VALE switch.
93 * Interfaces for a bridge are all in bdg_ports[].
94 * The array has fixed size, an empty entry does not terminate
95 * the search, but lookups only occur on attach/detach so we
96 * don't mind if they are slow.
97 *
98 * The bridge is non blocking on the transmit ports: excess
99 * packets are dropped if there is no room on the output port.
100 *
101 * bdg_lock protects accesses to the bdg_ports array.
102 * This is a rw lock (or equivalent).
103 */
104#define NM_BDG_IFNAMSIZ IFNAMSIZ
105struct nm_bridge {
106	/* XXX what is the proper alignment/layout ? */
107	BDG_RWLOCK_T	bdg_lock;	/* protects bdg_ports */
108	int		bdg_namelen;
109	uint32_t	bdg_active_ports;
110	char		bdg_basename[NM_BDG_IFNAMSIZ];
111
112	/* Indexes of active ports (up to active_ports)
113	 * and all other remaining ports.
114	 */
115	uint32_t	bdg_port_index[NM_BDG_MAXPORTS];
116	/* used by netmap_bdg_detach_common() */
117	uint32_t	tmp_bdg_port_index[NM_BDG_MAXPORTS];
118
119	struct netmap_vp_adapter *bdg_ports[NM_BDG_MAXPORTS];
120
121	/*
122	 * Programmable lookup functions to figure out the destination port.
123	 * It returns either of an index of the destination port,
124	 * NM_BDG_BROADCAST to broadcast this packet, or NM_BDG_NOPORT not to
125	 * forward this packet.  ring_nr is the source ring index, and the
126	 * function may overwrite this value to forward this packet to a
127	 * different ring index.
128	 * The function is set by netmap_bdg_regops().
129	 */
130	struct netmap_bdg_ops bdg_ops;
131	struct netmap_bdg_ops bdg_saved_ops;
132
133	/*
134	 * Contains the data structure used by the bdg_ops.lookup function.
135	 * By default points to *ht which is allocated on attach and used by the default lookup
136	 * otherwise will point to the data structure received by netmap_bdg_regops().
137	 */
138	void *private_data;
139	struct nm_hash_ent *ht;
140
141	/* Currently used to specify if the bridge is still in use while empty and
142	 * if it has been put in exclusive mode by an external module, see netmap_bdg_regops()
143	 * and netmap_bdg_create().
144	 */
145#define NM_BDG_ACTIVE		1
146#define NM_BDG_EXCLUSIVE	2
147#define NM_BDG_NEED_BWRAP	4
148	uint8_t			bdg_flags;
149
150
151#ifdef CONFIG_NET_NS
152	struct net *ns;
153#endif /* CONFIG_NET_NS */
154};
155
156static inline void *
157nm_bdg_get_auth_token(struct nm_bridge *b)
158{
159	return b->ht;
160}
161
162/* bridge not in exclusive mode ==> always valid
163 * bridge in exclusive mode (created through netmap_bdg_create()) ==> check authentication token
164 */
165static inline int
166nm_bdg_valid_auth_token(struct nm_bridge *b, void *auth_token)
167{
168	return !(b->bdg_flags & NM_BDG_EXCLUSIVE) || b->ht == auth_token;
169}
170
171int netmap_get_bdg_na(struct nmreq_header *hdr, struct netmap_adapter **na,
172	struct netmap_mem_d *nmd, int create, struct netmap_bdg_ops *ops);
173
174struct nm_bridge *nm_find_bridge(const char *name, int create, struct netmap_bdg_ops *ops);
175int netmap_bdg_free(struct nm_bridge *b);
176void netmap_bdg_detach_common(struct nm_bridge *b, int hw, int sw);
177int netmap_vp_bdg_ctl(struct nmreq_header *hdr, struct netmap_adapter *na);
178int netmap_bwrap_reg(struct netmap_adapter *, int onoff);
179int netmap_bdg_detach_locked(struct nmreq_header *hdr, void *auth_token);
180int netmap_vp_reg(struct netmap_adapter *na, int onoff);
181int netmap_vp_rxsync(struct netmap_kring *kring, int flags);
182int netmap_bwrap_intr_notify(struct netmap_kring *kring, int flags);
183int netmap_bwrap_notify(struct netmap_kring *kring, int flags);
184int netmap_bwrap_attach_common(struct netmap_adapter *na,
185		struct netmap_adapter *hwna);
186int netmap_bwrap_krings_create_common(struct netmap_adapter *na);
187void netmap_bwrap_krings_delete_common(struct netmap_adapter *na);
188struct nm_bridge *netmap_init_bridges2(u_int);
189void netmap_uninit_bridges2(struct nm_bridge *, u_int);
190int netmap_bdg_update_private_data(const char *name, bdg_update_private_data_fn_t callback,
191	void *callback_data, void *auth_token);
192int netmap_bdg_config(struct nm_ifreq *nifr);
193
194#define NM_NEED_BWRAP (-2)
195#endif /* _NET_NETMAP_BDG_H_ */
196
197