Example #1
0
inline MPLS_OUT_OPCODE_PROTOTYPE(mpls_out_op_set)
{
	struct dst_entry *dst = &(_mpls_as_nhlfe(data))->dst;

	MPLS_ENTER;
	/* Don't hold the dev we place in skb->dev, the dst is already
	   holding it for us */
	skb_set_dev(*pskb, dst->dev);
	mpls_nhlfe_hold(*nhlfe); /* dst_hold */

	/*
	 * Update the dst field of the skbuff in "real time"
	 */
	skb_dst_set(*pskb, dst);

	MPLS_EXIT;

	return MPLS_RESULT_SUCCESS;
}
Example #2
0
int 
mpls_attach_in2out(struct mpls_xconnect_req *req) 
{
	struct mpls_instr       *mi  = NULL; 
	struct mpls_nhlfe    *nhlfe = NULL;
	struct mpls_ilm     *ilm = NULL;
	unsigned short op = 0;
	int  labelspace, key;

	MPLS_ENTER;
	labelspace = req->mx_in.ml_index;

	/* Hold a ref to the ILM */
	key = mpls_label2key(labelspace,&(req->mx_in));
	ilm = mpls_get_ilm(key);
	if (unlikely(!ilm))  {
		MPLS_DEBUG("Node %u does not exist in radix tree\n",key);
		MPLS_EXIT;
		return -ESRCH;
	}

	/* Hold a ref to the NHLFE */
	key = mpls_label2key(0,&(req->mx_out));
	nhlfe = mpls_get_nhlfe(key);
	if (unlikely(!nhlfe)) {
		MPLS_DEBUG("Node %u does not exist in radix tree\n",key);
		mpls_ilm_release(ilm);
		MPLS_EXIT;
		return -ESRCH;
	}

	if (unlikely(!ilm->ilm_instr)) {
		MPLS_DEBUG("No instruction Set!")
		mpls_ilm_release(ilm);
		mpls_nhlfe_release(nhlfe);
		MPLS_EXIT;
		return -ESRCH;
	}



	/*
	 * Update the instructions: now, instead of "DLV"/"PEEK", now
	 * we "FWD". The NHLFE is not released (is held by the opcode). 
	 */

	/* Lookup the last instr */
	for (mi = ilm->ilm_instr; mi->mi_next;mi = mi->mi_next); /* nop*/

	op = mi->mi_opcode;

	switch (op) {
		case MPLS_OP_DLV:
			mi->mi_opcode = MPLS_OP_FWD;
			mi->mi_data   = (void*)nhlfe;
			break;
		case MPLS_OP_FWD:
			mpls_xc_event(MPLS_CMD_DELXC, ilm,
				_mpls_as_nhlfe(mi->mi_data));
			mpls_nhlfe_release(_mpls_as_nhlfe(mi->mi_data));
			mi->mi_data   = (void*)nhlfe;
			break;
		case MPLS_OP_PEEK:
			mi->mi_opcode = MPLS_OP_FWD;
			mi->mi_data   = (void*)nhlfe;
			break;
	}
	mpls_xc_event(MPLS_CMD_NEWXC, ilm, nhlfe);
	mpls_ilm_release(ilm);
	return 0; 
}