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