Beispiel #1
0
static int
dlcosmk_invoke_action(ipp_action_id_t aid, ipp_packet_t *packet)
{
	dlcosmk_data_t *dlcosmk_data;
	mblk_t *mp = NULL;
	int err;
	ip_priv_t *priv;

	ASSERT(packet != NULL);

	/* get mblk from ipp_packet structure */
	mp = ipp_packet_get_data(packet);
	priv = (ip_priv_t *)ipp_packet_get_private(packet);

	dlcosmk_data = (dlcosmk_data_t *)ipp_action_get_ptr(aid);
	ASSERT(dlcosmk_data != NULL);

	/* dlcosmk packet as configured */
	if ((err = dlcosmk_process(&mp, dlcosmk_data, priv->ill_index,
	    priv->proc)) != 0) {
		return (err);
	} else {
		/* return packet with next action set */
		return (ipp_packet_next(packet, dlcosmk_data->next_action));
	}
}
/* ARGSUSED */
static int
ipgpc_invoke_action(ipp_action_id_t aid, ipp_packet_t *packet)
{
	ipgpc_class_t *out_class;
	hrtime_t start, end;
	mblk_t *mp = NULL;
	ip_priv_t *priv = NULL;
	ill_t *ill = NULL;
	ipha_t *ipha;
	ip_proc_t callout_pos;
	int af;
	int rc;
	ipgpc_packet_t pkt;
	uint_t ill_idx;

	/* extract packet data */
	mp = ipp_packet_get_data(packet);
	ASSERT(mp != NULL);

	priv = (ip_priv_t *)ipp_packet_get_private(packet);
	ASSERT(priv != NULL);

	callout_pos = priv->proc;
	ill_idx = priv->ill_index;

	/* If we don't get an M_DATA, then return an error */
	if (mp->b_datap->db_type != M_DATA) {
		if ((mp->b_cont != NULL) &&
		    (mp->b_cont->b_datap->db_type == M_DATA)) {
			mp = mp->b_cont; /* jump over the M_CTL into M_DATA */
		} else {
			ipgpc0dbg(("ipgpc_invoke_action: no data\n"));
			atomic_add_64(&ipgpc_epackets, 1);
			return (EINVAL);
		}
	}

	/*
	 * Translate the callout_pos into the direction the packet is traveling
	 */
	if (callout_pos != IPP_LOCAL_IN) {
		if (callout_pos & IPP_LOCAL_OUT) {
			callout_pos = IPP_LOCAL_OUT;
		} else if (callout_pos & IPP_FWD_IN) {
			callout_pos = IPP_FWD_IN;
		} else {	/* IPP_FWD_OUT */
			callout_pos = IPP_FWD_OUT;
		}
	}

	/* parse the packet from the message block */
	ipha = (ipha_t *)mp->b_rptr;
	/* Determine IP Header Version */
	if (IPH_HDR_VERSION(ipha) == IPV4_VERSION) {
		parse_packet(&pkt, mp);
		af = AF_INET;
	} else {
		parse_packet6(&pkt, mp);
		af = AF_INET6;
	}

	pkt.direction = callout_pos; /* set packet direction */

	/* The ill_index could be 0 when called from forwarding (read) path */
	if (ill_idx > 0)
		ill = ill_lookup_on_ifindex_global_instance(ill_idx, B_FALSE);

	if (ill != NULL) {
		/*
		 * Since all IPP actions in an IPMP group are performed
		 * relative to the IPMP group interface, if this is an
		 * underlying interface in an IPMP group, use the IPMP
		 * group interface's index.
		 */
		if (IS_UNDER_IPMP(ill))
			pkt.if_index = ipmp_ill_get_ipmp_ifindex(ill);
		else
			pkt.if_index = ill->ill_phyint->phyint_ifindex;
		/* Got the field from the ILL, go ahead and refrele */
		ill_refrele(ill);
	} else {
		/* unknown if_index */
		pkt.if_index = IPGPC_UNSPECIFIED;
	}

	if (ipgpc_debug > 5) {
		/* print pkt under high debug level */
#ifdef	IPGPC_DEBUG
		print_packet(af, &pkt);
#endif
	}
	if (ipgpc_debug > 3) {
		start = gethrtime(); /* start timer */
	}

	/* classify this packet */
	out_class = ipgpc_classify(af, &pkt);

	if (ipgpc_debug > 3) {
		end = gethrtime(); /* stop timer */
	}

	/* ipgpc_classify will only return NULL if a memory error occured */
	if (out_class == NULL) {
		atomic_add_64(&ipgpc_epackets, 1);
		return (ENOMEM);
	}

	ipgpc1dbg(("ipgpc_invoke_action: class = %s", out_class->class_name));
	/* print time to classify(..) */
	ipgpc2dbg(("ipgpc_invoke_action: time = %lld nsec\n", (end - start)));

	if ((rc = ipp_packet_add_class(packet, out_class->class_name,
	    out_class->next_action)) != 0) {
		atomic_add_64(&ipgpc_epackets, 1);
		ipgpc0dbg(("ipgpc_invoke_action: ipp_packet_add_class " \
		    "failed with error %d", rc));
		return (rc);
	}
	return (ipp_packet_next(packet, IPP_ACTION_CONT));
}