1 /* 2 * Copyright (C) 2013-2016 Universita` di Pisa 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 28 /* 29 * This module implements the VALE switch for netmap 30 31 --- VALE SWITCH --- 32 33 NMG_LOCK() serializes all modifications to switches and ports. 34 A switch cannot be deleted until all ports are gone. 35 36 For each switch, an SX lock (RWlock on linux) protects 37 deletion of ports. When configuring or deleting a new port, the 38 lock is acquired in exclusive mode (after holding NMG_LOCK). 39 When forwarding, the lock is acquired in shared mode (without NMG_LOCK). 40 The lock is held throughout the entire forwarding cycle, 41 during which the thread may incur in a page fault. 42 Hence it is important that sleepable shared locks are used. 43 44 On the rx ring, the per-port lock is grabbed initially to reserve 45 a number of slot in the ring, then the lock is released, 46 packets are copied from source to destination, and then 47 the lock is acquired again and the receive ring is updated. 48 (A similar thing is done on the tx ring for NIC and host stack 49 ports attached to the switch) 50 51 */ 52 53 /* 54 * OS-specific code that is used only within this file. 55 * Other OS-specific code that must be accessed by drivers 56 * is present in netmap_kern.h 57 */ 58 59 #if defined(__FreeBSD__) 60 #include <sys/cdefs.h> /* prerequisite */ 61 __FBSDID("$FreeBSD$"); 62 63 #include <sys/types.h> 64 #include <sys/errno.h> 65 #include <sys/param.h> /* defines used in kernel.h */ 66 #include <sys/kernel.h> /* types used in module initialization */ 67 #include <sys/conf.h> /* cdevsw struct, UID, GID */ 68 #include <sys/sockio.h> 69 #include <sys/socketvar.h> /* struct socket */ 70 #include <sys/malloc.h> 71 #include <sys/poll.h> 72 #include <sys/rwlock.h> 73 #include <sys/socket.h> /* sockaddrs */ 74 #include <sys/selinfo.h> 75 #include <sys/sysctl.h> 76 #include <net/if.h> 77 #include <net/if_var.h> 78 #include <net/bpf.h> /* BIOCIMMEDIATE */ 79 #include <machine/bus.h> /* bus_dmamap_* */ 80 #include <sys/endian.h> 81 #include <sys/refcount.h> 82 83 84 #define BDG_RWLOCK_T struct rwlock // struct rwlock 85 86 #define BDG_RWINIT(b) \ 87 rw_init_flags(&(b)->bdg_lock, "bdg lock", RW_NOWITNESS) 88 #define BDG_WLOCK(b) rw_wlock(&(b)->bdg_lock) 89 #define BDG_WUNLOCK(b) rw_wunlock(&(b)->bdg_lock) 90 #define BDG_RLOCK(b) rw_rlock(&(b)->bdg_lock) 91 #define BDG_RTRYLOCK(b) rw_try_rlock(&(b)->bdg_lock) 92 #define BDG_RUNLOCK(b) rw_runlock(&(b)->bdg_lock) 93 #define BDG_RWDESTROY(b) rw_destroy(&(b)->bdg_lock) 94 95 96 #elif defined(linux) 97 98 #include "bsd_glue.h" 99 100 #elif defined(__APPLE__) 101 102 #warning OSX support is only partial 103 #include "osx_glue.h" 104 105 #elif defined(_WIN32) 106 #include "win_glue.h" 107 108 #else 109 110 #error Unsupported platform 111 112 #endif /* unsupported */ 113 114 /* 115 * common headers 116 */ 117 118 #include <net/netmap.h> 119 #include <dev/netmap/netmap_kern.h> 120 #include <dev/netmap/netmap_mem2.h> 121 122 #ifdef WITH_VALE 123 124 /* 125 * system parameters (most of them in netmap_kern.h) 126 * NM_BDG_NAME prefix for switch port names, default "vale" 127 * NM_BDG_MAXPORTS number of ports 128 * NM_BRIDGES max number of switches in the system. 129 * XXX should become a sysctl or tunable 130 * 131 * Switch ports are named valeX:Y where X is the switch name and Y 132 * is the port. If Y matches a physical interface name, the port is 133 * connected to a physical device. 134 * 135 * Unlike physical interfaces, switch ports use their own memory region 136 * for rings and buffers. 137 * The virtual interfaces use per-queue lock instead of core lock. 138 * In the tx loop, we aggregate traffic in batches to make all operations 139 * faster. The batch size is bridge_batch. 140 */ 141 #define NM_BDG_MAXRINGS 16 /* XXX unclear how many. */ 142 #define NM_BDG_MAXSLOTS 4096 /* XXX same as above */ 143 #define NM_BRIDGE_RINGSIZE 1024 /* in the device */ 144 #define NM_BDG_HASH 1024 /* forwarding table entries */ 145 #define NM_BDG_BATCH 1024 /* entries in the forwarding buffer */ 146 #define NM_MULTISEG 64 /* max size of a chain of bufs */ 147 /* actual size of the tables */ 148 #define NM_BDG_BATCH_MAX (NM_BDG_BATCH + NM_MULTISEG) 149 /* NM_FT_NULL terminates a list of slots in the ft */ 150 #define NM_FT_NULL NM_BDG_BATCH_MAX 151 152 153 /* 154 * bridge_batch is set via sysctl to the max batch size to be 155 * used in the bridge. The actual value may be larger as the 156 * last packet in the block may overflow the size. 157 */ 158 static int bridge_batch = NM_BDG_BATCH; /* bridge batch size */ 159 SYSBEGIN(vars_vale); 160 SYSCTL_DECL(_dev_netmap); 161 SYSCTL_INT(_dev_netmap, OID_AUTO, bridge_batch, CTLFLAG_RW, &bridge_batch, 0 , ""); 162 SYSEND; 163 164 static int netmap_vp_create(struct nmreq *, struct ifnet *, struct netmap_vp_adapter **); 165 static int netmap_vp_reg(struct netmap_adapter *na, int onoff); 166 static int netmap_bwrap_reg(struct netmap_adapter *, int onoff); 167 168 /* 169 * For each output interface, nm_bdg_q is used to construct a list. 170 * bq_len is the number of output buffers (we can have coalescing 171 * during the copy). 172 */ 173 struct nm_bdg_q { 174 uint16_t bq_head; 175 uint16_t bq_tail; 176 uint32_t bq_len; /* number of buffers */ 177 }; 178 179 /* XXX revise this */ 180 struct nm_hash_ent { 181 uint64_t mac; /* the top 2 bytes are the epoch */ 182 uint64_t ports; 183 }; 184 185 /* 186 * nm_bridge is a descriptor for a VALE switch. 187 * Interfaces for a bridge are all in bdg_ports[]. 188 * The array has fixed size, an empty entry does not terminate 189 * the search, but lookups only occur on attach/detach so we 190 * don't mind if they are slow. 191 * 192 * The bridge is non blocking on the transmit ports: excess 193 * packets are dropped if there is no room on the output port. 194 * 195 * bdg_lock protects accesses to the bdg_ports array. 196 * This is a rw lock (or equivalent). 197 */ 198 struct nm_bridge { 199 /* XXX what is the proper alignment/layout ? */ 200 BDG_RWLOCK_T bdg_lock; /* protects bdg_ports */ 201 int bdg_namelen; 202 uint32_t bdg_active_ports; /* 0 means free */ 203 char bdg_basename[IFNAMSIZ]; 204 205 /* Indexes of active ports (up to active_ports) 206 * and all other remaining ports. 207 */ 208 uint8_t bdg_port_index[NM_BDG_MAXPORTS]; 209 210 struct netmap_vp_adapter *bdg_ports[NM_BDG_MAXPORTS]; 211 212 213 /* 214 * The function to decide the destination port. 215 * It returns either of an index of the destination port, 216 * NM_BDG_BROADCAST to broadcast this packet, or NM_BDG_NOPORT not to 217 * forward this packet. ring_nr is the source ring index, and the 218 * function may overwrite this value to forward this packet to a 219 * different ring index. 220 * This function must be set by netmap_bdg_ctl(). 221 */ 222 struct netmap_bdg_ops bdg_ops; 223 224 /* the forwarding table, MAC+ports. 225 * XXX should be changed to an argument to be passed to 226 * the lookup function, and allocated on attach 227 */ 228 struct nm_hash_ent ht[NM_BDG_HASH]; 229 230 #ifdef CONFIG_NET_NS 231 struct net *ns; 232 #endif /* CONFIG_NET_NS */ 233 }; 234 235 const char* 236 netmap_bdg_name(struct netmap_vp_adapter *vp) 237 { 238 struct nm_bridge *b = vp->na_bdg; 239 if (b == NULL) 240 return NULL; 241 return b->bdg_basename; 242 } 243 244 245 #ifndef CONFIG_NET_NS 246 /* 247 * XXX in principle nm_bridges could be created dynamically 248 * Right now we have a static array and deletions are protected 249 * by an exclusive lock. 250 */ 251 static struct nm_bridge *nm_bridges; 252 #endif /* !CONFIG_NET_NS */ 253 254 255 /* 256 * this is a slightly optimized copy routine which rounds 257 * to multiple of 64 bytes and is often faster than dealing 258 * with other odd sizes. We assume there is enough room 259 * in the source and destination buffers. 260 * 261 * XXX only for multiples of 64 bytes, non overlapped. 262 */ 263 static inline void 264 pkt_copy(void *_src, void *_dst, int l) 265 { 266 uint64_t *src = _src; 267 uint64_t *dst = _dst; 268 if (unlikely(l >= 1024)) { 269 memcpy(dst, src, l); 270 return; 271 } 272 for (; likely(l > 0); l-=64) { 273 *dst++ = *src++; 274 *dst++ = *src++; 275 *dst++ = *src++; 276 *dst++ = *src++; 277 *dst++ = *src++; 278 *dst++ = *src++; 279 *dst++ = *src++; 280 *dst++ = *src++; 281 } 282 } 283 284 285 static int 286 nm_is_id_char(const char c) 287 { 288 return (c >= 'a' && c <= 'z') || 289 (c >= 'A' && c <= 'Z') || 290 (c >= '0' && c <= '9') || 291 (c == '_'); 292 } 293 294 /* Validate the name of a VALE bridge port and return the 295 * position of the ":" character. */ 296 static int 297 nm_vale_name_validate(const char *name) 298 { 299 int colon_pos = -1; 300 int i; 301 302 if (!name || strlen(name) < strlen(NM_BDG_NAME)) { 303 return -1; 304 } 305 306 for (i = 0; name[i]; i++) { 307 if (name[i] == ':') { 308 if (colon_pos != -1) { 309 return -1; 310 } 311 colon_pos = i; 312 } else if (!nm_is_id_char(name[i])) { 313 return -1; 314 } 315 } 316 317 if (i >= IFNAMSIZ) { 318 return -1; 319 } 320 321 return colon_pos; 322 } 323 324 /* 325 * locate a bridge among the existing ones. 326 * MUST BE CALLED WITH NMG_LOCK() 327 * 328 * a ':' in the name terminates the bridge name. Otherwise, just NM_NAME. 329 * We assume that this is called with a name of at least NM_NAME chars. 330 */ 331 static struct nm_bridge * 332 nm_find_bridge(const char *name, int create) 333 { 334 int i, namelen; 335 struct nm_bridge *b = NULL, *bridges; 336 u_int num_bridges; 337 338 NMG_LOCK_ASSERT(); 339 340 netmap_bns_getbridges(&bridges, &num_bridges); 341 342 namelen = nm_vale_name_validate(name); 343 if (namelen < 0) { 344 D("invalid bridge name %s", name ? name : NULL); 345 return NULL; 346 } 347 348 /* lookup the name, remember empty slot if there is one */ 349 for (i = 0; i < num_bridges; i++) { 350 struct nm_bridge *x = bridges + i; 351 352 if (x->bdg_active_ports == 0) { 353 if (create && b == NULL) 354 b = x; /* record empty slot */ 355 } else if (x->bdg_namelen != namelen) { 356 continue; 357 } else if (strncmp(name, x->bdg_basename, namelen) == 0) { 358 ND("found '%.*s' at %d", namelen, name, i); 359 b = x; 360 break; 361 } 362 } 363 if (i == num_bridges && b) { /* name not found, can create entry */ 364 /* initialize the bridge */ 365 strncpy(b->bdg_basename, name, namelen); 366 ND("create new bridge %s with ports %d", b->bdg_basename, 367 b->bdg_active_ports); 368 b->bdg_namelen = namelen; 369 b->bdg_active_ports = 0; 370 for (i = 0; i < NM_BDG_MAXPORTS; i++) 371 b->bdg_port_index[i] = i; 372 /* set the default function */ 373 b->bdg_ops.lookup = netmap_bdg_learning; 374 /* reset the MAC address table */ 375 bzero(b->ht, sizeof(struct nm_hash_ent) * NM_BDG_HASH); 376 NM_BNS_GET(b); 377 } 378 return b; 379 } 380 381 382 /* 383 * Free the forwarding tables for rings attached to switch ports. 384 */ 385 static void 386 nm_free_bdgfwd(struct netmap_adapter *na) 387 { 388 int nrings, i; 389 struct netmap_kring *kring; 390 391 NMG_LOCK_ASSERT(); 392 nrings = na->num_tx_rings; 393 kring = na->tx_rings; 394 for (i = 0; i < nrings; i++) { 395 if (kring[i].nkr_ft) { 396 free(kring[i].nkr_ft, M_DEVBUF); 397 kring[i].nkr_ft = NULL; /* protect from freeing twice */ 398 } 399 } 400 } 401 402 403 /* 404 * Allocate the forwarding tables for the rings attached to the bridge ports. 405 */ 406 static int 407 nm_alloc_bdgfwd(struct netmap_adapter *na) 408 { 409 int nrings, l, i, num_dstq; 410 struct netmap_kring *kring; 411 412 NMG_LOCK_ASSERT(); 413 /* all port:rings + broadcast */ 414 num_dstq = NM_BDG_MAXPORTS * NM_BDG_MAXRINGS + 1; 415 l = sizeof(struct nm_bdg_fwd) * NM_BDG_BATCH_MAX; 416 l += sizeof(struct nm_bdg_q) * num_dstq; 417 l += sizeof(uint16_t) * NM_BDG_BATCH_MAX; 418 419 nrings = netmap_real_rings(na, NR_TX); 420 kring = na->tx_rings; 421 for (i = 0; i < nrings; i++) { 422 struct nm_bdg_fwd *ft; 423 struct nm_bdg_q *dstq; 424 int j; 425 426 ft = malloc(l, M_DEVBUF, M_NOWAIT | M_ZERO); 427 if (!ft) { 428 nm_free_bdgfwd(na); 429 return ENOMEM; 430 } 431 dstq = (struct nm_bdg_q *)(ft + NM_BDG_BATCH_MAX); 432 for (j = 0; j < num_dstq; j++) { 433 dstq[j].bq_head = dstq[j].bq_tail = NM_FT_NULL; 434 dstq[j].bq_len = 0; 435 } 436 kring[i].nkr_ft = ft; 437 } 438 return 0; 439 } 440 441 442 /* remove from bridge b the ports in slots hw and sw 443 * (sw can be -1 if not needed) 444 */ 445 static void 446 netmap_bdg_detach_common(struct nm_bridge *b, int hw, int sw) 447 { 448 int s_hw = hw, s_sw = sw; 449 int i, lim =b->bdg_active_ports; 450 uint8_t tmp[NM_BDG_MAXPORTS]; 451 452 /* 453 New algorithm: 454 make a copy of bdg_port_index; 455 lookup NA(ifp)->bdg_port and SWNA(ifp)->bdg_port 456 in the array of bdg_port_index, replacing them with 457 entries from the bottom of the array; 458 decrement bdg_active_ports; 459 acquire BDG_WLOCK() and copy back the array. 460 */ 461 462 if (netmap_verbose) 463 D("detach %d and %d (lim %d)", hw, sw, lim); 464 /* make a copy of the list of active ports, update it, 465 * and then copy back within BDG_WLOCK(). 466 */ 467 memcpy(tmp, b->bdg_port_index, sizeof(tmp)); 468 for (i = 0; (hw >= 0 || sw >= 0) && i < lim; ) { 469 if (hw >= 0 && tmp[i] == hw) { 470 ND("detach hw %d at %d", hw, i); 471 lim--; /* point to last active port */ 472 tmp[i] = tmp[lim]; /* swap with i */ 473 tmp[lim] = hw; /* now this is inactive */ 474 hw = -1; 475 } else if (sw >= 0 && tmp[i] == sw) { 476 ND("detach sw %d at %d", sw, i); 477 lim--; 478 tmp[i] = tmp[lim]; 479 tmp[lim] = sw; 480 sw = -1; 481 } else { 482 i++; 483 } 484 } 485 if (hw >= 0 || sw >= 0) { 486 D("XXX delete failed hw %d sw %d, should panic...", hw, sw); 487 } 488 489 BDG_WLOCK(b); 490 if (b->bdg_ops.dtor) 491 b->bdg_ops.dtor(b->bdg_ports[s_hw]); 492 b->bdg_ports[s_hw] = NULL; 493 if (s_sw >= 0) { 494 b->bdg_ports[s_sw] = NULL; 495 } 496 memcpy(b->bdg_port_index, tmp, sizeof(tmp)); 497 b->bdg_active_ports = lim; 498 BDG_WUNLOCK(b); 499 500 ND("now %d active ports", lim); 501 if (lim == 0) { 502 ND("marking bridge %s as free", b->bdg_basename); 503 bzero(&b->bdg_ops, sizeof(b->bdg_ops)); 504 NM_BNS_PUT(b); 505 } 506 } 507 508 /* nm_bdg_ctl callback for VALE ports */ 509 static int 510 netmap_vp_bdg_ctl(struct netmap_adapter *na, struct nmreq *nmr, int attach) 511 { 512 struct netmap_vp_adapter *vpna = (struct netmap_vp_adapter *)na; 513 struct nm_bridge *b = vpna->na_bdg; 514 515 (void)nmr; // XXX merge ? 516 if (attach) 517 return 0; /* nothing to do */ 518 if (b) { 519 netmap_set_all_rings(na, 0 /* disable */); 520 netmap_bdg_detach_common(b, vpna->bdg_port, -1); 521 vpna->na_bdg = NULL; 522 netmap_set_all_rings(na, 1 /* enable */); 523 } 524 /* I have took reference just for attach */ 525 netmap_adapter_put(na); 526 return 0; 527 } 528 529 /* nm_dtor callback for ephemeral VALE ports */ 530 static void 531 netmap_vp_dtor(struct netmap_adapter *na) 532 { 533 struct netmap_vp_adapter *vpna = (struct netmap_vp_adapter*)na; 534 struct nm_bridge *b = vpna->na_bdg; 535 536 ND("%s has %d references", na->name, na->na_refcount); 537 538 if (b) { 539 netmap_bdg_detach_common(b, vpna->bdg_port, -1); 540 } 541 } 542 543 /* remove a persistent VALE port from the system */ 544 static int 545 nm_vi_destroy(const char *name) 546 { 547 struct ifnet *ifp; 548 int error; 549 550 ifp = ifunit_ref(name); 551 if (!ifp) 552 return ENXIO; 553 NMG_LOCK(); 554 /* make sure this is actually a VALE port */ 555 if (!NM_NA_VALID(ifp) || NA(ifp)->nm_register != netmap_vp_reg) { 556 error = EINVAL; 557 goto err; 558 } 559 560 if (NA(ifp)->na_refcount > 1) { 561 error = EBUSY; 562 goto err; 563 } 564 NMG_UNLOCK(); 565 566 D("destroying a persistent vale interface %s", ifp->if_xname); 567 /* Linux requires all the references are released 568 * before unregister 569 */ 570 if_rele(ifp); 571 netmap_detach(ifp); 572 nm_os_vi_detach(ifp); 573 return 0; 574 575 err: 576 NMG_UNLOCK(); 577 if_rele(ifp); 578 return error; 579 } 580 581 /* 582 * Create a virtual interface registered to the system. 583 * The interface will be attached to a bridge later. 584 */ 585 static int 586 nm_vi_create(struct nmreq *nmr) 587 { 588 struct ifnet *ifp; 589 struct netmap_vp_adapter *vpna; 590 int error; 591 592 /* don't include VALE prefix */ 593 if (!strncmp(nmr->nr_name, NM_BDG_NAME, strlen(NM_BDG_NAME))) 594 return EINVAL; 595 ifp = ifunit_ref(nmr->nr_name); 596 if (ifp) { /* already exist, cannot create new one */ 597 if_rele(ifp); 598 return EEXIST; 599 } 600 error = nm_os_vi_persist(nmr->nr_name, &ifp); 601 if (error) 602 return error; 603 604 NMG_LOCK(); 605 /* netmap_vp_create creates a struct netmap_vp_adapter */ 606 error = netmap_vp_create(nmr, ifp, &vpna); 607 if (error) { 608 D("error %d", error); 609 nm_os_vi_detach(ifp); 610 return error; 611 } 612 /* persist-specific routines */ 613 vpna->up.nm_bdg_ctl = netmap_vp_bdg_ctl; 614 netmap_adapter_get(&vpna->up); 615 NM_ATTACH_NA(ifp, &vpna->up); 616 NMG_UNLOCK(); 617 D("created %s", ifp->if_xname); 618 return 0; 619 } 620 621 /* Try to get a reference to a netmap adapter attached to a VALE switch. 622 * If the adapter is found (or is created), this function returns 0, a 623 * non NULL pointer is returned into *na, and the caller holds a 624 * reference to the adapter. 625 * If an adapter is not found, then no reference is grabbed and the 626 * function returns an error code, or 0 if there is just a VALE prefix 627 * mismatch. Therefore the caller holds a reference when 628 * (*na != NULL && return == 0). 629 */ 630 int 631 netmap_get_bdg_na(struct nmreq *nmr, struct netmap_adapter **na, int create) 632 { 633 char *nr_name = nmr->nr_name; 634 const char *ifname; 635 struct ifnet *ifp; 636 int error = 0; 637 struct netmap_vp_adapter *vpna, *hostna = NULL; 638 struct nm_bridge *b; 639 int i, j, cand = -1, cand2 = -1; 640 int needed; 641 642 *na = NULL; /* default return value */ 643 644 /* first try to see if this is a bridge port. */ 645 NMG_LOCK_ASSERT(); 646 if (strncmp(nr_name, NM_BDG_NAME, sizeof(NM_BDG_NAME) - 1)) { 647 return 0; /* no error, but no VALE prefix */ 648 } 649 650 b = nm_find_bridge(nr_name, create); 651 if (b == NULL) { 652 D("no bridges available for '%s'", nr_name); 653 return (create ? ENOMEM : ENXIO); 654 } 655 if (strlen(nr_name) < b->bdg_namelen) /* impossible */ 656 panic("x"); 657 658 /* Now we are sure that name starts with the bridge's name, 659 * lookup the port in the bridge. We need to scan the entire 660 * list. It is not important to hold a WLOCK on the bridge 661 * during the search because NMG_LOCK already guarantees 662 * that there are no other possible writers. 663 */ 664 665 /* lookup in the local list of ports */ 666 for (j = 0; j < b->bdg_active_ports; j++) { 667 i = b->bdg_port_index[j]; 668 vpna = b->bdg_ports[i]; 669 // KASSERT(na != NULL); 670 ND("checking %s", vpna->up.name); 671 if (!strcmp(vpna->up.name, nr_name)) { 672 netmap_adapter_get(&vpna->up); 673 ND("found existing if %s refs %d", nr_name) 674 *na = &vpna->up; 675 return 0; 676 } 677 } 678 /* not found, should we create it? */ 679 if (!create) 680 return ENXIO; 681 /* yes we should, see if we have space to attach entries */ 682 needed = 2; /* in some cases we only need 1 */ 683 if (b->bdg_active_ports + needed >= NM_BDG_MAXPORTS) { 684 D("bridge full %d, cannot create new port", b->bdg_active_ports); 685 return ENOMEM; 686 } 687 /* record the next two ports available, but do not allocate yet */ 688 cand = b->bdg_port_index[b->bdg_active_ports]; 689 cand2 = b->bdg_port_index[b->bdg_active_ports + 1]; 690 ND("+++ bridge %s port %s used %d avail %d %d", 691 b->bdg_basename, ifname, b->bdg_active_ports, cand, cand2); 692 693 /* 694 * try see if there is a matching NIC with this name 695 * (after the bridge's name) 696 */ 697 ifname = nr_name + b->bdg_namelen + 1; 698 ifp = ifunit_ref(ifname); 699 if (!ifp) { 700 /* Create an ephemeral virtual port 701 * This block contains all the ephemeral-specific logics 702 */ 703 if (nmr->nr_cmd) { 704 /* nr_cmd must be 0 for a virtual port */ 705 return EINVAL; 706 } 707 708 /* bdg_netmap_attach creates a struct netmap_adapter */ 709 error = netmap_vp_create(nmr, NULL, &vpna); 710 if (error) { 711 D("error %d", error); 712 free(ifp, M_DEVBUF); 713 return error; 714 } 715 /* shortcut - we can skip get_hw_na(), 716 * ownership check and nm_bdg_attach() 717 */ 718 } else { 719 struct netmap_adapter *hw; 720 721 error = netmap_get_hw_na(ifp, &hw); 722 if (error || hw == NULL) 723 goto out; 724 725 /* host adapter might not be created */ 726 error = hw->nm_bdg_attach(nr_name, hw); 727 if (error) 728 goto out; 729 vpna = hw->na_vp; 730 hostna = hw->na_hostvp; 731 if (nmr->nr_arg1 != NETMAP_BDG_HOST) 732 hostna = NULL; 733 } 734 735 BDG_WLOCK(b); 736 vpna->bdg_port = cand; 737 ND("NIC %p to bridge port %d", vpna, cand); 738 /* bind the port to the bridge (virtual ports are not active) */ 739 b->bdg_ports[cand] = vpna; 740 vpna->na_bdg = b; 741 b->bdg_active_ports++; 742 if (hostna != NULL) { 743 /* also bind the host stack to the bridge */ 744 b->bdg_ports[cand2] = hostna; 745 hostna->bdg_port = cand2; 746 hostna->na_bdg = b; 747 b->bdg_active_ports++; 748 ND("host %p to bridge port %d", hostna, cand2); 749 } 750 ND("if %s refs %d", ifname, vpna->up.na_refcount); 751 BDG_WUNLOCK(b); 752 *na = &vpna->up; 753 netmap_adapter_get(*na); 754 return 0; 755 756 out: 757 if_rele(ifp); 758 759 return error; 760 } 761 762 763 /* Process NETMAP_BDG_ATTACH */ 764 static int 765 nm_bdg_ctl_attach(struct nmreq *nmr) 766 { 767 struct netmap_adapter *na; 768 int error; 769 770 NMG_LOCK(); 771 772 error = netmap_get_bdg_na(nmr, &na, 1 /* create if not exists */); 773 if (error) /* no device */ 774 goto unlock_exit; 775 776 if (na == NULL) { /* VALE prefix missing */ 777 error = EINVAL; 778 goto unlock_exit; 779 } 780 781 if (NETMAP_OWNED_BY_ANY(na)) { 782 error = EBUSY; 783 goto unref_exit; 784 } 785 786 if (na->nm_bdg_ctl) { 787 /* nop for VALE ports. The bwrap needs to put the hwna 788 * in netmap mode (see netmap_bwrap_bdg_ctl) 789 */ 790 error = na->nm_bdg_ctl(na, nmr, 1); 791 if (error) 792 goto unref_exit; 793 ND("registered %s to netmap-mode", na->name); 794 } 795 NMG_UNLOCK(); 796 return 0; 797 798 unref_exit: 799 netmap_adapter_put(na); 800 unlock_exit: 801 NMG_UNLOCK(); 802 return error; 803 } 804 805 static inline int 806 nm_is_bwrap(struct netmap_adapter *na) 807 { 808 return na->nm_register == netmap_bwrap_reg; 809 } 810 811 /* process NETMAP_BDG_DETACH */ 812 static int 813 nm_bdg_ctl_detach(struct nmreq *nmr) 814 { 815 struct netmap_adapter *na; 816 int error; 817 818 NMG_LOCK(); 819 error = netmap_get_bdg_na(nmr, &na, 0 /* don't create */); 820 if (error) { /* no device, or another bridge or user owns the device */ 821 goto unlock_exit; 822 } 823 824 if (na == NULL) { /* VALE prefix missing */ 825 error = EINVAL; 826 goto unlock_exit; 827 } else if (nm_is_bwrap(na) && 828 ((struct netmap_bwrap_adapter *)na)->na_polling_state) { 829 /* Don't detach a NIC with polling */ 830 error = EBUSY; 831 netmap_adapter_put(na); 832 goto unlock_exit; 833 } 834 if (na->nm_bdg_ctl) { 835 /* remove the port from bridge. The bwrap 836 * also needs to put the hwna in normal mode 837 */ 838 error = na->nm_bdg_ctl(na, nmr, 0); 839 } 840 841 netmap_adapter_put(na); 842 unlock_exit: 843 NMG_UNLOCK(); 844 return error; 845 846 } 847 848 struct nm_bdg_polling_state; 849 struct 850 nm_bdg_kthread { 851 struct nm_kthread *nmk; 852 u_int qfirst; 853 u_int qlast; 854 struct nm_bdg_polling_state *bps; 855 }; 856 857 struct nm_bdg_polling_state { 858 bool configured; 859 bool stopped; 860 struct netmap_bwrap_adapter *bna; 861 u_int reg; 862 u_int qfirst; 863 u_int qlast; 864 u_int cpu_from; 865 u_int ncpus; 866 struct nm_bdg_kthread *kthreads; 867 }; 868 869 static void 870 netmap_bwrap_polling(void *data) 871 { 872 struct nm_bdg_kthread *nbk = data; 873 struct netmap_bwrap_adapter *bna; 874 u_int qfirst, qlast, i; 875 struct netmap_kring *kring0, *kring; 876 877 if (!nbk) 878 return; 879 qfirst = nbk->qfirst; 880 qlast = nbk->qlast; 881 bna = nbk->bps->bna; 882 kring0 = NMR(bna->hwna, NR_RX); 883 884 for (i = qfirst; i < qlast; i++) { 885 kring = kring0 + i; 886 kring->nm_notify(kring, 0); 887 } 888 } 889 890 static int 891 nm_bdg_create_kthreads(struct nm_bdg_polling_state *bps) 892 { 893 struct nm_kthread_cfg kcfg; 894 int i, j; 895 896 bps->kthreads = malloc(sizeof(struct nm_bdg_kthread) * bps->ncpus, 897 M_DEVBUF, M_NOWAIT | M_ZERO); 898 if (bps->kthreads == NULL) 899 return ENOMEM; 900 901 bzero(&kcfg, sizeof(kcfg)); 902 kcfg.worker_fn = netmap_bwrap_polling; 903 for (i = 0; i < bps->ncpus; i++) { 904 struct nm_bdg_kthread *t = bps->kthreads + i; 905 int all = (bps->ncpus == 1 && bps->reg == NR_REG_ALL_NIC); 906 int affinity = bps->cpu_from + i; 907 908 t->bps = bps; 909 t->qfirst = all ? bps->qfirst /* must be 0 */: affinity; 910 t->qlast = all ? bps->qlast : t->qfirst + 1; 911 D("kthread %d a:%u qf:%u ql:%u", i, affinity, t->qfirst, 912 t->qlast); 913 914 kcfg.type = i; 915 kcfg.worker_private = t; 916 t->nmk = nm_os_kthread_create(&kcfg, 0, NULL); 917 if (t->nmk == NULL) { 918 goto cleanup; 919 } 920 nm_os_kthread_set_affinity(t->nmk, affinity); 921 } 922 return 0; 923 924 cleanup: 925 for (j = 0; j < i; j++) { 926 struct nm_bdg_kthread *t = bps->kthreads + i; 927 nm_os_kthread_delete(t->nmk); 928 } 929 free(bps->kthreads, M_DEVBUF); 930 return EFAULT; 931 } 932 933 /* a version of ptnetmap_start_kthreads() */ 934 static int 935 nm_bdg_polling_start_kthreads(struct nm_bdg_polling_state *bps) 936 { 937 int error, i, j; 938 939 if (!bps) { 940 D("polling is not configured"); 941 return EFAULT; 942 } 943 bps->stopped = false; 944 945 for (i = 0; i < bps->ncpus; i++) { 946 struct nm_bdg_kthread *t = bps->kthreads + i; 947 error = nm_os_kthread_start(t->nmk); 948 if (error) { 949 D("error in nm_kthread_start()"); 950 goto cleanup; 951 } 952 } 953 return 0; 954 955 cleanup: 956 for (j = 0; j < i; j++) { 957 struct nm_bdg_kthread *t = bps->kthreads + i; 958 nm_os_kthread_stop(t->nmk); 959 } 960 bps->stopped = true; 961 return error; 962 } 963 964 static void 965 nm_bdg_polling_stop_delete_kthreads(struct nm_bdg_polling_state *bps) 966 { 967 int i; 968 969 if (!bps) 970 return; 971 972 for (i = 0; i < bps->ncpus; i++) { 973 struct nm_bdg_kthread *t = bps->kthreads + i; 974 nm_os_kthread_stop(t->nmk); 975 nm_os_kthread_delete(t->nmk); 976 } 977 bps->stopped = true; 978 } 979 980 static int 981 get_polling_cfg(struct nmreq *nmr, struct netmap_adapter *na, 982 struct nm_bdg_polling_state *bps) 983 { 984 int req_cpus, avail_cpus, core_from; 985 u_int reg, i, qfirst, qlast; 986 987 avail_cpus = nm_os_ncpus(); 988 req_cpus = nmr->nr_arg1; 989 990 if (req_cpus == 0) { 991 D("req_cpus must be > 0"); 992 return EINVAL; 993 } else if (req_cpus >= avail_cpus) { 994 D("for safety, we need at least one core left in the system"); 995 return EINVAL; 996 } 997 reg = nmr->nr_flags & NR_REG_MASK; 998 i = nmr->nr_ringid & NETMAP_RING_MASK; 999 /* 1000 * ONE_NIC: dedicate one core to one ring. If multiple cores 1001 * are specified, consecutive rings are also polled. 1002 * For example, if ringid=2 and 2 cores are given, 1003 * ring 2 and 3 are polled by core 2 and 3, respectively. 1004 * ALL_NIC: poll all the rings using a core specified by ringid. 1005 * the number of cores must be 1. 1006 */ 1007 if (reg == NR_REG_ONE_NIC) { 1008 if (i + req_cpus > nma_get_nrings(na, NR_RX)) { 1009 D("only %d rings exist (ring %u-%u is given)", 1010 nma_get_nrings(na, NR_RX), i, i+req_cpus); 1011 return EINVAL; 1012 } 1013 qfirst = i; 1014 qlast = qfirst + req_cpus; 1015 core_from = qfirst; 1016 } else if (reg == NR_REG_ALL_NIC) { 1017 if (req_cpus != 1) { 1018 D("ncpus must be 1 not %d for REG_ALL_NIC", req_cpus); 1019 return EINVAL; 1020 } 1021 qfirst = 0; 1022 qlast = nma_get_nrings(na, NR_RX); 1023 core_from = i; 1024 } else { 1025 D("reg must be ALL_NIC or ONE_NIC"); 1026 return EINVAL; 1027 } 1028 1029 bps->reg = reg; 1030 bps->qfirst = qfirst; 1031 bps->qlast = qlast; 1032 bps->cpu_from = core_from; 1033 bps->ncpus = req_cpus; 1034 D("%s qfirst %u qlast %u cpu_from %u ncpus %u", 1035 reg == NR_REG_ALL_NIC ? "REG_ALL_NIC" : "REG_ONE_NIC", 1036 qfirst, qlast, core_from, req_cpus); 1037 return 0; 1038 } 1039 1040 static int 1041 nm_bdg_ctl_polling_start(struct nmreq *nmr, struct netmap_adapter *na) 1042 { 1043 struct nm_bdg_polling_state *bps; 1044 struct netmap_bwrap_adapter *bna; 1045 int error; 1046 1047 bna = (struct netmap_bwrap_adapter *)na; 1048 if (bna->na_polling_state) { 1049 D("ERROR adapter already in polling mode"); 1050 return EFAULT; 1051 } 1052 1053 bps = malloc(sizeof(*bps), M_DEVBUF, M_NOWAIT | M_ZERO); 1054 if (!bps) 1055 return ENOMEM; 1056 bps->configured = false; 1057 bps->stopped = true; 1058 1059 if (get_polling_cfg(nmr, na, bps)) { 1060 free(bps, M_DEVBUF); 1061 return EINVAL; 1062 } 1063 1064 if (nm_bdg_create_kthreads(bps)) { 1065 free(bps, M_DEVBUF); 1066 return EFAULT; 1067 } 1068 1069 bps->configured = true; 1070 bna->na_polling_state = bps; 1071 bps->bna = bna; 1072 1073 /* disable interrupt if possible */ 1074 if (bna->hwna->nm_intr) 1075 bna->hwna->nm_intr(bna->hwna, 0); 1076 /* start kthread now */ 1077 error = nm_bdg_polling_start_kthreads(bps); 1078 if (error) { 1079 D("ERROR nm_bdg_polling_start_kthread()"); 1080 free(bps->kthreads, M_DEVBUF); 1081 free(bps, M_DEVBUF); 1082 bna->na_polling_state = NULL; 1083 if (bna->hwna->nm_intr) 1084 bna->hwna->nm_intr(bna->hwna, 1); 1085 } 1086 return error; 1087 } 1088 1089 static int 1090 nm_bdg_ctl_polling_stop(struct nmreq *nmr, struct netmap_adapter *na) 1091 { 1092 struct netmap_bwrap_adapter *bna = (struct netmap_bwrap_adapter *)na; 1093 struct nm_bdg_polling_state *bps; 1094 1095 if (!bna->na_polling_state) { 1096 D("ERROR adapter is not in polling mode"); 1097 return EFAULT; 1098 } 1099 bps = bna->na_polling_state; 1100 nm_bdg_polling_stop_delete_kthreads(bna->na_polling_state); 1101 bps->configured = false; 1102 free(bps, M_DEVBUF); 1103 bna->na_polling_state = NULL; 1104 /* reenable interrupt */ 1105 if (bna->hwna->nm_intr) 1106 bna->hwna->nm_intr(bna->hwna, 1); 1107 return 0; 1108 } 1109 1110 /* Called by either user's context (netmap_ioctl()) 1111 * or external kernel modules (e.g., Openvswitch). 1112 * Operation is indicated in nmr->nr_cmd. 1113 * NETMAP_BDG_OPS that sets configure/lookup/dtor functions to the bridge 1114 * requires bdg_ops argument; the other commands ignore this argument. 1115 * 1116 * Called without NMG_LOCK. 1117 */ 1118 int 1119 netmap_bdg_ctl(struct nmreq *nmr, struct netmap_bdg_ops *bdg_ops) 1120 { 1121 struct nm_bridge *b, *bridges; 1122 struct netmap_adapter *na; 1123 struct netmap_vp_adapter *vpna; 1124 char *name = nmr->nr_name; 1125 int cmd = nmr->nr_cmd, namelen = strlen(name); 1126 int error = 0, i, j; 1127 u_int num_bridges; 1128 1129 netmap_bns_getbridges(&bridges, &num_bridges); 1130 1131 switch (cmd) { 1132 case NETMAP_BDG_NEWIF: 1133 error = nm_vi_create(nmr); 1134 break; 1135 1136 case NETMAP_BDG_DELIF: 1137 error = nm_vi_destroy(nmr->nr_name); 1138 break; 1139 1140 case NETMAP_BDG_ATTACH: 1141 error = nm_bdg_ctl_attach(nmr); 1142 break; 1143 1144 case NETMAP_BDG_DETACH: 1145 error = nm_bdg_ctl_detach(nmr); 1146 break; 1147 1148 case NETMAP_BDG_LIST: 1149 /* this is used to enumerate bridges and ports */ 1150 if (namelen) { /* look up indexes of bridge and port */ 1151 if (strncmp(name, NM_BDG_NAME, strlen(NM_BDG_NAME))) { 1152 error = EINVAL; 1153 break; 1154 } 1155 NMG_LOCK(); 1156 b = nm_find_bridge(name, 0 /* don't create */); 1157 if (!b) { 1158 error = ENOENT; 1159 NMG_UNLOCK(); 1160 break; 1161 } 1162 1163 error = 0; 1164 nmr->nr_arg1 = b - bridges; /* bridge index */ 1165 nmr->nr_arg2 = NM_BDG_NOPORT; 1166 for (j = 0; j < b->bdg_active_ports; j++) { 1167 i = b->bdg_port_index[j]; 1168 vpna = b->bdg_ports[i]; 1169 if (vpna == NULL) { 1170 D("---AAAAAAAAARGH-------"); 1171 continue; 1172 } 1173 /* the former and the latter identify a 1174 * virtual port and a NIC, respectively 1175 */ 1176 if (!strcmp(vpna->up.name, name)) { 1177 nmr->nr_arg2 = i; /* port index */ 1178 break; 1179 } 1180 } 1181 NMG_UNLOCK(); 1182 } else { 1183 /* return the first non-empty entry starting from 1184 * bridge nr_arg1 and port nr_arg2. 1185 * 1186 * Users can detect the end of the same bridge by 1187 * seeing the new and old value of nr_arg1, and can 1188 * detect the end of all the bridge by error != 0 1189 */ 1190 i = nmr->nr_arg1; 1191 j = nmr->nr_arg2; 1192 1193 NMG_LOCK(); 1194 for (error = ENOENT; i < NM_BRIDGES; i++) { 1195 b = bridges + i; 1196 if (j >= b->bdg_active_ports) { 1197 j = 0; /* following bridges scan from 0 */ 1198 continue; 1199 } 1200 nmr->nr_arg1 = i; 1201 nmr->nr_arg2 = j; 1202 j = b->bdg_port_index[j]; 1203 vpna = b->bdg_ports[j]; 1204 strncpy(name, vpna->up.name, (size_t)IFNAMSIZ); 1205 error = 0; 1206 break; 1207 } 1208 NMG_UNLOCK(); 1209 } 1210 break; 1211 1212 case NETMAP_BDG_REGOPS: /* XXX this should not be available from userspace */ 1213 /* register callbacks to the given bridge. 1214 * nmr->nr_name may be just bridge's name (including ':' 1215 * if it is not just NM_NAME). 1216 */ 1217 if (!bdg_ops) { 1218 error = EINVAL; 1219 break; 1220 } 1221 NMG_LOCK(); 1222 b = nm_find_bridge(name, 0 /* don't create */); 1223 if (!b) { 1224 error = EINVAL; 1225 } else { 1226 b->bdg_ops = *bdg_ops; 1227 } 1228 NMG_UNLOCK(); 1229 break; 1230 1231 case NETMAP_BDG_VNET_HDR: 1232 /* Valid lengths for the virtio-net header are 0 (no header), 1233 10 and 12. */ 1234 if (nmr->nr_arg1 != 0 && 1235 nmr->nr_arg1 != sizeof(struct nm_vnet_hdr) && 1236 nmr->nr_arg1 != 12) { 1237 error = EINVAL; 1238 break; 1239 } 1240 NMG_LOCK(); 1241 error = netmap_get_bdg_na(nmr, &na, 0); 1242 if (na && !error) { 1243 vpna = (struct netmap_vp_adapter *)na; 1244 na->virt_hdr_len = nmr->nr_arg1; 1245 if (na->virt_hdr_len) { 1246 vpna->mfs = NETMAP_BUF_SIZE(na); 1247 } 1248 D("Using vnet_hdr_len %d for %p", na->virt_hdr_len, na); 1249 netmap_adapter_put(na); 1250 } else if (!na) { 1251 error = ENXIO; 1252 } 1253 NMG_UNLOCK(); 1254 break; 1255 1256 case NETMAP_BDG_POLLING_ON: 1257 case NETMAP_BDG_POLLING_OFF: 1258 NMG_LOCK(); 1259 error = netmap_get_bdg_na(nmr, &na, 0); 1260 if (na && !error) { 1261 if (!nm_is_bwrap(na)) { 1262 error = EOPNOTSUPP; 1263 } else if (cmd == NETMAP_BDG_POLLING_ON) { 1264 error = nm_bdg_ctl_polling_start(nmr, na); 1265 if (!error) 1266 netmap_adapter_get(na); 1267 } else { 1268 error = nm_bdg_ctl_polling_stop(nmr, na); 1269 if (!error) 1270 netmap_adapter_put(na); 1271 } 1272 netmap_adapter_put(na); 1273 } 1274 NMG_UNLOCK(); 1275 break; 1276 1277 default: 1278 D("invalid cmd (nmr->nr_cmd) (0x%x)", cmd); 1279 error = EINVAL; 1280 break; 1281 } 1282 return error; 1283 } 1284 1285 int 1286 netmap_bdg_config(struct nmreq *nmr) 1287 { 1288 struct nm_bridge *b; 1289 int error = EINVAL; 1290 1291 NMG_LOCK(); 1292 b = nm_find_bridge(nmr->nr_name, 0); 1293 if (!b) { 1294 NMG_UNLOCK(); 1295 return error; 1296 } 1297 NMG_UNLOCK(); 1298 /* Don't call config() with NMG_LOCK() held */ 1299 BDG_RLOCK(b); 1300 if (b->bdg_ops.config != NULL) 1301 error = b->bdg_ops.config((struct nm_ifreq *)nmr); 1302 BDG_RUNLOCK(b); 1303 return error; 1304 } 1305 1306 1307 /* nm_krings_create callback for VALE ports. 1308 * Calls the standard netmap_krings_create, then adds leases on rx 1309 * rings and bdgfwd on tx rings. 1310 */ 1311 static int 1312 netmap_vp_krings_create(struct netmap_adapter *na) 1313 { 1314 u_int tailroom; 1315 int error, i; 1316 uint32_t *leases; 1317 u_int nrx = netmap_real_rings(na, NR_RX); 1318 1319 /* 1320 * Leases are attached to RX rings on vale ports 1321 */ 1322 tailroom = sizeof(uint32_t) * na->num_rx_desc * nrx; 1323 1324 error = netmap_krings_create(na, tailroom); 1325 if (error) 1326 return error; 1327 1328 leases = na->tailroom; 1329 1330 for (i = 0; i < nrx; i++) { /* Receive rings */ 1331 na->rx_rings[i].nkr_leases = leases; 1332 leases += na->num_rx_desc; 1333 } 1334 1335 error = nm_alloc_bdgfwd(na); 1336 if (error) { 1337 netmap_krings_delete(na); 1338 return error; 1339 } 1340 1341 return 0; 1342 } 1343 1344 1345 /* nm_krings_delete callback for VALE ports. */ 1346 static void 1347 netmap_vp_krings_delete(struct netmap_adapter *na) 1348 { 1349 nm_free_bdgfwd(na); 1350 netmap_krings_delete(na); 1351 } 1352 1353 1354 static int 1355 nm_bdg_flush(struct nm_bdg_fwd *ft, u_int n, 1356 struct netmap_vp_adapter *na, u_int ring_nr); 1357 1358 1359 /* 1360 * main dispatch routine for the bridge. 1361 * Grab packets from a kring, move them into the ft structure 1362 * associated to the tx (input) port. Max one instance per port, 1363 * filtered on input (ioctl, poll or XXX). 1364 * Returns the next position in the ring. 1365 */ 1366 static int 1367 nm_bdg_preflush(struct netmap_kring *kring, u_int end) 1368 { 1369 struct netmap_vp_adapter *na = 1370 (struct netmap_vp_adapter*)kring->na; 1371 struct netmap_ring *ring = kring->ring; 1372 struct nm_bdg_fwd *ft; 1373 u_int ring_nr = kring->ring_id; 1374 u_int j = kring->nr_hwcur, lim = kring->nkr_num_slots - 1; 1375 u_int ft_i = 0; /* start from 0 */ 1376 u_int frags = 1; /* how many frags ? */ 1377 struct nm_bridge *b = na->na_bdg; 1378 1379 /* To protect against modifications to the bridge we acquire a 1380 * shared lock, waiting if we can sleep (if the source port is 1381 * attached to a user process) or with a trylock otherwise (NICs). 1382 */ 1383 ND("wait rlock for %d packets", ((j > end ? lim+1 : 0) + end) - j); 1384 if (na->up.na_flags & NAF_BDG_MAYSLEEP) 1385 BDG_RLOCK(b); 1386 else if (!BDG_RTRYLOCK(b)) 1387 return 0; 1388 ND(5, "rlock acquired for %d packets", ((j > end ? lim+1 : 0) + end) - j); 1389 ft = kring->nkr_ft; 1390 1391 for (; likely(j != end); j = nm_next(j, lim)) { 1392 struct netmap_slot *slot = &ring->slot[j]; 1393 char *buf; 1394 1395 ft[ft_i].ft_len = slot->len; 1396 ft[ft_i].ft_flags = slot->flags; 1397 1398 ND("flags is 0x%x", slot->flags); 1399 /* we do not use the buf changed flag, but we still need to reset it */ 1400 slot->flags &= ~NS_BUF_CHANGED; 1401 1402 /* this slot goes into a list so initialize the link field */ 1403 ft[ft_i].ft_next = NM_FT_NULL; 1404 buf = ft[ft_i].ft_buf = (slot->flags & NS_INDIRECT) ? 1405 (void *)(uintptr_t)slot->ptr : NMB(&na->up, slot); 1406 if (unlikely(buf == NULL)) { 1407 RD(5, "NULL %s buffer pointer from %s slot %d len %d", 1408 (slot->flags & NS_INDIRECT) ? "INDIRECT" : "DIRECT", 1409 kring->name, j, ft[ft_i].ft_len); 1410 buf = ft[ft_i].ft_buf = NETMAP_BUF_BASE(&na->up); 1411 ft[ft_i].ft_len = 0; 1412 ft[ft_i].ft_flags = 0; 1413 } 1414 __builtin_prefetch(buf); 1415 ++ft_i; 1416 if (slot->flags & NS_MOREFRAG) { 1417 frags++; 1418 continue; 1419 } 1420 if (unlikely(netmap_verbose && frags > 1)) 1421 RD(5, "%d frags at %d", frags, ft_i - frags); 1422 ft[ft_i - frags].ft_frags = frags; 1423 frags = 1; 1424 if (unlikely((int)ft_i >= bridge_batch)) 1425 ft_i = nm_bdg_flush(ft, ft_i, na, ring_nr); 1426 } 1427 if (frags > 1) { 1428 /* Here ft_i > 0, ft[ft_i-1].flags has NS_MOREFRAG, and we 1429 * have to fix frags count. */ 1430 frags--; 1431 ft[ft_i - 1].ft_flags &= ~NS_MOREFRAG; 1432 ft[ft_i - frags].ft_frags = frags; 1433 D("Truncate incomplete fragment at %d (%d frags)", ft_i, frags); 1434 } 1435 if (ft_i) 1436 ft_i = nm_bdg_flush(ft, ft_i, na, ring_nr); 1437 BDG_RUNLOCK(b); 1438 return j; 1439 } 1440 1441 1442 /* ----- FreeBSD if_bridge hash function ------- */ 1443 1444 /* 1445 * The following hash function is adapted from "Hash Functions" by Bob Jenkins 1446 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 1447 * 1448 * http://www.burtleburtle.net/bob/hash/spooky.html 1449 */ 1450 #define mix(a, b, c) \ 1451 do { \ 1452 a -= b; a -= c; a ^= (c >> 13); \ 1453 b -= c; b -= a; b ^= (a << 8); \ 1454 c -= a; c -= b; c ^= (b >> 13); \ 1455 a -= b; a -= c; a ^= (c >> 12); \ 1456 b -= c; b -= a; b ^= (a << 16); \ 1457 c -= a; c -= b; c ^= (b >> 5); \ 1458 a -= b; a -= c; a ^= (c >> 3); \ 1459 b -= c; b -= a; b ^= (a << 10); \ 1460 c -= a; c -= b; c ^= (b >> 15); \ 1461 } while (/*CONSTCOND*/0) 1462 1463 1464 static __inline uint32_t 1465 nm_bridge_rthash(const uint8_t *addr) 1466 { 1467 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = 0; // hask key 1468 1469 b += addr[5] << 8; 1470 b += addr[4]; 1471 a += addr[3] << 24; 1472 a += addr[2] << 16; 1473 a += addr[1] << 8; 1474 a += addr[0]; 1475 1476 mix(a, b, c); 1477 #define BRIDGE_RTHASH_MASK (NM_BDG_HASH-1) 1478 return (c & BRIDGE_RTHASH_MASK); 1479 } 1480 1481 #undef mix 1482 1483 1484 /* nm_register callback for VALE ports */ 1485 static int 1486 netmap_vp_reg(struct netmap_adapter *na, int onoff) 1487 { 1488 struct netmap_vp_adapter *vpna = 1489 (struct netmap_vp_adapter*)na; 1490 enum txrx t; 1491 int i; 1492 1493 /* persistent ports may be put in netmap mode 1494 * before being attached to a bridge 1495 */ 1496 if (vpna->na_bdg) 1497 BDG_WLOCK(vpna->na_bdg); 1498 if (onoff) { 1499 for_rx_tx(t) { 1500 for (i = 0; i < nma_get_nrings(na, t) + 1; i++) { 1501 struct netmap_kring *kring = &NMR(na, t)[i]; 1502 1503 if (nm_kring_pending_on(kring)) 1504 kring->nr_mode = NKR_NETMAP_ON; 1505 } 1506 } 1507 if (na->active_fds == 0) 1508 na->na_flags |= NAF_NETMAP_ON; 1509 /* XXX on FreeBSD, persistent VALE ports should also 1510 * toggle IFCAP_NETMAP in na->ifp (2014-03-16) 1511 */ 1512 } else { 1513 if (na->active_fds == 0) 1514 na->na_flags &= ~NAF_NETMAP_ON; 1515 for_rx_tx(t) { 1516 for (i = 0; i < nma_get_nrings(na, t) + 1; i++) { 1517 struct netmap_kring *kring = &NMR(na, t)[i]; 1518 1519 if (nm_kring_pending_off(kring)) 1520 kring->nr_mode = NKR_NETMAP_OFF; 1521 } 1522 } 1523 } 1524 if (vpna->na_bdg) 1525 BDG_WUNLOCK(vpna->na_bdg); 1526 return 0; 1527 } 1528 1529 1530 /* 1531 * Lookup function for a learning bridge. 1532 * Update the hash table with the source address, 1533 * and then returns the destination port index, and the 1534 * ring in *dst_ring (at the moment, always use ring 0) 1535 */ 1536 u_int 1537 netmap_bdg_learning(struct nm_bdg_fwd *ft, uint8_t *dst_ring, 1538 struct netmap_vp_adapter *na) 1539 { 1540 uint8_t *buf = ft->ft_buf; 1541 u_int buf_len = ft->ft_len; 1542 struct nm_hash_ent *ht = na->na_bdg->ht; 1543 uint32_t sh, dh; 1544 u_int dst, mysrc = na->bdg_port; 1545 uint64_t smac, dmac; 1546 uint8_t indbuf[12]; 1547 1548 /* safety check, unfortunately we have many cases */ 1549 if (buf_len >= 14 + na->up.virt_hdr_len) { 1550 /* virthdr + mac_hdr in the same slot */ 1551 buf += na->up.virt_hdr_len; 1552 buf_len -= na->up.virt_hdr_len; 1553 } else if (buf_len == na->up.virt_hdr_len && ft->ft_flags & NS_MOREFRAG) { 1554 /* only header in first fragment */ 1555 ft++; 1556 buf = ft->ft_buf; 1557 buf_len = ft->ft_len; 1558 } else { 1559 RD(5, "invalid buf format, length %d", buf_len); 1560 return NM_BDG_NOPORT; 1561 } 1562 1563 if (ft->ft_flags & NS_INDIRECT) { 1564 if (copyin(buf, indbuf, sizeof(indbuf))) { 1565 return NM_BDG_NOPORT; 1566 } 1567 buf = indbuf; 1568 } 1569 1570 dmac = le64toh(*(uint64_t *)(buf)) & 0xffffffffffff; 1571 smac = le64toh(*(uint64_t *)(buf + 4)); 1572 smac >>= 16; 1573 1574 /* 1575 * The hash is somewhat expensive, there might be some 1576 * worthwhile optimizations here. 1577 */ 1578 if (((buf[6] & 1) == 0) && (na->last_smac != smac)) { /* valid src */ 1579 uint8_t *s = buf+6; 1580 sh = nm_bridge_rthash(s); // XXX hash of source 1581 /* update source port forwarding entry */ 1582 na->last_smac = ht[sh].mac = smac; /* XXX expire ? */ 1583 ht[sh].ports = mysrc; 1584 if (netmap_verbose) 1585 D("src %02x:%02x:%02x:%02x:%02x:%02x on port %d", 1586 s[0], s[1], s[2], s[3], s[4], s[5], mysrc); 1587 } 1588 dst = NM_BDG_BROADCAST; 1589 if ((buf[0] & 1) == 0) { /* unicast */ 1590 dh = nm_bridge_rthash(buf); // XXX hash of dst 1591 if (ht[dh].mac == dmac) { /* found dst */ 1592 dst = ht[dh].ports; 1593 } 1594 /* XXX otherwise return NM_BDG_UNKNOWN ? */ 1595 } 1596 return dst; 1597 } 1598 1599 1600 /* 1601 * Available space in the ring. Only used in VALE code 1602 * and only with is_rx = 1 1603 */ 1604 static inline uint32_t 1605 nm_kr_space(struct netmap_kring *k, int is_rx) 1606 { 1607 int space; 1608 1609 if (is_rx) { 1610 int busy = k->nkr_hwlease - k->nr_hwcur; 1611 if (busy < 0) 1612 busy += k->nkr_num_slots; 1613 space = k->nkr_num_slots - 1 - busy; 1614 } else { 1615 /* XXX never used in this branch */ 1616 space = k->nr_hwtail - k->nkr_hwlease; 1617 if (space < 0) 1618 space += k->nkr_num_slots; 1619 } 1620 #if 0 1621 // sanity check 1622 if (k->nkr_hwlease >= k->nkr_num_slots || 1623 k->nr_hwcur >= k->nkr_num_slots || 1624 k->nr_tail >= k->nkr_num_slots || 1625 busy < 0 || 1626 busy >= k->nkr_num_slots) { 1627 D("invalid kring, cur %d tail %d lease %d lease_idx %d lim %d", k->nr_hwcur, k->nr_hwtail, k->nkr_hwlease, 1628 k->nkr_lease_idx, k->nkr_num_slots); 1629 } 1630 #endif 1631 return space; 1632 } 1633 1634 1635 1636 1637 /* make a lease on the kring for N positions. return the 1638 * lease index 1639 * XXX only used in VALE code and with is_rx = 1 1640 */ 1641 static inline uint32_t 1642 nm_kr_lease(struct netmap_kring *k, u_int n, int is_rx) 1643 { 1644 uint32_t lim = k->nkr_num_slots - 1; 1645 uint32_t lease_idx = k->nkr_lease_idx; 1646 1647 k->nkr_leases[lease_idx] = NR_NOSLOT; 1648 k->nkr_lease_idx = nm_next(lease_idx, lim); 1649 1650 if (n > nm_kr_space(k, is_rx)) { 1651 D("invalid request for %d slots", n); 1652 panic("x"); 1653 } 1654 /* XXX verify that there are n slots */ 1655 k->nkr_hwlease += n; 1656 if (k->nkr_hwlease > lim) 1657 k->nkr_hwlease -= lim + 1; 1658 1659 if (k->nkr_hwlease >= k->nkr_num_slots || 1660 k->nr_hwcur >= k->nkr_num_slots || 1661 k->nr_hwtail >= k->nkr_num_slots || 1662 k->nkr_lease_idx >= k->nkr_num_slots) { 1663 D("invalid kring %s, cur %d tail %d lease %d lease_idx %d lim %d", 1664 k->na->name, 1665 k->nr_hwcur, k->nr_hwtail, k->nkr_hwlease, 1666 k->nkr_lease_idx, k->nkr_num_slots); 1667 } 1668 return lease_idx; 1669 } 1670 1671 /* 1672 * 1673 * This flush routine supports only unicast and broadcast but a large 1674 * number of ports, and lets us replace the learn and dispatch functions. 1675 */ 1676 int 1677 nm_bdg_flush(struct nm_bdg_fwd *ft, u_int n, struct netmap_vp_adapter *na, 1678 u_int ring_nr) 1679 { 1680 struct nm_bdg_q *dst_ents, *brddst; 1681 uint16_t num_dsts = 0, *dsts; 1682 struct nm_bridge *b = na->na_bdg; 1683 u_int i, me = na->bdg_port; 1684 1685 /* 1686 * The work area (pointed by ft) is followed by an array of 1687 * pointers to queues , dst_ents; there are NM_BDG_MAXRINGS 1688 * queues per port plus one for the broadcast traffic. 1689 * Then we have an array of destination indexes. 1690 */ 1691 dst_ents = (struct nm_bdg_q *)(ft + NM_BDG_BATCH_MAX); 1692 dsts = (uint16_t *)(dst_ents + NM_BDG_MAXPORTS * NM_BDG_MAXRINGS + 1); 1693 1694 /* first pass: find a destination for each packet in the batch */ 1695 for (i = 0; likely(i < n); i += ft[i].ft_frags) { 1696 uint8_t dst_ring = ring_nr; /* default, same ring as origin */ 1697 uint16_t dst_port, d_i; 1698 struct nm_bdg_q *d; 1699 1700 ND("slot %d frags %d", i, ft[i].ft_frags); 1701 /* Drop the packet if the virtio-net header is not into the first 1702 fragment nor at the very beginning of the second. */ 1703 if (unlikely(na->up.virt_hdr_len > ft[i].ft_len)) 1704 continue; 1705 dst_port = b->bdg_ops.lookup(&ft[i], &dst_ring, na); 1706 if (netmap_verbose > 255) 1707 RD(5, "slot %d port %d -> %d", i, me, dst_port); 1708 if (dst_port == NM_BDG_NOPORT) 1709 continue; /* this packet is identified to be dropped */ 1710 else if (unlikely(dst_port > NM_BDG_MAXPORTS)) 1711 continue; 1712 else if (dst_port == NM_BDG_BROADCAST) 1713 dst_ring = 0; /* broadcasts always go to ring 0 */ 1714 else if (unlikely(dst_port == me || 1715 !b->bdg_ports[dst_port])) 1716 continue; 1717 1718 /* get a position in the scratch pad */ 1719 d_i = dst_port * NM_BDG_MAXRINGS + dst_ring; 1720 d = dst_ents + d_i; 1721 1722 /* append the first fragment to the list */ 1723 if (d->bq_head == NM_FT_NULL) { /* new destination */ 1724 d->bq_head = d->bq_tail = i; 1725 /* remember this position to be scanned later */ 1726 if (dst_port != NM_BDG_BROADCAST) 1727 dsts[num_dsts++] = d_i; 1728 } else { 1729 ft[d->bq_tail].ft_next = i; 1730 d->bq_tail = i; 1731 } 1732 d->bq_len += ft[i].ft_frags; 1733 } 1734 1735 /* 1736 * Broadcast traffic goes to ring 0 on all destinations. 1737 * So we need to add these rings to the list of ports to scan. 1738 * XXX at the moment we scan all NM_BDG_MAXPORTS ports, which is 1739 * expensive. We should keep a compact list of active destinations 1740 * so we could shorten this loop. 1741 */ 1742 brddst = dst_ents + NM_BDG_BROADCAST * NM_BDG_MAXRINGS; 1743 if (brddst->bq_head != NM_FT_NULL) { 1744 u_int j; 1745 for (j = 0; likely(j < b->bdg_active_ports); j++) { 1746 uint16_t d_i; 1747 i = b->bdg_port_index[j]; 1748 if (unlikely(i == me)) 1749 continue; 1750 d_i = i * NM_BDG_MAXRINGS; 1751 if (dst_ents[d_i].bq_head == NM_FT_NULL) 1752 dsts[num_dsts++] = d_i; 1753 } 1754 } 1755 1756 ND(5, "pass 1 done %d pkts %d dsts", n, num_dsts); 1757 /* second pass: scan destinations */ 1758 for (i = 0; i < num_dsts; i++) { 1759 struct netmap_vp_adapter *dst_na; 1760 struct netmap_kring *kring; 1761 struct netmap_ring *ring; 1762 u_int dst_nr, lim, j, d_i, next, brd_next; 1763 u_int needed, howmany; 1764 int retry = netmap_txsync_retry; 1765 struct nm_bdg_q *d; 1766 uint32_t my_start = 0, lease_idx = 0; 1767 int nrings; 1768 int virt_hdr_mismatch = 0; 1769 1770 d_i = dsts[i]; 1771 ND("second pass %d port %d", i, d_i); 1772 d = dst_ents + d_i; 1773 // XXX fix the division 1774 dst_na = b->bdg_ports[d_i/NM_BDG_MAXRINGS]; 1775 /* protect from the lookup function returning an inactive 1776 * destination port 1777 */ 1778 if (unlikely(dst_na == NULL)) 1779 goto cleanup; 1780 if (dst_na->up.na_flags & NAF_SW_ONLY) 1781 goto cleanup; 1782 /* 1783 * The interface may be in !netmap mode in two cases: 1784 * - when na is attached but not activated yet; 1785 * - when na is being deactivated but is still attached. 1786 */ 1787 if (unlikely(!nm_netmap_on(&dst_na->up))) { 1788 ND("not in netmap mode!"); 1789 goto cleanup; 1790 } 1791 1792 /* there is at least one either unicast or broadcast packet */ 1793 brd_next = brddst->bq_head; 1794 next = d->bq_head; 1795 /* we need to reserve this many slots. If fewer are 1796 * available, some packets will be dropped. 1797 * Packets may have multiple fragments, so we may not use 1798 * there is a chance that we may not use all of the slots 1799 * we have claimed, so we will need to handle the leftover 1800 * ones when we regain the lock. 1801 */ 1802 needed = d->bq_len + brddst->bq_len; 1803 1804 if (unlikely(dst_na->up.virt_hdr_len != na->up.virt_hdr_len)) { 1805 RD(3, "virt_hdr_mismatch, src %d dst %d", na->up.virt_hdr_len, 1806 dst_na->up.virt_hdr_len); 1807 /* There is a virtio-net header/offloadings mismatch between 1808 * source and destination. The slower mismatch datapath will 1809 * be used to cope with all the mismatches. 1810 */ 1811 virt_hdr_mismatch = 1; 1812 if (dst_na->mfs < na->mfs) { 1813 /* We may need to do segmentation offloadings, and so 1814 * we may need a number of destination slots greater 1815 * than the number of input slots ('needed'). 1816 * We look for the smallest integer 'x' which satisfies: 1817 * needed * na->mfs + x * H <= x * na->mfs 1818 * where 'H' is the length of the longest header that may 1819 * be replicated in the segmentation process (e.g. for 1820 * TCPv4 we must account for ethernet header, IP header 1821 * and TCPv4 header). 1822 */ 1823 needed = (needed * na->mfs) / 1824 (dst_na->mfs - WORST_CASE_GSO_HEADER) + 1; 1825 ND(3, "srcmtu=%u, dstmtu=%u, x=%u", na->mfs, dst_na->mfs, needed); 1826 } 1827 } 1828 1829 ND(5, "pass 2 dst %d is %x %s", 1830 i, d_i, is_vp ? "virtual" : "nic/host"); 1831 dst_nr = d_i & (NM_BDG_MAXRINGS-1); 1832 nrings = dst_na->up.num_rx_rings; 1833 if (dst_nr >= nrings) 1834 dst_nr = dst_nr % nrings; 1835 kring = &dst_na->up.rx_rings[dst_nr]; 1836 ring = kring->ring; 1837 lim = kring->nkr_num_slots - 1; 1838 1839 retry: 1840 1841 if (dst_na->retry && retry) { 1842 /* try to get some free slot from the previous run */ 1843 kring->nm_notify(kring, 0); 1844 /* actually useful only for bwraps, since there 1845 * the notify will trigger a txsync on the hwna. VALE ports 1846 * have dst_na->retry == 0 1847 */ 1848 } 1849 /* reserve the buffers in the queue and an entry 1850 * to report completion, and drop lock. 1851 * XXX this might become a helper function. 1852 */ 1853 mtx_lock(&kring->q_lock); 1854 if (kring->nkr_stopped) { 1855 mtx_unlock(&kring->q_lock); 1856 goto cleanup; 1857 } 1858 my_start = j = kring->nkr_hwlease; 1859 howmany = nm_kr_space(kring, 1); 1860 if (needed < howmany) 1861 howmany = needed; 1862 lease_idx = nm_kr_lease(kring, howmany, 1); 1863 mtx_unlock(&kring->q_lock); 1864 1865 /* only retry if we need more than available slots */ 1866 if (retry && needed <= howmany) 1867 retry = 0; 1868 1869 /* copy to the destination queue */ 1870 while (howmany > 0) { 1871 struct netmap_slot *slot; 1872 struct nm_bdg_fwd *ft_p, *ft_end; 1873 u_int cnt; 1874 1875 /* find the queue from which we pick next packet. 1876 * NM_FT_NULL is always higher than valid indexes 1877 * so we never dereference it if the other list 1878 * has packets (and if both are empty we never 1879 * get here). 1880 */ 1881 if (next < brd_next) { 1882 ft_p = ft + next; 1883 next = ft_p->ft_next; 1884 } else { /* insert broadcast */ 1885 ft_p = ft + brd_next; 1886 brd_next = ft_p->ft_next; 1887 } 1888 cnt = ft_p->ft_frags; // cnt > 0 1889 if (unlikely(cnt > howmany)) 1890 break; /* no more space */ 1891 if (netmap_verbose && cnt > 1) 1892 RD(5, "rx %d frags to %d", cnt, j); 1893 ft_end = ft_p + cnt; 1894 if (unlikely(virt_hdr_mismatch)) { 1895 bdg_mismatch_datapath(na, dst_na, ft_p, ring, &j, lim, &howmany); 1896 } else { 1897 howmany -= cnt; 1898 do { 1899 char *dst, *src = ft_p->ft_buf; 1900 size_t copy_len = ft_p->ft_len, dst_len = copy_len; 1901 1902 slot = &ring->slot[j]; 1903 dst = NMB(&dst_na->up, slot); 1904 1905 ND("send [%d] %d(%d) bytes at %s:%d", 1906 i, (int)copy_len, (int)dst_len, 1907 NM_IFPNAME(dst_ifp), j); 1908 /* round to a multiple of 64 */ 1909 copy_len = (copy_len + 63) & ~63; 1910 1911 if (unlikely(copy_len > NETMAP_BUF_SIZE(&dst_na->up) || 1912 copy_len > NETMAP_BUF_SIZE(&na->up))) { 1913 RD(5, "invalid len %d, down to 64", (int)copy_len); 1914 copy_len = dst_len = 64; // XXX 1915 } 1916 if (ft_p->ft_flags & NS_INDIRECT) { 1917 if (copyin(src, dst, copy_len)) { 1918 // invalid user pointer, pretend len is 0 1919 dst_len = 0; 1920 } 1921 } else { 1922 //memcpy(dst, src, copy_len); 1923 pkt_copy(src, dst, (int)copy_len); 1924 } 1925 slot->len = dst_len; 1926 slot->flags = (cnt << 8)| NS_MOREFRAG; 1927 j = nm_next(j, lim); 1928 needed--; 1929 ft_p++; 1930 } while (ft_p != ft_end); 1931 slot->flags = (cnt << 8); /* clear flag on last entry */ 1932 } 1933 /* are we done ? */ 1934 if (next == NM_FT_NULL && brd_next == NM_FT_NULL) 1935 break; 1936 } 1937 { 1938 /* current position */ 1939 uint32_t *p = kring->nkr_leases; /* shorthand */ 1940 uint32_t update_pos; 1941 int still_locked = 1; 1942 1943 mtx_lock(&kring->q_lock); 1944 if (unlikely(howmany > 0)) { 1945 /* not used all bufs. If i am the last one 1946 * i can recover the slots, otherwise must 1947 * fill them with 0 to mark empty packets. 1948 */ 1949 ND("leftover %d bufs", howmany); 1950 if (nm_next(lease_idx, lim) == kring->nkr_lease_idx) { 1951 /* yes i am the last one */ 1952 ND("roll back nkr_hwlease to %d", j); 1953 kring->nkr_hwlease = j; 1954 } else { 1955 while (howmany-- > 0) { 1956 ring->slot[j].len = 0; 1957 ring->slot[j].flags = 0; 1958 j = nm_next(j, lim); 1959 } 1960 } 1961 } 1962 p[lease_idx] = j; /* report I am done */ 1963 1964 update_pos = kring->nr_hwtail; 1965 1966 if (my_start == update_pos) { 1967 /* all slots before my_start have been reported, 1968 * so scan subsequent leases to see if other ranges 1969 * have been completed, and to a selwakeup or txsync. 1970 */ 1971 while (lease_idx != kring->nkr_lease_idx && 1972 p[lease_idx] != NR_NOSLOT) { 1973 j = p[lease_idx]; 1974 p[lease_idx] = NR_NOSLOT; 1975 lease_idx = nm_next(lease_idx, lim); 1976 } 1977 /* j is the new 'write' position. j != my_start 1978 * means there are new buffers to report 1979 */ 1980 if (likely(j != my_start)) { 1981 kring->nr_hwtail = j; 1982 still_locked = 0; 1983 mtx_unlock(&kring->q_lock); 1984 kring->nm_notify(kring, 0); 1985 /* this is netmap_notify for VALE ports and 1986 * netmap_bwrap_notify for bwrap. The latter will 1987 * trigger a txsync on the underlying hwna 1988 */ 1989 if (dst_na->retry && retry--) { 1990 /* XXX this is going to call nm_notify again. 1991 * Only useful for bwrap in virtual machines 1992 */ 1993 goto retry; 1994 } 1995 } 1996 } 1997 if (still_locked) 1998 mtx_unlock(&kring->q_lock); 1999 } 2000 cleanup: 2001 d->bq_head = d->bq_tail = NM_FT_NULL; /* cleanup */ 2002 d->bq_len = 0; 2003 } 2004 brddst->bq_head = brddst->bq_tail = NM_FT_NULL; /* cleanup */ 2005 brddst->bq_len = 0; 2006 return 0; 2007 } 2008 2009 /* nm_txsync callback for VALE ports */ 2010 static int 2011 netmap_vp_txsync(struct netmap_kring *kring, int flags) 2012 { 2013 struct netmap_vp_adapter *na = 2014 (struct netmap_vp_adapter *)kring->na; 2015 u_int done; 2016 u_int const lim = kring->nkr_num_slots - 1; 2017 u_int const head = kring->rhead; 2018 2019 if (bridge_batch <= 0) { /* testing only */ 2020 done = head; // used all 2021 goto done; 2022 } 2023 if (!na->na_bdg) { 2024 done = head; 2025 goto done; 2026 } 2027 if (bridge_batch > NM_BDG_BATCH) 2028 bridge_batch = NM_BDG_BATCH; 2029 2030 done = nm_bdg_preflush(kring, head); 2031 done: 2032 if (done != head) 2033 D("early break at %d/ %d, tail %d", done, head, kring->nr_hwtail); 2034 /* 2035 * packets between 'done' and 'cur' are left unsent. 2036 */ 2037 kring->nr_hwcur = done; 2038 kring->nr_hwtail = nm_prev(done, lim); 2039 if (netmap_verbose) 2040 D("%s ring %d flags %d", na->up.name, kring->ring_id, flags); 2041 return 0; 2042 } 2043 2044 2045 /* rxsync code used by VALE ports nm_rxsync callback and also 2046 * internally by the brwap 2047 */ 2048 static int 2049 netmap_vp_rxsync_locked(struct netmap_kring *kring, int flags) 2050 { 2051 struct netmap_adapter *na = kring->na; 2052 struct netmap_ring *ring = kring->ring; 2053 u_int nm_i, lim = kring->nkr_num_slots - 1; 2054 u_int head = kring->rhead; 2055 int n; 2056 2057 if (head > lim) { 2058 D("ouch dangerous reset!!!"); 2059 n = netmap_ring_reinit(kring); 2060 goto done; 2061 } 2062 2063 /* First part, import newly received packets. */ 2064 /* actually nothing to do here, they are already in the kring */ 2065 2066 /* Second part, skip past packets that userspace has released. */ 2067 nm_i = kring->nr_hwcur; 2068 if (nm_i != head) { 2069 /* consistency check, but nothing really important here */ 2070 for (n = 0; likely(nm_i != head); n++) { 2071 struct netmap_slot *slot = &ring->slot[nm_i]; 2072 void *addr = NMB(na, slot); 2073 2074 if (addr == NETMAP_BUF_BASE(kring->na)) { /* bad buf */ 2075 D("bad buffer index %d, ignore ?", 2076 slot->buf_idx); 2077 } 2078 slot->flags &= ~NS_BUF_CHANGED; 2079 nm_i = nm_next(nm_i, lim); 2080 } 2081 kring->nr_hwcur = head; 2082 } 2083 2084 n = 0; 2085 done: 2086 return n; 2087 } 2088 2089 /* 2090 * nm_rxsync callback for VALE ports 2091 * user process reading from a VALE switch. 2092 * Already protected against concurrent calls from userspace, 2093 * but we must acquire the queue's lock to protect against 2094 * writers on the same queue. 2095 */ 2096 static int 2097 netmap_vp_rxsync(struct netmap_kring *kring, int flags) 2098 { 2099 int n; 2100 2101 mtx_lock(&kring->q_lock); 2102 n = netmap_vp_rxsync_locked(kring, flags); 2103 mtx_unlock(&kring->q_lock); 2104 return n; 2105 } 2106 2107 2108 /* nm_bdg_attach callback for VALE ports 2109 * The na_vp port is this same netmap_adapter. There is no host port. 2110 */ 2111 static int 2112 netmap_vp_bdg_attach(const char *name, struct netmap_adapter *na) 2113 { 2114 struct netmap_vp_adapter *vpna = (struct netmap_vp_adapter *)na; 2115 2116 if (vpna->na_bdg) 2117 return EBUSY; 2118 na->na_vp = vpna; 2119 strncpy(na->name, name, sizeof(na->name)); 2120 na->na_hostvp = NULL; 2121 return 0; 2122 } 2123 2124 /* create a netmap_vp_adapter that describes a VALE port. 2125 * Only persistent VALE ports have a non-null ifp. 2126 */ 2127 static int 2128 netmap_vp_create(struct nmreq *nmr, struct ifnet *ifp, struct netmap_vp_adapter **ret) 2129 { 2130 struct netmap_vp_adapter *vpna; 2131 struct netmap_adapter *na; 2132 int error; 2133 u_int npipes = 0; 2134 2135 vpna = malloc(sizeof(*vpna), M_DEVBUF, M_NOWAIT | M_ZERO); 2136 if (vpna == NULL) 2137 return ENOMEM; 2138 2139 na = &vpna->up; 2140 2141 na->ifp = ifp; 2142 strncpy(na->name, nmr->nr_name, sizeof(na->name)); 2143 2144 /* bound checking */ 2145 na->num_tx_rings = nmr->nr_tx_rings; 2146 nm_bound_var(&na->num_tx_rings, 1, 1, NM_BDG_MAXRINGS, NULL); 2147 nmr->nr_tx_rings = na->num_tx_rings; // write back 2148 na->num_rx_rings = nmr->nr_rx_rings; 2149 nm_bound_var(&na->num_rx_rings, 1, 1, NM_BDG_MAXRINGS, NULL); 2150 nmr->nr_rx_rings = na->num_rx_rings; // write back 2151 nm_bound_var(&nmr->nr_tx_slots, NM_BRIDGE_RINGSIZE, 2152 1, NM_BDG_MAXSLOTS, NULL); 2153 na->num_tx_desc = nmr->nr_tx_slots; 2154 nm_bound_var(&nmr->nr_rx_slots, NM_BRIDGE_RINGSIZE, 2155 1, NM_BDG_MAXSLOTS, NULL); 2156 /* validate number of pipes. We want at least 1, 2157 * but probably can do with some more. 2158 * So let's use 2 as default (when 0 is supplied) 2159 */ 2160 npipes = nmr->nr_arg1; 2161 nm_bound_var(&npipes, 2, 1, NM_MAXPIPES, NULL); 2162 nmr->nr_arg1 = npipes; /* write back */ 2163 /* validate extra bufs */ 2164 nm_bound_var(&nmr->nr_arg3, 0, 0, 2165 128*NM_BDG_MAXSLOTS, NULL); 2166 na->num_rx_desc = nmr->nr_rx_slots; 2167 vpna->mfs = 1514; 2168 vpna->last_smac = ~0llu; 2169 /*if (vpna->mfs > netmap_buf_size) TODO netmap_buf_size is zero?? 2170 vpna->mfs = netmap_buf_size; */ 2171 if (netmap_verbose) 2172 D("max frame size %u", vpna->mfs); 2173 2174 na->na_flags |= NAF_BDG_MAYSLEEP; 2175 /* persistent VALE ports look like hw devices 2176 * with a native netmap adapter 2177 */ 2178 if (ifp) 2179 na->na_flags |= NAF_NATIVE; 2180 na->nm_txsync = netmap_vp_txsync; 2181 na->nm_rxsync = netmap_vp_rxsync; 2182 na->nm_register = netmap_vp_reg; 2183 na->nm_krings_create = netmap_vp_krings_create; 2184 na->nm_krings_delete = netmap_vp_krings_delete; 2185 na->nm_dtor = netmap_vp_dtor; 2186 na->nm_mem = netmap_mem_private_new(na->name, 2187 na->num_tx_rings, na->num_tx_desc, 2188 na->num_rx_rings, na->num_rx_desc, 2189 nmr->nr_arg3, npipes, &error); 2190 if (na->nm_mem == NULL) 2191 goto err; 2192 na->nm_bdg_attach = netmap_vp_bdg_attach; 2193 /* other nmd fields are set in the common routine */ 2194 error = netmap_attach_common(na); 2195 if (error) 2196 goto err; 2197 *ret = vpna; 2198 return 0; 2199 2200 err: 2201 if (na->nm_mem != NULL) 2202 netmap_mem_delete(na->nm_mem); 2203 free(vpna, M_DEVBUF); 2204 return error; 2205 } 2206 2207 /* Bridge wrapper code (bwrap). 2208 * This is used to connect a non-VALE-port netmap_adapter (hwna) to a 2209 * VALE switch. 2210 * The main task is to swap the meaning of tx and rx rings to match the 2211 * expectations of the VALE switch code (see nm_bdg_flush). 2212 * 2213 * The bwrap works by interposing a netmap_bwrap_adapter between the 2214 * rest of the system and the hwna. The netmap_bwrap_adapter looks like 2215 * a netmap_vp_adapter to the rest the system, but, internally, it 2216 * translates all callbacks to what the hwna expects. 2217 * 2218 * Note that we have to intercept callbacks coming from two sides: 2219 * 2220 * - callbacks coming from the netmap module are intercepted by 2221 * passing around the netmap_bwrap_adapter instead of the hwna 2222 * 2223 * - callbacks coming from outside of the netmap module only know 2224 * about the hwna. This, however, only happens in interrupt 2225 * handlers, where only the hwna->nm_notify callback is called. 2226 * What the bwrap does is to overwrite the hwna->nm_notify callback 2227 * with its own netmap_bwrap_intr_notify. 2228 * XXX This assumes that the hwna->nm_notify callback was the 2229 * standard netmap_notify(), as it is the case for nic adapters. 2230 * Any additional action performed by hwna->nm_notify will not be 2231 * performed by netmap_bwrap_intr_notify. 2232 * 2233 * Additionally, the bwrap can optionally attach the host rings pair 2234 * of the wrapped adapter to a different port of the switch. 2235 */ 2236 2237 2238 static void 2239 netmap_bwrap_dtor(struct netmap_adapter *na) 2240 { 2241 struct netmap_bwrap_adapter *bna = (struct netmap_bwrap_adapter*)na; 2242 struct netmap_adapter *hwna = bna->hwna; 2243 struct nm_bridge *b = bna->up.na_bdg, 2244 *bh = bna->host.na_bdg; 2245 2246 if (b) { 2247 netmap_bdg_detach_common(b, bna->up.bdg_port, 2248 (bh ? bna->host.bdg_port : -1)); 2249 } 2250 2251 ND("na %p", na); 2252 na->ifp = NULL; 2253 bna->host.up.ifp = NULL; 2254 hwna->na_private = NULL; 2255 hwna->na_vp = hwna->na_hostvp = NULL; 2256 hwna->na_flags &= ~NAF_BUSY; 2257 netmap_adapter_put(hwna); 2258 2259 } 2260 2261 2262 /* 2263 * Intr callback for NICs connected to a bridge. 2264 * Simply ignore tx interrupts (maybe we could try to recover space ?) 2265 * and pass received packets from nic to the bridge. 2266 * 2267 * XXX TODO check locking: this is called from the interrupt 2268 * handler so we should make sure that the interface is not 2269 * disconnected while passing down an interrupt. 2270 * 2271 * Note, no user process can access this NIC or the host stack. 2272 * The only part of the ring that is significant are the slots, 2273 * and head/cur/tail are set from the kring as needed 2274 * (part as a receive ring, part as a transmit ring). 2275 * 2276 * callback that overwrites the hwna notify callback. 2277 * Packets come from the outside or from the host stack and are put on an 2278 * hwna rx ring. 2279 * The bridge wrapper then sends the packets through the bridge. 2280 */ 2281 static int 2282 netmap_bwrap_intr_notify(struct netmap_kring *kring, int flags) 2283 { 2284 struct netmap_adapter *na = kring->na; 2285 struct netmap_bwrap_adapter *bna = na->na_private; 2286 struct netmap_kring *bkring; 2287 struct netmap_vp_adapter *vpna = &bna->up; 2288 u_int ring_nr = kring->ring_id; 2289 int ret = NM_IRQ_COMPLETED; 2290 int error; 2291 2292 if (netmap_verbose) 2293 D("%s %s 0x%x", na->name, kring->name, flags); 2294 2295 bkring = &vpna->up.tx_rings[ring_nr]; 2296 2297 /* make sure the ring is not disabled */ 2298 if (nm_kr_tryget(kring, 0 /* can't sleep */, NULL)) { 2299 return EIO; 2300 } 2301 2302 if (netmap_verbose) 2303 D("%s head %d cur %d tail %d", na->name, 2304 kring->rhead, kring->rcur, kring->rtail); 2305 2306 /* simulate a user wakeup on the rx ring 2307 * fetch packets that have arrived. 2308 */ 2309 error = kring->nm_sync(kring, 0); 2310 if (error) 2311 goto put_out; 2312 if (kring->nr_hwcur == kring->nr_hwtail) { 2313 if (netmap_verbose) 2314 D("how strange, interrupt with no packets on %s", 2315 na->name); 2316 goto put_out; 2317 } 2318 2319 /* new packets are kring->rcur to kring->nr_hwtail, and the bkring 2320 * had hwcur == bkring->rhead. So advance bkring->rhead to kring->nr_hwtail 2321 * to push all packets out. 2322 */ 2323 bkring->rhead = bkring->rcur = kring->nr_hwtail; 2324 2325 netmap_vp_txsync(bkring, flags); 2326 2327 /* mark all buffers as released on this ring */ 2328 kring->rhead = kring->rcur = kring->rtail = kring->nr_hwtail; 2329 /* another call to actually release the buffers */ 2330 error = kring->nm_sync(kring, 0); 2331 2332 /* The second rxsync may have further advanced hwtail. If this happens, 2333 * return NM_IRQ_RESCHED, otherwise just return NM_IRQ_COMPLETED. */ 2334 if (kring->rcur != kring->nr_hwtail) { 2335 ret = NM_IRQ_RESCHED; 2336 } 2337 put_out: 2338 nm_kr_put(kring); 2339 2340 return error ? error : ret; 2341 } 2342 2343 2344 /* nm_register callback for bwrap */ 2345 static int 2346 netmap_bwrap_reg(struct netmap_adapter *na, int onoff) 2347 { 2348 struct netmap_bwrap_adapter *bna = 2349 (struct netmap_bwrap_adapter *)na; 2350 struct netmap_adapter *hwna = bna->hwna; 2351 struct netmap_vp_adapter *hostna = &bna->host; 2352 int error, i; 2353 enum txrx t; 2354 2355 ND("%s %s", na->name, onoff ? "on" : "off"); 2356 2357 if (onoff) { 2358 /* netmap_do_regif has been called on the bwrap na. 2359 * We need to pass the information about the 2360 * memory allocator down to the hwna before 2361 * putting it in netmap mode 2362 */ 2363 hwna->na_lut = na->na_lut; 2364 2365 if (hostna->na_bdg) { 2366 /* if the host rings have been attached to switch, 2367 * we need to copy the memory allocator information 2368 * in the hostna also 2369 */ 2370 hostna->up.na_lut = na->na_lut; 2371 } 2372 2373 /* cross-link the netmap rings 2374 * The original number of rings comes from hwna, 2375 * rx rings on one side equals tx rings on the other. 2376 */ 2377 for_rx_tx(t) { 2378 enum txrx r = nm_txrx_swap(t); /* swap NR_TX <-> NR_RX */ 2379 for (i = 0; i < nma_get_nrings(hwna, r) + 1; i++) { 2380 NMR(hwna, r)[i].ring = NMR(na, t)[i].ring; 2381 } 2382 } 2383 2384 if (na->na_flags & NAF_HOST_RINGS) { 2385 struct netmap_adapter *hna = &hostna->up; 2386 /* the hostna rings are the host rings of the bwrap. 2387 * The corresponding krings must point back to the 2388 * hostna 2389 */ 2390 hna->tx_rings = &na->tx_rings[na->num_tx_rings]; 2391 hna->tx_rings[0].na = hna; 2392 hna->rx_rings = &na->rx_rings[na->num_rx_rings]; 2393 hna->rx_rings[0].na = hna; 2394 } 2395 } 2396 2397 /* pass down the pending ring state information */ 2398 for_rx_tx(t) { 2399 for (i = 0; i < nma_get_nrings(na, t) + 1; i++) 2400 NMR(hwna, t)[i].nr_pending_mode = 2401 NMR(na, t)[i].nr_pending_mode; 2402 } 2403 2404 /* forward the request to the hwna */ 2405 error = hwna->nm_register(hwna, onoff); 2406 if (error) 2407 return error; 2408 2409 /* copy up the current ring state information */ 2410 for_rx_tx(t) { 2411 for (i = 0; i < nma_get_nrings(na, t) + 1; i++) 2412 NMR(na, t)[i].nr_mode = 2413 NMR(hwna, t)[i].nr_mode; 2414 } 2415 2416 /* impersonate a netmap_vp_adapter */ 2417 netmap_vp_reg(na, onoff); 2418 if (hostna->na_bdg) 2419 netmap_vp_reg(&hostna->up, onoff); 2420 2421 if (onoff) { 2422 u_int i; 2423 /* intercept the hwna nm_nofify callback on the hw rings */ 2424 for (i = 0; i < hwna->num_rx_rings; i++) { 2425 hwna->rx_rings[i].save_notify = hwna->rx_rings[i].nm_notify; 2426 hwna->rx_rings[i].nm_notify = netmap_bwrap_intr_notify; 2427 } 2428 i = hwna->num_rx_rings; /* for safety */ 2429 /* save the host ring notify unconditionally */ 2430 hwna->rx_rings[i].save_notify = hwna->rx_rings[i].nm_notify; 2431 if (hostna->na_bdg) { 2432 /* also intercept the host ring notify */ 2433 hwna->rx_rings[i].nm_notify = netmap_bwrap_intr_notify; 2434 } 2435 if (na->active_fds == 0) 2436 na->na_flags |= NAF_NETMAP_ON; 2437 } else { 2438 u_int i; 2439 2440 if (na->active_fds == 0) 2441 na->na_flags &= ~NAF_NETMAP_ON; 2442 2443 /* reset all notify callbacks (including host ring) */ 2444 for (i = 0; i <= hwna->num_rx_rings; i++) { 2445 hwna->rx_rings[i].nm_notify = hwna->rx_rings[i].save_notify; 2446 hwna->rx_rings[i].save_notify = NULL; 2447 } 2448 hwna->na_lut.lut = NULL; 2449 hwna->na_lut.objtotal = 0; 2450 hwna->na_lut.objsize = 0; 2451 } 2452 2453 return 0; 2454 } 2455 2456 /* nm_config callback for bwrap */ 2457 static int 2458 netmap_bwrap_config(struct netmap_adapter *na, u_int *txr, u_int *txd, 2459 u_int *rxr, u_int *rxd) 2460 { 2461 struct netmap_bwrap_adapter *bna = 2462 (struct netmap_bwrap_adapter *)na; 2463 struct netmap_adapter *hwna = bna->hwna; 2464 2465 /* forward the request */ 2466 netmap_update_config(hwna); 2467 /* swap the results */ 2468 *txr = hwna->num_rx_rings; 2469 *txd = hwna->num_rx_desc; 2470 *rxr = hwna->num_tx_rings; 2471 *rxd = hwna->num_rx_desc; 2472 2473 return 0; 2474 } 2475 2476 2477 /* nm_krings_create callback for bwrap */ 2478 static int 2479 netmap_bwrap_krings_create(struct netmap_adapter *na) 2480 { 2481 struct netmap_bwrap_adapter *bna = 2482 (struct netmap_bwrap_adapter *)na; 2483 struct netmap_adapter *hwna = bna->hwna; 2484 int i, error = 0; 2485 enum txrx t; 2486 2487 ND("%s", na->name); 2488 2489 /* impersonate a netmap_vp_adapter */ 2490 error = netmap_vp_krings_create(na); 2491 if (error) 2492 return error; 2493 2494 /* also create the hwna krings */ 2495 error = hwna->nm_krings_create(hwna); 2496 if (error) { 2497 goto err_del_vp_rings; 2498 } 2499 2500 /* get each ring slot number from the corresponding hwna ring */ 2501 for_rx_tx(t) { 2502 enum txrx r = nm_txrx_swap(t); /* swap NR_TX <-> NR_RX */ 2503 for (i = 0; i < nma_get_nrings(hwna, r) + 1; i++) { 2504 NMR(na, t)[i].nkr_num_slots = NMR(hwna, r)[i].nkr_num_slots; 2505 } 2506 } 2507 2508 return 0; 2509 2510 err_del_vp_rings: 2511 netmap_vp_krings_delete(na); 2512 2513 return error; 2514 } 2515 2516 2517 static void 2518 netmap_bwrap_krings_delete(struct netmap_adapter *na) 2519 { 2520 struct netmap_bwrap_adapter *bna = 2521 (struct netmap_bwrap_adapter *)na; 2522 struct netmap_adapter *hwna = bna->hwna; 2523 2524 ND("%s", na->name); 2525 2526 hwna->nm_krings_delete(hwna); 2527 netmap_vp_krings_delete(na); 2528 } 2529 2530 2531 /* notify method for the bridge-->hwna direction */ 2532 static int 2533 netmap_bwrap_notify(struct netmap_kring *kring, int flags) 2534 { 2535 struct netmap_adapter *na = kring->na; 2536 struct netmap_bwrap_adapter *bna = na->na_private; 2537 struct netmap_adapter *hwna = bna->hwna; 2538 u_int ring_n = kring->ring_id; 2539 u_int lim = kring->nkr_num_slots - 1; 2540 struct netmap_kring *hw_kring; 2541 int error; 2542 2543 ND("%s: na %s hwna %s", 2544 (kring ? kring->name : "NULL!"), 2545 (na ? na->name : "NULL!"), 2546 (hwna ? hwna->name : "NULL!")); 2547 hw_kring = &hwna->tx_rings[ring_n]; 2548 2549 if (nm_kr_tryget(hw_kring, 0, NULL)) { 2550 return ENXIO; 2551 } 2552 2553 /* first step: simulate a user wakeup on the rx ring */ 2554 netmap_vp_rxsync(kring, flags); 2555 ND("%s[%d] PRE rx(c%3d t%3d l%3d) ring(h%3d c%3d t%3d) tx(c%3d ht%3d t%3d)", 2556 na->name, ring_n, 2557 kring->nr_hwcur, kring->nr_hwtail, kring->nkr_hwlease, 2558 ring->head, ring->cur, ring->tail, 2559 hw_kring->nr_hwcur, hw_kring->nr_hwtail, hw_ring->rtail); 2560 /* second step: the new packets are sent on the tx ring 2561 * (which is actually the same ring) 2562 */ 2563 hw_kring->rhead = hw_kring->rcur = kring->nr_hwtail; 2564 error = hw_kring->nm_sync(hw_kring, flags); 2565 if (error) 2566 goto put_out; 2567 2568 /* third step: now we are back the rx ring */ 2569 /* claim ownership on all hw owned bufs */ 2570 kring->rhead = kring->rcur = nm_next(hw_kring->nr_hwtail, lim); /* skip past reserved slot */ 2571 2572 /* fourth step: the user goes to sleep again, causing another rxsync */ 2573 netmap_vp_rxsync(kring, flags); 2574 ND("%s[%d] PST rx(c%3d t%3d l%3d) ring(h%3d c%3d t%3d) tx(c%3d ht%3d t%3d)", 2575 na->name, ring_n, 2576 kring->nr_hwcur, kring->nr_hwtail, kring->nkr_hwlease, 2577 ring->head, ring->cur, ring->tail, 2578 hw_kring->nr_hwcur, hw_kring->nr_hwtail, hw_kring->rtail); 2579 put_out: 2580 nm_kr_put(hw_kring); 2581 2582 return error ? error : NM_IRQ_COMPLETED; 2583 } 2584 2585 2586 /* nm_bdg_ctl callback for the bwrap. 2587 * Called on bridge-attach and detach, as an effect of vale-ctl -[ahd]. 2588 * On attach, it needs to provide a fake netmap_priv_d structure and 2589 * perform a netmap_do_regif() on the bwrap. This will put both the 2590 * bwrap and the hwna in netmap mode, with the netmap rings shared 2591 * and cross linked. Moroever, it will start intercepting interrupts 2592 * directed to hwna. 2593 */ 2594 static int 2595 netmap_bwrap_bdg_ctl(struct netmap_adapter *na, struct nmreq *nmr, int attach) 2596 { 2597 struct netmap_priv_d *npriv; 2598 struct netmap_bwrap_adapter *bna = (struct netmap_bwrap_adapter*)na; 2599 int error = 0; 2600 2601 if (attach) { 2602 if (NETMAP_OWNED_BY_ANY(na)) { 2603 return EBUSY; 2604 } 2605 if (bna->na_kpriv) { 2606 /* nothing to do */ 2607 return 0; 2608 } 2609 npriv = netmap_priv_new(); 2610 if (npriv == NULL) 2611 return ENOMEM; 2612 npriv->np_ifp = na->ifp; /* let the priv destructor release the ref */ 2613 error = netmap_do_regif(npriv, na, 0, NR_REG_NIC_SW); 2614 if (error) { 2615 netmap_priv_delete(npriv); 2616 return error; 2617 } 2618 bna->na_kpriv = npriv; 2619 na->na_flags |= NAF_BUSY; 2620 } else { 2621 if (na->active_fds == 0) /* not registered */ 2622 return EINVAL; 2623 netmap_priv_delete(bna->na_kpriv); 2624 bna->na_kpriv = NULL; 2625 na->na_flags &= ~NAF_BUSY; 2626 } 2627 return error; 2628 2629 } 2630 2631 /* attach a bridge wrapper to the 'real' device */ 2632 int 2633 netmap_bwrap_attach(const char *nr_name, struct netmap_adapter *hwna) 2634 { 2635 struct netmap_bwrap_adapter *bna; 2636 struct netmap_adapter *na = NULL; 2637 struct netmap_adapter *hostna = NULL; 2638 int error = 0; 2639 enum txrx t; 2640 2641 /* make sure the NIC is not already in use */ 2642 if (NETMAP_OWNED_BY_ANY(hwna)) { 2643 D("NIC %s busy, cannot attach to bridge", hwna->name); 2644 return EBUSY; 2645 } 2646 2647 bna = malloc(sizeof(*bna), M_DEVBUF, M_NOWAIT | M_ZERO); 2648 if (bna == NULL) { 2649 return ENOMEM; 2650 } 2651 2652 na = &bna->up.up; 2653 /* make bwrap ifp point to the real ifp */ 2654 na->ifp = hwna->ifp; 2655 na->na_private = bna; 2656 strncpy(na->name, nr_name, sizeof(na->name)); 2657 /* fill the ring data for the bwrap adapter with rx/tx meanings 2658 * swapped. The real cross-linking will be done during register, 2659 * when all the krings will have been created. 2660 */ 2661 for_rx_tx(t) { 2662 enum txrx r = nm_txrx_swap(t); /* swap NR_TX <-> NR_RX */ 2663 nma_set_nrings(na, t, nma_get_nrings(hwna, r)); 2664 nma_set_ndesc(na, t, nma_get_ndesc(hwna, r)); 2665 } 2666 na->nm_dtor = netmap_bwrap_dtor; 2667 na->nm_register = netmap_bwrap_reg; 2668 // na->nm_txsync = netmap_bwrap_txsync; 2669 // na->nm_rxsync = netmap_bwrap_rxsync; 2670 na->nm_config = netmap_bwrap_config; 2671 na->nm_krings_create = netmap_bwrap_krings_create; 2672 na->nm_krings_delete = netmap_bwrap_krings_delete; 2673 na->nm_notify = netmap_bwrap_notify; 2674 na->nm_bdg_ctl = netmap_bwrap_bdg_ctl; 2675 na->pdev = hwna->pdev; 2676 na->nm_mem = hwna->nm_mem; 2677 na->virt_hdr_len = hwna->virt_hdr_len; 2678 bna->up.retry = 1; /* XXX maybe this should depend on the hwna */ 2679 2680 bna->hwna = hwna; 2681 netmap_adapter_get(hwna); 2682 hwna->na_private = bna; /* weak reference */ 2683 hwna->na_vp = &bna->up; 2684 2685 if (hwna->na_flags & NAF_HOST_RINGS) { 2686 if (hwna->na_flags & NAF_SW_ONLY) 2687 na->na_flags |= NAF_SW_ONLY; 2688 na->na_flags |= NAF_HOST_RINGS; 2689 hostna = &bna->host.up; 2690 snprintf(hostna->name, sizeof(hostna->name), "%s^", nr_name); 2691 hostna->ifp = hwna->ifp; 2692 for_rx_tx(t) { 2693 enum txrx r = nm_txrx_swap(t); 2694 nma_set_nrings(hostna, t, 1); 2695 nma_set_ndesc(hostna, t, nma_get_ndesc(hwna, r)); 2696 } 2697 // hostna->nm_txsync = netmap_bwrap_host_txsync; 2698 // hostna->nm_rxsync = netmap_bwrap_host_rxsync; 2699 hostna->nm_notify = netmap_bwrap_notify; 2700 hostna->nm_mem = na->nm_mem; 2701 hostna->na_private = bna; 2702 hostna->na_vp = &bna->up; 2703 na->na_hostvp = hwna->na_hostvp = 2704 hostna->na_hostvp = &bna->host; 2705 hostna->na_flags = NAF_BUSY; /* prevent NIOCREGIF */ 2706 } 2707 2708 ND("%s<->%s txr %d txd %d rxr %d rxd %d", 2709 na->name, ifp->if_xname, 2710 na->num_tx_rings, na->num_tx_desc, 2711 na->num_rx_rings, na->num_rx_desc); 2712 2713 error = netmap_attach_common(na); 2714 if (error) { 2715 goto err_free; 2716 } 2717 hwna->na_flags |= NAF_BUSY; 2718 return 0; 2719 2720 err_free: 2721 hwna->na_vp = hwna->na_hostvp = NULL; 2722 netmap_adapter_put(hwna); 2723 free(bna, M_DEVBUF); 2724 return error; 2725 2726 } 2727 2728 struct nm_bridge * 2729 netmap_init_bridges2(u_int n) 2730 { 2731 int i; 2732 struct nm_bridge *b; 2733 2734 b = malloc(sizeof(struct nm_bridge) * n, M_DEVBUF, 2735 M_NOWAIT | M_ZERO); 2736 if (b == NULL) 2737 return NULL; 2738 for (i = 0; i < n; i++) 2739 BDG_RWINIT(&b[i]); 2740 return b; 2741 } 2742 2743 void 2744 netmap_uninit_bridges2(struct nm_bridge *b, u_int n) 2745 { 2746 int i; 2747 2748 if (b == NULL) 2749 return; 2750 2751 for (i = 0; i < n; i++) 2752 BDG_RWDESTROY(&b[i]); 2753 free(b, M_DEVBUF); 2754 } 2755 2756 int 2757 netmap_init_bridges(void) 2758 { 2759 #ifdef CONFIG_NET_NS 2760 return netmap_bns_register(); 2761 #else 2762 nm_bridges = netmap_init_bridges2(NM_BRIDGES); 2763 if (nm_bridges == NULL) 2764 return ENOMEM; 2765 return 0; 2766 #endif 2767 } 2768 2769 void 2770 netmap_uninit_bridges(void) 2771 { 2772 #ifdef CONFIG_NET_NS 2773 netmap_bns_unregister(); 2774 #else 2775 netmap_uninit_bridges2(nm_bridges, NM_BRIDGES); 2776 #endif 2777 } 2778 #endif /* WITH_VALE */ 2779