📄 ldp_label_mapping.c
字号:
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; } if (attr->hopCountTlvExists) { memcpy(&map->hopCountTlv, &attr->hopCountTlv, sizeof(mplsLdpHopTlv_t)); map->hopCountTlvExists = 1; } if (attr->pathVecTlvExists) { memcpy(&map->pathVecTlv, &attr->pathVecTlv, sizeof(mplsLdpPathTlv_t)); map->pathVecTlvExists = 1; } if (attr->lblMsgIdTlvExists) { memcpy(&map->lblMsgIdTlv, &attr->lblMsgIdTlv, sizeof(mplsLdpLblMsgIdTlv_t)); map->lblMsgIdTlvExists = 1; } if (attr->lspidTlvExists) { memcpy(&map->lspidTlv, &attr->lspidTlv, sizeof(mplsLdpLspIdTlv_t)); map->lspidTlvExists = 1; } if (attr->trafficTlvExists) { memcpy(&map->trafficTlv, &attr->trafficTlv, sizeof(mplsLdpTrafficTlv_t)); map->trafficTlvExists = 1; }}void ldp_label_mapping_initial_callback(mpls_timer_handle timer, void *extra, mpls_cfg_handle handle){ ldp_session *s = (ldp_session *) extra; ldp_global *g = (ldp_global*)handle; ldp_attr *ds_attr = NULL; ldp_attr *us_attr = NULL; ldp_session *nh_session = NULL; mpls_bool done = MPLS_BOOL_FALSE; ldp_fec *f; ldp_nexthop *nh; LDP_ENTER(g->user_data, "ldp_label_mapping_initial_callback"); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER, "Initial Label Mapping fired: session(%d)\n", s->index); mpls_lock_get(g->global_lock); mpls_timer_stop(g->timer_handle, timer); f = MPLS_LIST_HEAD(&g->fec); while (f) { nh = MPLS_LIST_HEAD(&f->nh_root); while (nh) { switch (f->info.type) { case MPLS_FEC_PREFIX: LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ROUTE, "Processing prefix FEC: %08x/%d ", f->info.u.prefix.network.u.ipv4, f->info.u.prefix.length); break; case MPLS_FEC_HOST: LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ROUTE, "Processing host FEC: %08x ", f->info.u.host.u.ipv4); break; case MPLS_FEC_L2CC: LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ROUTE, "Processingu L2CC FEC: %d %d %d ", f->info.u.l2cc.connection_id, f->info.u.l2cc.group_id, f->info.u.l2cc.type); break; default: MPLS_ASSERT(0); } if (nh->info.type & MPLS_NH_IP) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ROUTE, "via %08x\n", nh->addr->address.u.ipv4); } if (nh->info.type & MPLS_NH_IF && nh->iff) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ROUTE, "via %p\n", nh->iff->handle); } /* are we allowed to export this route from the rib */ if (mpls_policy_export_check(g->user_data, &f->info, &nh->info) == MPLS_BOOL_FALSE) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_POLICY, "Rejected by export policy\n"); goto ldp_label_mapping_initial_callback_end_nh; } /* have we already sent a mapping for this fec to the new session? */ if ((us_attr = ldp_attr_find_upstream_state2(g, s, f, LDP_LSP_STATE_MAP_SENT))) { /* no need to sent another mapping */ LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ROUTE, "Already sent this FEC to session %d\n", s->index); goto ldp_label_mapping_initial_callback_end_nh; } if (!(nh_session = ldp_get_next_hop_session_for_fec2(f,nh))) { ds_attr = NULL; } else { if (nh_session->index == s->index) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ROUTE, "Nexthop session(%d) == session(%d)\n", nh_session->index, s->index); goto ldp_label_mapping_initial_callback_end_nh; } ds_attr = ldp_attr_find_downstream_state2(g, nh_session, f, LDP_LSP_STATE_MAP_RECV); } if ((g->label_merge != MPLS_BOOL_TRUE) && ldp_attr_num_us2ds(ds_attr)) { /* we have a ds label, but can't use it */ ds_attr = NULL; } us_attr = NULL; if (ds_attr) { /* we can use it, merge on baby */ ldp_label_mapping_with_xc(g, s, f, &us_attr, ds_attr); } else { /* we don't have a ds label */ /* we will be egress? */ if (g->lsp_control_mode == LDP_CONTROL_ORDERED) { if (mpls_policy_egress_check(g->user_data, &f->info, &nh->info) == MPLS_BOOL_TRUE) { ldp_label_mapping_with_xc(g, s, f, &us_attr, NULL); } } else { ldp_label_mapping_with_xc(g, s, f, &us_attr, NULL); } }ldp_label_mapping_initial_callback_end_nh: nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec); } f = MPLS_LIST_NEXT(&g->fec, f, _global); } done = MPLS_BOOL_TRUE; if (done == MPLS_BOOL_TRUE) { mpls_timer_delete(g->timer_handle, timer); MPLS_REFCNT_RELEASE(s, ldp_session_delete); s->initial_distribution_timer = (mpls_timer_handle) 0; } else { mpls_timer_start(g->timer_handle, timer, MPLS_TIMER_ONESHOT); /* need to mark the session with where it left off */ } mpls_lock_release(g->global_lock); LDP_EXIT(g->user_data, "ldp_label_mapping_initial_callback");}mpls_return_enum ldp_label_mapping_send(ldp_global * g, ldp_session * s, ldp_fec *f, ldp_attr * us_attr, ldp_attr * ds_attr){ ldp_inlabel *in = NULL; ldp_attr *us_temp, *existing = NULL; LDP_ENTER(g->user_data, "ldp_label_mapping_send"); MPLS_ASSERT(us_attr);#if 0 /* * before we can enable this, inlabels need to keep track of all of * the attr that link to it. Then when running in DU independent mode we * can correctly attach the us and ds attrs involved when propogating a * new mapping for a FEC we've already distributed labels for */ existing = ldp_attr_find_upstream_map_in_labelspace(f, s->cfg_label_space);#endif if (existing) { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING, "Using an existing label\n"); in = existing->inlabel; ldp_attr_add_inlabel(g, us_attr, in); } else { LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING, "Generating a label\n"); in = ldp_inlabel_create_complete(g, s, us_attr); } if (!in) { /* SL.1-3 */ goto Send_Label_9; } LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING, "In Label Added\n"); us_attr->state = LDP_LSP_STATE_MAP_SENT; us_attr->msg_id = g->message_identifier; ldp_label_mapping_prepare_msg(s->tx_message, g->message_identifier++, us_attr); if (ldp_mesg_send_tcp(g, s, s->tx_message) != MPLS_SUCCESS) { /* SL.4 */ LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR, "Failed sending Label Mapping to %s\n", s->session_name); goto ldp_label_mapping_send_error; } LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL, "Label Mapping Sent to %s for %08x/%d\n", s->session_name, us_attr->fecTlv.fecElArray[0].addressEl.address, us_attr->fecTlv.fecElArray[0].addressEl.preLen); us_attr->state = LDP_LSP_STATE_MAP_SENT; /* SL.6,7 */ LDP_EXIT(g->user_data, "ldp_label_mapping_send"); return MPLS_SUCCESS; /* SL.8 */Send_Label_9: LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_STATE, "No Label Resources\n"); while ((us_temp = ldp_attr_find_upstream_state2(g, s, us_attr->fec, LDP_LSP_STATE_REQ_RECV)) != NULL) { /* SL.9 */ ldp_notif_send(g, s, us_temp, LDP_NOTIF_NO_LABEL_RESOURCES_AVAILABLE); /* SL.10 */ s->no_label_resource_sent = MPLS_BOOL_TRUE; /* SL.12 */ us_temp->state = LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT; /* SL.13 */ } LDP_EXIT(g->user_data, "ldp_label_mapping_send"); return MPLS_SUCCESS;ldp_label_mapping_send_error: LDP_EXIT(g->user_data, "ldp_label_mapping_send-error"); return MPLS_FAILURE;}void ldp_label_mapping_prepare_msg(ldp_mesg * msg, uint32_t msgid, ldp_attr * s_attr){ mplsLdpLblMapMsg_t *map = NULL; int i; MPLS_ASSERT(msg); ldp_mesg_prepare(msg, MPLS_LBLMAP_MSGTYPE, msgid); map = &msg->u.map; if (s_attr->fecTlvExists) { /* JLEU: only 1 FEC is allowed!! */ map->fecTlvExists = 1; map->baseMsg.msgLength += setupFecTlv(&map->fecTlv); map->baseMsg.msgLength += addFecElem2FecTlv(&map->fecTlv, &s_attr->fecTlv.fecElArray[0]); } if (s_attr->genLblTlvExists) { map->genLblTlvExists = 1; map->baseMsg.msgLength += setupGenLblTlv(&map->genLblTlv, s_attr->genLblTlv.label); } if (s_attr->atmLblTlvExists) { map->atmLblTlvExists = 1; map->baseMsg.msgLength += setupAtmLblTlv(&map->atmLblTlv, 0, 0, s_attr->atmLblTlv.flags.flags.vpi, s_attr->atmLblTlv.vci); } if (s_attr->frLblTlvExists) { map->frLblTlvExists = 1; map->baseMsg.msgLength += setupFrLblTlv(&map->frLblTlv, 0, s_attr->frLblTlv.flags.flags.len, s_attr->frLblTlv.flags.flags.dlci); } if (s_attr->hopCountTlvExists) { map->hopCountTlvExists = 1; map->baseMsg.msgLength += setupHopCountTlv(&map->hopCountTlv, s_attr->hopCountTlv.hcValue); } if (s_attr->pathVecTlvExists) { map->pathVecTlvExists = 1; map->baseMsg.msgLength += setupPathTlv(&map->pathVecTlv); for (i = 0; i < MPLS_MAXHOPSNUMBER; i++) { if (s_attr->pathVecTlv.lsrId[i]) { map->baseMsg.msgLength += addLsrId2PathTlv(&map->pathVecTlv, s_attr->pathVecTlv.lsrId[i]); } } }#if 0 if (s_attr->lblMsgIdTlvExists) { } if (s_attr->lspidTlvExists) { } if (s_attr->trafficTlvExists) { }#endif}mpls_return_enum ldp_label_mapping_process(ldp_global * g, ldp_session * s, ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * f){ mpls_return_enum retval = MPLS_SUCCESS; ldp_session *peer = NULL; ldp_attr_list *us_list = NULL; ldp_attr_list *ds_list = NULL; ldp_attr *ds_attr = NULL; ldp_attr *ds_temp = NULL; ldp_attr *us_attr = NULL; ldp_attr *us_temp = NULL; ldp_attr dumb_attr; ldp_nexthop *nh = NULL; ldp_outlabel *out = NULL; mpls_bool requested = MPLS_BOOL_FALSE; ldp_attr *existing = NULL; mpls_bool need_request = MPLS_BOOL_FALSE; LDP_ENTER(g->user_data, "ldp_label_mapping_process"); LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL, "Label Mapping Recv from %s for %08x/%d\n", s->session_name, r_attr->fecTlv.fecElArray[0].addressEl.address, r_attr->fecTlv.fecElArray[0].addressEl.preLen); if ((ds_attr = ldp_attr_find_downstream_state2(g, s, f, LDP_LSP_STATE_REQ_SENT)) != NULL) { /* LMp.1 */ /* just remove the req from the tree, we will use the r_attr sent to us */ ldp_attr_delete_downstream(g, s, ds_attr); requested = MPLS_BOOL_TRUE; } else { requested = MPLS_BOOL_FALSE; } ds_attr = r_attr; ds_attr->state = LDP_LSP_STATE_MAP_RECV; /* LMp.2 */ /* * ds_attr is the mapping we will keep and is NOT in the tree, unless * it is an update mapping ... */ if (Check_Received_Attributes(g, s, ds_attr, MPLS_LBLMAP_MSGTYPE) == MPLS_SUCCESS) { /* LMp.3 */ goto LMp_9; } /* * A loop was detected */ if ((ds_list = ldp_attr_find_downstream_all2(g, s, f))) { ds_temp = MPLS_LIST_HEAD(ds_list); /* * check all the labels this session has received from "s" for "fec" * do we have a duplicat? */ while (ds_temp) { if ((ds_temp->state == LDP_LSP_STATE_MAP_RECV) && /* LMp.4 */ ldp_attr_is_equal(ds_temp, ds_attr, LDP_ATTR_LABEL) == /* LMp.5 */ MPLS_BOOL_TRUE) { /* remove record of the label and remove it switching */ ldp_attr_remove_complete(g, ds_temp, MPLS_BOOL_TRUE); /* LMp.6,7 */ /* * I think this is supposed to be 32 NOT 33, we need to release * it don't we? */ goto LMp_33; } ds_temp = MPLS_LIST_NEXT(ds_list, ds_temp, _fs); } } LDP_PRINT(g->user_data, "Receive_Label_Map_8: send release"); if (ldp_label_release_send(g, s, ds_attr, LDP_NOTIF_LOOP_DETECTED) != MPLS_SUCCESS) { /* LMp.8 */ retval = MPLS_FAILURE; } goto LMp_33;LMp_9: /* * No Loop Detected */ ds_temp = ldp_attr_find_downstream_state2(g, s, f, LDP_LSP_STATE_MAP_RECV); if (requested == MPLS_BOOL_TRUE ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -