📄 rsvp_resv.c
字号:
(Object_header *) pkt->pkt_map->rsvp_confirm); NeworMod = 1; } if (!new_RSB) { /* * If active RSB is not new, check whether STYLE, FLOWSPEC, * or SCOPE objects have changed; if so, copy changed * object into RSB and turn on the NeworMod flag. */ if (rp->rs_style != style) { rp->rs_style = style; NeworMod = 1; } if (Compare_Flowspecs(specp, rp->rs_spec) != SPECS_EQL) { /* If flowspec has changed, keep old one in case * Admission Control fails, and pass new one * to link layer. */ rp->rs_oldspec = rp->rs_spec; rp->rs_spec = copy_spec(specp); rc = LL_ModFlowspec(rp->rs_OIf, destp, rp); if (rc != LLDAL_RC_LATER) /* synchronous */ Complete_ModFlowspec(destp, rp, rc); if (rc == LLDAL_RC_ERROR) return(-1); NeworMod = 1; } if ((pkt->pkt_map->rsvp_scope_list) && !match_scope(rp->rs_scope, pkt->pkt_map->rsvp_scope_list)){ clear_scope_union(destp); /* Recompute scope union */ if (rp->rs_scope) free(rp->rs_scope); rp->rs_scope = copy_scope(pkt->pkt_map->rsvp_scope_list); NeworMod = 1; } } return(NeworMod);}intComplete_NewFlow(Session *destp, RSB *rp, int rc) { if (rc == LLDAL_RC_ERROR) { /* * Admission Control failed for new RSB. Send * error msg using side-effect variable rsvp_errno * and delete RSB. */ rsvp_RSB_err(destp, rp, Get_Errcode(rsvp_errno), Get_Errval(rsvp_errno) /* , 0 XXX */); kill_newRSB(destp, rp); return(-1); } /* If resv state (may have) changed and not API, * do RESV_EVENT upcall now. */ if (!IsHopAPI(&rp->rs_nhop)) api_RESV_EVENT_upcall(destp, rp); return(0);}intComplete_ModFlowspec(Session *destp, RSB *rp, int rc) { if (rc == LLDAL_RC_ERROR) { /* * Admission Control failed for existing RSB. Send * error msg using side-effect variable rsvp_errno * and restore previous flowspec. Delete any * confirmation object. */ rsvp_RSB_err(destp, rp, Get_Errcode(rsvp_errno), Get_Errval(rsvp_errno) /* , ERROR_SPECF_InPlace XXX */); if (rp->rs_oldspec) { free((char *) rp->rs_spec); rp->rs_spec = rp->rs_oldspec; rp->rs_oldspec = NULL; } if (rp->rs_confirm) free(rp->rs_confirm); rp->rs_confirm = NULL; return(-1); } else if (rp->rs_oldspec) { free((char *) rp->rs_oldspec); rp->rs_oldspec = NULL; } /* If resv state (may have) changed and network reservation, * do RESV_EVENT upcall now. */ if (!IsHopAPI(&rp->rs_nhop)) api_RESV_EVENT_upcall(destp, rp); return(0);}intComplete_ModFilter(Session *destp, RSB *rp, int rc) { if (rc == LLDAL_RC_ERROR) { rsvp_RSB_err(destp, rp, Get_Errcode(rsvp_errno), Get_Errval(rsvp_errno) /* , ERROR_SPECF_InPlace XXX */); return(-1); } /* If resv state (may have) changed and not API, * do RESV_EVENT upcall now. */ if (!IsHopAPI(&rp->rs_nhop)) api_RESV_EVENT_upcall(destp, rp); return(0);}intComplete_DelFlow(Session *destp, RSB *rp, int rc) { /* If resv state (may have) changed and not from API, * do RESV_EVENT upcall now. * Mark as teardown by deleting flowspec. */ if (!IsHopAPI(&rp->rs_nhop)) { free(rp->rs_spec); rp->rs_spec = NULL; api_RESV_EVENT_upcall(destp, rp); } return(0);}/* * accept_resv_tear(): Process an incoming ResvTear message */intaccept_resv_tear( int in_if, /* Alleged outgoing iface (IGNORED) */ struct packet *pkt) { Session *destp; PSB *sp; RSB *rp; FiltSpecStar filtss; packet_area data; struct packet *outpkt; int out_vif; style_t style = Style(pkt); int Refresh_Needed; int m_size = (char *) &pkt->pkt_map->rsvp_list - (char *) pkt->pkt_map; int i, j, nmatch, rc; RSVP_HOP *nhopp; /* The logical outgoing interface OI is taken from the LIH in * the NHOP object. */ /* Changed by Mohit from * out_vif = hop_lih(pkt->rsvp_nhop); */ out_vif = IsHopAPI(pkt->rsvp_nhop) ? api_num : hop_lih(pkt->rsvp_nhop); nhopp = pkt->pkt_map->rsvp_hop; Incr_ifstats(out_vif, rsvpstat_msgs_in[RSVP_RESV_TEAR]); /* Check that INTEGRITY was included if it is required. */ if ((IF_FLAGS(out_vif)&IF_FLAG_Intgrty) && pkt->pkt_map->rsvp_integrity == NULL) return PKT_ERR_INTEGRITY; destp = locate_session(pkt->rsvp_sess); if (!destp) return(0); /* Check that styles match. Send BAD_STYLE error if not, * and ignore ResvTear message [THIS CASE NOT IN SPEC] */ if ((rp = destp->d_RSB_list) && (rp->rs_style != style)) { rsvp_resv_err(RSVP_Err_BAD_STYLE, 0, 0, (FiltSpecStar *) -1 /*all*/, pkt); return(0); } /* Process the flow descriptor list in the ResvTear message to * tear down local reservation state in style-dependent manner. */ if (!Style_is_Shared(style)) { /* FF */ filtss.fst_count = 1; for (i = 0; i < pkt->rsvp_nflwd; i++) { filtss.fst_filtp0 = filter_of(FlowDesc_of(pkt, i)); rp = locate_RSB(destp, nhopp, &filtss, style); Refresh_Needed |= kill_RSB(destp, rp); } } else { /* WF or SE */ rp = locate_RSB(destp, nhopp, NULL, style); if (!rp) return(0); /* * Mark filter specs to be torn down */ for (i=0; i < pkt->rsvp_nflwd; i++) { for (j= 0; j < rp->rs_fcount; j++) { if (match_filter( filter_of(FlowDesc_of(pkt, i)), rp->rs_Filtp(j))) { free(rp->rs_Filtp(j)); rp->rs_Filt_TTD(j) = 0; } } } /* Squeeze out marked filter spec entries. If filters * are all gone, delete RSB and update LL; else just * update LL. */ coalesce_filtstar(rp->rs_filtstar); if (rp->rs_fcount == 0) Refresh_Needed |= kill_RSB(destp, rp); else { rc = LL_ModFilter(rp->rs_OIf, destp, rp); if (rc != LLDAL_RC_LATER) Complete_ModFilter(destp, rp, rc); if (rc == LLDAL_RC_ERROR) return(-1); } } /* Create ResvTear msg template. Copy into map everything * up to flow descriptor list. Make a separate copy of the * HOP object, since we will change it when we send Tear msg(s). */ outpkt = new_packet_area(&data); memcpy((char*) outpkt->pkt_map, (char *) pkt->pkt_map, m_size); outpkt->pkt_map->rsvp_hop = (RSVP_HOP *) copy_object((Object_header *)nhopp); outpkt->pkt_map->rsvp_UnkObjList = pkt->pkt_map->rsvp_UnkObjList; outpkt->rsvp_scope = NULL; outpkt->rsvp_nflwd = 0; /* Forward ResvTear messages to all PHOPs whose PSBs route * to the RSB that has been deleted. Include a particular * sender only if there are no other RSBs that were merged * with the deleted RSB. * * Select each PSB whose OutInterface_list includes the * outgoing interface OI (more strictly, that routes to NHOP). * For distinct style, SENDER_TEMPLATE must also match a * filter spec in the received ResvTear. * * This logic assumes that PSBs are ordered by phop address. */ nmatch = 0; for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) { if (IsHopAPI(&sp->ps_phop)) continue; if (!IsRoutePSB2nhop(destp, sp, nhopp)) continue; if (Style_is_Wildcard(style)) { nmatch++; resv_tear_PSB(destp, sp, Style(pkt), NULL, outpkt); } else { for (j = 0; j < pkt->rsvp_nflwd; j++) { if (match_filter(sp->ps_templ, filter_of(FlowDesc_of(pkt, j)))) { nmatch++; /* Do PSB-specific processing to build * flow descriptor list in outpkt, if * appropriate. */ resv_tear_PSB(destp, sp, Style(pkt), filter_of(FlowDesc_of(pkt,j)), outpkt); } } } /* If the next PSB is for a different PHOP or the last * PSB has been processed, forward any ResvTear message * that has been built. */ if (sp->ps_next == NULL || !hop_addr_eq(&sp->ps_next->ps_phop,&sp->ps_phop)) { if (outpkt->rsvp_nflwd) send_resv_out(sp, outpkt); outpkt->rsvp_nflwd = 0; } } /* If any PSB's were found in the preceding step, and if the * Resv_Refresh_Needed flag is now on, execute the RESV REFRESH * sequence. resv_tear_PSB has set bits for incoming * interfaces to be refreshed. */ if (nmatch > 0 && (Refresh_Needed)) resv_refresh(destp, 0); free(outpkt->pkt_map->rsvp_hop); dump_ds(1); /* Log state change */ return(0);}/* Do PSB-specific processing to create Resv_Tear message: build flow * descriptor list in outpkt. */voidresv_tear_PSB( Session *destp, PSB *sp, style_t style, FILTER_SPEC *filtp, /* NULL for wildcard */ struct packet *outpkt) { FlowDesc *outflwdp; PSB *BSBp, *tsp; /* Delete last FLOWSPEC sent to this PSB, and blockade state. */ tsp = (Style_is_Wildcard(style))? sp->ps_1stphop: sp; if (tsp->ps_resv_spec) { free(tsp->ps_resv_spec); tsp->ps_resv_spec = NULL; } BSBp = tsp; if (BSBp->ps_BSB_Qb) { free(BSBp->ps_BSB_Qb); BSBp->ps_BSB_Qb = NULL; BSBp->ps_BSB_Tb = 0; } /* - Search for an RSB (for any outgoing interface) to which the * PSB routes and whose FILTER_SPEC matches the PSB. * * - If an RSB is found, set to send a Resv refresh message to * it, and return. */ if (RSB_match_path(destp, sp)) { bmp_set(&(destp->d_r_incifs), sp->ps_in_if); return; } /* - Otherwise, add filter spec to the new ResvTear message * being built. We omit flowspec, as the protocol spec allows. */ outflwdp = FlowDesc_of(outpkt, outpkt->rsvp_nflwd); outflwdp->rsvp_specp = NULL; if (!Style_is_Wildcard(style) || outpkt->rsvp_nflwd == 0) { outflwdp->rsvp_filtp = filtp; outpkt->rsvp_nflwd++; }}/* * Resv refresh timeout has occurred. Refresh all Resv state for * given session. */ intresv_refresh_TimeOut(Session *destp) { PSB *sp; /* Clear last_FLOWSPEC pointers in all PSBs, and then * call common routine resv_refresh(). */ for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) { if (sp->ps_resv_spec) free(sp->ps_resv_spec); sp->ps_resv_spec = NULL; } return resv_refresh(destp, 0);} /* * resv_refresh(): Sends refresh Resv refresh message(s). * * Spec says resv refreshes are to be sent to specific PHOPs, or * to all PHOPs. This implementation cuts a corner, by sending * resv refreshes to specific incoming interfaces, selected by * bits in d_r_incifs; no bits => all. * * Parameter IsResvErr is 1 if entered from processing ResvErr. * * Returns: 0 if timer should be rescheduled, else -1. */intresv_refresh(Session *destp, int IsResvErr) { struct packet *pkt; packet_area data; PSB *sp; RSB *rp; style_t style; /* Time out any expired state for this Session, and if it's * all gone, return -1 => cancel refresh timer. */ cleanup_resv_state(destp); /* Create an output message containing INTEGRITY, * SESSION, RSVP_HOP, and TIME_VALUES objects. */ pkt = new_packet_area(&data); common_resv_header(pkt, destp); /* * Determine style for these reservations from the first * RSB for the session, and move the STYLE object into * the proto-message. */ rp = destp->d_RSB_list; if (!rp) return(-1); style = rp->rs_style; pkt->pkt_map->rsvp_style = &Style_Obj; Init_Object(&Style_Obj,STYLE,STYLE_CTYPE); Style_of(pkt)->style_word = style; /* If style is wildcard, form union of SCOPE lists from RSB's, * with local senders deleted. Call this scope_union. */ if (Style_is_Wildcard(style)) form_scope_union(destp); /* Initialize globals. Then select each sender PSB for desired * incinf and call resv_refresh_PSB() to add its contribution * to merged (& packed) Resv refresh message. For last PSB * for same PHOP, resv_refresh_PSB sends resulting Resv. */ pkt->rsvp_nflwd = 0; max_specp = NULL; confRSBp = NULL; UnkObjL_perPHOP = NULL; for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) { /* * Ignore senders whose incoming interfaces are not needed now. */ if (!bmp_zero(&(destp->d_r_incifs))&& !bmp_tst(&(destp->d_r_incifs), sp->ps_in_if)) continue; resv_refresh_PSB(destp, sp, pkt, IsResvErr); } pkt->rsvp_nflwd = 0; bmp_rst(&(destp->d_r_incifs)); if (confRSBp) { free(confRSBp->rs_confirm); confRSBp->rs_confirm = NULL; } return(0);}/* * resv_refresh_PSB(): Process one PSB to generate Resv refresh * message for its PHOP. If this is last PSB for PHOP, * send the Resv message. */intresv_refresh_PSB( Session *destp, PSB *sp, struct packet *pkt, int IsResvErr) { RSB *rp; PSB *BSBp; FlowDesc *flwdp; FLOWSPEC *fwd_specp; style_t style = Style(pkt); int B_Merge = 0; int i, n_match, cmp; packet_map *mapp = pkt->pkt_map; int Need_Scope = 0; Fobject *UnkObjectL; BSBp = (Style_is_Wildcard(style))? sp->ps_1stphop: sp; n_match = 0; UnkObjectL = NULL; /* * 1. Select all RSBs whose Filter_spec_lists match the * SENDER_TEMPLATE object and whose OI appears in the * OutInterface_list of the PSB * (i.e., to which the given PSB will route). */ for (rp = destp->d_RSB_list; rp != NULL; rp = rp->rs_next) { if (!PSBmaps2RSB(destp, sp, rp)) continue; /* If sender in PSB is API, then: * (a) If RSB has a CONFIRM object, then create and send * a ResvConf message containing the object, delete it. * (b) Continue with next RSB. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -