1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 * $FreeBSD$ 29 */ 30 #ifndef _NET_NETMAP_BDG_H_ 31 #define _NET_NETMAP_BDG_H_ 32 33 #if defined(__FreeBSD__) 34 #define BDG_RWLOCK_T struct rwlock // struct rwlock 35 36 #define BDG_RWINIT(b) \ 37 rw_init_flags(&(b)->bdg_lock, "bdg lock", RW_NOWITNESS) 38 #define BDG_WLOCK(b) rw_wlock(&(b)->bdg_lock) 39 #define BDG_WUNLOCK(b) rw_wunlock(&(b)->bdg_lock) 40 #define BDG_RLOCK(b) rw_rlock(&(b)->bdg_lock) 41 #define BDG_RTRYLOCK(b) rw_try_rlock(&(b)->bdg_lock) 42 #define BDG_RUNLOCK(b) rw_runlock(&(b)->bdg_lock) 43 #define BDG_RWDESTROY(b) rw_destroy(&(b)->bdg_lock) 44 45 #endif /* __FreeBSD__ */ 46 47 /* 48 * The following bridge-related functions are used by other 49 * kernel modules. 50 * 51 * VALE only supports unicast or broadcast. The lookup 52 * function can return 0 .. NM_BDG_MAXPORTS-1 for regular ports, 53 * NM_BDG_MAXPORTS for broadcast, NM_BDG_MAXPORTS+1 to indicate 54 * drop. 55 */ 56 typedef uint32_t (*bdg_lookup_fn_t)(struct nm_bdg_fwd *ft, uint8_t *ring_nr, 57 struct netmap_vp_adapter *, void *private_data); 58 typedef int (*bdg_config_fn_t)(struct nm_ifreq *); 59 typedef void (*bdg_dtor_fn_t)(const struct netmap_vp_adapter *); 60 typedef void *(*bdg_update_private_data_fn_t)(void *private_data, void *callback_data, int *error); 61 typedef int (*bdg_vp_create_fn_t)(struct nmreq_header *hdr, 62 struct ifnet *ifp, struct netmap_mem_d *nmd, 63 struct netmap_vp_adapter **ret); 64 typedef int (*bdg_bwrap_attach_fn_t)(const char *nr_name, struct netmap_adapter *hwna); 65 struct netmap_bdg_ops { 66 bdg_lookup_fn_t lookup; 67 bdg_config_fn_t config; 68 bdg_dtor_fn_t dtor; 69 bdg_vp_create_fn_t vp_create; 70 bdg_bwrap_attach_fn_t bwrap_attach; 71 char name[IFNAMSIZ]; 72 }; 73 int netmap_bwrap_attach(const char *name, struct netmap_adapter *, struct netmap_bdg_ops *); 74 int netmap_bdg_regops(const char *name, struct netmap_bdg_ops *bdg_ops, void *private_data, void *auth_token); 75 76 #define NM_BRIDGES 8 /* number of bridges */ 77 #define NM_BDG_MAXPORTS 254 /* up to 254 */ 78 #define NM_BDG_BROADCAST NM_BDG_MAXPORTS 79 #define NM_BDG_NOPORT (NM_BDG_MAXPORTS+1) 80 81 /* XXX Should go away after fixing find_bridge() - Michio */ 82 #define NM_BDG_HASH 1024 /* forwarding table entries */ 83 84 /* XXX revise this */ 85 struct nm_hash_ent { 86 uint64_t mac; /* the top 2 bytes are the epoch */ 87 uint64_t ports; 88 }; 89 90 /* Default size for the Maximum Frame Size. */ 91 #define NM_BDG_MFS_DEFAULT 1514 92 93 /* 94 * nm_bridge is a descriptor for a VALE switch. 95 * Interfaces for a bridge are all in bdg_ports[]. 96 * The array has fixed size, an empty entry does not terminate 97 * the search, but lookups only occur on attach/detach so we 98 * don't mind if they are slow. 99 * 100 * The bridge is non blocking on the transmit ports: excess 101 * packets are dropped if there is no room on the output port. 102 * 103 * bdg_lock protects accesses to the bdg_ports array. 104 * This is a rw lock (or equivalent). 105 */ 106 #define NM_BDG_IFNAMSIZ IFNAMSIZ 107 struct nm_bridge { 108 /* XXX what is the proper alignment/layout ? */ 109 BDG_RWLOCK_T bdg_lock; /* protects bdg_ports */ 110 int bdg_namelen; 111 uint32_t bdg_active_ports; 112 char bdg_basename[NM_BDG_IFNAMSIZ]; 113 114 /* Indexes of active ports (up to active_ports) 115 * and all other remaining ports. 116 */ 117 uint32_t bdg_port_index[NM_BDG_MAXPORTS]; 118 /* used by netmap_bdg_detach_common() */ 119 uint32_t tmp_bdg_port_index[NM_BDG_MAXPORTS]; 120 121 struct netmap_vp_adapter *bdg_ports[NM_BDG_MAXPORTS]; 122 123 /* 124 * Programmable lookup functions to figure out the destination port. 125 * It returns either of an index of the destination port, 126 * NM_BDG_BROADCAST to broadcast this packet, or NM_BDG_NOPORT not to 127 * forward this packet. ring_nr is the source ring index, and the 128 * function may overwrite this value to forward this packet to a 129 * different ring index. 130 * The function is set by netmap_bdg_regops(). 131 */ 132 struct netmap_bdg_ops bdg_ops; 133 struct netmap_bdg_ops bdg_saved_ops; 134 135 /* 136 * Contains the data structure used by the bdg_ops.lookup function. 137 * By default points to *ht which is allocated on attach and used by the default lookup 138 * otherwise will point to the data structure received by netmap_bdg_regops(). 139 */ 140 void *private_data; 141 struct nm_hash_ent *ht; 142 143 /* Currently used to specify if the bridge is still in use while empty and 144 * if it has been put in exclusive mode by an external module, see netmap_bdg_regops() 145 * and netmap_bdg_create(). 146 */ 147 #define NM_BDG_ACTIVE 1 148 #define NM_BDG_EXCLUSIVE 2 149 #define NM_BDG_NEED_BWRAP 4 150 uint8_t bdg_flags; 151 152 153 #ifdef CONFIG_NET_NS 154 struct net *ns; 155 #endif /* CONFIG_NET_NS */ 156 }; 157 158 static inline void * 159 nm_bdg_get_auth_token(struct nm_bridge *b) 160 { 161 return b->ht; 162 } 163 164 /* bridge not in exclusive mode ==> always valid 165 * bridge in exclusive mode (created through netmap_bdg_create()) ==> check authentication token 166 */ 167 static inline int 168 nm_bdg_valid_auth_token(struct nm_bridge *b, void *auth_token) 169 { 170 return !(b->bdg_flags & NM_BDG_EXCLUSIVE) || b->ht == auth_token; 171 } 172 173 int netmap_get_bdg_na(struct nmreq_header *hdr, struct netmap_adapter **na, 174 struct netmap_mem_d *nmd, int create, struct netmap_bdg_ops *ops); 175 176 struct nm_bridge *nm_find_bridge(const char *name, int create, struct netmap_bdg_ops *ops); 177 int netmap_bdg_free(struct nm_bridge *b); 178 void netmap_bdg_detach_common(struct nm_bridge *b, int hw, int sw); 179 int netmap_vp_bdg_ctl(struct nmreq_header *hdr, struct netmap_adapter *na); 180 int netmap_bwrap_reg(struct netmap_adapter *, int onoff); 181 int netmap_bdg_detach_locked(struct nmreq_header *hdr, void *auth_token); 182 int netmap_vp_reg(struct netmap_adapter *na, int onoff); 183 int netmap_vp_rxsync(struct netmap_kring *kring, int flags); 184 int netmap_bwrap_intr_notify(struct netmap_kring *kring, int flags); 185 int netmap_bwrap_notify(struct netmap_kring *kring, int flags); 186 int netmap_bwrap_attach_common(struct netmap_adapter *na, 187 struct netmap_adapter *hwna); 188 int netmap_bwrap_krings_create_common(struct netmap_adapter *na); 189 void netmap_bwrap_krings_delete_common(struct netmap_adapter *na); 190 struct nm_bridge *netmap_init_bridges2(u_int); 191 void netmap_uninit_bridges2(struct nm_bridge *, u_int); 192 int netmap_bdg_update_private_data(const char *name, bdg_update_private_data_fn_t callback, 193 void *callback_data, void *auth_token); 194 int netmap_bdg_config(struct nm_ifreq *nifr); 195 196 #define NM_NEED_BWRAP (-2) 197 #endif /* _NET_NETMAP_BDG_H_ */ 198 199