Print this page
11490 SRS ring polling disabled for VLANs
11491 Want DLS bypass for VLAN traffic
11492 add VLVF bypass to ixgbe core
2869 duplicate packets with vnics over aggrs
11489 DLS stat delete and aggr kstat can deadlock
Portions contributed by: Theo Schlossnagle <jesus@omniti.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>

@@ -19,10 +19,12 @@
  * CDDL HEADER END
  */
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2012 OmniTI Computer Consulting, Inc  All rights reserved.
+ * Copyright 2018 Joyent, Inc.
  */
 
 /*
  * IEEE 802.3ad Link Aggregation - Link Aggregation MAC ports.
  *

@@ -371,14 +373,18 @@
         port->lp_link_duplex = link_duplex;
 
         /* link speed changes? */
         ifspeed = aggr_port_stat(port, MAC_STAT_IFSPEED);
         if (port->lp_ifspeed != ifspeed) {
+                mutex_enter(&grp->lg_stat_lock);
+
                 if (port->lp_state == AGGR_PORT_STATE_ATTACHED)
                         do_detach |= (ifspeed != grp->lg_ifspeed);
                 else
                         do_attach |= (ifspeed == grp->lg_ifspeed);
+
+                mutex_exit(&grp->lg_stat_lock);
         }
         port->lp_ifspeed = ifspeed;
 
         if (do_attach) {
                 /* attempt to attach the port to the aggregation */

@@ -526,12 +532,19 @@
                 /* already in desired promiscous mode */
                 return (0);
 
         if (on) {
                 mac_rx_clear(port->lp_mch);
+
+                /*
+                 * We use the promisc callback because without hardware
+                 * rings, we deliver through flows that will cause duplicate
+                 * delivery of packets when we've flipped into this mode
+                 * to compensate for the lack of hardware MAC matching
+                 */
                 rc = mac_promisc_add(port->lp_mch, MAC_CLIENT_PROMISC_ALL,
-                    aggr_recv_cb, port, &port->lp_mphp,
+                    aggr_recv_promisc_cb, port, &port->lp_mphp,
                     MAC_PROMISC_FLAGS_NO_TX_LOOP);
                 if (rc != 0) {
                         mac_rx_set(port->lp_mch, aggr_recv_cb, port);
                         return (rc);
                 }

@@ -676,6 +689,46 @@
         } else {
                 ASSERT(port->lp_hwgh != NULL);
                 (void) mac_hwgroup_remmac(port->lp_hwgh, mac_addr);
         }
         mac_perim_exit(pmph);
+}
+
+int
+aggr_port_addvlan(aggr_port_t *port, uint16_t vid)
+{
+        mac_perim_handle_t      pmph;
+        int                     err;
+
+        ASSERT(MAC_PERIM_HELD(port->lp_grp->lg_mh));
+        mac_perim_enter_by_mh(port->lp_mh, &pmph);
+
+        /*
+         * Add the VLAN filter to the HW group if the port has a HW
+         * group. If the port doesn't have a HW group, then it will
+         * implicitly allow tagged traffic to pass and there is
+         * nothing to do.
+         */
+        if (port->lp_hwgh == NULL)
+                return (0);
+
+        err = mac_hwgroup_addvlan(port->lp_hwgh, vid);
+        mac_perim_exit(pmph);
+        return (err);
+}
+
+int
+aggr_port_remvlan(aggr_port_t *port, uint16_t vid)
+{
+        mac_perim_handle_t      pmph;
+        int                     err;
+
+        ASSERT(MAC_PERIM_HELD(port->lp_grp->lg_mh));
+        mac_perim_enter_by_mh(port->lp_mh, &pmph);
+
+        if (port->lp_hwgh == NULL)
+                return (0);
+
+        err = mac_hwgroup_remvlan(port->lp_hwgh, vid);
+        mac_perim_exit(pmph);
+        return (err);
 }