Пример #1
0
static int
i40e_pf_host_process_cmd_config_promisc_mode(
					struct i40e_pf_vf *vf,
					uint8_t *msg,
					uint16_t msglen)
{
	int ret = I40E_SUCCESS;
	struct i40e_virtchnl_promisc_info *promisc =
				(struct i40e_virtchnl_promisc_info *)msg;
	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
	bool unicast = FALSE, multicast = FALSE;

	if (msg == NULL || msglen != sizeof(*promisc)) {
		ret = I40E_ERR_PARAM;
		goto send_msg;
	}

	if (promisc->flags & I40E_FLAG_VF_UNICAST_PROMISC)
		unicast = TRUE;
	ret = i40e_aq_set_vsi_unicast_promiscuous(hw,
			vf->vsi->seid, unicast, NULL);
	if (ret != I40E_SUCCESS)
		goto send_msg;

	if (promisc->flags & I40E_FLAG_VF_MULTICAST_PROMISC)
		multicast = TRUE;
	ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid,
						multicast, NULL);

send_msg:
	i40e_pf_host_send_msg_to_vf(vf,
		I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, ret, NULL, 0);

	return ret;
}
Пример #2
0
/*
 * See the big theory statement in i40e_main.c for multicast address management.
 */
static int
i40e_multicast_add(i40e_t *i40e, const uint8_t *multicast_address)
{
	struct i40e_hw *hw = &i40e->i40e_hw_space;
	struct i40e_aqc_add_macvlan_element_data filt;
	i40e_maddr_t *mc;
	int ret;

	ASSERT(MUTEX_HELD(&i40e->i40e_general_lock));

	if (i40e->i40e_resources.ifr_nmcastfilt_used ==
	    i40e->i40e_resources.ifr_nmcastfilt) {
		if (i40e->i40e_mcast_promisc_count == 0 &&
		    i40e->i40e_promisc_on == B_FALSE) {
			ret = i40e_aq_set_vsi_multicast_promiscuous(hw,
			    i40e->i40e_vsi_id, B_TRUE, NULL);
			if (ret != I40E_SUCCESS) {
				i40e_error(i40e, "failed to enable multicast "
				    "promiscuous mode on VSI %d: %d",
				    i40e->i40e_vsi_id, ret);
				return (EIO);
			}
		}
		i40e->i40e_mcast_promisc_count++;
		return (0);
	}

	mc = &i40e->i40e_maddrs[i40e->i40e_resources.ifr_nmcastfilt_used];
	bzero(&filt, sizeof (filt));
	bcopy(multicast_address, filt.mac_addr, ETHERADDRL);
	filt.flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH |
	    I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;

	if ((ret = i40e_aq_add_macvlan(hw, i40e->i40e_vsi_id, &filt, 1,
	    NULL)) != I40E_SUCCESS) {
		i40e_error(i40e, "failed to add mac address "
		    "%2x:%2x:%2x:%2x:%2x:%2x to multicast filter: %d",
		    multicast_address[0], multicast_address[1],
		    multicast_address[2], multicast_address[3],
		    multicast_address[4], multicast_address[5],
		    ret);
		return (EIO);
	}

	bcopy(multicast_address, mc->ima_mac, ETHERADDRL);
	i40e->i40e_resources.ifr_nmcastfilt_used++;
	return (0);
}
Пример #3
0
/*
 * See the big theory statement in i40e_main.c for multicast address management.
 */
static int
i40e_multicast_remove(i40e_t *i40e, const uint8_t *multicast_address)
{
	int i, ret;
	struct i40e_hw *hw = &i40e->i40e_hw_space;

	ASSERT(MUTEX_HELD(&i40e->i40e_general_lock));

	for (i = 0; i < i40e->i40e_resources.ifr_nmcastfilt_used; i++) {
		struct i40e_aqc_remove_macvlan_element_data filt;
		int last;

		if (bcmp(multicast_address, i40e->i40e_maddrs[i].ima_mac,
		    ETHERADDRL) != 0) {
			continue;
		}

		bzero(&filt, sizeof (filt));
		bcopy(multicast_address, filt.mac_addr, ETHERADDRL);
		filt.flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH |
		    I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;

		if (i40e_aq_remove_macvlan(hw, i40e->i40e_vsi_id,
		    &filt, 1, NULL) != I40E_SUCCESS) {
			i40e_error(i40e, "failed to remove mac address "
			    "%2x:%2x:%2x:%2x:%2x:%2x from multicast "
			    "filter: %d",
			    multicast_address[0], multicast_address[1],
			    multicast_address[2], multicast_address[3],
			    multicast_address[4], multicast_address[5],
			    filt.error_code);
			return (EIO);
		}

		last = i40e->i40e_resources.ifr_nmcastfilt_used - 1;
		if (i != last) {
			bcopy(&i40e->i40e_maddrs[last], &i40e->i40e_maddrs[i],
			    sizeof (i40e_maddr_t));
			bzero(&i40e->i40e_maddrs[last], sizeof (i40e_maddr_t));
		}

		ASSERT(i40e->i40e_resources.ifr_nmcastfilt_used > 0);
		i40e->i40e_resources.ifr_nmcastfilt_used--;
		return (0);
	}

	if (i40e->i40e_mcast_promisc_count > 0) {
		if (i40e->i40e_mcast_promisc_count == 1 &&
		    i40e->i40e_promisc_on == B_FALSE) {
			ret = i40e_aq_set_vsi_multicast_promiscuous(hw,
			    i40e->i40e_vsi_id, B_FALSE, NULL);
			if (ret != I40E_SUCCESS) {
				i40e_error(i40e, "failed to disable "
				    "multicast promiscuous mode on VSI %d: %d",
				    i40e->i40e_vsi_id, ret);
				return (EIO);
			}
		}
		i40e->i40e_mcast_promisc_count--;

		return (0);
	}

	return (ENOENT);
}
Пример #4
0
/*
 * Enable and disable promiscuous mode as requested. We have to toggle both
 * unicast and multicast. Note that multicast may already be enabled due to the
 * i40e_m_multicast may toggle it itself. See i40e_main.c for more information
 * on this.
 */
static int
i40e_m_promisc(void *arg, boolean_t on)
{
	i40e_t *i40e = arg;
	struct i40e_hw *hw = &i40e->i40e_hw_space;
	int ret = 0, err = 0;

	mutex_enter(&i40e->i40e_general_lock);
	if (i40e->i40e_state & I40E_SUSPENDED) {
		ret = ECANCELED;
		goto done;
	}


	ret = i40e_aq_set_vsi_unicast_promiscuous(hw, i40e->i40e_vsi_id,
	    on, NULL);
	if (ret != I40E_SUCCESS) {
		i40e_error(i40e, "failed to %s unicast promiscuity on "
		    "the default VSI: %d", on == B_TRUE ? "enable" : "disable",
		    ret);
		err = EIO;
		goto done;
	}

	/*
	 * If we have a non-zero mcast_promisc_count, then it has already been
	 * enabled or we need to leave it that way and not touch it.
	 */
	if (i40e->i40e_mcast_promisc_count > 0) {
		i40e->i40e_promisc_on = on;
		goto done;
	}

	ret = i40e_aq_set_vsi_multicast_promiscuous(hw, i40e->i40e_vsi_id,
	    on, NULL);
	if (ret != I40E_SUCCESS) {
		i40e_error(i40e, "failed to %s multicast promiscuity on "
		    "the default VSI: %d", on == B_TRUE ? "enable" : "disable",
		    ret);

		/*
		 * Try our best to put us back into a state that MAC expects us
		 * to be in.
		 */
		ret = i40e_aq_set_vsi_unicast_promiscuous(hw, i40e->i40e_vsi_id,
		    !on, NULL);
		if (ret != I40E_SUCCESS) {
			i40e_error(i40e, "failed to %s unicast promiscuity on "
			    "the default VSI after toggling multicast failed: "
			    "%d", on == B_TRUE ? "disable" : "enable", ret);
		}

		err = EIO;
		goto done;
	} else {
		i40e->i40e_promisc_on = on;
	}

done:
	mutex_exit(&i40e->i40e_general_lock);
	return (err);
}