Example #1
0
avb_status_t avb_1722_1_adp_advertising_periodic(chanend c_tx, chanend ptp)
{
	guid_t ptp_current;

	switch (adp_advertise_state)
	{
		case ADP_ADVERTISE_IDLE:
			break;

		case ADP_ADVERTISE_WAITING:
			if (avb_timer_expired(&adp_readvertise_timer))
			{
				adp_advertise_state = ADP_ADVERTISE_ADVERTISE_1;
			}
			break;

		case ADP_ADVERTISE_ADVERTISE_0:
			avb_1722_1_adp_change_ptp_grandmaster(ptp_current.c);
			start_avb_timer(&ptp_monitor_timer, 1); //Every second
			adp_advertise_state = ADP_ADVERTISE_ADVERTISE_1;
			// Fall through and send immediately

		case ADP_ADVERTISE_ADVERTISE_1:
			avb_1722_1_create_adp_packet(ENTITY_AVAILABLE, my_guid);
			mac_tx(c_tx, avb_1722_1_buf, AVB_1722_1_ADP_PACKET_SIZE, ETH_BROADCAST);

			start_avb_timer(&adp_readvertise_timer, AVB_1722_1_ADP_REPEAT_TIME);
			adp_advertise_state = ADP_ADVERTISE_WAITING;
			avb_1722_1_available_index++;
			break;

		case ADP_ADVERTISE_DEPARTING:
			avb_1722_1_create_adp_packet(ENTITY_DEPARTING, my_guid);
			mac_tx(c_tx, avb_1722_1_buf, AVB_1722_1_ADP_PACKET_SIZE, ETH_BROADCAST);

			adp_advertise_state = ADP_ADVERTISE_IDLE;
			avb_1722_1_available_index = 0;

			break;

		default:
			break;
	}

	if (ADP_ADVERTISE_IDLE != adp_advertise_state)
	{
		if(avb_timer_expired(&ptp_monitor_timer))
		{
			ptp_get_current_grandmaster(ptp, ptp_current.c);
			if(as_grandmaster_id.l != ptp_current.l)
			{
				avb_1722_1_adp_change_ptp_grandmaster(ptp_current.c);
				adp_advertise_state = ADP_ADVERTISE_ADVERTISE_1;
			}
			start_avb_timer(&ptp_monitor_timer, 1); //Every second
		}
	}

	return AVB_NO_STATUS;
}
Example #2
0
static int
mac_bpf_tx(uintptr_t chandle, mblk_t *pkt)
{
	/*
	 * If the mac layer cannot deliver a packet as requested by BPF then
	 * simply have the mac layer drop it. BPF isn't interested in doing
	 * any amount of retry - that's left to the application.
	 */
	return (mac_tx((mac_client_handle_t)chandle, pkt, 0,
	    MAC_DROP_ON_NO_DESC, NULL));
}
Example #3
0
avb_status_t process_avb_1722_1_aecp_packet(unsigned char dest_addr[6], avb_1722_1_aecp_packet_t *pkt, chanend c_tx)
{
	int message_type = GET_1722_1_MSG_TYPE(((avb_1722_1_packet_header_t*)pkt));
	if (compare_guid(pkt->target_guid, &my_guid)==0) return AVB_1722_1_OK;

	switch (message_type)
	{
		case AECP_CMD_AVDECC_MSG_COMMAND:
		{
			avb_1722_1_aecp_avdecc_msg_t *msg = &(pkt->data.avdecc);
			process_avb_1722_1_aecp_avdecc_msg(msg);
			break;
		}
		case AECP_CMD_ADDRESS_ACCESS_COMMAND:
		{
			break;
		}
		case AECP_CMD_AVC_COMMAND:
		{
# if AVB_1722_1_USE_AVC
			uint32_t length = 0 ;
			struct ethernet_hdr_t *eth_hdr = (ethernet_hdr_t*) &avb_1722_1_buf[0];
			avb_1722_1_packet_header_t *pkt_hdr = (avb_1722_1_packet_header_t*) (eth_hdr + 1);
			avb_1722_1_aecp_avc_t* payload = (avb_1722_1_aecp_avc_t*)avb_1722_1_create_aecp_packet(dest_addr, AECP_CMD_AVC_RESPONSE, pkt);
			bcopy(pkt->data.payload, payload, 514);
			length = ((uint32_t)payload->avc_length[0] << 8) | payload->avc_length[1];
			processAVCCommand(payload->avc_command_response, &length);
			payload->avc_length[0] = (length >> 8) & 0xff;
			payload->avc_length[1] = length & 0xff;
			SET_1722_1_DATALENGTH(pkt_hdr, length+12);
			mac_tx(c_tx, avb_1722_1_buf, sizeof(ethernet_hdr_t)+sizeof(avb_1722_1_packet_header_t)+36+length, ETH_BROADCAST);
#endif
			break;
		}
		case AECP_CMD_VENDOR_UNIQUE_COMMAND:
		{
			break;
		}
		case AECP_CMD_EXTENDED_COMMAND:
		{
			break;
		}
		default:
			// This node is not expecting a response
			break;
	}
	return AVB_1722_1_OK;
}
Example #4
0
/*
 * Send a message out over the physical device
 * via the MAC layer.
 *
 * Returns any mblks that it was unable to transmit.
 */
mblk_t *
vsw_tx_msg(vsw_t *vswp, mblk_t *mp, int caller, vsw_port_t *port)
{
	mac_client_handle_t	mch;
	mac_unicast_handle_t	muh;

	READ_MACCL_ENTER(vswp, port, caller);

	mch = (caller == VSW_LOCALDEV) ? vswp->mch : port->p_mch;
	muh = (caller == VSW_LOCALDEV) ? vswp->muh : port->p_muh;

	if (mch == NULL || muh == NULL) {
		RW_MACCL_EXIT(vswp, port, caller);
		return (mp);
	}

	/* packets are sent or dropped */
	(void) mac_tx(mch, mp, 0, MAC_DROP_ON_NO_DESC, NULL);
	RW_MACCL_EXIT(vswp, port, caller);
	return (NULL);
}
Example #5
0
/*
 * Packets from the peer come here.  We pass them to the mac device.
 */
static void
xnbo_to_mac(xnb_t *xnbp, mblk_t *mp)
{
	xnbo_t *xnbop = xnbp->xnb_flavour_data;

	ASSERT(mp != NULL);

	if (!xnbop->o_running) {
		xnbp->xnb_stat_tx_too_early++;
		goto fail;
	}

	if (mac_tx(xnbop->o_mch, mp, 0,
	    MAC_DROP_ON_NO_DESC, NULL) != NULL) {
		xnbp->xnb_stat_mac_full++;
	}

	return;

fail:
	freemsgchain(mp);
}
Example #6
0
avb_status_t avb_1722_1_adp_discovery_periodic(chanend c_tx)
{
	switch (adp_discovery_state)
	{
		case ADP_DISCOVERY_IDLE:
			break;

		case ADP_DISCOVERY_WAITING:
		{
			unsigned lost=0;
			if (avb_timer_expired(&adp_discovery_timer))
			{
				adp_two_second_counter++;
				lost = avb_1722_1_entity_database_check_timeout();
				start_avb_timer(&adp_discovery_timer, 1);
			}
			return (lost > 0) ? AVB_1722_1_ENTITY_REMOVED : AVB_NO_STATUS;
		}
		case ADP_DISCOVERY_DISCOVER:
		{
				avb_1722_1_create_adp_packet(ENTITY_DISCOVER, discover_guid);
				mac_tx(c_tx, avb_1722_1_buf, AVB_1722_1_ADP_PACKET_SIZE, ETH_BROADCAST);
				adp_discovery_state = ADP_DISCOVERY_WAITING;
				break;
		}
		case ADP_DISCOVERY_ADDED:
		{
			adp_discovery_state = ADP_DISCOVERY_WAITING;
			return AVB_1722_1_ENTITY_ADDED;
		}
		case ADP_DISCOVERY_REMOVED:
		{
			adp_discovery_state = ADP_DISCOVERY_WAITING;
			return AVB_1722_1_ENTITY_REMOVED;
		}
	}

	return AVB_NO_STATUS;
}
Example #7
0
// this forces the sending of the current PDU.  this happens when
// that PDU has had all of the attributes that it is going to get,
// or when adding an attribute has filled the PDU up.
static void force_send(chanend c_tx)
{
  char *buf = &send_buf[0];
  char *ptr = send_ptr;

  // Strip out attribute length fields for MMRP and MVRP
  strip_attribute_list_length_fields();

  if (ptr != buf+sizeof(mrp_ethernet_hdr)+sizeof(mrp_header)) {

	// Check that the buffer is long enough for a valid ethernet packet
    char *end = ptr + 4;
    if (end < buf + 64) end = buf + 64;

    // Pad with zero if necessary
    for (char *p = ptr;p<end;p++) *p = 0;

    // Transmit
    mac_tx(c_tx, (unsigned int *) buf, end - buf, ETH_BROADCAST);
  }
  send_ptr = buf+sizeof(mrp_ethernet_hdr)+sizeof(mrp_header);
  return;
}
/* ARGSUSED */
static int
sdpfp_senduio(sock_lower_handle_t handle, struct uio *uiop,
    struct nmsghdr *msg, struct cred *cred)
{
	struct sockaddr_ll *sol;
	mac_client_handle_t mch;
	struct pfpsock *ps;
	boolean_t new_open;
	mac_handle_t mh;
	size_t mpsize;
	uint_t maxsdu;
	mblk_t *mp0;
	mblk_t *mp;
	int error;

	mp = NULL;
	mp0 = NULL;
	new_open = B_FALSE;
	ps = (struct pfpsock *)handle;
	mh = ps->ps_mh;
	mch = ps->ps_mch;
	maxsdu = ps->ps_max_sdu;

	sol = (struct sockaddr_ll *)msg->msg_name;
	if (sol == NULL) {
		/*
		 * If no sockaddr_ll has been provided with the send call,
		 * use the one constructed when the socket was bound to an
		 * interface and fail if it hasn't been bound.
		 */
		if (!ps->ps_bound) {
			ks_stats.kp_send_unbound.value.ui64++;
			return (EPROTO);
		}
		sol = (struct sockaddr_ll *)&ps->ps_sock;
	} else {
		/*
		 * Verify the sockaddr_ll message passed down before using
		 * it to send a packet out with. If it refers to an interface
		 * that has not been bound, it is necessary to open it.
		 */
		struct sockaddr_ll *sll;

		if (msg->msg_namelen < sizeof (struct sockaddr_ll)) {
			ks_stats.kp_send_short_msg.value.ui64++;
			return (EINVAL);
		}

		if (sol->sll_family != AF_PACKET) {
			ks_stats.kp_send_wrong_family.value.ui64++;
			return (EAFNOSUPPORT);
		}

		sll = (struct sockaddr_ll *)&ps->ps_sock;
		if (sol->sll_ifindex != sll->sll_ifindex) {
			error = pfp_open_index(sol->sll_ifindex, &mh, &mch,
			    cred);
			if (error != 0) {
				ks_stats.kp_send_open_fail.value.ui64++;
				return (error);
			}
			mac_sdu_get(mh, NULL, &maxsdu);
			new_open = B_TRUE;
		}
	}

	mpsize = uiop->uio_resid;
	if (mpsize > maxsdu) {
		ks_stats.kp_send_too_big.value.ui64++;
		error = EMSGSIZE;
		goto done;
	}

	if ((mp = allocb(mpsize, BPRI_HI)) == NULL) {
		ks_stats.kp_send_alloc_fail.value.ui64++;
		error = ENOBUFS;
		goto done;
	}

	mp->b_wptr = mp->b_rptr + mpsize;
	error = uiomove(mp->b_rptr, mpsize, UIO_WRITE, uiop);
	if (error != 0) {
		ks_stats.kp_send_uiomove_fail.value.ui64++;
		goto done;
	}

	if (ps->ps_type == SOCK_DGRAM) {
		mp0 = mac_header(mh, sol->sll_addr, sol->sll_protocol, mp, 0);
		if (mp0 == NULL) {
			ks_stats.kp_send_no_memory.value.ui64++;
			error = ENOBUFS;
			goto done;
		}
		linkb(mp0, mp);
		mp = mp0;
	}

	/*
	 * As this is sending datagrams and no promise is made about
	 * how or if a packet will be sent/delivered, no effort is to
	 * be expended in recovering from a situation where the packet
	 * cannot be sent - it is just dropped.
	 */
	error = mac_tx(mch, mp, 0, MAC_DROP_ON_NO_DESC, NULL);
	if (error == 0) {
		mp = NULL;
		ks_stats.kp_send_ok.value.ui64++;
	} else {
		ks_stats.kp_send_failed.value.ui64++;
	}

done:

	if (new_open) {
		ASSERT(mch != ps->ps_mch);
		ASSERT(mh != ps->ps_mh);
		pfp_close(mh, mch);
	}
	if (mp != NULL)
		freemsg(mp);

	return (error);

}