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>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/mac/mac_client.c
          +++ new/usr/src/uts/common/io/mac/mac_client.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright (c) 2014, Joyent, Inc.  All rights reserved.
       24 + * Copyright 2018 Joyent, Inc.
  25   25   * Copyright 2017 RackTop Systems.
  26   26   */
  27   27  
  28   28  /*
  29   29   * - General Introduction:
  30   30   *
  31   31   * This file contains the implementation of the MAC client kernel
  32   32   * API and related code. The MAC client API allows a kernel module
  33   33   * to gain access to a MAC instance (physical NIC, link aggregation, etc).
  34   34   * It allows a MAC client to associate itself with a MAC address,
↓ open down ↓ 823 lines elided ↑ open up ↑
 858  858          bcopy(map->ma_addr, flow_desc.fd_dst_mac, map->ma_len);
 859  859          mac_flow_set_desc(flent, &flow_desc);
 860  860  
 861  861          /*
 862  862           * The v6 local and SLAAC addrs (used by mac protection) need to be
 863  863           * regenerated because our mac address has changed.
 864  864           */
 865  865          mac_protect_update_mac_token(mcip);
 866  866  
 867  867          /*
 868      -         * A MAC client could have one MAC address but multiple
 869      -         * VLANs. In that case update the flow entries corresponding
 870      -         * to all VLANs of the MAC client.
      868 +         * When there are multiple VLANs sharing the same MAC address,
      869 +         * each gets its own MAC client, except when running on sun4v
      870 +         * vsw. In that case the mci_flent_list is used to place
      871 +         * multiple VLAN flows on one MAC client. If we ever get rid
      872 +         * of vsw then this code can go, but until then we need to
      873 +         * update all flow entries.
 871  874           */
 872  875          for (flent = mcip->mci_flent_list; flent != NULL;
 873  876              flent = flent->fe_client_next) {
 874  877                  mac_flow_get_desc(flent, &flow_desc);
 875  878                  if (!(flent->fe_type & FLOW_PRIMARY_MAC ||
 876  879                      flent->fe_type & FLOW_VNIC_MAC))
 877  880                          continue;
 878  881  
 879  882                  bcopy(map->ma_addr, flow_desc.fd_dst_mac, map->ma_len);
 880  883                  mac_flow_set_desc(flent, &flow_desc);
↓ open down ↓ 137 lines elided ↑ open up ↑
1018 1021  
1019 1022          /*
1020 1023           * If the new value is the same as the current primary address value,
1021 1024           * there's nothing to do.
1022 1025           */
1023 1026          if (bcmp(addr, mip->mi_addr, mip->mi_type->mt_addr_length) == 0) {
1024 1027                  i_mac_perim_exit(mip);
1025 1028                  return (0);
1026 1029          }
1027 1030  
1028      -        if (mac_find_macaddr(mip, (uint8_t *)addr) != 0) {
     1031 +        if (mac_find_macaddr(mip, (uint8_t *)addr) != NULL) {
1029 1032                  i_mac_perim_exit(mip);
1030 1033                  return (EBUSY);
1031 1034          }
1032 1035  
1033 1036          map = mac_find_macaddr(mip, mip->mi_addr);
1034 1037          ASSERT(map != NULL);
1035 1038  
1036 1039          /*
1037 1040           * Update the MAC address.
1038 1041           */
1039 1042          if (mip->mi_state_flags & MIS_IS_AGGR) {
1040 1043                  mac_capab_aggr_t aggr_cap;
1041 1044  
1042 1045                  /*
1043      -                 * If the mac is an aggregation, other than the unicast
     1046 +                 * If the MAC is an aggregation, other than the unicast
1044 1047                   * addresses programming, aggr must be informed about this
1045      -                 * primary unicst address change to change its mac address
     1048 +                 * primary unicst address change to change its MAC address
1046 1049                   * policy to be user-specified.
1047 1050                   */
1048 1051                  ASSERT(map->ma_type == MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED);
1049 1052                  VERIFY(i_mac_capab_get(mh, MAC_CAPAB_AGGR, &aggr_cap));
1050 1053                  err = aggr_cap.mca_unicst(mip->mi_driver, addr);
1051 1054                  if (err == 0)
1052 1055                          bcopy(addr, map->ma_addr, map->ma_len);
1053 1056          } else {
1054 1057                  err = mac_update_macaddr(map, (uint8_t *)addr);
1055 1058          }
↓ open down ↓ 311 lines elided ↑ open up ↑
1367 1370          if ((flags & MAC_OPEN_FLAGS_IS_VNIC) != 0)
1368 1371                  mcip->mci_state_flags |= MCIS_IS_VNIC;
1369 1372  
1370 1373          if ((flags & MAC_OPEN_FLAGS_EXCLUSIVE) != 0)
1371 1374                  mcip->mci_state_flags |= MCIS_EXCLUSIVE;
1372 1375  
1373 1376          if ((flags & MAC_OPEN_FLAGS_IS_AGGR_PORT) != 0)
1374 1377                  mcip->mci_state_flags |= MCIS_IS_AGGR_PORT;
1375 1378  
1376 1379          if (mip->mi_state_flags & MIS_IS_AGGR)
1377      -                mcip->mci_state_flags |= MCIS_IS_AGGR;
     1380 +                mcip->mci_state_flags |= MCIS_IS_AGGR_CLIENT;
1378 1381  
1379 1382          if ((flags & MAC_OPEN_FLAGS_USE_DATALINK_NAME) != 0) {
1380 1383                  datalink_id_t   linkid;
1381 1384  
1382 1385                  ASSERT(name == NULL);
1383 1386                  if ((err = dls_devnet_macname2linkid(mip->mi_name,
1384 1387                      &linkid)) != 0) {
1385 1388                          goto done;
1386 1389                  }
1387 1390                  if ((err = dls_mgmt_get_linkinfo(linkid, mcip->mci_name, NULL,
↓ open down ↓ 144 lines elided ↑ open up ↑
1532 1535          mac_client_remove(mcip);
1533 1536  
1534 1537          i_mac_perim_exit(mip);
1535 1538          mcip->mci_subflow_tab = NULL;
1536 1539          mcip->mci_state_flags = 0;
1537 1540          mcip->mci_tx_flag = 0;
1538 1541          kmem_cache_free(mac_client_impl_cache, mch);
1539 1542  }
1540 1543  
1541 1544  /*
1542      - * Set the rx bypass receive callback.
     1545 + * Set the Rx bypass receive callback and return B_TRUE. Return
     1546 + * B_FALSE if it's not possible to enable bypass.
1543 1547   */
1544 1548  boolean_t
1545 1549  mac_rx_bypass_set(mac_client_handle_t mch, mac_direct_rx_t rx_fn, void *arg1)
1546 1550  {
1547 1551          mac_client_impl_t       *mcip = (mac_client_impl_t *)mch;
1548 1552          mac_impl_t              *mip = mcip->mci_mip;
1549 1553  
1550 1554          ASSERT(MAC_PERIM_HELD((mac_handle_t)mip));
1551 1555  
1552 1556          /*
1553      -         * If the mac_client is a VLAN, we should not do DLS bypass and
1554      -         * instead let the packets come up via mac_rx_deliver so the vlan
1555      -         * header can be stripped.
     1557 +         * If the client has more than one VLAN then process packets
     1558 +         * through DLS. This should happen only when sun4v vsw is on
     1559 +         * the scene.
1556 1560           */
1557      -        if (mcip->mci_nvids > 0)
     1561 +        if (mcip->mci_nvids > 1)
1558 1562                  return (B_FALSE);
1559 1563  
1560 1564          /*
1561 1565           * These are not accessed directly in the data path, and hence
1562 1566           * don't need any protection
1563 1567           */
1564 1568          mcip->mci_direct_rx_fn = rx_fn;
1565 1569          mcip->mci_direct_rx_arg = arg1;
1566 1570          return (B_TRUE);
1567 1571  }
↓ open down ↓ 33 lines elided ↑ open up ↑
1601 1605           */
1602 1606          i_mac_perim_enter(mip);
1603 1607          mac_rx_client_quiesce(mch);
1604 1608  
1605 1609          mcip->mci_rx_fn = rx_fn;
1606 1610          mcip->mci_rx_arg = arg;
1607 1611          mac_rx_client_restart(mch);
1608 1612          i_mac_perim_exit(mip);
1609 1613  
1610 1614          /*
1611      -         * If we're changing the rx function on the primary mac of a vnic,
1612      -         * make sure any secondary macs on the vnic are updated as well.
     1615 +         * If we're changing the Rx function on the primary MAC of a VNIC,
     1616 +         * make sure any secondary addresses on the VNIC are updated as well.
1613 1617           */
1614 1618          if (umip != NULL) {
1615 1619                  ASSERT((umip->mi_state_flags & MIS_IS_VNIC) != 0);
1616 1620                  mac_vnic_secondary_update(umip);
1617 1621          }
1618 1622  }
1619 1623  
1620 1624  /*
1621 1625   * Reset the receive callback for the specified MAC client.
1622 1626   */
↓ open down ↓ 157 lines elided ↑ open up ↑
1780 1784                                           * If this is a static group, we
1781 1785                                           * need to release the group. The
1782 1786                                           * client will remain in the same
1783 1787                                           * group till some other client
1784 1788                                           * needs this group.
1785 1789                                           */
1786 1790                                          MAC_RX_GRP_RELEASED(mip);
1787 1791                                  }
1788 1792                          /* Let check if we can give this an excl group */
1789 1793                          } else if (group == defgrp) {
     1794 +                                /*
     1795 +                                 * If multiple clients share an
     1796 +                                 * address then they must stay on the
     1797 +                                 * default group.
     1798 +                                 */
     1799 +                                if (mac_check_macaddr_shared(mcip->mci_unicast))
     1800 +                                        return (0);
     1801 +
1790 1802                                  ngrp = mac_reserve_rx_group(mcip, mac_addr,
1791 1803                                      B_TRUE);
1792 1804                                  /* Couldn't give it a group, that's fine */
1793 1805                                  if (ngrp == NULL)
1794 1806                                          return (0);
1795 1807                                  /* Switch to H/W */
1796 1808                                  if (mac_rx_switch_group(mcip, defgrp, ngrp) !=
1797 1809                                      0) {
1798 1810                                          mac_stop_group(ngrp);
1799 1811                                          return (0);
↓ open down ↓ 2 lines elided ↑ open up ↑
1802 1814                          /*
1803 1815                           * If the client is in the default group, we will
1804 1816                           * just clear the MRP_RX_RINGS and leave it as
1805 1817                           * it rather than look for an exclusive group
1806 1818                           * for it.
1807 1819                           */
1808 1820                          return (0);
1809 1821                  }
1810 1822  
1811 1823                  if (group == defgrp && ((mrp->mrp_nrxrings > 0) || unspec)) {
     1824 +                        /*
     1825 +                         * We are requesting Rx rings. Try to reserve
     1826 +                         * a non-default group.
     1827 +                         *
     1828 +                         * If multiple clients share an address then
     1829 +                         * they must stay on the default group.
     1830 +                         */
     1831 +                        if (mac_check_macaddr_shared(mcip->mci_unicast))
     1832 +                                return (EINVAL);
     1833 +
1812 1834                          ngrp = mac_reserve_rx_group(mcip, mac_addr, B_TRUE);
1813 1835                          if (ngrp == NULL)
1814 1836                                  return (ENOSPC);
1815 1837  
1816 1838                          /* Switch to H/W */
1817 1839                          if (mac_rx_switch_group(mcip, defgrp, ngrp) != 0) {
1818 1840                                  mac_release_rx_group(mcip, ngrp);
1819 1841                                  return (ENOSPC);
1820 1842                          }
1821 1843                          MAC_RX_GRP_RESERVED(mip);
↓ open down ↓ 337 lines elided ↑ open up ↑
2159 2181           *
2160 2182           * We set FLOW_PRIMARY_MAC for the primary MAC address,
2161 2183           * FLOW_VNIC for everything else.
2162 2184           */
2163 2185          if (is_primary)
2164 2186                  flent_flags = FLOW_PRIMARY_MAC;
2165 2187          else
2166 2188                  flent_flags = FLOW_VNIC_MAC;
2167 2189  
2168 2190          /*
2169      -         * For the first flow we use the mac client's name - mci_name, for
2170      -         * subsequent ones we just create a name with the vid. This is
     2191 +         * For the first flow we use the MAC client's name - mci_name, for
     2192 +         * subsequent ones we just create a name with the VID. This is
2171 2193           * so that we can add these flows to the same flow table. This is
2172      -         * fine as the flow name (except for the one with the mac client's
     2194 +         * fine as the flow name (except for the one with the MAC client's
2173 2195           * name) is not visible. When the first flow is removed, we just replace
2174 2196           * its fdesc with another from the list, so we will still retain the
2175 2197           * flent with the MAC client's flow name.
2176 2198           */
2177 2199          if (first_flow) {
2178 2200                  bcopy(mcip->mci_name, flowname, MAXFLOWNAMELEN);
2179 2201          } else {
2180 2202                  (void) sprintf(flowname, "%s%u", mcip->mci_name, vid);
2181 2203                  flent_flags = FLOW_NO_STATS;
2182 2204          }
↓ open down ↓ 137 lines elided ↑ open up ↑
2320 2342                   */
2321 2343                  if ((err = mac_datapath_setup(mcip, flent, SRST_LINK)) != 0)
2322 2344                          goto bail;
2323 2345  
2324 2346                  if (no_unicast)
2325 2347                          goto done_setup;
2326 2348                  /*
2327 2349                   * The unicast MAC address must have been added successfully.
2328 2350                   */
2329 2351                  ASSERT(mcip->mci_unicast != NULL);
     2352 +
2330 2353                  /*
2331 2354                   * Push down the sub-flows that were defined on this link
2332 2355                   * hitherto. The flows are added to the active flow table
2333 2356                   * and SRS, softrings etc. are created as needed.
2334 2357                   */
2335 2358                  mac_link_init_flows((mac_client_handle_t)mcip);
2336 2359          } else {
2337 2360                  mac_address_t *map = mcip->mci_unicast;
2338 2361  
2339 2362                  ASSERT(!no_unicast);
2340 2363                  /*
2341      -                 * A unicast flow already exists for that MAC client,
2342      -                 * this flow must be the same mac address but with
2343      -                 * different VID. It has been checked by mac_addr_in_use().
     2364 +                 * A unicast flow already exists for that MAC client
     2365 +                 * so this flow must be the same MAC address but with
     2366 +                 * a different VID. It has been checked by
     2367 +                 * mac_addr_in_use().
2344 2368                   *
2345      -                 * We will use the SRS etc. from the mci_flent. Note that
2346      -                 * We don't need to create kstat for this as except for
2347      -                 * the fdesc, everything will be used from in the 1st flent.
     2369 +                 * We will use the SRS etc. from the initial
     2370 +                 * mci_flent. We don't need to create a kstat for
     2371 +                 * this, as except for the fdesc, everything will be
     2372 +                 * used from the first flent.
     2373 +                 *
     2374 +                 * The only time we should see multiple flents on the
     2375 +                 * same MAC client is on the sun4v vsw. If we removed
     2376 +                 * that code we should be able to remove the entire
     2377 +                 * notion of multiple flents on a MAC client (this
     2378 +                 * doesn't affect sub/user flows because they have
     2379 +                 * their own list unrelated to mci_flent_list).
2348 2380                   */
2349      -
2350 2381                  if (bcmp(mac_addr, map->ma_addr, map->ma_len) != 0) {
2351 2382                          err = EINVAL;
2352 2383                          goto bail;
2353 2384                  }
2354 2385  
2355 2386                  if ((err = mac_unicast_flow_create(mcip, mac_addr, vid,
2356 2387                      isprimary, B_FALSE, &flent, NULL)) != 0) {
2357 2388                          goto bail;
2358 2389                  }
2359 2390                  if ((err = mac_flow_add(mip->mi_flow_tab, flent)) != 0) {
↓ open down ↓ 108 lines elided ↑ open up ↑
2468 2499          boolean_t               check_dups = !(flags & MAC_UNICAST_NODUPCHECK);
2469 2500          boolean_t               fastpath_disabled = B_FALSE;
2470 2501          boolean_t               is_primary = (flags & MAC_UNICAST_PRIMARY);
2471 2502          boolean_t               is_unicast_hw = (flags & MAC_UNICAST_HW);
2472 2503          mac_resource_props_t    *mrp;
2473 2504          boolean_t               passive_client = B_FALSE;
2474 2505          mac_unicast_impl_t      *muip;
2475 2506          boolean_t               is_vnic_primary =
2476 2507              (flags & MAC_UNICAST_VNIC_PRIMARY);
2477 2508  
2478      -        /* when VID is non-zero, the underlying MAC can not be VNIC */
2479      -        ASSERT(!((mip->mi_state_flags & MIS_IS_VNIC) && (vid != 0)));
     2509 +        /*
     2510 +         * When the VID is non-zero the underlying MAC cannot be a
     2511 +         * VNIC. I.e., dladm create-vlan cannot take a VNIC as
     2512 +         * argument, only the primary MAC client.
     2513 +         */
     2514 +        ASSERT(!((mip->mi_state_flags & MIS_IS_VNIC) && (vid != VLAN_ID_NONE)));
2480 2515  
2481 2516          /*
2482 2517           * Can't unicast add if the client asked only for minimal datapath
2483 2518           * setup.
2484 2519           */
2485 2520          if (mcip->mci_state_flags & MCIS_NO_UNICAST_ADDR)
2486 2521                  return (ENOTSUP);
2487 2522  
2488 2523          /*
2489 2524           * Check for an attempted use of the current Port VLAN ID, if enabled.
2490 2525           * No client may use it.
2491 2526           */
2492      -        if (mip->mi_pvid != 0 && vid == mip->mi_pvid)
     2527 +        if (mip->mi_pvid != VLAN_ID_NONE && vid == mip->mi_pvid)
2493 2528                  return (EBUSY);
2494 2529  
2495 2530          /*
2496 2531           * Check whether it's the primary client and flag it.
2497 2532           */
2498      -        if (!(mcip->mci_state_flags & MCIS_IS_VNIC) && is_primary && vid == 0)
     2533 +        if (!(mcip->mci_state_flags & MCIS_IS_VNIC) && is_primary &&
     2534 +            vid == VLAN_ID_NONE)
2499 2535                  mcip->mci_flags |= MAC_CLIENT_FLAGS_PRIMARY;
2500 2536  
2501 2537          /*
2502 2538           * is_vnic_primary is true when we come here as a VLAN VNIC
2503      -         * which uses the primary mac client's address but with a non-zero
     2539 +         * which uses the primary MAC client's address but with a non-zero
2504 2540           * VID. In this case the MAC address is not specified by an upper
2505 2541           * MAC client.
2506 2542           */
2507 2543          if ((mcip->mci_state_flags & MCIS_IS_VNIC) && is_primary &&
2508 2544              !is_vnic_primary) {
2509 2545                  /*
2510 2546                   * The address is being set by the upper MAC client
2511 2547                   * of a VNIC. The MAC address was already set by the
2512 2548                   * VNIC driver during VNIC creation.
2513 2549                   *
↓ open down ↓ 31 lines elided ↑ open up ↑
2545 2581                          }
2546 2582                          mcip->mci_flags |= MAC_CLIENT_FLAGS_PASSIVE_PRIMARY;
2547 2583                          passive_client = B_TRUE;
2548 2584                  }
2549 2585  
2550 2586                  mcip->mci_flags |= MAC_CLIENT_FLAGS_VNIC_PRIMARY;
2551 2587  
2552 2588                  /*
2553 2589                   * Create a handle for vid 0.
2554 2590                   */
2555      -                ASSERT(vid == 0);
     2591 +                ASSERT(vid == VLAN_ID_NONE);
2556 2592                  muip = kmem_zalloc(sizeof (mac_unicast_impl_t), KM_SLEEP);
2557 2593                  muip->mui_vid = vid;
2558 2594                  *mah = (mac_unicast_handle_t)muip;
2559 2595                  /*
2560 2596                   * This will be used by the caller to defer setting the
2561 2597                   * rx functions.
2562 2598                   */
2563 2599                  if (passive_client)
2564 2600                          return (EAGAIN);
2565 2601                  return (0);
2566 2602          }
2567 2603  
2568 2604          /* primary MAC clients cannot be opened on top of anchor VNICs */
2569 2605          if ((is_vnic_primary || is_primary) &&
2570 2606              i_mac_capab_get((mac_handle_t)mip, MAC_CAPAB_ANCHOR_VNIC, NULL)) {
2571 2607                  return (ENXIO);
2572 2608          }
2573 2609  
2574 2610          /*
2575      -         * If this is a VNIC/VLAN, disable softmac fast-path.
     2611 +         * If this is a VNIC/VLAN, disable softmac fast-path. This is
     2612 +         * only relevant to legacy devices which use softmac to
     2613 +         * interface with GLDv3.
2576 2614           */
2577 2615          if (mcip->mci_state_flags & MCIS_IS_VNIC) {
2578 2616                  err = mac_fastpath_disable((mac_handle_t)mip);
2579 2617                  if (err != 0)
2580 2618                          return (err);
2581 2619                  fastpath_disabled = B_TRUE;
2582 2620          }
2583 2621  
2584 2622          /*
2585 2623           * Return EBUSY if:
↓ open down ↓ 27 lines elided ↑ open up ↑
2613 2651                  /*
2614 2652                   * Apply the property cached in the mac_impl_t to the primary
2615 2653                   * mac client. If the mac client is a VNIC or an aggregation
2616 2654                   * port, its property should be set in the mcip when the
2617 2655                   * VNIC/aggr was created.
2618 2656                   */
2619 2657                  mac_get_resources((mac_handle_t)mip, mrp);
2620 2658                  (void) mac_client_set_resources(mch, mrp);
2621 2659          } else if (mcip->mci_state_flags & MCIS_IS_VNIC) {
2622 2660                  /*
2623      -                 * This is a primary VLAN client, we don't support
2624      -                 * specifying rings property for this as it inherits the
2625      -                 * rings property from its MAC.
     2661 +                 * This is a VLAN client sharing the address of the
     2662 +                 * primary MAC client; i.e., one created via dladm
     2663 +                 * create-vlan. We don't support specifying ring
     2664 +                 * properties for this type of client as it inherits
     2665 +                 * these from the primary MAC client.
2626 2666                   */
2627 2667                  if (is_vnic_primary) {
2628 2668                          mac_resource_props_t    *vmrp;
2629 2669  
2630 2670                          vmrp = MCIP_RESOURCE_PROPS(mcip);
2631 2671                          if (vmrp->mrp_mask & MRP_RX_RINGS ||
2632 2672                              vmrp->mrp_mask & MRP_TX_RINGS) {
2633 2673                                  if (fastpath_disabled)
2634 2674                                          mac_fastpath_enable((mac_handle_t)mip);
2635 2675                                  kmem_free(mrp, sizeof (*mrp));
↓ open down ↓ 38 lines elided ↑ open up ↑
2674 2714                   */
2675 2715                  if (check_dups && bcmp(mip->mi_addr, mac_addr, mac_len) == 0) {
2676 2716                          *diag = MAC_DIAG_MACADDR_NIC;
2677 2717                          err = EINVAL;
2678 2718                          goto bail_out;
2679 2719                  }
2680 2720          }
2681 2721  
2682 2722          /*
2683 2723           * Set the flags here so that if this is a passive client, we
2684      -         * can return  and set it when we call mac_client_datapath_setup
     2724 +         * can return and set it when we call mac_client_datapath_setup
2685 2725           * when this becomes the active client. If we defer to using these
2686 2726           * flags to mac_client_datapath_setup, then for a passive client,
2687 2727           * we'd have to store the flags somewhere (probably fe_flags)
2688 2728           * and then use it.
2689 2729           */
2690 2730          if (!MCIP_DATAPATH_SETUP(mcip)) {
2691 2731                  if (is_unicast_hw) {
2692 2732                          /*
2693 2733                           * The client requires a hardware MAC address slot
2694 2734                           * for that unicast address. Since we support only
↓ open down ↓ 282 lines elided ↑ open up ↑
2977 3017          mac_client_impl_t *mcip = (mac_client_impl_t *)mch;
2978 3018          mac_unicast_impl_t *muip = (mac_unicast_impl_t *)mah;
2979 3019          mac_unicast_impl_t *pre;
2980 3020          mac_impl_t *mip = mcip->mci_mip;
2981 3021          flow_entry_t            *flent;
2982 3022          uint16_t mui_vid;
2983 3023  
2984 3024          i_mac_perim_enter(mip);
2985 3025          if (mcip->mci_flags & MAC_CLIENT_FLAGS_VNIC_PRIMARY) {
2986 3026                  /*
2987      -                 * Called made by the upper MAC client of a VNIC.
     3027 +                 * Call made by the upper MAC client of a VNIC.
2988 3028                   * There's nothing much to do, the unicast address will
2989 3029                   * be removed by the VNIC driver when the VNIC is deleted,
2990 3030                   * but let's ensure that all our transmit is done before
2991 3031                   * the client does a mac_client_stop lest it trigger an
2992 3032                   * assert in the driver.
2993 3033                   */
2994      -                ASSERT(muip->mui_vid == 0);
     3034 +                ASSERT(muip->mui_vid == VLAN_ID_NONE);
2995 3035  
2996 3036                  mac_tx_client_flush(mcip);
2997 3037  
2998 3038                  if ((mcip->mci_flags & MAC_CLIENT_FLAGS_PASSIVE_PRIMARY) != 0) {
2999 3039                          mcip->mci_flags &= ~MAC_CLIENT_FLAGS_PASSIVE_PRIMARY;
3000 3040                          if (mcip->mci_rx_p_fn != NULL) {
3001 3041                                  mac_rx_set(mch, mcip->mci_rx_p_fn,
3002 3042                                      mcip->mci_rx_p_arg);
3003 3043                                  mcip->mci_rx_p_fn = NULL;
3004 3044                                  mcip->mci_rx_p_arg = NULL;
↓ open down ↓ 43 lines elided ↑ open up ↑
3048 3088                  if (mcip->mci_state_flags & MCIS_STRIP_DISABLE)
3049 3089                          mcip->mci_state_flags &= ~MCIS_STRIP_DISABLE;
3050 3090  
3051 3091                  if (mcip->mci_state_flags & MCIS_DISABLE_TX_VID_CHECK)
3052 3092                          mcip->mci_state_flags &= ~MCIS_DISABLE_TX_VID_CHECK;
3053 3093  
3054 3094                  kmem_free(muip, sizeof (mac_unicast_impl_t));
3055 3095                  i_mac_perim_exit(mip);
3056 3096                  return (0);
3057 3097          }
     3098 +
3058 3099          /*
3059 3100           * Remove the VID from the list of client's VIDs.
3060 3101           */
3061 3102          pre = mcip->mci_unicast_list;
3062 3103          if (muip == pre) {
3063 3104                  mcip->mci_unicast_list = muip->mui_next;
3064 3105          } else {
3065 3106                  while ((pre->mui_next != NULL) && (pre->mui_next != muip))
3066 3107                          pre = pre->mui_next;
3067 3108                  ASSERT(pre->mui_next == muip);
↓ open down ↓ 6 lines elided ↑ open up ↑
3074 3115                  /*
3075 3116                   * This MAC client is shared by more than one unicast
3076 3117                   * addresses, so we will just remove the flent
3077 3118                   * corresponding to the address being removed. We don't invoke
3078 3119                   * mac_rx_classify_flow_rem() since the additional flow is
3079 3120                   * not associated with its own separate set of SRS and rings,
3080 3121                   * and these constructs are still needed for the remaining
3081 3122                   * flows.
3082 3123                   */
3083 3124                  flent = mac_client_get_flow(mcip, muip);
3084      -                ASSERT(flent != NULL);
     3125 +                VERIFY3P(flent, !=, NULL);
3085 3126  
3086 3127                  /*
3087 3128                   * The first one is disappearing, need to make sure
3088 3129                   * we replace it with another from the list of
3089 3130                   * shared clients.
3090 3131                   */
3091 3132                  if (flent == mcip->mci_flent)
3092 3133                          flent = mac_client_swap_mciflent(mcip);
3093 3134                  mac_client_remove_flow_from_list(mcip, flent);
3094 3135                  mac_flow_remove(mip->mi_flow_tab, flent, B_FALSE);
↓ open down ↓ 7 lines elided ↑ open up ↑
3102 3143                  mac_client_bcast_refresh(mcip, mac_client_update_mcast,
3103 3144                      (void *)flent, B_FALSE);
3104 3145  
3105 3146                  if (mip->mi_type->mt_brdcst_addr != NULL) {
3106 3147                          mac_bcast_delete(mcip, mip->mi_type->mt_brdcst_addr,
3107 3148                              muip->mui_vid);
3108 3149                  }
3109 3150  
3110 3151                  FLOW_FINAL_REFRELE(flent);
3111 3152                  ASSERT(!(mcip->mci_state_flags & MCIS_EXCLUSIVE));
     3153 +
3112 3154                  /*
3113 3155                   * Enable fastpath if this is a VNIC or a VLAN.
3114 3156                   */
3115 3157                  if (mcip->mci_state_flags & MCIS_IS_VNIC)
3116 3158                          mac_fastpath_enable((mac_handle_t)mip);
3117 3159                  mac_stop((mac_handle_t)mip);
3118 3160                  i_mac_perim_exit(mip);
3119 3161                  return (0);
3120 3162          }
3121 3163  
3122 3164          mui_vid = muip->mui_vid;
3123 3165          mac_client_datapath_teardown(mch, muip, flent);
3124 3166  
3125      -        if ((mcip->mci_flags & MAC_CLIENT_FLAGS_PRIMARY) && mui_vid == 0) {
     3167 +        if ((mcip->mci_flags & MAC_CLIENT_FLAGS_PRIMARY) &&
     3168 +            mui_vid == VLAN_ID_NONE) {
3126 3169                  mcip->mci_flags &= ~MAC_CLIENT_FLAGS_PRIMARY;
3127 3170          } else {
3128 3171                  i_mac_perim_exit(mip);
3129 3172                  return (0);
3130 3173          }
3131 3174  
3132 3175          /*
3133 3176           * If we are removing the primary, check if we have a passive primary
3134 3177           * client that we need to activate now.
3135 3178           */
↓ open down ↓ 2441 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX