📄 ldp_fec.c
字号:
MPLS_REFCNT_RELEASE2(g, nh, ldp_nexthop_delete);}mpls_return_enum ldp_fec_process_add(ldp_global * g, ldp_fec * f, ldp_nexthop *nh, ldp_session *nh_session){ ldp_session *peer = NULL; ldp_attr *ds_attr = NULL; ldp_attr *us_attr = NULL; mpls_bool egress = MPLS_BOOL_FALSE; ldp_outlabel *out; LDP_ENTER(g->user_data, "ldp_fec_process_add"); /* * find the info about the next hop for this FEC */ if (!nh_session) { nh_session = ldp_session_for_nexthop(nh); } if (nh_session) { ds_attr = ldp_attr_find_downstream_state2(g, nh_session, f, LDP_LSP_STATE_MAP_RECV); if (ds_attr && !ds_attr->outlabel) { out = ldp_outlabel_create_complete(g, nh_session, ds_attr, nh); if (!out) { return MPLS_FAILURE; } ds_attr->outlabel = out; } } /* * for every peer except the nh hop peer, check to see if we need to * send a mapping */ peer = MPLS_LIST_HEAD(&g->session); while (peer != NULL) { /* FEC.1 */ if ((peer->state != LDP_STATE_OPERATIONAL) || (nh_session && peer->index == nh_session->index)) { goto next_peer; } /* have I already sent a mapping for FEC to peer */ if ((us_attr = ldp_attr_find_upstream_state2(g, peer, f, LDP_LSP_STATE_MAP_SENT))) { /* yep, don't send another */ if (ds_attr) { if (ldp_inlabel_add_outlabel(g, us_attr->inlabel, ds_attr->outlabel) != MPLS_SUCCESS) { return MPLS_FAILURE; } } goto next_peer; } if (peer->oper_distribution_mode == LDP_DISTRIBUTION_UNSOLICITED) { if (g->lsp_control_mode == LDP_CONTROL_INDEPENDENT) { us_attr = ldp_attr_find_upstream_state2(g, peer, f, LDP_LSP_STATE_REQ_RECV); /* FEC.1.DUI3,4 */ if (ldp_label_mapping_with_xc(g, peer, f, &us_attr, ds_attr) != MPLS_SUCCESS) { if (!us_attr->in_tree) { ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); } goto next_peer; } } else { /* *LDP_CONTROL_ORDERED */ if (ds_attr || egress == MPLS_BOOL_TRUE) { /* FEC.1.DUO2 */ if (!(us_attr = ldp_attr_create(&f->info))) { return MPLS_FAILURE; } /* FEC.1.DUO3-4 */ if ((egress == MPLS_BOOL_TRUE) && (mpls_policy_egress_check( g->user_data, &f->info, &nh->info) == MPLS_BOOL_TRUE)) { goto next_peer; } if (ldp_label_mapping_with_xc(g, peer, f, &us_attr, ds_attr) != MPLS_SUCCESS) { return MPLS_FAILURE; } } } } next_peer: peer = MPLS_LIST_NEXT(&g->session, peer, _global); } if (ds_attr) { /* FEC.2 */ if (ldp_label_mapping_process(g, nh_session, NULL, NULL, ds_attr, f) == MPLS_FAILURE) { /* FEC.5 */ return MPLS_FAILURE; } return MPLS_SUCCESS; } /* * LDP_DISTRIBUTION_ONDEMAND */ /* FEC.3 */ if (nh_session && nh_session->oper_distribution_mode == LDP_DISTRIBUTION_ONDEMAND) { /* assume we're always "request when needed" */ ds_attr = NULL; if (ldp_label_request_for_xc(g, nh_session, &f->info, NULL, &ds_attr) == MPLS_FAILURE) { /* FEC.4 */ return MPLS_FAILURE; } } LDP_EXIT(g->user_data, "ldp_fec_process_add"); return MPLS_SUCCESS; /* FEC.6 */}mpls_return_enum ldp_fec_process_change(ldp_global * g, ldp_fec * f, ldp_nexthop *nh, ldp_nexthop *nh_old, ldp_session *nh_session_old) { ldp_session *peer = NULL; ldp_attr *us_attr = NULL; ldp_attr *ds_attr = NULL; ldp_session *nh_session = NULL; LDP_ENTER(g->user_data, "ldp_fec_process_change"); if (!nh_session_old) { nh_session_old = ldp_session_for_nexthop(nh_old); } /* * NH 1-5 decide if we need to release an existing mapping */ ds_attr = ldp_attr_find_downstream_state2(g, nh_session_old, f, LDP_LSP_STATE_MAP_RECV); if (!ds_attr) { /* NH.1 */ goto Detect_Change_Fec_Next_Hop_6; } if (ds_attr->ingress == MPLS_BOOL_TRUE) {#if MPLS_USE_LSR lsr_ftn ftn; ftn.outsegment_index = ds_attr->outlabel->info.handle; memcpy(&ftn.fec, &f->info, sizeof(mpls_fec)); lsr_cfg_ftn_set2(g->lsr_handle, &ftn, LSR_CFG_DEL);#else mpls_mpls_fec2out_del(g->mpls_handle, &f->info, &ds_attr->outlabel->info);#endif ds_attr->ingress = MPLS_BOOL_FALSE; ds_attr->outlabel->merge_count--; } if (g->label_retention_mode == LDP_RETENTION_LIBERAL) { /* NH.3 */ ldp_attr *us_temp; us_attr = MPLS_LIST_HEAD(&ds_attr->us_attr_root); while (us_attr) { /* need to walk the list in such a way as not to * "pull the rug out from under me self" */ us_temp = MPLS_LIST_NEXT(&ds_attr->us_attr_root, us_attr, _ds_attr); if (us_attr->state == LDP_LSP_STATE_MAP_SENT) { ldp_inlabel_del_outlabel(g, us_attr->inlabel); /* NH.2 */ ldp_attr_del_us2ds(us_attr, ds_attr); } us_attr = us_temp; } goto Detect_Change_Fec_Next_Hop_6; } ldp_label_release_send(g, nh_session_old, ds_attr, LDP_NOTIF_NONE); /* NH.4 */ ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* NH.2,5 */Detect_Change_Fec_Next_Hop_6: /* * NH 6-9 decides is we need to send a label request abort */ ds_attr = ldp_attr_find_downstream_state2(g, nh_session_old, f, LDP_LSP_STATE_REQ_SENT); if (ds_attr) { /* NH.6 */ if (g->label_retention_mode != LDP_RETENTION_CONSERVATIVE) { /* NH.7 */ /* NH.8,9 */ if (ldp_label_abort_send(g, nh_session_old, ds_attr) != MPLS_SUCCESS) { return MPLS_FAILURE; } } } /* * NH 10-12 decides if we can use a mapping from our database */ if (!(nh_session = ldp_get_next_hop_session_for_fec2(f,nh))) { goto Detect_Change_Fec_Next_Hop_16; } ds_attr = ldp_attr_find_downstream_state2(g, nh_session, f, LDP_LSP_STATE_MAP_RECV); if (!ds_attr) { /* NH.11 */ goto Detect_Change_Fec_Next_Hop_13; } if (ldp_label_mapping_process(g, nh_session, NULL, NULL, ds_attr, f) != MPLS_SUCCESS) { /* NH.12 */ return MPLS_FAILURE; } goto Detect_Change_Fec_Next_Hop_20;Detect_Change_Fec_Next_Hop_13: /* * NH 13-15 decides if we need to make a label request */ if (nh_session->oper_distribution_mode == LDP_DISTRIBUTION_ONDEMAND && g->label_retention_mode == LDP_RETENTION_CONSERVATIVE) { /* NH.14-15 */ if (ldp_label_request_for_xc(g, nh_session, &f->info, NULL, &ds_attr) != MPLS_SUCCESS) { return MPLS_FAILURE; } } goto Detect_Change_Fec_Next_Hop_20;Detect_Change_Fec_Next_Hop_16: peer = MPLS_LIST_HEAD(&g->session); while (peer) { if (peer->state == LDP_STATE_OPERATIONAL) { us_attr = ldp_attr_find_upstream_state2(g, peer, f, LDP_LSP_STATE_MAP_SENT); if (us_attr) { /* NH.17 */ if (ldp_label_withdraw_send(g, peer, us_attr, LDP_NOTIF_NONE) != MPLS_SUCCESS) { /* NH.18 */ ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); return MPLS_FAILURE; } } } peer = MPLS_LIST_NEXT(&g->session, peer, _global); }Detect_Change_Fec_Next_Hop_20: LDP_EXIT(g->user_data, "ldp_fec_process_change"); return MPLS_SUCCESS;}void mpls_fec2ldp_fec(mpls_fec * a, ldp_fec * b){ memcpy(&b->info, a, sizeof(mpls_fec));}void mpls_fec2fec_tlv(mpls_fec * lf, mplsLdpFecTlv_t * tlv, int i){ tlv->fecElArray[i].addressEl.addressFam = 1; switch (lf->type) { case MPLS_FEC_PREFIX: tlv->fecElArray[i].addressEl.type = MPLS_PREFIX_FEC; tlv->fecElArray[i].addressEl.preLen = lf->u.prefix.length; tlv->fecElArray[i].addressEl.address = lf->u.prefix.network.u.ipv4; tlv->fecElemTypes[i] = MPLS_PREFIX_FEC; break; case MPLS_FEC_HOST: tlv->fecElArray[i].addressEl.type = MPLS_HOSTADR_FEC; tlv->fecElArray[i].addressEl.preLen = MPLS_IPv4LEN; tlv->fecElArray[i].addressEl.address = lf->u.host.u.ipv4; tlv->fecElemTypes[i] = MPLS_HOSTADR_FEC; break; default: MPLS_ASSERT(0); }}void fec_tlv2mpls_fec(mplsLdpFecTlv_t * tlv, int i, mpls_fec * lf) { switch (tlv->fecElemTypes[i]) { case MPLS_PREFIX_FEC: lf->type = MPLS_FEC_PREFIX; lf->u.prefix.length = tlv->fecElArray[i].addressEl.preLen; lf->u.prefix.network.u.ipv4 = tlv->fecElArray[i].addressEl.address; lf->u.prefix.network.type = MPLS_FAMILY_IPV4; break; case MPLS_HOSTADR_FEC: lf->type = MPLS_FEC_HOST; lf->u.host.u.ipv4 = tlv->fecElArray[i].addressEl.address; lf->u.host.type = MPLS_FAMILY_IPV4; break; default: MPLS_ASSERT(0); }}mpls_bool ldp_fec_empty(ldp_fec *fec){ if (MPLS_LIST_EMPTY(&fec->fs_root_us) && MPLS_LIST_EMPTY(&fec->nh_root) && MPLS_LIST_EMPTY(&fec->fs_root_ds)) { return MPLS_BOOL_TRUE; } return MPLS_BOOL_FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -