xref: /freebsd/sys/dev/netmap/netmap_bdg.h (revision b6e66be22bdce2aadcf52ee6230faa1e6cd3f805)
12a7db7a6SVincenzo Maffione /*-
22a7db7a6SVincenzo Maffione  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
32a7db7a6SVincenzo Maffione  *
42a7db7a6SVincenzo Maffione  * Copyright (C) 2013-2018 Universita` di Pisa
52a7db7a6SVincenzo Maffione  * All rights reserved.
62a7db7a6SVincenzo Maffione  *
72a7db7a6SVincenzo Maffione  * Redistribution and use in source and binary forms, with or without
82a7db7a6SVincenzo Maffione  * modification, are permitted provided that the following conditions
92a7db7a6SVincenzo Maffione  * are met:
102a7db7a6SVincenzo Maffione  *   1. Redistributions of source code must retain the above copyright
112a7db7a6SVincenzo Maffione  *      notice, this list of conditions and the following disclaimer.
122a7db7a6SVincenzo Maffione  *   2. Redistributions in binary form must reproduce the above copyright
132a7db7a6SVincenzo Maffione  *      notice, this list of conditions and the following disclaimer in the
142a7db7a6SVincenzo Maffione  *      documentation and/or other materials provided with the distribution.
152a7db7a6SVincenzo Maffione  *
162a7db7a6SVincenzo Maffione  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
172a7db7a6SVincenzo Maffione  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
182a7db7a6SVincenzo Maffione  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
192a7db7a6SVincenzo Maffione  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
202a7db7a6SVincenzo Maffione  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
212a7db7a6SVincenzo Maffione  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
222a7db7a6SVincenzo Maffione  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
232a7db7a6SVincenzo Maffione  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
242a7db7a6SVincenzo Maffione  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
252a7db7a6SVincenzo Maffione  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
262a7db7a6SVincenzo Maffione  * SUCH DAMAGE.
272a7db7a6SVincenzo Maffione  *
282a7db7a6SVincenzo Maffione  * $FreeBSD$
292a7db7a6SVincenzo Maffione  */
302a7db7a6SVincenzo Maffione #ifndef _NET_NETMAP_BDG_H_
312a7db7a6SVincenzo Maffione #define _NET_NETMAP_BDG_H_
322a7db7a6SVincenzo Maffione 
332a7db7a6SVincenzo Maffione #if defined(__FreeBSD__)
342a7db7a6SVincenzo Maffione #define BDG_RWLOCK_T		struct rwlock // struct rwlock
352a7db7a6SVincenzo Maffione 
362a7db7a6SVincenzo Maffione #define	BDG_RWINIT(b)		\
372a7db7a6SVincenzo Maffione 	rw_init_flags(&(b)->bdg_lock, "bdg lock", RW_NOWITNESS)
382a7db7a6SVincenzo Maffione #define BDG_WLOCK(b)		rw_wlock(&(b)->bdg_lock)
392a7db7a6SVincenzo Maffione #define BDG_WUNLOCK(b)		rw_wunlock(&(b)->bdg_lock)
402a7db7a6SVincenzo Maffione #define BDG_RLOCK(b)		rw_rlock(&(b)->bdg_lock)
412a7db7a6SVincenzo Maffione #define BDG_RTRYLOCK(b)		rw_try_rlock(&(b)->bdg_lock)
422a7db7a6SVincenzo Maffione #define BDG_RUNLOCK(b)		rw_runlock(&(b)->bdg_lock)
432a7db7a6SVincenzo Maffione #define BDG_RWDESTROY(b)	rw_destroy(&(b)->bdg_lock)
442a7db7a6SVincenzo Maffione 
452a7db7a6SVincenzo Maffione #endif /* __FreeBSD__ */
462a7db7a6SVincenzo Maffione 
47*b6e66be2SVincenzo Maffione /*
48*b6e66be2SVincenzo Maffione  * The following bridge-related functions are used by other
49*b6e66be2SVincenzo Maffione  * kernel modules.
50*b6e66be2SVincenzo Maffione  *
51*b6e66be2SVincenzo Maffione  * VALE only supports unicast or broadcast. The lookup
52*b6e66be2SVincenzo Maffione  * function can return 0 .. NM_BDG_MAXPORTS-1 for regular ports,
53*b6e66be2SVincenzo Maffione  * NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 to indicate
54*b6e66be2SVincenzo Maffione  * drop.
55*b6e66be2SVincenzo Maffione  */
56*b6e66be2SVincenzo Maffione typedef uint32_t (*bdg_lookup_fn_t)(struct nm_bdg_fwd *ft, uint8_t *ring_nr,
57*b6e66be2SVincenzo Maffione 		struct netmap_vp_adapter *, void *private_data);
58*b6e66be2SVincenzo Maffione typedef int (*bdg_config_fn_t)(struct nm_ifreq *);
59*b6e66be2SVincenzo Maffione typedef void (*bdg_dtor_fn_t)(const struct netmap_vp_adapter *);
60*b6e66be2SVincenzo Maffione typedef void *(*bdg_update_private_data_fn_t)(void *private_data, void *callback_data, int *error);
61*b6e66be2SVincenzo Maffione typedef int (*bdg_vp_create_fn_t)(struct nmreq_header *hdr,
62*b6e66be2SVincenzo Maffione 		struct ifnet *ifp, struct netmap_mem_d *nmd,
63*b6e66be2SVincenzo Maffione 		struct netmap_vp_adapter **ret);
64*b6e66be2SVincenzo Maffione typedef int (*bdg_bwrap_attach_fn_t)(const char *nr_name, struct netmap_adapter *hwna);
65*b6e66be2SVincenzo Maffione struct netmap_bdg_ops {
66*b6e66be2SVincenzo Maffione 	bdg_lookup_fn_t lookup;
67*b6e66be2SVincenzo Maffione 	bdg_config_fn_t config;
68*b6e66be2SVincenzo Maffione 	bdg_dtor_fn_t	dtor;
69*b6e66be2SVincenzo Maffione 	bdg_vp_create_fn_t	vp_create;
70*b6e66be2SVincenzo Maffione 	bdg_bwrap_attach_fn_t	bwrap_attach;
71*b6e66be2SVincenzo Maffione 	char name[IFNAMSIZ];
72*b6e66be2SVincenzo Maffione };
73*b6e66be2SVincenzo Maffione int netmap_bwrap_attach(const char *name, struct netmap_adapter *, struct netmap_bdg_ops *);
74*b6e66be2SVincenzo Maffione int netmap_bdg_regops(const char *name, struct netmap_bdg_ops *bdg_ops, void *private_data, void *auth_token);
75*b6e66be2SVincenzo Maffione 
76*b6e66be2SVincenzo Maffione #define	NM_BRIDGES		8	/* number of bridges */
77*b6e66be2SVincenzo Maffione #define	NM_BDG_MAXPORTS		254	/* up to 254 */
78*b6e66be2SVincenzo Maffione #define	NM_BDG_BROADCAST	NM_BDG_MAXPORTS
79*b6e66be2SVincenzo Maffione #define	NM_BDG_NOPORT		(NM_BDG_MAXPORTS+1)
80*b6e66be2SVincenzo Maffione 
812a7db7a6SVincenzo Maffione /* XXX Should go away after fixing find_bridge() - Michio */
822a7db7a6SVincenzo Maffione #define NM_BDG_HASH		1024	/* forwarding table entries */
832a7db7a6SVincenzo Maffione 
842a7db7a6SVincenzo Maffione /* XXX revise this */
852a7db7a6SVincenzo Maffione struct nm_hash_ent {
862a7db7a6SVincenzo Maffione 	uint64_t	mac;	/* the top 2 bytes are the epoch */
872a7db7a6SVincenzo Maffione 	uint64_t	ports;
882a7db7a6SVincenzo Maffione };
892a7db7a6SVincenzo Maffione 
902a7db7a6SVincenzo Maffione /* Default size for the Maximum Frame Size. */
912a7db7a6SVincenzo Maffione #define NM_BDG_MFS_DEFAULT	1514
922a7db7a6SVincenzo Maffione 
932a7db7a6SVincenzo Maffione /*
942a7db7a6SVincenzo Maffione  * nm_bridge is a descriptor for a VALE switch.
952a7db7a6SVincenzo Maffione  * Interfaces for a bridge are all in bdg_ports[].
962a7db7a6SVincenzo Maffione  * The array has fixed size, an empty entry does not terminate
972a7db7a6SVincenzo Maffione  * the search, but lookups only occur on attach/detach so we
982a7db7a6SVincenzo Maffione  * don't mind if they are slow.
992a7db7a6SVincenzo Maffione  *
1002a7db7a6SVincenzo Maffione  * The bridge is non blocking on the transmit ports: excess
1012a7db7a6SVincenzo Maffione  * packets are dropped if there is no room on the output port.
1022a7db7a6SVincenzo Maffione  *
1032a7db7a6SVincenzo Maffione  * bdg_lock protects accesses to the bdg_ports array.
1042a7db7a6SVincenzo Maffione  * This is a rw lock (or equivalent).
1052a7db7a6SVincenzo Maffione  */
1062a7db7a6SVincenzo Maffione #define NM_BDG_IFNAMSIZ IFNAMSIZ
1072a7db7a6SVincenzo Maffione struct nm_bridge {
1082a7db7a6SVincenzo Maffione 	/* XXX what is the proper alignment/layout ? */
1092a7db7a6SVincenzo Maffione 	BDG_RWLOCK_T	bdg_lock;	/* protects bdg_ports */
1102a7db7a6SVincenzo Maffione 	int		bdg_namelen;
1112a7db7a6SVincenzo Maffione 	uint32_t	bdg_active_ports;
1122a7db7a6SVincenzo Maffione 	char		bdg_basename[NM_BDG_IFNAMSIZ];
1132a7db7a6SVincenzo Maffione 
1142a7db7a6SVincenzo Maffione 	/* Indexes of active ports (up to active_ports)
1152a7db7a6SVincenzo Maffione 	 * and all other remaining ports.
1162a7db7a6SVincenzo Maffione 	 */
1172a7db7a6SVincenzo Maffione 	uint32_t	bdg_port_index[NM_BDG_MAXPORTS];
1182a7db7a6SVincenzo Maffione 	/* used by netmap_bdg_detach_common() */
1192a7db7a6SVincenzo Maffione 	uint32_t	tmp_bdg_port_index[NM_BDG_MAXPORTS];
1202a7db7a6SVincenzo Maffione 
1212a7db7a6SVincenzo Maffione 	struct netmap_vp_adapter *bdg_ports[NM_BDG_MAXPORTS];
1222a7db7a6SVincenzo Maffione 
1232a7db7a6SVincenzo Maffione 	/*
1242a7db7a6SVincenzo Maffione 	 * Programmable lookup functions to figure out the destination port.
1252a7db7a6SVincenzo Maffione 	 * It returns either of an index of the destination port,
1262a7db7a6SVincenzo Maffione 	 * NM_BDG_BROADCAST to broadcast this packet, or NM_BDG_NOPORT not to
1272a7db7a6SVincenzo Maffione 	 * forward this packet.  ring_nr is the source ring index, and the
1282a7db7a6SVincenzo Maffione 	 * function may overwrite this value to forward this packet to a
1292a7db7a6SVincenzo Maffione 	 * different ring index.
1302a7db7a6SVincenzo Maffione 	 * The function is set by netmap_bdg_regops().
1312a7db7a6SVincenzo Maffione 	 */
132*b6e66be2SVincenzo Maffione 	struct netmap_bdg_ops bdg_ops;
133*b6e66be2SVincenzo Maffione 	struct netmap_bdg_ops bdg_saved_ops;
1342a7db7a6SVincenzo Maffione 
1352a7db7a6SVincenzo Maffione 	/*
1362a7db7a6SVincenzo Maffione 	 * Contains the data structure used by the bdg_ops.lookup function.
1372a7db7a6SVincenzo Maffione 	 * By default points to *ht which is allocated on attach and used by the default lookup
1382a7db7a6SVincenzo Maffione 	 * otherwise will point to the data structure received by netmap_bdg_regops().
1392a7db7a6SVincenzo Maffione 	 */
1402a7db7a6SVincenzo Maffione 	void *private_data;
1412a7db7a6SVincenzo Maffione 	struct nm_hash_ent *ht;
1422a7db7a6SVincenzo Maffione 
1432a7db7a6SVincenzo Maffione 	/* Currently used to specify if the bridge is still in use while empty and
1442a7db7a6SVincenzo Maffione 	 * if it has been put in exclusive mode by an external module, see netmap_bdg_regops()
1452a7db7a6SVincenzo Maffione 	 * and netmap_bdg_create().
1462a7db7a6SVincenzo Maffione 	 */
1472a7db7a6SVincenzo Maffione #define NM_BDG_ACTIVE		1
1482a7db7a6SVincenzo Maffione #define NM_BDG_EXCLUSIVE	2
149*b6e66be2SVincenzo Maffione #define NM_BDG_NEED_BWRAP	4
1502a7db7a6SVincenzo Maffione 	uint8_t			bdg_flags;
1512a7db7a6SVincenzo Maffione 
1522a7db7a6SVincenzo Maffione 
1532a7db7a6SVincenzo Maffione #ifdef CONFIG_NET_NS
1542a7db7a6SVincenzo Maffione 	struct net *ns;
1552a7db7a6SVincenzo Maffione #endif /* CONFIG_NET_NS */
1562a7db7a6SVincenzo Maffione };
1572a7db7a6SVincenzo Maffione 
1582a7db7a6SVincenzo Maffione static inline void *
1592a7db7a6SVincenzo Maffione nm_bdg_get_auth_token(struct nm_bridge *b)
1602a7db7a6SVincenzo Maffione {
1612a7db7a6SVincenzo Maffione 	return b->ht;
1622a7db7a6SVincenzo Maffione }
1632a7db7a6SVincenzo Maffione 
1642a7db7a6SVincenzo Maffione /* bridge not in exclusive mode ==> always valid
1652a7db7a6SVincenzo Maffione  * bridge in exclusive mode (created through netmap_bdg_create()) ==> check authentication token
1662a7db7a6SVincenzo Maffione  */
1672a7db7a6SVincenzo Maffione static inline int
1682a7db7a6SVincenzo Maffione nm_bdg_valid_auth_token(struct nm_bridge *b, void *auth_token)
1692a7db7a6SVincenzo Maffione {
1702a7db7a6SVincenzo Maffione 	return !(b->bdg_flags & NM_BDG_EXCLUSIVE) || b->ht == auth_token;
1712a7db7a6SVincenzo Maffione }
1722a7db7a6SVincenzo Maffione 
1732a7db7a6SVincenzo Maffione int netmap_get_bdg_na(struct nmreq_header *hdr, struct netmap_adapter **na,
1742a7db7a6SVincenzo Maffione 	struct netmap_mem_d *nmd, int create, struct netmap_bdg_ops *ops);
1752a7db7a6SVincenzo Maffione 
1762a7db7a6SVincenzo Maffione struct nm_bridge *nm_find_bridge(const char *name, int create, struct netmap_bdg_ops *ops);
1772a7db7a6SVincenzo Maffione int netmap_bdg_free(struct nm_bridge *b);
1782a7db7a6SVincenzo Maffione void netmap_bdg_detach_common(struct nm_bridge *b, int hw, int sw);
1792a7db7a6SVincenzo Maffione int netmap_vp_bdg_ctl(struct nmreq_header *hdr, struct netmap_adapter *na);
1802a7db7a6SVincenzo Maffione int netmap_bwrap_reg(struct netmap_adapter *, int onoff);
1812a7db7a6SVincenzo Maffione int netmap_vp_reg(struct netmap_adapter *na, int onoff);
1822a7db7a6SVincenzo Maffione int netmap_vp_rxsync(struct netmap_kring *kring, int flags);
1832a7db7a6SVincenzo Maffione int netmap_bwrap_notify(struct netmap_kring *kring, int flags);
1842a7db7a6SVincenzo Maffione int netmap_bwrap_attach_common(struct netmap_adapter *na,
1852a7db7a6SVincenzo Maffione 		struct netmap_adapter *hwna);
1862a7db7a6SVincenzo Maffione int netmap_bwrap_krings_create_common(struct netmap_adapter *na);
1872a7db7a6SVincenzo Maffione void netmap_bwrap_krings_delete_common(struct netmap_adapter *na);
188*b6e66be2SVincenzo Maffione struct nm_bridge *netmap_init_bridges2(u_int);
189*b6e66be2SVincenzo Maffione void netmap_uninit_bridges2(struct nm_bridge *, u_int);
190*b6e66be2SVincenzo Maffione int netmap_bdg_update_private_data(const char *name, bdg_update_private_data_fn_t callback,
191*b6e66be2SVincenzo Maffione 	void *callback_data, void *auth_token);
192*b6e66be2SVincenzo Maffione int netmap_bdg_config(struct nm_ifreq *nifr);
193*b6e66be2SVincenzo Maffione int nm_is_bwrap(struct netmap_adapter *);
194*b6e66be2SVincenzo Maffione 
1952a7db7a6SVincenzo Maffione #define NM_NEED_BWRAP (-2)
1962a7db7a6SVincenzo Maffione #endif /* _NET_NETMAP_BDG_H_ */
1972a7db7a6SVincenzo Maffione 
198