if_llatbl.c (286577) | if_llatbl.c (286616) |
---|---|
1/* 2 * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved. 3 * Copyright (c) 2004-2008 Qing Li. All rights reserved. 4 * Copyright (c) 2008 Kip Macy. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 11 unchanged lines hidden (view full) --- 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved. 3 * Copyright (c) 2004-2008 Qing Li. All rights reserved. 4 * Copyright (c) 2008 Kip Macy. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 11 unchanged lines hidden (view full) --- 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/net/if_llatbl.c 286577 2015-08-10 12:03:59Z melifaro $"); | 28__FBSDID("$FreeBSD: head/sys/net/if_llatbl.c 286616 2015-08-11 05:51:00Z melifaro $"); |
29 30#include "opt_ddb.h" 31#include "opt_inet.h" 32#include "opt_inet6.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/malloc.h> --- 28 unchanged lines hidden (view full) --- 65static VNET_DEFINE(SLIST_HEAD(, lltable), lltables); 66#define V_lltables VNET(lltables) 67 68static void vnet_lltable_init(void); 69 70struct rwlock lltable_rwlock; 71RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock"); 72 | 29 30#include "opt_ddb.h" 31#include "opt_inet.h" 32#include "opt_inet6.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/malloc.h> --- 28 unchanged lines hidden (view full) --- 65static VNET_DEFINE(SLIST_HEAD(, lltable), lltables); 66#define V_lltables VNET(lltables) 67 68static void vnet_lltable_init(void); 69 70struct rwlock lltable_rwlock; 71RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock"); 72 |
73static void lltable_unlink(struct lltable *llt); |
|
73static void llentries_unlink(struct lltable *llt, struct llentries *head); 74 75static void htable_unlink_entry(struct llentry *lle); 76static void htable_link_entry(struct lltable *llt, struct llentry *lle); 77static int htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, 78 void *farg); 79 80/* --- 52 unchanged lines hidden (view full) --- 133static int 134htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg) 135{ 136 struct llentry *lle, *next; 137 int i, error; 138 139 error = 0; 140 | 74static void llentries_unlink(struct lltable *llt, struct llentries *head); 75 76static void htable_unlink_entry(struct llentry *lle); 77static void htable_link_entry(struct lltable *llt, struct llentry *lle); 78static int htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, 79 void *farg); 80 81/* --- 52 unchanged lines hidden (view full) --- 134static int 135htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg) 136{ 137 struct llentry *lle, *next; 138 int i, error; 139 140 error = 0; 141 |
141 for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) { | 142 for (i = 0; i < llt->llt_hsize; i++) { |
142 LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { 143 error = f(llt, lle, farg); 144 if (error != 0) 145 break; 146 } 147 } 148 149 return (error); --- 5 unchanged lines hidden (view full) --- 155 struct llentries *lleh; 156 uint32_t hashidx; 157 158 if ((lle->la_flags & LLE_LINKED) != 0) 159 return; 160 161 IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp); 162 | 143 LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { 144 error = f(llt, lle, farg); 145 if (error != 0) 146 break; 147 } 148 } 149 150 return (error); --- 5 unchanged lines hidden (view full) --- 156 struct llentries *lleh; 157 uint32_t hashidx; 158 159 if ((lle->la_flags & LLE_LINKED) != 0) 160 return; 161 162 IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp); 163 |
163 hashidx = llt->llt_hash(lle, LLTBL_HASHTBL_SIZE); | 164 hashidx = llt->llt_hash(lle, llt->llt_hsize); |
164 lleh = &llt->lle_head[hashidx]; 165 166 lle->lle_tbl = llt; 167 lle->lle_head = lleh; 168 lle->la_flags |= LLE_LINKED; 169 LIST_INSERT_HEAD(lleh, lle, lle_next); 170} 171 --- 54 unchanged lines hidden (view full) --- 226 llentries_unlink(llt, &pmd.dchain); 227 IF_AFDATA_WUNLOCK(llt->llt_ifp); 228 229 LIST_FOREACH_SAFE(lle, &pmd.dchain, lle_chain, next) 230 llt->llt_free_entry(llt, lle); 231} 232 233static void | 165 lleh = &llt->lle_head[hashidx]; 166 167 lle->lle_tbl = llt; 168 lle->lle_head = lleh; 169 lle->la_flags |= LLE_LINKED; 170 LIST_INSERT_HEAD(lleh, lle, lle_next); 171} 172 --- 54 unchanged lines hidden (view full) --- 227 llentries_unlink(llt, &pmd.dchain); 228 IF_AFDATA_WUNLOCK(llt->llt_ifp); 229 230 LIST_FOREACH_SAFE(lle, &pmd.dchain, lle_chain, next) 231 llt->llt_free_entry(llt, lle); 232} 233 234static void |
235htable_free_tbl(struct lltable *llt) 236{ 237 238 free(llt->lle_head, M_LLTABLE); 239 free(llt, M_LLTABLE); 240} 241 242static void |
|
234llentries_unlink(struct lltable *llt, struct llentries *head) 235{ 236 struct llentry *lle, *next; 237 238 LIST_FOREACH_SAFE(lle, head, lle_chain, next) 239 llt->llt_unlink_entry(lle); 240} 241 --- 108 unchanged lines hidden (view full) --- 350void 351lltable_free(struct lltable *llt) 352{ 353 struct llentry *lle, *next; 354 struct llentries dchain; 355 356 KASSERT(llt != NULL, ("%s: llt is NULL", __func__)); 357 | 243llentries_unlink(struct lltable *llt, struct llentries *head) 244{ 245 struct llentry *lle, *next; 246 247 LIST_FOREACH_SAFE(lle, head, lle_chain, next) 248 llt->llt_unlink_entry(lle); 249} 250 --- 108 unchanged lines hidden (view full) --- 359void 360lltable_free(struct lltable *llt) 361{ 362 struct llentry *lle, *next; 363 struct llentries dchain; 364 365 KASSERT(llt != NULL, ("%s: llt is NULL", __func__)); 366 |
358 LLTABLE_WLOCK(); 359 SLIST_REMOVE(&V_lltables, llt, lltable, llt_link); 360 LLTABLE_WUNLOCK(); | 367 lltable_unlink(llt); |
361 362 LIST_INIT(&dchain); 363 IF_AFDATA_WLOCK(llt->llt_ifp); 364 /* Push all lles to @dchain */ 365 lltable_foreach_lle(llt, lltable_free_cb, &dchain); 366 llentries_unlink(llt, &dchain); 367 IF_AFDATA_WUNLOCK(llt->llt_ifp); 368 369 LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) { 370 if (callout_stop(&lle->la_timer)) 371 LLE_REMREF(lle); 372 llentry_free(lle); 373 } 374 | 368 369 LIST_INIT(&dchain); 370 IF_AFDATA_WLOCK(llt->llt_ifp); 371 /* Push all lles to @dchain */ 372 lltable_foreach_lle(llt, lltable_free_cb, &dchain); 373 llentries_unlink(llt, &dchain); 374 IF_AFDATA_WUNLOCK(llt->llt_ifp); 375 376 LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) { 377 if (callout_stop(&lle->la_timer)) 378 LLE_REMREF(lle); 379 llentry_free(lle); 380 } 381 |
375 free(llt, M_LLTABLE); | 382 llt->llt_free_tbl(llt); |
376} 377 378#if 0 379void 380lltable_drain(int af) 381{ 382 struct lltable *llt; 383 struct llentry *lle; 384 register int i; 385 386 LLTABLE_RLOCK(); 387 SLIST_FOREACH(llt, &V_lltables, llt_link) { 388 if (llt->llt_af != af) 389 continue; 390 | 383} 384 385#if 0 386void 387lltable_drain(int af) 388{ 389 struct lltable *llt; 390 struct llentry *lle; 391 register int i; 392 393 LLTABLE_RLOCK(); 394 SLIST_FOREACH(llt, &V_lltables, llt_link) { 395 if (llt->llt_af != af) 396 continue; 397 |
391 for (i=0; i < LLTBL_HASHTBL_SIZE; i++) { | 398 for (i=0; i < llt->llt_hsize; i++) { |
392 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) { 393 LLE_WLOCK(lle); 394 if (lle->la_hold) { 395 m_freem(lle->la_hold); 396 lle->la_hold = NULL; 397 } 398 LLE_WUNLOCK(lle); 399 } --- 14 unchanged lines hidden (view full) --- 414 if (llt->llt_af != af) 415 continue; 416 417 llt->llt_prefix_free(llt, prefix, mask, flags); 418 } 419 LLTABLE_RUNLOCK(); 420} 421 | 399 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) { 400 LLE_WLOCK(lle); 401 if (lle->la_hold) { 402 m_freem(lle->la_hold); 403 lle->la_hold = NULL; 404 } 405 LLE_WUNLOCK(lle); 406 } --- 14 unchanged lines hidden (view full) --- 421 if (llt->llt_af != af) 422 continue; 423 424 llt->llt_prefix_free(llt, prefix, mask, flags); 425 } 426 LLTABLE_RUNLOCK(); 427} 428 |
422/* 423 * Create a new lltable. 424 */ | |
425struct lltable * | 429struct lltable * |
426lltable_init(struct ifnet *ifp, int af) | 430lltable_allocate_htbl(uint32_t hsize) |
427{ 428 struct lltable *llt; | 431{ 432 struct lltable *llt; |
429 register int i; | 433 int i; |
430 | 434 |
431 llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK); | 435 llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO); 436 llt->llt_hsize = hsize; 437 llt->lle_head = malloc(sizeof(struct llentries) * hsize, 438 M_LLTABLE, M_WAITOK | M_ZERO); |
432 | 439 |
433 llt->llt_af = af; 434 llt->llt_ifp = ifp; 435 for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) | 440 for (i = 0; i < llt->llt_hsize; i++) |
436 LIST_INIT(&llt->lle_head[i]); 437 438 /* Set some default callbacks */ 439 llt->llt_link_entry = htable_link_entry; 440 llt->llt_unlink_entry = htable_unlink_entry; 441 llt->llt_prefix_free = htable_prefix_free; 442 llt->llt_foreach_entry = htable_foreach_lle; | 441 LIST_INIT(&llt->lle_head[i]); 442 443 /* Set some default callbacks */ 444 llt->llt_link_entry = htable_link_entry; 445 llt->llt_unlink_entry = htable_unlink_entry; 446 llt->llt_prefix_free = htable_prefix_free; 447 llt->llt_foreach_entry = htable_foreach_lle; |
448 llt->llt_free_tbl = htable_free_tbl; |
|
443 | 449 |
450 return (llt); 451} 452 453/* 454 * Links lltable to global llt list. 455 */ 456void 457lltable_link(struct lltable *llt) 458{ 459 |
|
444 LLTABLE_WLOCK(); 445 SLIST_INSERT_HEAD(&V_lltables, llt, llt_link); 446 LLTABLE_WUNLOCK(); | 460 LLTABLE_WLOCK(); 461 SLIST_INSERT_HEAD(&V_lltables, llt, llt_link); 462 LLTABLE_WUNLOCK(); |
463} |
|
447 | 464 |
448 return (llt); | 465static void 466lltable_unlink(struct lltable *llt) 467{ 468 469 LLTABLE_WLOCK(); 470 SLIST_REMOVE(&V_lltables, llt, lltable, llt_link); 471 LLTABLE_WUNLOCK(); 472 |
449} 450 451/* 452 * External methods used by lltable consumers 453 */ 454 455int 456lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg) --- 223 unchanged lines hidden (view full) --- 680llatbl_llt_show(struct lltable *llt) 681{ 682 int i; 683 struct llentry *lle; 684 685 db_printf("llt=%p llt_af=%d llt_ifp=%p\n", 686 llt, llt->llt_af, llt->llt_ifp); 687 | 473} 474 475/* 476 * External methods used by lltable consumers 477 */ 478 479int 480lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg) --- 223 unchanged lines hidden (view full) --- 704llatbl_llt_show(struct lltable *llt) 705{ 706 int i; 707 struct llentry *lle; 708 709 db_printf("llt=%p llt_af=%d llt_ifp=%p\n", 710 llt, llt->llt_af, llt->llt_ifp); 711 |
688 for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) { | 712 for (i = 0; i < llt->llt_hsize; i++) { |
689 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) { 690 691 llatbl_lle_show((struct llentry_sa *)lle); 692 if (db_pager_quit) 693 return; 694 } 695 } 696} --- 38 unchanged lines hidden --- | 713 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) { 714 715 llatbl_lle_show((struct llentry_sa *)lle); 716 if (db_pager_quit) 717 return; 718 } 719 } 720} --- 38 unchanged lines hidden --- |