ieee8023ad_lacp.c (169741) | ieee8023ad_lacp.c (170599) |
---|---|
1/* $NetBSD: ieee8023ad_lacp.c,v 1.3 2005/12/11 12:24:54 christos Exp $ */ 2 3/*- 4 * Copyright (c)2005 YAMAMOTO Takashi, 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 1/* $NetBSD: ieee8023ad_lacp.c,v 1.3 2005/12/11 12:24:54 christos Exp $ */ 2 3/*- 4 * Copyright (c)2005 YAMAMOTO Takashi, 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/net/ieee8023ad_lacp.c 169741 2007-05-19 09:37:04Z thompsa $"); | 30__FBSDID("$FreeBSD: head/sys/net/ieee8023ad_lacp.c 170599 2007-06-12 07:29:11Z thompsa $"); |
31 32#include <sys/param.h> 33#include <sys/callout.h> 34#include <sys/mbuf.h> 35#include <sys/systm.h> 36#include <sys/malloc.h> 37#include <sys/kernel.h> /* hz */ 38#include <sys/socket.h> /* for net/if.h */ --- 172 unchanged lines hidden (view full) --- 211 [LACP_TIMER_CURRENT_WHILE] = lacp_sm_rx_timer, 212 [LACP_TIMER_PERIODIC] = lacp_sm_ptx_timer, 213 [LACP_TIMER_WAIT_WHILE] = lacp_sm_mux_timer, 214}; 215 216void 217lacp_input(struct lagg_port *lgp, struct mbuf *m) 218{ | 31 32#include <sys/param.h> 33#include <sys/callout.h> 34#include <sys/mbuf.h> 35#include <sys/systm.h> 36#include <sys/malloc.h> 37#include <sys/kernel.h> /* hz */ 38#include <sys/socket.h> /* for net/if.h */ --- 172 unchanged lines hidden (view full) --- 211 [LACP_TIMER_CURRENT_WHILE] = lacp_sm_rx_timer, 212 [LACP_TIMER_PERIODIC] = lacp_sm_ptx_timer, 213 [LACP_TIMER_WAIT_WHILE] = lacp_sm_mux_timer, 214}; 215 216void 217lacp_input(struct lagg_port *lgp, struct mbuf *m) 218{ |
219 struct lagg_softc *lgs = lgp->lp_lagg; 220 struct lacp_softc *lsc = LACP_SOFTC(lgs); | 219 struct lagg_softc *sc = lgp->lp_softc; 220 struct lacp_softc *lsc = LACP_SOFTC(sc); |
221 uint8_t subtype; 222 223 if (m->m_pkthdr.len < sizeof(struct ether_header) + sizeof(subtype)) { 224 m_freem(m); 225 return; 226 } 227 228 m_copydata(m, sizeof(struct ether_header), sizeof(subtype), &subtype); --- 13 unchanged lines hidden (view full) --- 242 break; 243 } 244} 245 246static void 247lacp_dequeue(void *arg, int pending) 248{ 249 struct lacp_softc *lsc = (struct lacp_softc *)arg; | 221 uint8_t subtype; 222 223 if (m->m_pkthdr.len < sizeof(struct ether_header) + sizeof(subtype)) { 224 m_freem(m); 225 return; 226 } 227 228 m_copydata(m, sizeof(struct ether_header), sizeof(subtype), &subtype); --- 13 unchanged lines hidden (view full) --- 242 break; 243 } 244} 245 246static void 247lacp_dequeue(void *arg, int pending) 248{ 249 struct lacp_softc *lsc = (struct lacp_softc *)arg; |
250 struct lagg_softc *sc = lsc->lsc_lagg; | 250 struct lagg_softc *sc = lsc->lsc_softc; |
251 struct lagg_port *lgp; 252 struct mbuf *m; 253 254 LAGG_WLOCK(sc); 255 for (;;) { 256 IF_DEQUEUE(&lsc->lsc_queue, m); 257 if (m == NULL) 258 break; --- 8 unchanged lines hidden (view full) --- 267 */ 268static int 269lacp_pdu_input(struct lagg_port *lgp, struct mbuf *m) 270{ 271 struct lacp_port *lp = LACP_PORT(lgp); 272 struct lacpdu *du; 273 int error = 0; 274 | 251 struct lagg_port *lgp; 252 struct mbuf *m; 253 254 LAGG_WLOCK(sc); 255 for (;;) { 256 IF_DEQUEUE(&lsc->lsc_queue, m); 257 if (m == NULL) 258 break; --- 8 unchanged lines hidden (view full) --- 267 */ 268static int 269lacp_pdu_input(struct lagg_port *lgp, struct mbuf *m) 270{ 271 struct lacp_port *lp = LACP_PORT(lgp); 272 struct lacpdu *du; 273 int error = 0; 274 |
275 LAGG_WLOCK_ASSERT(lgp->lp_lagg); | 275 LAGG_WLOCK_ASSERT(lgp->lp_softc); |
276 | 276 |
277 if (__predict_false(lp->lp_flags & LACP_PORT_DETACHING)) { 278 goto bad; 279 } 280 | |
281 if (m->m_pkthdr.len != sizeof(*du)) { 282 goto bad; 283 } 284 285 if ((m->m_flags & M_MCAST) == 0) { 286 goto bad; 287 } 288 --- 6 unchanged lines hidden (view full) --- 295 296 du = mtod(m, struct lacpdu *); 297 298 if (memcmp(&du->ldu_eh.ether_dhost, 299 ðermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) { 300 goto bad; 301 } 302 | 277 if (m->m_pkthdr.len != sizeof(*du)) { 278 goto bad; 279 } 280 281 if ((m->m_flags & M_MCAST) == 0) { 282 goto bad; 283 } 284 --- 6 unchanged lines hidden (view full) --- 291 292 du = mtod(m, struct lacpdu *); 293 294 if (memcmp(&du->ldu_eh.ether_dhost, 295 ðermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) { 296 goto bad; 297 } 298 |
303 /* XXX 304 KASSERT(du->ldu_sph.sph_subtype == SLOWPROTOCOLS_SUBTYPE_LACP, 305 ("a very bad kassert!")); 306 */ 307 | |
308 /* 309 * ignore the version for compatibility with 310 * the future protocol revisions. 311 */ | 299 /* 300 * ignore the version for compatibility with 301 * the future protocol revisions. 302 */ |
312 | |
313#if 0 314 if (du->ldu_sph.sph_version != 1) { 315 goto bad; 316 } 317#endif 318 319 /* 320 * ignore tlv types for compatibility with 321 * the future protocol revisions. 322 */ | 303#if 0 304 if (du->ldu_sph.sph_version != 1) { 305 goto bad; 306 } 307#endif 308 309 /* 310 * ignore tlv types for compatibility with 311 * the future protocol revisions. 312 */ |
323 | |
324 if (tlv_check(du, sizeof(*du), &du->ldu_tlv_actor, 325 lacp_info_tlv_template, FALSE)) { 326 goto bad; 327 } 328 329#if defined(LACP_DEBUG) 330 LACP_DPRINTF((lp, "lacpdu receive\n")); 331 lacp_dump_lacpdu(du); --- 8 unchanged lines hidden (view full) --- 340 m_freem(m); 341 return (EINVAL); 342} 343 344static void 345lacp_fill_actorinfo(struct lacp_port *lp, struct lacp_peerinfo *info) 346{ 347 struct lagg_port *lgp = lp->lp_lagg; | 313 if (tlv_check(du, sizeof(*du), &du->ldu_tlv_actor, 314 lacp_info_tlv_template, FALSE)) { 315 goto bad; 316 } 317 318#if defined(LACP_DEBUG) 319 LACP_DPRINTF((lp, "lacpdu receive\n")); 320 lacp_dump_lacpdu(du); --- 8 unchanged lines hidden (view full) --- 329 m_freem(m); 330 return (EINVAL); 331} 332 333static void 334lacp_fill_actorinfo(struct lacp_port *lp, struct lacp_peerinfo *info) 335{ 336 struct lagg_port *lgp = lp->lp_lagg; |
348 struct lagg_softc *lgs = lgp->lp_lagg; | 337 struct lagg_softc *sc = lgp->lp_softc; |
349 350 info->lip_systemid.lsi_prio = htons(LACP_SYSTEM_PRIO); 351 memcpy(&info->lip_systemid.lsi_mac, | 338 339 info->lip_systemid.lsi_prio = htons(LACP_SYSTEM_PRIO); 340 memcpy(&info->lip_systemid.lsi_mac, |
352 IF_LLADDR(lgs->sc_ifp), ETHER_ADDR_LEN); | 341 IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); |
353 info->lip_portid.lpi_prio = htons(LACP_PORT_PRIO); 354 info->lip_portid.lpi_portno = htons(lp->lp_ifp->if_index); 355 info->lip_state = lp->lp_state; 356} 357 358static void 359lacp_fill_markerinfo(struct lacp_port *lp, struct lacp_markerinfo *info) 360{ --- 8 unchanged lines hidden (view full) --- 369static int 370lacp_xmit_lacpdu(struct lacp_port *lp) 371{ 372 struct lagg_port *lgp = lp->lp_lagg; 373 struct mbuf *m; 374 struct lacpdu *du; 375 int error; 376 | 342 info->lip_portid.lpi_prio = htons(LACP_PORT_PRIO); 343 info->lip_portid.lpi_portno = htons(lp->lp_ifp->if_index); 344 info->lip_state = lp->lp_state; 345} 346 347static void 348lacp_fill_markerinfo(struct lacp_port *lp, struct lacp_markerinfo *info) 349{ --- 8 unchanged lines hidden (view full) --- 358static int 359lacp_xmit_lacpdu(struct lacp_port *lp) 360{ 361 struct lagg_port *lgp = lp->lp_lagg; 362 struct mbuf *m; 363 struct lacpdu *du; 364 int error; 365 |
377 LAGG_WLOCK_ASSERT(lgp->lp_lagg); | 366 LAGG_WLOCK_ASSERT(lgp->lp_softc); |
378 379 m = m_gethdr(M_DONTWAIT, MT_DATA); 380 if (m == NULL) { 381 return (ENOMEM); 382 } 383 m->m_len = m->m_pkthdr.len = sizeof(*du); 384 385 du = mtod(m, struct lacpdu *); --- 37 unchanged lines hidden (view full) --- 423static int 424lacp_xmit_marker(struct lacp_port *lp) 425{ 426 struct lagg_port *lgp = lp->lp_lagg; 427 struct mbuf *m; 428 struct markerdu *mdu; 429 int error; 430 | 367 368 m = m_gethdr(M_DONTWAIT, MT_DATA); 369 if (m == NULL) { 370 return (ENOMEM); 371 } 372 m->m_len = m->m_pkthdr.len = sizeof(*du); 373 374 du = mtod(m, struct lacpdu *); --- 37 unchanged lines hidden (view full) --- 412static int 413lacp_xmit_marker(struct lacp_port *lp) 414{ 415 struct lagg_port *lgp = lp->lp_lagg; 416 struct mbuf *m; 417 struct markerdu *mdu; 418 int error; 419 |
431 LAGG_WLOCK_ASSERT(lgp->lp_lagg); | 420 LAGG_WLOCK_ASSERT(lgp->lp_softc); |
432 433 m = m_gethdr(M_DONTWAIT, MT_DATA); 434 if (m == NULL) { 435 return (ENOMEM); 436 } 437 m->m_len = m->m_pkthdr.len = sizeof(*mdu); 438 439 mdu = mtod(m, struct markerdu *); --- 26 unchanged lines hidden (view full) --- 466 struct lacp_port *lp = LACP_PORT(lgp); 467 struct ifnet *ifp = lgp->lp_ifp; 468 struct ifmediareq ifmr; 469 int error = 0; 470 u_int media; 471 uint8_t old_state; 472 uint16_t old_key; 473 | 421 422 m = m_gethdr(M_DONTWAIT, MT_DATA); 423 if (m == NULL) { 424 return (ENOMEM); 425 } 426 m->m_len = m->m_pkthdr.len = sizeof(*mdu); 427 428 mdu = mtod(m, struct markerdu *); --- 26 unchanged lines hidden (view full) --- 455 struct lacp_port *lp = LACP_PORT(lgp); 456 struct ifnet *ifp = lgp->lp_ifp; 457 struct ifmediareq ifmr; 458 int error = 0; 459 u_int media; 460 uint8_t old_state; 461 uint16_t old_key; 462 |
474 LAGG_WLOCK_ASSERT(lgp->lp_lagg); | 463 LAGG_WLOCK_ASSERT(lgp->lp_softc); |
475 476 bzero((char *)&ifmr, sizeof(ifmr)); 477 error = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t)&ifmr); 478 if (error != 0) 479 return; 480 481 media = ifmr.ifm_active; 482 LACP_DPRINTF((lp, "media changed 0x%x -> 0x%x, ether = %d, fdx = %d, " 483 "link = %d\n", lp->lp_media, media, IFM_TYPE(media) == IFM_ETHER, 484 (media & IFM_FDX) != 0, ifp->if_link_state == LINK_STATE_UP)); 485 old_state = lp->lp_state; 486 old_key = lp->lp_key; 487 488 lp->lp_media = media; | 464 465 bzero((char *)&ifmr, sizeof(ifmr)); 466 error = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t)&ifmr); 467 if (error != 0) 468 return; 469 470 media = ifmr.ifm_active; 471 LACP_DPRINTF((lp, "media changed 0x%x -> 0x%x, ether = %d, fdx = %d, " 472 "link = %d\n", lp->lp_media, media, IFM_TYPE(media) == IFM_ETHER, 473 (media & IFM_FDX) != 0, ifp->if_link_state == LINK_STATE_UP)); 474 old_state = lp->lp_state; 475 old_key = lp->lp_key; 476 477 lp->lp_media = media; |
489 /* | 478 /* |
490 * If the port is not an active full duplex Ethernet link then it can 491 * not be aggregated. 492 */ 493 if (IFM_TYPE(media) != IFM_ETHER || (media & IFM_FDX) == 0 || 494 ifp->if_link_state != LINK_STATE_UP) { 495 lacp_port_disable(lp); 496 } else { 497 lacp_port_enable(lp); --- 5 unchanged lines hidden (view full) --- 503 lp->lp_selected = LACP_UNSELECTED; 504 } 505} 506 507static void 508lacp_tick(void *arg) 509{ 510 struct lacp_softc *lsc = arg; | 479 * If the port is not an active full duplex Ethernet link then it can 480 * not be aggregated. 481 */ 482 if (IFM_TYPE(media) != IFM_ETHER || (media & IFM_FDX) == 0 || 483 ifp->if_link_state != LINK_STATE_UP) { 484 lacp_port_disable(lp); 485 } else { 486 lacp_port_enable(lp); --- 5 unchanged lines hidden (view full) --- 492 lp->lp_selected = LACP_UNSELECTED; 493 } 494} 495 496static void 497lacp_tick(void *arg) 498{ 499 struct lacp_softc *lsc = arg; |
511 struct lagg_softc *sc = lsc->lsc_lagg; | 500 struct lagg_softc *sc = lsc->lsc_softc; |
512 struct lacp_port *lp; 513 514 LAGG_WLOCK(sc); 515 LIST_FOREACH(lp, &lsc->lsc_ports, lp_next) { 516 if ((lp->lp_state & LACP_STATE_AGGREGATION) == 0) 517 continue; 518 519 lacp_run_timers(lp); --- 5 unchanged lines hidden (view full) --- 525 } 526 LAGG_WUNLOCK(sc); 527 callout_reset(&lsc->lsc_callout, hz, lacp_tick, lsc); 528} 529 530int 531lacp_port_create(struct lagg_port *lgp) 532{ | 501 struct lacp_port *lp; 502 503 LAGG_WLOCK(sc); 504 LIST_FOREACH(lp, &lsc->lsc_ports, lp_next) { 505 if ((lp->lp_state & LACP_STATE_AGGREGATION) == 0) 506 continue; 507 508 lacp_run_timers(lp); --- 5 unchanged lines hidden (view full) --- 514 } 515 LAGG_WUNLOCK(sc); 516 callout_reset(&lsc->lsc_callout, hz, lacp_tick, lsc); 517} 518 519int 520lacp_port_create(struct lagg_port *lgp) 521{ |
533 struct lagg_softc *lgs = lgp->lp_lagg; 534 struct lacp_softc *lsc = LACP_SOFTC(lgs); | 522 struct lagg_softc *sc = lgp->lp_softc; 523 struct lacp_softc *lsc = LACP_SOFTC(sc); |
535 struct lacp_port *lp; 536 struct ifnet *ifp = lgp->lp_ifp; 537 struct sockaddr_dl sdl; 538 struct ifmultiaddr *rifma = NULL; 539 int error; 540 541 boolean_t active = TRUE; /* XXX should be configurable */ 542 boolean_t fast = FALSE; /* XXX should be configurable */ 543 | 524 struct lacp_port *lp; 525 struct ifnet *ifp = lgp->lp_ifp; 526 struct sockaddr_dl sdl; 527 struct ifmultiaddr *rifma = NULL; 528 int error; 529 530 boolean_t active = TRUE; /* XXX should be configurable */ 531 boolean_t fast = FALSE; /* XXX should be configurable */ 532 |
544 LAGG_WLOCK_ASSERT(lgs); | 533 LAGG_WLOCK_ASSERT(sc); |
545 546 bzero((char *)&sdl, sizeof(sdl)); 547 sdl.sdl_len = sizeof(sdl); 548 sdl.sdl_family = AF_LINK; 549 sdl.sdl_index = ifp->if_index; 550 sdl.sdl_type = IFT_ETHER; 551 sdl.sdl_alen = ETHER_ADDR_LEN; 552 --- 31 unchanged lines hidden (view full) --- 584} 585 586void 587lacp_port_destroy(struct lagg_port *lgp) 588{ 589 struct lacp_port *lp = LACP_PORT(lgp); 590 int i; 591 | 534 535 bzero((char *)&sdl, sizeof(sdl)); 536 sdl.sdl_len = sizeof(sdl); 537 sdl.sdl_family = AF_LINK; 538 sdl.sdl_index = ifp->if_index; 539 sdl.sdl_type = IFT_ETHER; 540 sdl.sdl_alen = ETHER_ADDR_LEN; 541 --- 31 unchanged lines hidden (view full) --- 573} 574 575void 576lacp_port_destroy(struct lagg_port *lgp) 577{ 578 struct lacp_port *lp = LACP_PORT(lgp); 579 int i; 580 |
592 LAGG_WLOCK_ASSERT(lgp->lp_lagg); | 581 LAGG_WLOCK_ASSERT(lgp->lp_softc); |
593 594 for (i = 0; i < LACP_NTIMER; i++) { 595 LACP_TIMER_DISARM(lp, i); 596 } 597 598 lacp_disable_collecting(lp); 599 lacp_disable_distributing(lp); 600 lacp_unselect(lp); --- 48 unchanged lines hidden (view full) --- 649{ 650 struct lacp_aggregator *la = lp->lp_aggregator; 651 struct lacp_softc *lsc = lp->lp_lsc; 652 struct lagg_port *lgp = lp->lp_lagg; 653#if defined(LACP_DEBUG) 654 char buf[LACP_LAGIDSTR_MAX+1]; 655#endif /* defined(LACP_DEBUG) */ 656 | 582 583 for (i = 0; i < LACP_NTIMER; i++) { 584 LACP_TIMER_DISARM(lp, i); 585 } 586 587 lacp_disable_collecting(lp); 588 lacp_disable_distributing(lp); 589 lacp_unselect(lp); --- 48 unchanged lines hidden (view full) --- 638{ 639 struct lacp_aggregator *la = lp->lp_aggregator; 640 struct lacp_softc *lsc = lp->lp_lsc; 641 struct lagg_port *lgp = lp->lp_lagg; 642#if defined(LACP_DEBUG) 643 char buf[LACP_LAGIDSTR_MAX+1]; 644#endif /* defined(LACP_DEBUG) */ 645 |
657 LAGG_WLOCK_ASSERT(lgp->lp_lagg); | 646 LAGG_WLOCK_ASSERT(lgp->lp_softc); |
658 659 if (la == NULL || (lp->lp_state & LACP_STATE_DISTRIBUTING) == 0) { 660 return; 661 } 662 663 KASSERT(!TAILQ_EMPTY(&la->la_ports), ("no aggregator ports")); 664 KASSERT(la->la_nports > 0, ("nports invalid (%d)", la->la_nports)); 665 KASSERT(la->la_refcnt >= la->la_nports, ("aggregator refcnt invalid")); --- 21 unchanged lines hidden (view full) --- 687{ 688 struct lacp_aggregator *la = lp->lp_aggregator; 689 struct lacp_softc *lsc = lp->lp_lsc; 690 struct lagg_port *lgp = lp->lp_lagg; 691#if defined(LACP_DEBUG) 692 char buf[LACP_LAGIDSTR_MAX+1]; 693#endif /* defined(LACP_DEBUG) */ 694 | 647 648 if (la == NULL || (lp->lp_state & LACP_STATE_DISTRIBUTING) == 0) { 649 return; 650 } 651 652 KASSERT(!TAILQ_EMPTY(&la->la_ports), ("no aggregator ports")); 653 KASSERT(la->la_nports > 0, ("nports invalid (%d)", la->la_nports)); 654 KASSERT(la->la_refcnt >= la->la_nports, ("aggregator refcnt invalid")); --- 21 unchanged lines hidden (view full) --- 676{ 677 struct lacp_aggregator *la = lp->lp_aggregator; 678 struct lacp_softc *lsc = lp->lp_lsc; 679 struct lagg_port *lgp = lp->lp_lagg; 680#if defined(LACP_DEBUG) 681 char buf[LACP_LAGIDSTR_MAX+1]; 682#endif /* defined(LACP_DEBUG) */ 683 |
695 LAGG_WLOCK_ASSERT(lgp->lp_lagg); | 684 LAGG_WLOCK_ASSERT(lgp->lp_softc); |
696 697 if ((lp->lp_state & LACP_STATE_DISTRIBUTING) != 0) { 698 return; 699 } 700 701 LACP_DPRINTF((lp, "enable distributing on aggregator %s, " 702 "nports %d -> %d\n", 703 lacp_format_lagid_aggregator(la, buf, sizeof(buf)), --- 18 unchanged lines hidden (view full) --- 722{ 723 struct lacp_softc *lsc = vp; 724 725 LACP_DPRINTF((NULL, "%s\n", __func__)); 726 lsc->lsc_suppress_distributing = FALSE; 727} 728 729int | 685 686 if ((lp->lp_state & LACP_STATE_DISTRIBUTING) != 0) { 687 return; 688 } 689 690 LACP_DPRINTF((lp, "enable distributing on aggregator %s, " 691 "nports %d -> %d\n", 692 lacp_format_lagid_aggregator(la, buf, sizeof(buf)), --- 18 unchanged lines hidden (view full) --- 711{ 712 struct lacp_softc *lsc = vp; 713 714 LACP_DPRINTF((NULL, "%s\n", __func__)); 715 lsc->lsc_suppress_distributing = FALSE; 716} 717 718int |
730lacp_attach(struct lagg_softc *lgs) | 719lacp_attach(struct lagg_softc *sc) |
731{ 732 struct lacp_softc *lsc; 733 | 720{ 721 struct lacp_softc *lsc; 722 |
734 LAGG_WLOCK_ASSERT(lgs); | 723 LAGG_WLOCK_ASSERT(sc); |
735 736 lsc = malloc(sizeof(struct lacp_softc), 737 M_DEVBUF, M_NOWAIT|M_ZERO); 738 if (lsc == NULL) 739 return (ENOMEM); 740 | 724 725 lsc = malloc(sizeof(struct lacp_softc), 726 M_DEVBUF, M_NOWAIT|M_ZERO); 727 if (lsc == NULL) 728 return (ENOMEM); 729 |
741 lgs->sc_psc = (caddr_t)lsc; 742 lsc->lsc_lagg = lgs; | 730 sc->sc_psc = (caddr_t)lsc; 731 lsc->lsc_softc = sc; |
743 744 lsc->lsc_hashkey = arc4random(); 745 lsc->lsc_active_aggregator = NULL; 746 TAILQ_INIT(&lsc->lsc_aggregators); 747 LIST_INIT(&lsc->lsc_ports); 748 749 TASK_INIT(&lsc->lsc_qtask, 0, lacp_dequeue, lsc); 750 mtx_init(&lsc->lsc_queue.ifq_mtx, "lacp queue", NULL, MTX_DEF); 751 lsc->lsc_queue.ifq_maxlen = ifqmaxlen; 752 753 callout_init(&lsc->lsc_transit_callout, CALLOUT_MPSAFE); 754 callout_init(&lsc->lsc_callout, CALLOUT_MPSAFE); 755 756 /* if the lagg is already up then do the same */ | 732 733 lsc->lsc_hashkey = arc4random(); 734 lsc->lsc_active_aggregator = NULL; 735 TAILQ_INIT(&lsc->lsc_aggregators); 736 LIST_INIT(&lsc->lsc_ports); 737 738 TASK_INIT(&lsc->lsc_qtask, 0, lacp_dequeue, lsc); 739 mtx_init(&lsc->lsc_queue.ifq_mtx, "lacp queue", NULL, MTX_DEF); 740 lsc->lsc_queue.ifq_maxlen = ifqmaxlen; 741 742 callout_init(&lsc->lsc_transit_callout, CALLOUT_MPSAFE); 743 callout_init(&lsc->lsc_callout, CALLOUT_MPSAFE); 744 745 /* if the lagg is already up then do the same */ |
757 if (lgs->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) 758 lacp_init(lgs); | 746 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) 747 lacp_init(sc); |
759 760 return (0); 761} 762 763int | 748 749 return (0); 750} 751 752int |
764lacp_detach(struct lagg_softc *lgs) | 753lacp_detach(struct lagg_softc *sc) |
765{ | 754{ |
766 struct lacp_softc *lsc = LACP_SOFTC(lgs); | 755 struct lacp_softc *lsc = LACP_SOFTC(sc); |
767 768 KASSERT(TAILQ_EMPTY(&lsc->lsc_aggregators), 769 ("aggregators still active")); 770 KASSERT(lsc->lsc_active_aggregator == NULL, 771 ("aggregator still attached")); 772 | 756 757 KASSERT(TAILQ_EMPTY(&lsc->lsc_aggregators), 758 ("aggregators still active")); 759 KASSERT(lsc->lsc_active_aggregator == NULL, 760 ("aggregator still attached")); 761 |
773 lgs->sc_psc = NULL; | 762 sc->sc_psc = NULL; |
774 callout_drain(&lsc->lsc_transit_callout); 775 callout_drain(&lsc->lsc_callout); 776 taskqueue_drain(taskqueue_swi, &lsc->lsc_qtask); 777 IF_DRAIN(&lsc->lsc_queue); 778 mtx_destroy(&lsc->lsc_queue.ifq_mtx); 779 780 free(lsc, M_DEVBUF); 781 return (0); 782} 783 784void | 763 callout_drain(&lsc->lsc_transit_callout); 764 callout_drain(&lsc->lsc_callout); 765 taskqueue_drain(taskqueue_swi, &lsc->lsc_qtask); 766 IF_DRAIN(&lsc->lsc_queue); 767 mtx_destroy(&lsc->lsc_queue.ifq_mtx); 768 769 free(lsc, M_DEVBUF); 770 return (0); 771} 772 773void |
785lacp_init(struct lagg_softc *lgs) | 774lacp_init(struct lagg_softc *sc) |
786{ | 775{ |
787 struct lacp_softc *lsc = LACP_SOFTC(lgs); | 776 struct lacp_softc *lsc = LACP_SOFTC(sc); |
788 789 callout_reset(&lsc->lsc_callout, hz, lacp_tick, lsc); 790} 791 792void | 777 778 callout_reset(&lsc->lsc_callout, hz, lacp_tick, lsc); 779} 780 781void |
793lacp_stop(struct lagg_softc *lgs) | 782lacp_stop(struct lagg_softc *sc) |
794{ | 783{ |
795 struct lacp_softc *lsc = LACP_SOFTC(lgs); | 784 struct lacp_softc *lsc = LACP_SOFTC(sc); |
796 797 callout_stop(&lsc->lsc_transit_callout); 798 callout_stop(&lsc->lsc_callout); 799} 800 801struct lagg_port * | 785 786 callout_stop(&lsc->lsc_transit_callout); 787 callout_stop(&lsc->lsc_callout); 788} 789 790struct lagg_port * |
802lacp_select_tx_port(struct lagg_softc *lgs, struct mbuf *m) | 791lacp_select_tx_port(struct lagg_softc *sc, struct mbuf *m) |
803{ | 792{ |
804 struct lacp_softc *lsc = LACP_SOFTC(lgs); | 793 struct lacp_softc *lsc = LACP_SOFTC(sc); |
805 struct lacp_aggregator *la; 806 struct lacp_port *lp; 807 uint32_t hash; 808 int nports; 809 | 794 struct lacp_aggregator *la; 795 struct lacp_port *lp; 796 uint32_t hash; 797 int nports; 798 |
810 LAGG_RLOCK_ASSERT(lgs); | 799 LAGG_RLOCK_ASSERT(sc); |
811 812 if (__predict_false(lsc->lsc_suppress_distributing)) { 813 LACP_DPRINTF((NULL, "%s: waiting transit\n", __func__)); 814 return (NULL); 815 } 816 817 la = lsc->lsc_active_aggregator; 818 if (__predict_false(la == NULL)) { --- 157 unchanged lines hidden (view full) --- 976 } 977 } 978} 979 980static uint16_t 981lacp_compose_key(struct lacp_port *lp) 982{ 983 struct lagg_port *lgp = lp->lp_lagg; | 800 801 if (__predict_false(lsc->lsc_suppress_distributing)) { 802 LACP_DPRINTF((NULL, "%s: waiting transit\n", __func__)); 803 return (NULL); 804 } 805 806 la = lsc->lsc_active_aggregator; 807 if (__predict_false(la == NULL)) { --- 157 unchanged lines hidden (view full) --- 965 } 966 } 967} 968 969static uint16_t 970lacp_compose_key(struct lacp_port *lp) 971{ 972 struct lagg_port *lgp = lp->lp_lagg; |
984 struct lagg_softc *lgs = lgp->lp_lagg; | 973 struct lagg_softc *sc = lgp->lp_softc; |
985 u_int media = lp->lp_media; 986 uint16_t key; 987 988 if ((lp->lp_state & LACP_STATE_AGGREGATION) == 0) { 989 990 /* 991 * non-aggregatable links should have unique keys. 992 * --- 8 unchanged lines hidden (view full) --- 1001 u_int subtype = IFM_SUBTYPE(media); 1002 1003 KASSERT(IFM_TYPE(media) == IFM_ETHER, ("invalid media type")); 1004 KASSERT((media & IFM_FDX) != 0, ("aggregating HDX interface")); 1005 1006 /* bit 0..4: IFM_SUBTYPE */ 1007 key = subtype; 1008 /* bit 5..14: (some bits of) if_index of lagg device */ | 974 u_int media = lp->lp_media; 975 uint16_t key; 976 977 if ((lp->lp_state & LACP_STATE_AGGREGATION) == 0) { 978 979 /* 980 * non-aggregatable links should have unique keys. 981 * --- 8 unchanged lines hidden (view full) --- 990 u_int subtype = IFM_SUBTYPE(media); 991 992 KASSERT(IFM_TYPE(media) == IFM_ETHER, ("invalid media type")); 993 KASSERT((media & IFM_FDX) != 0, ("aggregating HDX interface")); 994 995 /* bit 0..4: IFM_SUBTYPE */ 996 key = subtype; 997 /* bit 5..14: (some bits of) if_index of lagg device */ |
1009 key |= 0x7fe0 & ((lgs->sc_ifp->if_index) << 5); | 998 key |= 0x7fe0 & ((sc->sc_ifp->if_index) << 5); |
1010 /* bit 15: 0 */ 1011 } 1012 return (htons(key)); 1013} 1014 1015static void 1016lacp_aggregator_addref(struct lacp_softc *lsc, struct lacp_aggregator *la) 1017{ --- 657 unchanged lines hidden (view full) --- 1675{ 1676 struct lacp_port *lp = LACP_PORT(lgp); 1677 struct lacp_port *lp2; 1678 struct lacp_softc *lsc = lp->lp_lsc; 1679 struct markerdu *mdu; 1680 int error = 0; 1681 int pending = 0; 1682 | 999 /* bit 15: 0 */ 1000 } 1001 return (htons(key)); 1002} 1003 1004static void 1005lacp_aggregator_addref(struct lacp_softc *lsc, struct lacp_aggregator *la) 1006{ --- 657 unchanged lines hidden (view full) --- 1664{ 1665 struct lacp_port *lp = LACP_PORT(lgp); 1666 struct lacp_port *lp2; 1667 struct lacp_softc *lsc = lp->lp_lsc; 1668 struct markerdu *mdu; 1669 int error = 0; 1670 int pending = 0; 1671 |
1683 LAGG_RLOCK_ASSERT(lgp->lp_lagg); | 1672 LAGG_RLOCK_ASSERT(lgp->lp_softc); |
1684 | 1673 |
1685 if (__predict_false(lp->lp_flags & LACP_PORT_DETACHING)) { 1686 goto bad; 1687 } 1688 | |
1689 if (m->m_pkthdr.len != sizeof(*mdu)) { 1690 goto bad; 1691 } 1692 1693 if ((m->m_flags & M_MCAST) == 0) { 1694 goto bad; 1695 } 1696 --- 6 unchanged lines hidden (view full) --- 1703 1704 mdu = mtod(m, struct markerdu *); 1705 1706 if (memcmp(&mdu->mdu_eh.ether_dhost, 1707 ðermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) { 1708 goto bad; 1709 } 1710 | 1674 if (m->m_pkthdr.len != sizeof(*mdu)) { 1675 goto bad; 1676 } 1677 1678 if ((m->m_flags & M_MCAST) == 0) { 1679 goto bad; 1680 } 1681 --- 6 unchanged lines hidden (view full) --- 1688 1689 mdu = mtod(m, struct markerdu *); 1690 1691 if (memcmp(&mdu->mdu_eh.ether_dhost, 1692 ðermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) { 1693 goto bad; 1694 } 1695 |
1711 /* XXX 1712 KASSERT(mdu->mdu_sph.sph_subtype == SLOWPROTOCOLS_SUBTYPE_MARKER, 1713 ("a very bad kassert!")); 1714 */ 1715 | |
1716 if (mdu->mdu_sph.sph_version != 1) { 1717 goto bad; 1718 } 1719 1720 switch (mdu->mdu_tlv.tlv_type) { 1721 case MARKER_TYPE_INFO: 1722 if (tlv_check(mdu, sizeof(*mdu), &mdu->mdu_tlv, 1723 marker_info_tlv_template, TRUE)) { --- 211 unchanged lines hidden --- | 1696 if (mdu->mdu_sph.sph_version != 1) { 1697 goto bad; 1698 } 1699 1700 switch (mdu->mdu_tlv.tlv_type) { 1701 case MARKER_TYPE_INFO: 1702 if (tlv_check(mdu, sizeof(*mdu), &mdu->mdu_tlv, 1703 marker_info_tlv_template, TRUE)) { --- 211 unchanged lines hidden --- |