📄 ldp_label_mapping.c
字号:
/* * Copyright (C) James R. Leu 2000 * jleu@mindspring.com * * This software is covered under the LGPL, for more * info check out http://www.gnu.org/copyleft/lgpl.html */#include "ldp_struct.h"#include "ldp_session.h"#include "ldp_attr.h"#include "ldp_fec.h"#include "ldp_mesg.h"#include "ldp_notif.h"#include "ldp_entity.h"#include "ldp_inlabel.h"#include "ldp_outlabel.h"#include "ldp_nexthop.h"#include "ldp_global.h"#include "ldp_pdu_setup.h"#include "ldp_label_rel_with.h"#include "ldp_label_mapping.h"#include "ldp_label_request.h"#include "mpls_timer_impl.h"#include "mpls_fib_impl.h"#include "mpls_lock_impl.h"#include "mpls_tree_impl.h"#include "mpls_trace_impl.h"#include "mpls_mm_impl.h"#include "mpls_policy_impl.h"#if MPLS_USE_LSR#include "lsr_cfg.h"#else#include "mpls_mpls_impl.h"#endifmpls_return_enum ldp_label_mapping_with_xc(ldp_global * g, ldp_session * s, ldp_fec * f, ldp_attr ** us_attr, ldp_attr * ds_attr){ mpls_return_enum result = MPLS_SUCCESS; mpls_bool propogating = MPLS_BOOL_TRUE; mpls_bool egress = MPLS_BOOL_TRUE; mpls_bool created = MPLS_BOOL_FALSE; MPLS_ASSERT(us_attr); if (!(*us_attr)) { if (!((*us_attr) = ldp_attr_create(&f->info))) { return MPLS_FAILURE; } created = MPLS_BOOL_TRUE; } if (!ds_attr) { propogating = MPLS_BOOL_FALSE; egress = MPLS_BOOL_TRUE; } Prepare_Label_Mapping_Attributes(g, s, &f->info, ds_attr, (*us_attr), propogating, MPLS_BOOL_TRUE, egress); result = ldp_label_mapping_send(g, s, f, (*us_attr), ds_attr); if (result != MPLS_SUCCESS) { if (created == MPLS_BOOL_TRUE) { ldp_attr_delete(*us_attr); } return result; } if (created == MPLS_BOOL_TRUE) { result = ldp_attr_insert_upstream2(g, s, (*us_attr), f); if (result != MPLS_SUCCESS) { ldp_attr_delete(*us_attr); return result; } } /* * If we have a downstream mapping (not neccessarily installed) and * the downstream and upstream session are not the same.... */ if (ds_attr && ((*us_attr)->session->index != ds_attr->session->index)) { /* then link the attra */ ldp_attr_add_us2ds((*us_attr), ds_attr); /* if we just created the upstream, and we have install the * downstream, then cross connect them */ if ((created == MPLS_BOOL_TRUE) && ds_attr->outlabel) { if ((*us_attr)->inlabel->outlabel) { /* * if we use an existing upstream mapping (in ldp_label_mapping_send()) * the inlabel will already be be connected to an outlabel; */ MPLS_ASSERT((*us_attr)->inlabel->outlabel == ds_attr->outlabel); } else { LDP_TRACE_LOG(g->user_data,MPLS_TRACE_STATE_ALL,LDP_TRACE_FLAG_BINDING, "Cross Connect Added for %08x/%d from %s -> %s\n", f->info.u.prefix.network.u.ipv4, f->info.u.prefix.length, (*us_attr)->session->session_name, ds_attr->session->session_name); result = ldp_inlabel_add_outlabel(g,(*us_attr)->inlabel, ds_attr->outlabel); if (result != MPLS_SUCCESS) { return result; } } } } return MPLS_SUCCESS;}ldp_session *ldp_get_next_hop_session_for_fec2(ldp_fec * f, ldp_nexthop *nh) { ldp_session *session = NULL; /* * find the info about the next hop for this FEC */ if (nh->addr && nh->addr->session_root.count > 0) { session = mpls_link_list_head_data(&nh->addr->session_root); } else if (nh->iff && nh->iff->is_p2p == MPLS_BOOL_TRUE && &nh->iff->entity) { ldp_adj *adj = MPLS_LIST_HEAD(&nh->iff->entity->adj_root); session = adj ? adj->session : NULL; } return session;}mpls_return_enum ldp_get_next_hop_session_for_fec(ldp_global * g, mpls_fec * fec, mpls_nexthop *nh, ldp_session ** next_hop_session){ ldp_fec *f = NULL; ldp_nexthop *n = NULL; MPLS_ASSERT(next_hop_session); if (!(f = ldp_fec_find(g, fec))) { return MPLS_NO_ROUTE; } if (!(n = ldp_fec_nexthop_find(f, nh))) { return MPLS_NO_ROUTE; } *next_hop_session = ldp_get_next_hop_session_for_fec2(f,n); return (*next_hop_session) ? MPLS_SUCCESS : MPLS_FAILURE;}mpls_return_enum Check_Received_Attributes(ldp_global * g, ldp_session * s, ldp_attr * r_attr, uint16_t type){ int count = 0; int i; if (!r_attr->hopCountTlvExists) { /* CRa.1 */ goto Check_Received_Attributes_5; } if (r_attr->hopCountTlv.hcValue >= s->cfg_hop_count_limit) { /* CRa.2 */ LDP_PRINT(g->user_data, "CRa.2\n"); goto Check_Received_Attributes_6; } if (!r_attr->pathVecTlvExists) { /* CRa.3 */ goto Check_Received_Attributes_5; } for (i = 0; i < MPLS_MAXHOPSNUMBER; i++) { /* CRa.4 */ if (r_attr->pathVecTlv.lsrId[i]) { count++; if (r_attr->pathVecTlv.lsrId[i] == g->lsr_identifier.u.ipv4) { goto Check_Received_Attributes_6; LDP_PRINT(g->user_data, "CRa.4a\n"); } if (count > s->oper_path_vector_limit) { goto Check_Received_Attributes_6; LDP_PRINT(g->user_data, "CRa.4b\n"); } } }Check_Received_Attributes_5: return MPLS_SUCCESS;Check_Received_Attributes_6: if (type != MPLS_LBLMAP_MSGTYPE) { ldp_notif_send(g, s, r_attr, LDP_NOTIF_LOOP_DETECTED); /* CRa.7 */ } return MPLS_FAILURE; /* CRa.8 */}void Prepare_Label_Mapping_Attributes(ldp_global * g, ldp_session * s, mpls_fec * fec, ldp_attr * r_attr, ldp_attr * s_attr, mpls_bool propogating, mpls_bool already, mpls_bool egress){ ldp_attr dummy; int i; /* NOTE: PMpA.21 is the end of the procedure (ie return) */ /* this function uses goto quite extensivly for a REASON!! */ /* Check Appedix A of the LDP draft */ LDP_ENTER(g->user_data, "Prepare_Label_Mapping_Attributes"); if (!r_attr) { memset(&dummy, 0, sizeof(ldp_attr)); mpls_fec2fec_tlv(fec, &dummy.fecTlv, 0); dummy.fecTlvExists = 1; dummy.fecTlv.numberFecElements = 1; r_attr = &dummy; } if (!(s->oper_loop_detection == LDP_LOOP_HOPCOUNT || s->oper_loop_detection == LDP_LOOP_HOPCOUNT_PATHVECTOR || r_attr->hopCountTlvExists)) { /* PMpA.1 */ LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return; } if (egress) {/* PMpA.2 */ /* I'm egress (for now) */ s_attr->hopCountTlvExists = 1; s_attr->hopCountTlv.hcValue = 1; /* PMpA.3 */ LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return; } if (!(r_attr->hopCountTlvExists)) { /* PMpA.4 */ goto Prepare_Label_Mapping_Attributes_8; } if (!(g->ttl_less_domain == MPLS_BOOL_TRUE && s->cfg_remote_in_ttl_less_domain == MPLS_BOOL_TRUE)) { /* PMpA.5 */ goto Prepare_Label_Mapping_Attributes_7; } s_attr->hopCountTlvExists = 1; s_attr->hopCountTlv.hcValue = 1; /* PMpA.6 */ goto Prepare_Label_Mapping_Attributes_9;Prepare_Label_Mapping_Attributes_7: s_attr->hopCountTlvExists = 1; s_attr->hopCountTlv.hcValue = (r_attr->hopCountTlv.hcValue) ? (r_attr->hopCountTlv.hcValue + 1) : 0; goto Prepare_Label_Mapping_Attributes_9;Prepare_Label_Mapping_Attributes_8: s_attr->hopCountTlvExists = 1; s_attr->hopCountTlv.hcValue = 0;Prepare_Label_Mapping_Attributes_9: if (s->oper_loop_detection == LDP_LOOP_NONE) { LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return; } if (r_attr->pathVecTlvExists) { /* PMpA.10 */ goto Prepare_Label_Mapping_Attributes_19; } if (propogating == MPLS_BOOL_FALSE) { /* PMpA.11 */ goto Prepare_Label_Mapping_Attributes_20; } if (g->label_merge != MPLS_BOOL_TRUE) { /* PMpA.12 */ goto Prepare_Label_Mapping_Attributes_14; } if (already == MPLS_BOOL_FALSE) { /* PMpA.13 */ goto Prepare_Label_Mapping_Attributes_20; }Prepare_Label_Mapping_Attributes_14: if (!r_attr->hopCountTlvExists) { LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return; } if (r_attr->hopCountTlv.hcValue == 0) { /* PMpA.15 */ goto Prepare_Label_Mapping_Attributes_20; } if (already == MPLS_BOOL_FALSE) { /* PMpA.16 */ LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return; } /* r_attr contain PrevHopCount _IF_ we had one */ LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return; /* PMpA.17 */ if (r_attr->hopCountTlv.hcValue != 0) { /* PMpA.18 */ LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return; }Prepare_Label_Mapping_Attributes_19: s_attr->pathVecTlvExists = 1; s_attr->pathVecTlv.lsrId[0] = g->lsr_identifier.u.ipv4; for (i = 1; i < (MPLS_MAXHOPSNUMBER - 1); i++) { if (r_attr->pathVecTlv.lsrId[i - 1]) { s_attr->pathVecTlv.lsrId[0] = r_attr->pathVecTlv.lsrId[i - 1]; } } LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return;Prepare_Label_Mapping_Attributes_20: s_attr->pathVecTlvExists = 1; s_attr->pathVecTlv.lsrId[0] = g->lsr_identifier.u.ipv4; LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes"); return;}void map2attr(mplsLdpLblMapMsg_t * map, ldp_attr * attr, uint32_t flag){ attr->msg_id = map->baseMsg.msgId; if (map->fecTlvExists && flag & LDP_ATTR_FEC) { memcpy(&attr->fecTlv, &map->fecTlv, sizeof(mplsLdpFecTlv_t)); attr->fecTlvExists = 1; } if (map->genLblTlvExists && flag & LDP_ATTR_LABEL) { memcpy(&attr->genLblTlv, &map->genLblTlv, sizeof(mplsLdpGenLblTlv_t)); attr->genLblTlvExists = 1; } else if (map->atmLblTlvExists && flag & LDP_ATTR_LABEL) { memcpy(&attr->atmLblTlv, &map->atmLblTlv, sizeof(mplsLdpAtmLblTlv_t)); attr->atmLblTlvExists = 1; } else if (map->frLblTlvExists && flag & LDP_ATTR_LABEL) { memcpy(&attr->frLblTlv, &map->frLblTlv, sizeof(mplsLdpFrLblTlv_t)); attr->frLblTlvExists = 1; } if (map->hopCountTlvExists && flag & LDP_ATTR_HOPCOUNT) { memcpy(&attr->hopCountTlv, &map->hopCountTlv, sizeof(mplsLdpHopTlv_t)); attr->hopCountTlvExists = 1; } if (map->pathVecTlvExists && flag & LDP_ATTR_PATH) { memcpy(&attr->pathVecTlv, &map->pathVecTlv, sizeof(mplsLdpPathTlv_t)); attr->pathVecTlvExists = 1; } if (map->lblMsgIdTlvExists && flag & LDP_ATTR_MSGID) { memcpy(&attr->lblMsgIdTlv, &map->lblMsgIdTlv, sizeof(mplsLdpLblMsgIdTlv_t)); attr->lblMsgIdTlvExists = 1; } if (map->lspidTlvExists && flag & LDP_ATTR_LSPID) { memcpy(&attr->lspidTlv, &map->lspidTlv, sizeof(mplsLdpLspIdTlv_t)); attr->lspidTlvExists = 1; } if (map->trafficTlvExists && flag & LDP_ATTR_TRAFFIC) { memcpy(&attr->trafficTlv, &map->trafficTlv, sizeof(mplsLdpTrafficTlv_t)); attr->trafficTlvExists = 1; }}void attr2map(ldp_attr * attr, mplsLdpLblMapMsg_t * map){ if (attr->fecTlvExists) { memcpy(&map->fecTlv, &attr->fecTlv, sizeof(mplsLdpFecTlv_t)); map->fecTlvExists = 1; } if (attr->genLblTlvExists) { memcpy(&map->genLblTlv, &attr->genLblTlv, sizeof(mplsLdpGenLblTlv_t)); map->genLblTlvExists = 1; } if (attr->atmLblTlvExists) { memcpy(&map->atmLblTlv, &attr->atmLblTlv, sizeof(mplsLdpAtmLblTlv_t)); map->atmLblTlvExists = 1; } if (attr->frLblTlvExists) { memcpy(&map->frLblTlv, &attr->frLblTlv, sizeof(mplsLdpFrLblTlv_t)); map->frLblTlvExists = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -