Beispiel #1
0
void ldp_attr_add_us2ds(ldp_attr * us, ldp_attr * ds)
{

  if (!us || !ds) {
    return;
  }
  if (ldp_attr_us_partof_ds(us, ds) == MPLS_BOOL_TRUE) {
    return;
  }
  MPLS_REFCNT_HOLD(us);
  MPLS_LIST_ADD_TAIL(&ds->us_attr_root, us, _ds_attr, ldp_attr);
  MPLS_REFCNT_HOLD(ds);
  us->ds_attr = ds;
}
Beispiel #2
0
void ldp_nexthop_add_if(ldp_nexthop * nh, ldp_if * i)
{
  MPLS_ASSERT(nh && i);
  MPLS_REFCNT_HOLD(i);
  nh->info.if_handle = i->handle;
  nh->iff = i;
}
Beispiel #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);
}
Beispiel #4
0
mpls_return_enum ldp_inlabel_add_outlabel(ldp_global *g, ldp_inlabel *i,
  ldp_outlabel *o) {
  mpls_return_enum result;

  MPLS_ASSERT(i && o);
  MPLS_ASSERT(i->outlabel == NULL);

#if MPLS_USE_LSR
  {
    lsr_xconnect xcon;
    xcon.insegment_index = i->info.handle;
    xcon.outsegment_index = o->info.handle;
    xcon.info.owner = MPLS_OWNER_LDP;
    result = lsr_cfg_xconnect_set2(g->lsr_handle, &xcon, LSR_CFG_ADD|
      LSR_XCONNECT_CFG_OUTSEGMENT|LSR_XCONNECT_CFG_INSEGMENT|
      LSR_XCONNECT_CFG_LSPID|LSR_XCONNECT_CFG_OWNER);
  }
#else
  result = mpls_mpls_xconnect_add(g->mpls_handle, &i->info, &o->info);
#endif
  if (result == MPLS_SUCCESS) {
    MPLS_REFCNT_HOLD(o);
    i->outlabel = o;
    _ldp_outlabel_add_inlabel(o, i);
  }
  return result;
}
Beispiel #5
0
void ldp_nexthop_add_outlabel2(ldp_nexthop * n, ldp_outlabel * o)
{
  MPLS_ASSERT(n && o);
  MPLS_REFCNT_HOLD(o);
  MPLS_LIST_ADD_HEAD(&n->outlabel_root, o, _nexthop, ldp_outlabel);
  memcpy(&o->info.nexthop, &n->info, sizeof(mpls_nexthop));
}
Beispiel #6
0
mpls_return_enum _ldp_resource_add_tunnel(ldp_resource * r, ldp_tunnel * t)
{
  if (r && t) {
    MPLS_REFCNT_HOLD(t);
    r->tunnel = t;
    return MPLS_SUCCESS;
  }
  return MPLS_FAILURE;
}
Beispiel #7
0
mpls_return_enum ldp_attr_add_session(ldp_attr * a, ldp_session * s)
{
  if (a && s) {
    MPLS_REFCNT_HOLD(s);
    a->session = s;
    _ldp_session_add_attr(s, a);
    return MPLS_SUCCESS;
  }
  return MPLS_FAILURE;
}
Beispiel #8
0
mpls_return_enum ldp_attr_add_outlabel(ldp_attr * a, ldp_outlabel * o)
{
  if (a && o) {
    MPLS_REFCNT_HOLD(o);
    a->outlabel = o;
    _ldp_outlabel_add_attr(o, a);
    return MPLS_SUCCESS;
  }
  return MPLS_FAILURE;
}
Beispiel #9
0
mpls_return_enum ldp_attr_add_inlabel(ldp_global *g, ldp_attr * a, ldp_inlabel * i)
{
  if (a && i) {
    MPLS_REFCNT_HOLD(i);
    a->inlabel = i;
    _ldp_inlabel_add_attr(g, i, a);
    return MPLS_SUCCESS;
  }
  return MPLS_FAILURE;
}
Beispiel #10
0
mpls_return_enum _ldp_inlabel_add_session(ldp_inlabel * i, ldp_session * s)
{
  MPLS_ASSERT(i && s);

  MPLS_REFCNT_HOLD(s);
  if (mpls_link_list_add_tail(&i->session_root, s) == MPLS_SUCCESS) {
    return MPLS_SUCCESS;
  }
  MPLS_REFCNT_RELEASE(s, ldp_session_delete);
  return MPLS_FAILURE;
}
Beispiel #11
0
void ldp_adj_add_session(ldp_adj * a, ldp_session * s)
{
    MPLS_ASSERT(a && s);

    LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_PERIODIC,
                  "Adj(%d) bound to sesssion(%d)\n",a->index,s->index);

    MPLS_REFCNT_HOLD(s);
    a->session = s;
    _ldp_session_add_adj(s, a);
}
Beispiel #12
0
mpls_return_enum _ldp_inlabel_add_attr(ldp_inlabel * i, ldp_attr * a)
{
  MPLS_ASSERT(i && a);

  MPLS_REFCNT_HOLD(a);
  if (mpls_link_list_add_tail(&i->attr_root, a) == MPLS_SUCCESS) {
    i->reuse_count++;
    return MPLS_SUCCESS;
  }
  MPLS_REFCNT_RELEASE(a, ldp_attr_delete);
  return MPLS_FAILURE;
}
Beispiel #13
0
mpls_return_enum ldp_adj_startup(ldp_global * g, ldp_adj * a, int request)
{
    ldp_entity *e;

    MPLS_ASSERT(a && (e = a->entity));
    /* with recent changes to when the session gets created I think this
     * assert is not longer valid - jleu 2003-02-20
    MPLS_ASSERT(!a->session);
     */
    MPLS_ASSERT(a->state != LDP_NONE);

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

    /* ldp-11 3.5.2. Hello Message */
    if (e->hellotime_timer != 0xFFFF) {
        MPLS_REFCNT_HOLD(a);
        a->hellotime_recv_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
                                  e->hellotime_timer, (void *)a, g, ldp_hello_timeout_callback);

        if (mpls_timer_handle_verify(g->timer_handle, a->hellotime_recv_timer) ==
                MPLS_BOOL_FALSE) {
            MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
            goto ldp_adj_startup_error;
        }
    }

    if (request && mpls_timer_handle_verify(g->timer_handle,
                                            e->p.peer->hellotime_send_timer) == MPLS_BOOL_FALSE) {
        /* request is ONLY specific with indirect adj */
        ldp_hello_send(g, e);
    }

    a->state = MPLS_OPER_UP;

    if (e->hellotime_timer != 0xFFFF) {
        mpls_timer_start(g->timer_handle, a->hellotime_recv_timer,
                         MPLS_TIMER_ONESHOT);
    }

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

    return MPLS_SUCCESS;

ldp_adj_startup_error:

    LDP_EXIT(g->user_data, "ldp_adj_startup: error");

    return MPLS_FAILURE;
}
Beispiel #14
0
mpls_return_enum ldp_fec_add_nexthop(ldp_global *g, ldp_fec * f,
  ldp_nexthop * nh)
{
  MPLS_ASSERT(f && nh);

  MPLS_REFCNT_HOLD(nh);
  MPLS_LIST_ADD_HEAD(&f->nh_root, nh, _fec, ldp_nexthop);

  ldp_nexthop_add_fec(nh, f);

  if (nh->info.type & MPLS_NH_IP) {
    ldp_addr *addr = NULL;
    if (!(addr = ldp_addr_find(g, &nh->info.ip))) {
      if (!(addr = ldp_addr_insert(g, &nh->info.ip))) {
        goto ldp_fec_add_nexthop_error;
      }
    }

    ldp_addr_add_nexthop(addr, nh);
  }

  if (nh->info.type & MPLS_NH_IF) {
    ldp_if *iff = NULL;
    if ((iff = ldp_global_find_if_handle(g, nh->info.if_handle))) {
      ldp_if_add_nexthop(iff, nh);
    }
  }

  if (nh->info.type & MPLS_NH_OUTSEGMENT) {
    ldp_outlabel *out = NULL;
    MPLS_ASSERT((out = ldp_global_find_outlabel_handle(g,
      nh->info.outsegment_handle)));

    ldp_outlabel_add_nexthop(out, nh);
  }
  return MPLS_SUCCESS;

ldp_fec_add_nexthop_error:

  ldp_fec_del_nexthop(g, f, nh);
  return MPLS_FATAL;
}
Beispiel #15
0
mpls_return_enum ldp_adj_recv_start(ldp_global * g, ldp_adj * a)
{
    mpls_return_enum result = MPLS_SUCCESS;

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

    MPLS_REFCNT_HOLD(a);
    a->hellotime_recv_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
                              a->entity->hellotime_timer, (void *)a, g, ldp_hello_timeout_callback);

    if (mpls_timer_handle_verify(g->timer_handle, a->hellotime_recv_timer) ==
            MPLS_BOOL_FALSE) {
        MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
        result = MPLS_FAILURE;
    }

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

    return result;
}
Beispiel #16
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);
}
Beispiel #17
0
mpls_return_enum ldp_adj_shutdown(ldp_global * g, ldp_adj * a)
{
    ldp_entity *e;

    MPLS_ASSERT(g && a && (e = a->entity));

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

    MPLS_REFCNT_HOLD(a);

    if (a->session) {
        ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE);
        /* session_shutdown does ldp_adj_del_session(a); */
    }

    ldp_adj_recv_stop(g, a);

    if (e->entity_type == LDP_INDIRECT &&
            e->p.peer->target_role == LDP_PASSIVE) {
        /* we started sending due to a targeted hello with "request"
         * now that the adj is down we can stop
         */
        ldp_peer_send_stop(g, e->p.peer);
    }

    ldp_entity_del_adj(e, a);
    if (a->state == MPLS_OPER_UP) {
        _ldp_global_del_adj(g, a);
    }

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

    MPLS_REFCNT_RELEASE(a, ldp_adj_delete);

    return MPLS_SUCCESS;
}
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;
}
Beispiel #19
0
void _ldp_adj_add_entity(ldp_adj * a, ldp_entity * e)
{
    MPLS_ASSERT(a && e);
    MPLS_REFCNT_HOLD(e);
    a->entity = e;
}
Beispiel #20
0
void ldp_nexthop_add_addr(ldp_nexthop * nh, ldp_addr * a)
{
  MPLS_ASSERT(nh && a);
  MPLS_REFCNT_HOLD(a);
  nh->addr = a;
}
Beispiel #21
0
void ldp_attr_add_fec(ldp_attr *a, ldp_fec *fec) {
  MPLS_ASSERT(a && fec);
  MPLS_REFCNT_HOLD(fec);
  a->fec = fec;
}
Beispiel #22
0
void ldp_nexthop_add_fec(ldp_nexthop *nh, ldp_fec *f)
{
  MPLS_ASSERT(nh && f);
  MPLS_REFCNT_HOLD(f);
  nh->fec = f;
}
Beispiel #23
0
void ldp_nexthop_add_outlabel(ldp_nexthop * nh, ldp_outlabel * o)
{
  MPLS_ASSERT(nh && o);
  MPLS_REFCNT_HOLD(o);
  nh->outlabel = o;
}