Ejemplo n.º 1
0
errno_t
ifnet_allocate(
	const struct ifnet_init_params *init,
	ifnet_t *interface)
{
	int error;
	struct ifnet *ifp = NULL;
	
	if (init->family == 0)
		return EINVAL;
	if (init->name == NULL ||
		init->output == NULL)
		return EINVAL;
	if (strlen(init->name) >= IFNAMSIZ)
		return EINVAL;
	if ((init->type & 0xFFFFFF00) != 0 || init->type == 0)
		return EINVAL;
	
	error = dlil_if_acquire(init->family, init->uniqueid, init->uniqueid_len, &ifp);
	if (error == 0)
	{
		/*
		 * Cast ifp->if_name as non const. dlil_if_acquire sets it up
		 * to point to storage of at least IFNAMSIZ bytes. It is safe
		 * to write to this.
		 */
		strncpy(_cast_non_const(ifp->if_name), init->name, IFNAMSIZ);
		ifp->if_type = init->type;
		ifp->if_family = init->family;
		ifp->if_unit = init->unit;
		ifp->if_output = init->output;
		ifp->if_demux = init->demux;
		ifp->if_add_proto = init->add_proto;
		ifp->if_del_proto = init->del_proto;
		ifp->if_check_multi = init->check_multi;
		ifp->if_framer = init->framer;
		ifp->if_softc = init->softc;
		ifp->if_ioctl = init->ioctl;
		ifp->if_set_bpf_tap = init->set_bpf_tap;
		ifp->if_free = ifnet_kpi_free;
		ifp->if_event = init->event;
		ifp->if_kpi_storage = init->detach;
		ifp->if_eflags |= IFEF_USEKPI;
		
		if (init->broadcast_len && init->broadcast_addr) {
			if (init->broadcast_len > sizeof(ifp->if_broadcast.u.buffer)) {
				MALLOC(ifp->if_broadcast.u.ptr, u_char*, init->broadcast_len, M_IFADDR, M_NOWAIT);
				if (ifp->if_broadcast.u.ptr == NULL) {
					error = ENOMEM;
				}
				else {
					bcopy(init->broadcast_addr, ifp->if_broadcast.u.ptr, init->broadcast_len);
				}
			}
			else {
Ejemplo n.º 2
0
errno_t
ifnet_allocate_extended(const struct ifnet_init_eparams *einit0,
    ifnet_t *interface)
{
	struct ifnet_init_eparams einit;
	struct ifnet *ifp = NULL;
	int error;

	einit = *einit0;

	if (einit.ver != IFNET_INIT_CURRENT_VERSION ||
	    einit.len < sizeof (einit))
		return (EINVAL);

	if (einit.family == 0 || einit.name == NULL ||
	    strlen(einit.name) >= IFNAMSIZ ||
	    (einit.type & 0xFFFFFF00) != 0 || einit.type == 0)
		return (EINVAL);

	if (einit.flags & IFNET_INIT_LEGACY) {
		if (einit.output == NULL || einit.flags != IFNET_INIT_LEGACY)
			return (EINVAL);

		einit.pre_enqueue = NULL;
		einit.start = NULL;
		einit.output_ctl = NULL;
		einit.output_sched_model = IFNET_SCHED_MODEL_NORMAL;
		einit.input_poll = NULL;
		einit.input_ctl = NULL;
	} else {
		if (einit.start == NULL)
			return (EINVAL);

		einit.output = NULL;
		if (einit.output_sched_model >= IFNET_SCHED_MODEL_MAX)
			return (EINVAL);

		if (einit.flags & IFNET_INIT_INPUT_POLL) {
			if (einit.input_poll == NULL || einit.input_ctl == NULL)
				return (EINVAL);
		} else {
			einit.input_poll = NULL;
			einit.input_ctl = NULL;
		}
	}

	error = dlil_if_acquire(einit.family, einit.uniqueid,
	    einit.uniqueid_len, &ifp);

	if (error == 0) {
		u_int64_t br;

		/*
		 * Cast ifp->if_name as non const. dlil_if_acquire sets it up
		 * to point to storage of at least IFNAMSIZ bytes. It is safe
		 * to write to this.
		 */
		strncpy(_cast_non_const(ifp->if_name), einit.name, IFNAMSIZ);
		ifp->if_type		= einit.type;
		ifp->if_family		= einit.family;
		ifp->if_unit		= einit.unit;
		ifp->if_output		= einit.output;
		ifp->if_pre_enqueue	= einit.pre_enqueue;
		ifp->if_start		= einit.start;
		ifp->if_output_ctl	= einit.output_ctl;
		ifp->if_output_sched_model = einit.output_sched_model;
		ifp->if_output_bw.eff_bw = einit.output_bw;
		ifp->if_output_bw.max_bw = einit.output_bw_max;
		ifp->if_input_poll	= einit.input_poll;
		ifp->if_input_ctl	= einit.input_ctl;
		ifp->if_input_bw.eff_bw	= einit.input_bw;
		ifp->if_input_bw.max_bw	= einit.input_bw_max;
		ifp->if_demux		= einit.demux;
		ifp->if_add_proto	= einit.add_proto;
		ifp->if_del_proto	= einit.del_proto;
		ifp->if_check_multi	= einit.check_multi;
		ifp->if_framer		= einit.framer;
		ifp->if_softc		= einit.softc;
		ifp->if_ioctl		= einit.ioctl;
		ifp->if_set_bpf_tap	= einit.set_bpf_tap;
		ifp->if_free		= ifnet_kpi_free;
		ifp->if_event		= einit.event;
		ifp->if_kpi_storage	= einit.detach;

		if (ifp->if_output_bw.eff_bw > ifp->if_output_bw.max_bw)
			ifp->if_output_bw.max_bw = ifp->if_output_bw.eff_bw;
		else if (ifp->if_output_bw.eff_bw == 0)
			ifp->if_output_bw.eff_bw = ifp->if_output_bw.max_bw;

		if (ifp->if_input_bw.eff_bw > ifp->if_input_bw.max_bw)
			ifp->if_input_bw.max_bw = ifp->if_input_bw.eff_bw;
		else if (ifp->if_input_bw.eff_bw == 0)
			ifp->if_input_bw.eff_bw = ifp->if_input_bw.max_bw;

		if (ifp->if_output_bw.max_bw == 0)
			ifp->if_output_bw = ifp->if_input_bw;
		else if (ifp->if_input_bw.max_bw == 0)
			ifp->if_input_bw = ifp->if_output_bw;

		if (ifp->if_ioctl == NULL)
			ifp->if_ioctl = ifp_if_ioctl;

		/* Pin if_baudrate to 32 bits */
		br = MAX(ifp->if_output_bw.max_bw, ifp->if_input_bw.max_bw);
		if (br != 0)
			ifp->if_baudrate = (br > 0xFFFFFFFF) ? 0xFFFFFFFF : br;

		if (ifp->if_start != NULL) {
			ifp->if_eflags |= IFEF_TXSTART;
			if (ifp->if_pre_enqueue == NULL)
				ifp->if_pre_enqueue = ifnet_enqueue;
			ifp->if_output = ifp->if_pre_enqueue;
		} else {
			ifp->if_eflags &= ~IFEF_TXSTART;
		}

		if (ifp->if_input_poll != NULL)
			ifp->if_eflags |= IFEF_RXPOLL;
		else
			ifp->if_eflags &= ~IFEF_RXPOLL;

		VERIFY(!(einit.flags & IFNET_INIT_LEGACY) ||
		    (ifp->if_pre_enqueue == NULL && ifp->if_start == NULL &&
		    ifp->if_output_ctl == NULL && ifp->if_input_poll == NULL &&
		    ifp->if_input_ctl == NULL));
		VERIFY(!(einit.flags & IFNET_INIT_INPUT_POLL) ||
		    (ifp->if_input_poll != NULL && ifp->if_input_ctl != NULL));

		if (einit.broadcast_len && einit.broadcast_addr) {
			if (einit.broadcast_len >
			    sizeof (ifp->if_broadcast.u.buffer)) {
				MALLOC(ifp->if_broadcast.u.ptr, u_char *,
				    einit.broadcast_len, M_IFADDR, M_NOWAIT);
				if (ifp->if_broadcast.u.ptr == NULL) {
					error = ENOMEM;
				} else {
					bcopy(einit.broadcast_addr,
					    ifp->if_broadcast.u.ptr,
					    einit.broadcast_len);
				}
			} else {