void ldp_adj_del_session(ldp_adj * a, ldp_session * s) { MPLS_ASSERT(a && s); _ldp_session_del_adj(s, a); MPLS_REFCNT_RELEASE(s, ldp_session_delete); a->session = NULL; }
void _ldp_inlabel_del_attr(ldp_inlabel * i, ldp_attr * a) { MPLS_ASSERT(i && a); mpls_link_list_remove_data(&i->attr_root, a); MPLS_REFCNT_RELEASE(a, ldp_attr_delete); i->reuse_count--; }
void ldp_nexthop_del_outlabel2(ldp_global *g, ldp_nexthop * n, ldp_outlabel * o) { MPLS_ASSERT(n && o); MPLS_LIST_REMOVE(&n->outlabel_root, o, _nexthop); ldp_outlabel_del_nexthop2(g, o); MPLS_REFCNT_RELEASE(o, ldp_outlabel_delete); }
mpls_return_enum _ldp_resource_del_tunnel(ldp_resource * r) { if (r && r->tunnel) { MPLS_REFCNT_RELEASE(r->tunnel, ldp_tunnel_delete); r->tunnel = NULL; return MPLS_SUCCESS; } return MPLS_FAILURE; }
mpls_return_enum ldp_attr_del_session(ldp_global *g, ldp_attr * a) { if (a && a->session) { _ldp_session_del_attr(g, a->session, a); MPLS_REFCNT_RELEASE(a->session, ldp_session_delete); a->session = NULL; return MPLS_SUCCESS; } return MPLS_FAILURE; }
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; }
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; }
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; }
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; }
mpls_return_enum ldp_inlabel_del_outlabel(ldp_global *g, ldp_inlabel * i) { MPLS_ASSERT(i && i->outlabel); { #if MPLS_USE_LSR lsr_xconnect xcon; xcon.insegment_index = i->info.handle; xcon.outsegment_index = i->outlabel->info.handle; lsr_cfg_xconnect_set2(g->lsr_handle, &xcon, LSR_CFG_DEL); #else mpls_mpls_xconnect_del(g->mpls_handle, &i->info, &i->outlabel->info); #endif _ldp_outlabel_del_inlabel(i->outlabel, i); MPLS_REFCNT_RELEASE(i->outlabel, ldp_outlabel_delete); i->outlabel = NULL; } return MPLS_SUCCESS; }
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; }
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; }
void ldp_nexthop_del_outlabel(ldp_nexthop * nh) { MPLS_ASSERT(nh); MPLS_REFCNT_RELEASE(nh->outlabel, ldp_outlabel_delete); nh->outlabel = NULL; }
void _ldp_inlabel_del_session(ldp_inlabel * i, ldp_session * s) { MPLS_ASSERT(i && s); mpls_link_list_remove_data(&i->session_root, s); MPLS_REFCNT_RELEASE(s, ldp_session_delete); }
void _ldp_adj_del_entity(ldp_adj * a, ldp_entity *e) { MPLS_ASSERT(a && e); MPLS_REFCNT_RELEASE(e, ldp_entity_delete); a->entity = NULL; }
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"); }
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"); }