Esempio n. 1
0
mpls_return_enum ldp_adj_recv_stop(ldp_global * g, ldp_adj * a)
{

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

    if (mpls_timer_handle_verify(g->timer_handle, a->hellotime_recv_timer) ==
            MPLS_BOOL_TRUE) {
        mpls_timer_stop(g->timer_handle, a->hellotime_recv_timer);
        mpls_timer_delete(g->timer_handle, a->hellotime_recv_timer);
        a->hellotime_recv_timer = (mpls_timer_handle) 0;
        MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
    }

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

    return MPLS_SUCCESS;
}
Esempio n. 2
0
void ldp_label_request_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_nexthop *nh = NULL;
  ldp_fec *f = NULL;

  ldp_session *nh_session = NULL;
  mpls_bool done = MPLS_BOOL_FALSE;

  ldp_attr *attr = NULL;
  ldp_fs *fs = NULL;
  ldp_attr *ds_attr = NULL;

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

  LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
    "Initial Label Request Callback fired: session(%d)\n", s->index);

  mpls_lock_get(g->global_lock);

  mpls_timer_stop(g->timer_handle, timer);

  if ((f = MPLS_LIST_HEAD(&g->fec))) {
    do {
      if ((nh = MPLS_LIST_HEAD(&f->nh_root))) {
        do {
          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, "Processing 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) {
            LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
              LDP_TRACE_FLAG_ROUTE, "via %p\n", nh->iff->handle);
          }

          /* check to see if export policy allows us to 'see' this route */
          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_DEBUG, "Rejected by export policy\n");
            continue;
          }

	  /* find the next hop session corresponding to this FEC */
	  nh_session = ldp_session_for_nexthop(nh);

          /* do we have a valid next hop session, and is the nexp hop session
           * this session? */
          if ((!nh_session) || (nh_session->index != s->index)) {
            continue;
          }

          /* have we already sent a label request to this peer for this FEC? */
          if (ldp_attr_find_downstream_state(g, s, &f->info,
	    LDP_LSP_STATE_REQ_SENT)) {
            continue;
          }

          /* clear out info from the last FEC */
          ds_attr = NULL;

          /* jleu: duplicate code from ldp_attr_find_upstream_state_any */
          fs = MPLS_LIST_HEAD(&f->fs_root_us);
          while (fs) {
            attr = MPLS_LIST_HEAD(&fs->attr_root);
            while (attr) {
              if (attr->state == LDP_LSP_STATE_REQ_RECV ||
	        attr->state == LDP_LSP_STATE_MAP_SENT) {
	        if (!ds_attr) {
                  /* this is not neccessarily going to be XC'd to something */
                  ldp_label_request_for_xc(g, s, &f->info, attr, &ds_attr);
	        }
	      }
              attr = MPLS_LIST_NEXT(&fs->attr_root, attr, _fs);
            }
            fs = MPLS_LIST_NEXT(&f->fs_root_us, fs, _fec);
          }
      
          if (!ds_attr) {
            /*
	     * we did not find any received requests or sent mappings so
	     * send a request and xc it to nothing
	     */
            ldp_label_request_for_xc(g, s, &f->info, NULL, &ds_attr);
          }
        } while ((nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec)));
      }
    } while ((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_request_initial_callback");
}
Esempio n. 3
0
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");
}