Exemple #1
0
void ldp_attr_del_us2ds(ldp_global *g, ldp_attr * us, ldp_attr * ds)
{
  if (!us || !ds) {
    return;
  }
  if (ldp_attr_us_partof_ds(us, ds) == MPLS_BOOL_TRUE) {
    us->ds_attr = NULL;
    MPLS_REFCNT_RELEASE2(g, ds, ldp_attr_delete);
    MPLS_LIST_REMOVE(&ds->us_attr_root, us, _ds_attr);
    MPLS_REFCNT_RELEASE2(g, us, ldp_attr_delete);
  } else {
    MPLS_ASSERT(0);
  }
}
Exemple #2
0
void ldp_attr_del_fec(ldp_global *g, ldp_attr *a) {
  MPLS_ASSERT(a);
  if (a->fec) {
    MPLS_REFCNT_RELEASE2(g, a->fec, ldp_fec_delete);
    a->fec = NULL;
  }
}
Exemple #3
0
void ldp_attr_delete_upstream(ldp_global * g, ldp_session * s, ldp_attr * a)
{
  ldp_fec *fnode = NULL;
  ldp_fs *fs = NULL;

  MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE);

  MPLS_REFCNT_HOLD(a);

  /* find the fec node in the tree */
  if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_FALSE))) {
    /* find the upstream fs for this session, on the fec */
    if ((fs = _ldp_fec_find_fs_us(fnode, s, MPLS_BOOL_FALSE))) {
      /* remove this attr from the fs, if this was the last
       * attr on the fs, then remove the fs from the fec node
       */
      if (_ldp_fs_del_attr(g, fs, a) == MPLS_BOOL_TRUE) {
        _ldp_fec_del_fs_us(fnode, fs);
      }
    }
  }

  ldp_attr_del_session(g, a);
  ldp_attr_del_fec(g, a);

  a->in_tree = MPLS_BOOL_FALSE;
  MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete);
}
Exemple #4
0
mpls_return_enum ldp_attr_del_outlabel(ldp_global * g, ldp_attr * a)
{
  if (a && a->outlabel) {
    _ldp_outlabel_del_attr(g, a->outlabel);
    MPLS_REFCNT_RELEASE2(g, a->outlabel, ldp_outlabel_delete);
    a->outlabel = NULL;
    return MPLS_SUCCESS;
  }
  return MPLS_FAILURE;
}
Exemple #5
0
void ldp_fec_del_nexthop(ldp_global *g, ldp_fec * f, ldp_nexthop *nh)
{
  MPLS_ASSERT(f && nh);

  if (nh->addr) {
    ldp_addr_del_nexthop(g, nh->addr, nh);
  }
  if (nh->iff) {
    ldp_if_del_nexthop(g, nh->iff, nh);
  }
  if (nh->outlabel) {
    ldp_outlabel_del_nexthop(g, nh->outlabel, nh);
  }

  MPLS_LIST_REMOVE(&f->nh_root, nh, _fec);
  ldp_nexthop_del_fec(g, nh);

  MPLS_REFCNT_RELEASE2(g, nh, ldp_nexthop_delete);
}
Exemple #6
0
void ldp_attr_delete_downstream(ldp_global * g, ldp_session * s, ldp_attr * a)
{
  ldp_fec *fnode = NULL;
  ldp_fs *fs = NULL;

  MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE);

  MPLS_REFCNT_HOLD(a);
  /* see ldp_attr_delete_upstream for more info */
  if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_FALSE))) {
    if ((fs = _ldp_fec_find_fs_ds(fnode, s, MPLS_BOOL_FALSE))) {
      if (_ldp_fs_del_attr(g, fs, a) == MPLS_BOOL_TRUE) {
        _ldp_fec_del_fs_ds(fnode, fs);
      }
    }
  }

  ldp_attr_del_session(g, a);
  ldp_attr_del_fec(g, a);

  a->in_tree = MPLS_BOOL_FALSE;
  MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete);
}
Exemple #7
0
void ldp_nexthop_del_if(ldp_global *g, ldp_nexthop * nh)
{
  MPLS_ASSERT(nh);
  MPLS_REFCNT_RELEASE2(g, nh->iff, ldp_if_delete);
  nh->iff = NULL;
}
Exemple #8
0
void ldp_nexthop_del_fec(ldp_global *g, ldp_nexthop * nh)
{
  MPLS_ASSERT(nh);
  MPLS_REFCNT_RELEASE2(g, nh->fec, ldp_fec_delete);
  nh->fec = NULL;
}
Exemple #9
0
void ldp_nexthop_del_addr(ldp_global *g, ldp_nexthop * nh)
{
  MPLS_ASSERT(nh);
  MPLS_REFCNT_RELEASE2(g, nh->addr, ldp_addr_delete);
  nh->addr = NULL;
}
mpls_return_enum ldp_label_withdraw_process(ldp_global * g, ldp_session * s,
  ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * f)
{
  mpls_bool label_exists = MPLS_BOOL_FALSE;
  ldp_attr_list *ds_list = NULL;
  ldp_attr *ds_attr = NULL;
  ldp_attr *ds_temp = NULL;
  ldp_attr *us_temp = NULL;
  ldp_nexthop *nh = NULL;
  mpls_return_enum retval = MPLS_SUCCESS;

  LDP_ENTER(g->user_data, "ldp_label_withdraw_process");

  LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
    "Withdraw Recv for %s\n", s->session_name);

  if (r_attr->genLblTlvExists || r_attr->atmLblTlvExists
    || r_attr->frLblTlvExists) {
    label_exists = MPLS_BOOL_TRUE;
  } else {
    MPLS_ASSERT(0);
  }

  if (f) {
    if ((ds_list = ldp_attr_find_downstream_all2(g, s, f)) != NULL) {
      ds_temp = MPLS_LIST_HEAD(ds_list);
      while (ds_temp) {
        if (ds_temp->state == LDP_LSP_STATE_MAP_RECV) { /* LWd.3 */
          if (ldp_attr_is_equal(r_attr, ds_temp, LDP_ATTR_LABEL)) {
            ds_attr = ds_temp;
	    break;
          }
        }
        ds_temp = MPLS_LIST_NEXT(ds_list, ds_temp, _fs);
      }
    }

    if (!ds_attr) {
      retval = MPLS_FAILURE;
      LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
        "Withdraw Recv for a non-existant mapping from %s\n",s->session_name);
      goto LWd_13;
    }

    /*
     * we want to remove it from the tree, but not delete it yet
     * so hold a refcnt, we will release that refcnt at the end, thus
     * deleting it if no one else it holding a refcnt
     */
    MPLS_REFCNT_HOLD(ds_attr);
    ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* LWd.4 */

    /* LWd.2 */
    if (ldp_label_release_send(g, s, ds_attr, LDP_NOTIF_NONE) != MPLS_SUCCESS) {
      retval = MPLS_FATAL;
      goto LWd_13;
    }

    if (g->lsp_control_mode == LDP_CONTROL_ORDERED) { /* LWd.5 */
      goto LWd_8;
    }

    if (s->oper_distribution_mode != LDP_DISTRIBUTION_ONDEMAND) { /* LWd.6 */
      goto LWd_13;
    }

    MPLS_ASSERT((nh = ldp_nexthop_for_fec_session(f, s)));
    retval = ldp_fec_process_add(g, f, nh, s);	/* LWd.7 */
    goto LWd_13;

  LWd_8:
    /* I can only propogate a label withdraw to the upstreams attached
       to the downstream found above */

    us_temp = MPLS_LIST_HEAD(&ds_attr->us_attr_root);
    while (us_temp) {
      if (us_temp->state == LDP_LSP_STATE_MAP_SENT) {
        if (ldp_label_withdraw_send(g, us_temp->session, us_temp,
            LDP_NOTIF_NONE) != MPLS_SUCCESS) { /* LWd.11 */
          retval = MPLS_FATAL;
          goto LWd_13;
        }
      }
      us_temp = MPLS_LIST_NEXT(&ds_attr->us_attr_root, us_temp, _ds_attr);
    }
  } else {
    /* JLEU: process wildcard FEC stuff here */
    MPLS_ASSERT(0);
  }

LWd_13:
  if (ds_attr) {
    MPLS_REFCNT_RELEASE2(g, ds_attr, ldp_attr_delete);
  }

  LDP_EXIT(g->user_data, "ldp_label_withdraw_process");

  return retval;
}