Deleted Added
full compact
22c22
< __FBSDID("$FreeBSD: head/sys/net/if_lagg.c 289400 2015-10-16 01:16:01Z hrs $");
---
> __FBSDID("$FreeBSD: head/sys/net/if_lagg.c 290239 2015-11-01 19:59:04Z melifaro $");
103c103
< static void lagg_port_lladdr(struct lagg_port *, uint8_t *);
---
> static void lagg_port_lladdr(struct lagg_port *, uint8_t *, lagg_llqtype);
545a546
> LAGG_UNLOCK_ASSERT(sc);
560c561,566
< static void
---
> /*
> * Set link-layer address on the lagg interface itself.
> *
> * Set noinline to be dtrace-friendly
> */
> static __noinline void
579a586,589
> /*
> * Send notification request for lagg interface
> * itself. Note that new lladdr is already set.
> */
584c594,595
< lagg_port_lladdr(&lp, lladdr);
---
> /* Do not request lladdr change */
> lagg_port_lladdr(&lp, lladdr, LAGG_LLQTYPE_VIRT);
625,626c636,644
< static void
< lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr)
---
> /*
> * Enqueue interface lladdr notification.
> * If request is already queued, it is updated.
> * If setting lladdr is also desired, @do_change has to be set to 1.
> *
> * Set noinline to be dtrace-friendly
> */
> static __noinline void
> lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr, lagg_llqtype llq_type)
631,632d648
< int pending = 0;
< int primary;
636,638c652,657
< primary = (sc->sc_primary->lp_ifp == ifp) ? 1 : 0;
< if (primary == 0 && (lp->lp_detaching ||
< memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0))
---
> /*
> * Do not enqueue requests where lladdr is the same for
> * "physical" interfaces (e.g. ports in lagg)
> */
> if (llq_type == LAGG_LLQTYPE_PHYS &&
> memcmp(IF_LLADDR(ifp), lladdr, ETHER_ADDR_LEN) == 0)
643,645c662,665
< if (llq->llq_ifp == ifp && llq->llq_primary == primary) {
< pending = 1;
< break;
---
> if (llq->llq_ifp == ifp) {
> /* Update lladdr, it may have changed */
> bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
> return;
649,653c669,671
< if (!pending) {
< llq = malloc(sizeof(struct lagg_llq), M_DEVBUF, M_NOWAIT);
< if (llq == NULL) /* XXX what to do */
< return;
< }
---
> llq = malloc(sizeof(struct lagg_llq), M_DEVBUF, M_NOWAIT | M_ZERO);
> if (llq == NULL) /* XXX what to do */
> return;
655d672
< /* Update the lladdr even if pending, it may have changed */
657c674
< llq->llq_primary = primary;
---
> llq->llq_type = llq_type;
658a676,677
> /* XXX: We should insert to tail */
> SLIST_INSERT_HEAD(&sc->sc_llq_head, llq, llq_entries);
660,662d678
< if (!pending)
< SLIST_INSERT_HEAD(&sc->sc_llq_head, llq, llq_entries);
<
667a684,685
> *
> * Set noinline to be dtrace-friendly
669c687
< static void
---
> static __noinline void
691,695c709,716
< if (llq->llq_primary == 0) {
< /*
< * Set the link layer address on the laggport interface.
< * if_setlladdr() triggers gratuitous ARPs for INET.
< */
---
> error = 0;
>
> /*
> * Set the link layer address on the laggport interface.
> * Note that if_setlladdr() or iflladdr_event handler
> * may result in arp transmission / lltable updates.
> */
> if (llq->llq_type == LAGG_LLQTYPE_PHYS)
698,701c719,722
< if (error)
< printf("%s: setlladdr failed on %s\n", __func__,
< ifp->if_xname);
< } else
---
> if (error)
> printf("%s: setlladdr failed on %s\n", __func__,
> ifp->if_xname);
> else
733c754
< if (ifp->if_type != IFT_ETHER)
---
> if (ifp->if_type != IFT_ETHER && ifp->if_type != IFT_L2VLAN)
786a808
> /* First port in lagg. Update/notify lagg lladdress */
789,790c811,816
< /* Update link layer address for this port */
< lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp));
---
>
> /*
> * Update link layer address for this port and
> * send notifications to other subsystems.
> */
> lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp), LAGG_LLQTYPE_PHYS);
876c902
< lagg_port_lladdr(lp, lp->lp_lladdr);
---
> lagg_port_lladdr(lp, lp->lp_lladdr, LAGG_LLQTYPE_PHYS);
907a934,936
> /* Mark lp0 as new primary */
> sc->sc_primary = lp0;
>
909,910c938,940
< * Update link layer address for each port. No port is
< * marked as primary at this moment.
---
> * Enqueue lladdr update/notification for each port
> * (new primary needs update as well, to switch from
> * old lladdr to its 'real' one).
913,920c943
< lagg_port_lladdr(lp_ptr, lladdr);
< /*
< * Mark lp0 as the new primary. This invokes an
< * iflladdr_event.
< */
< sc->sc_primary = lp0;
< if (lp0 != NULL)
< lagg_port_lladdr(lp0, lladdr);
---
> lagg_port_lladdr(lp_ptr, lladdr, LAGG_LLQTYPE_PHYS);
1152d1174
< struct lagg_port *lp;
1153a1176
> struct lagg_port *lp;
1161c1184,1189
< /* Update the port lladdrs */
---
>
> /*
> * Update the port lladdrs if needed.
> * This might be if_setlladdr() notification
> * that lladdr has been changed.
> */
1163c1191
< lagg_port_lladdr(lp, IF_LLADDR(ifp));
---
> lagg_port_lladdr(lp, IF_LLADDR(ifp), LAGG_LLQTYPE_PHYS);
1246a1275
> LAGG_UNLOCK_ASSERT(sc);