4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai/*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * CDDL HEADER START
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai *
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * The contents of this file are subject to the terms of the
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Common Development and Distribution License (the "License").
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * You may not use this file except in compliance with the License.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai *
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * or http://www.opensolaris.org/os/licensing.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * See the License for the specific language governing permissions
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * and limitations under the License.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai *
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * When distributing Covered Code, include this CDDL HEADER in each
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * If applicable, add the following below this CDDL HEADER, with the
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * fields enclosed by brackets "[]" replaced with your own identifying
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * information: Portions Copyright [yyyy] [name of copyright owner]
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai *
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * CDDL HEADER END
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai/*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Use is subject to license terms.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai/*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * bridged - bridging control daemon. This module provides DLPI-specific
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * functions for interface to libdlpi.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <stdio.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <stdlib.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <unistd.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <string.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <sys/types.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <syslog.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <stropts.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <stp_in.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <net/if_types.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <net/if_dl.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <sys/ethernet.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include <sys/pfmod.h>
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#include "global.h"
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaistatic const uchar_t bridge_group_address[] = BRIDGE_GROUP_ADDRESS;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaistatic const ushort_t bpdu_filter[] = {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ENF_PUSHWORD | 0, /* check for 1:80:c2:0:0:0 dest. */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ENF_PUSHLIT | ENF_CAND,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#ifdef _BIG_ENDIAN
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai 0x0180,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#else
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai 0x8001,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#endif
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ENF_PUSHWORD | 1,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ENF_PUSHLIT | ENF_CAND,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#ifdef _BIG_ENDIAN
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai 0xC200,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#else
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai 0x00C2,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#endif
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ENF_PUSHWORD | 2,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ENF_PUSHZERO | ENF_CAND,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ENF_PUSHWORD | 7, /* check for SSAP/DSAP 42 42 */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ENF_PUSHLIT | ENF_CAND,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai 0x4242,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai};
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai/*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Because we're called by dlpi_recv(), we're called with the engine lock held.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai/*ARGSUSED*/
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaistatic void
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaidlpi_notify(dlpi_handle_t dlpi, dlpi_notifyinfo_t *info, void *arg)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai{
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai struct portdata *port = arg;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai int rc;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai switch (info->dni_note) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai case DL_NOTE_SPEED:
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* libdlpi gives us Kbps, and we want Mbps */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (port->speed == info->dni_speed / 1000)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->speed = info->dni_speed / 1000;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if ((rc = STP_IN_changed_port_speed(port->port_index,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->speed)) != 0)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_ERR, "STP can't change port speed on %s: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->name, STP_IN_get_error_explanation(rc));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai case DL_NOTE_PHYS_ADDR:
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (memcmp(info->dni_physaddr, port->mac_addr, ETHERADDRL) != 0)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai rstp_change_mac(port, info->dni_physaddr);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai case DL_NOTE_LINK_DOWN:
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (!port->phys_status)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->phys_status = B_FALSE;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (!port->admin_status || protect != DLADM_BRIDGE_PROT_STP ||
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->sdu_failed)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if ((rc = STP_IN_enable_port(port->port_index, False)) != 0)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_ERR, "STP can't disable port %s: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->name, STP_IN_get_error_explanation(rc));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai case DL_NOTE_LINK_UP:
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (port->phys_status)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->phys_status = B_TRUE;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (!port->admin_status || protect != DLADM_BRIDGE_PROT_STP ||
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->sdu_failed) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->bpdu_protect = B_FALSE;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * If we're not running STP, and the link state has just come
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * up, then clear out any protection shutdown state, and allow
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * us to forward again.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (port->admin_non_stp && port->bpdu_protect) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->bpdu_protect = B_FALSE;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai enable_forwarding(port);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if ((rc = STP_IN_enable_port(port->port_index, True)) != 0)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_ERR, "STP can't enable port %s: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->name, STP_IN_get_error_explanation(rc));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai break;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai}
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaiboolean_t
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaiport_dlpi_open(const char *portname, struct portdata *port,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai datalink_class_t class)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai{
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai uchar_t addrbuf[DLPI_PHYSADDR_MAX];
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai size_t alen = DLPI_PHYSADDR_MAX;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai int rc;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai char addrstr[ETHERADDRL * 3];
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * We use DLPI 'raw' mode so that we get access to the received
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Ethernet 802 length field. libdlpi otherwise eats this value. Note
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * that 'raw' mode support is required in order to use snoop, so it's
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * expected to be common, even if it's not documented.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai rc = dlpi_open(portname, &port->dlpi, DLPI_RAW);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (rc != DLPI_SUCCESS) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_ERR, "can't open %s: %s", portname,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai dlpi_strerror(rc));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai return (B_FALSE);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->phys_status = B_TRUE;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->sdu_failed = B_FALSE;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->bpdu_protect = B_FALSE;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Now that the driver is open, we can get at least the initial value
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * of the interface speed. We need to do this before establishing the
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * notify callback, so that it can update us later.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai get_dladm_speed(port);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Save off the libdlpi port name, as it's dynamically allocated, and
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * the name we're passed is not.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->name = dlpi_linkname(port->dlpi);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /*
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * We can't bind SAP 0 or enable multicast on an etherstub. It's ok,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * though, because there's no real hardware involved.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (class != DATALINK_CLASS_ETHERSTUB) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if ((rc = dlpi_bind(port->dlpi, 0, NULL)) != DLPI_SUCCESS) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_ERR, "can't bind %s: %s", portname,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai dlpi_strerror(rc));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai return (B_FALSE);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if ((rc = dlpi_enabmulti(port->dlpi, bridge_group_address,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai sizeof (bridge_group_address))) != DLPI_SUCCESS) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_ERR, "can't enable multicast on %s: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai portname, dlpi_strerror(rc));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai return (B_FALSE);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if ((rc = dlpi_enabnotify(port->dlpi,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai DL_NOTE_PHYS_ADDR | DL_NOTE_LINK_DOWN | DL_NOTE_LINK_UP |
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai DL_NOTE_SPEED, dlpi_notify, port, &port->notifyid)) !=
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai DLPI_SUCCESS) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_WARNING, "no DLPI notification on %s: %s", portname,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai dlpi_strerror(rc));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai rc = dlpi_get_physaddr(port->dlpi, DL_CURR_PHYS_ADDR, addrbuf, &alen);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (rc != DLPI_SUCCESS) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_ERR, "unable to get MAC address on %s: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->name, dlpi_strerror(rc));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai return (B_FALSE);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (alen != ETHERADDRL) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_ERR, "bad MAC address length %d on %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai alen, port->name);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai return (B_FALSE);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai (void) memcpy(port->mac_addr, addrbuf, ETHERADDRL);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (class != DATALINK_CLASS_ETHERSTUB) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai int fd = dlpi_fd(port->dlpi);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai int lowflag = 1;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (strioctl(fd, DLIOCLOWLINK, &lowflag, sizeof (lowflag)) != 0)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_WARNING, "low-link notify failed on %s: %m",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai portname);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (ioctl(fd, I_PUSH, "pfmod") == 0) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai struct packetfilt pf;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai pf.Pf_Priority = 0;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai pf.Pf_FilterLen = sizeof (bpdu_filter) /
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai sizeof (*bpdu_filter);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai (void) memcpy(pf.Pf_Filter, bpdu_filter,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai sizeof (bpdu_filter));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (strioctl(fd, PFIOCSETF, &pf, sizeof (pf)) == -1)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_WARNING,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai "pfil ioctl failed on %s: %m", portname);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai } else {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_WARNING, "pfil push failed on %s: %m",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai portname);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (debugging) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai (void) _link_ntoa(port->mac_addr, addrstr, ETHERADDRL,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai IFT_OTHER);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai syslog(LOG_DEBUG, "got MAC address %s on %s", addrstr,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->name);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai }
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai return (B_TRUE);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai}