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