⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldp_fec.c

📁 实现了MPLS中的标签分发协议(LDP 3036 )的基本功能
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -