📄 rsvp_resv.c
字号:
break; } return(rp);}/* * Return pointer to RSB for (SESSION, NHOP, [FILTER_SPEC *]), * or NULL if none is found. */RSB *locate_RSB(Session *destp, RSVP_HOP *nhopp, FiltSpecStar *filtssp, style_t style) { RSB *rp; for (rp = destp->d_RSB_list; rp != NULL; rp = rp->rs_next) { if (!hop_eq(nhopp,&rp->rs_nhop)) continue; if (Style_is_Shared(style) || match_filter(filtssp->fst_filtp0, rp->rs_filter0)) break; } return(rp);}RSB *make_RSB( Session *destp, int count) { int n; RSB *rp; n = SizeofFiltSpecStar(1) + sizeof(RSB); rp = (RSB *) malloc(n); if (!rp) return(NULL); memset((char *)rp, 0, n);#ifndef LPM rp->rs_next = destp->d_RSB_list; destp->d_RSB_list = rp;#endif /* Intially, a one-slot FiltSpecStar is allocated contiguous to * RSB. But if count>1, enlarge it by malloc. */ rp->rs_filtstar = (FiltSpecStar *)((char *) rp + sizeof(RSB)); rp->rs_filtstar->fst_size = 1; rp->rs_filtstar->fst_count = 0; while (rp->rs_filtstar->fst_size < count) { if (!enlarge_RSB_filtstar(rp)) { if (rp->rs_filtstar->fst_size > 1) free(rp->rs_filtstar); free(rp); return(NULL); } } return(rp);}/* Enlarge filtspecstar of given RSB. Malloc a new area. */intenlarge_RSB_filtstar(RSB *rp) { int orig_size = rp->rs_filtstar->fst_size; int new_size = orig_size+4; int L = SizeofFiltSpecStar(new_size); FiltSpecStar *fsp = malloc(L); if (!fsp) return(0); memset((char *)fsp, 0, L); memcpy((char *)fsp, (char *)rp->rs_filtstar, SizeofFiltSpecStar(orig_size)); fsp->fst_size = new_size; if (orig_size > 1) free(rp->rs_filtstar); rp->rs_filtstar = fsp; return(1);}/* kill_RSB(): Delete specified reservation request element RSB and adjust * TC reservation state accordingly. */intkill_RSB(Session *destp, RSB *rp) { if (!rp) return 0; return (kill_RSB1(destp, rp, 1));}/* kill_newRSB(): Delete specified RSB that was in process of being * created, but not yet reflected in TC reservation. */voidkill_newRSB(Session *destp, RSB *rp) { kill_RSB1(destp, rp, 0);}/* Common inner routine for kill_[new]RSB() * Returns Refresh_Needed */intkill_RSB1(Session *destp, RSB *rp, int isold) { RSB **rpp; int i; int Refresh_Needed = 0; /* Delete RSB from list, and then call LL_DelFlow to make * make LL reservation consistent with reduced set of RSBs * (unless RSB was new). * Note: Deleting a reservation request cannot increase the * kernel flowspec. In the unlikely event that this results * in an Admission Control failure, we just ignore it; the * original reservation will stay in place. */ for (rpp = &destp->d_RSB_list; (*rpp) != NULL && (*rpp) != rp; rpp = &((*rpp)->rs_next)); if (*rpp != NULL) *rpp = rp->rs_next; if (isold) { int rc; /* Note: for FF style, have not yet deleted filter spec */ rc = LL_DelFlow(rp->rs_OIf, destp, rp); if (rc != LLDAL_RC_LATER) Complete_DelFlow(destp, rp, 0); Refresh_Needed = 1; } /* If this was last RSB for session, delete Resv refresh timer */ if (destp->d_RSB_list == NULL) { del_from_timer((char *) destp, TIMEV_RESV); destp->d_timevalr.timev_R = 0; } /* Free everything in sight... */ if (rp->rs_spec) free(rp->rs_spec); for (i=0; i < rp->rs_fcount; i++) if (rp->rs_Filtp(i)) free(rp->rs_Filtp(i)); if (rp->rs_filtstar->fst_size > 1) free(rp->rs_filtstar); if (rp->rs_fwd_spec) free(rp->rs_fwd_spec); if (rp->rs_scope) { free(rp->rs_scope); clear_scope_union(destp); /* Set to recompute scope union */ } if (rp->rs_confirm) free(rp->rs_confirm); FQkill(&rp->rs_UnkObjList); free((char *)rp); return(Refresh_Needed);}/* Update RSB time-to-die from MIN of ttd's of filter specs. */voidresv_update_ttd(RSB *rp, u_int32_t ttd) { int j; for (j= 0; j < rp->rs_fcount; j++) ttd = MIN(ttd, rp->rs_Filt_TTD(j)); rp->rs_ttd = ttd;}/* Buy storage and initialize FILTER_SPEC* structure with n slots. */FiltSpecStar *Get_FiltSpecStar(int n) { FiltSpecStar *filtssp; int len = SizeofFiltSpecStar(n); filtssp = (FiltSpecStar *) malloc(len); if (filtssp) { memset((char *)filtssp, 0, len); filtssp->fst_size = n; } return(filtssp);}/* Return index in FILTER_SPEC* vector of filter matching *filtp, * or -1. But if filtp = NULL, look for empty slot. If can't find * one, try to expand; if that fails, return -1. */intfind_fstar( FILTER_SPEC *filtp, FiltSpecStar *filtssp) { int i; if (!filtssp) return 0; /* Wildcard */ if (!filtp) { for (i= 0; i < filtssp->fst_count; i++) { if (filtssp->fst_Filtp(i) == NULL) return(i); } /* * Empty slot not found. Get next slot if available. */ if (filtssp->fst_count < filtssp->fst_size) return(filtssp->fst_count++); return(-1); } for (i= 0; i < filtssp->fst_count; i++) { if (match_filter(filtp, filtssp->fst_Filtp(i))) return(i); } return(-1);}/* Return 1 if FILTER_SPEC matches a filter in FILTER_SPEC*, else 0. * */intmatch_filt2star(FILTER_SPEC *filtp, FiltSpecStar *fssp) { int i; for (i= 0; i < fssp->fst_count; i++) { if ((fssp->fst_Filtp(i)) && match_filter(filtp, fssp->fst_Filtp(i))) return(1); } return(0);}/* Coalesce (RSB) FILTER SPEC list, removing entries whose TTD is zero. */voidcoalesce_filtstar(FiltSpecStar *filtssp) { int i, j; i = 0; for (j= 0; j < filtssp->fst_count; j++) { if (filtssp->fst_Filt_TTD(j)) { filtssp->fst_Filtp(i) = filtssp->fst_Filtp(j); filtssp->fst_Filt_TTD(i++) = filtssp->fst_Filt_TTD(j); } } filtssp->fst_count = i;}voidmap2FiltStar(struct packet *pkt, FiltSpecStar *filtssp) { int i; filtssp->fst_count = pkt->rsvp_nflwd; for (i=0; i < pkt->rsvp_nflwd; i++) { filtssp->fst_Filtp(i) = filter_of(FlowDesc_of(pkt, i)); filtssp->fst_Filt_TTD(i) = 0; }}/* * Decide whether a SCOPE object is needed in WF Resv refresh message * to given PHOP P for which there is path state. * * A SCOPE object is needed for phop P with path state if: * there is an RSB R to which data from P is routed, AND * o R has a SCOPE list, OR * o There path state for a PHOP P' != P, such that data * form P' is also routed to R */intis_scope_needed(Session *destp, PSB *psbp) { RSB *rp; PSB *sp; /* For each RSB R... */ for (rp = destp->d_RSB_list; rp != NULL; rp = rp->rs_next) { if (!IsRoutePSB2nhop(destp, psbp, &rp->rs_rsvp_nhop)) continue; /* If RSB has SCOPE list, return True. Otherwise, * scan list of PSBs for those that route to R. * If PSB has PHOP != P, then return true. */ if (rp->rs_scope) return(1); for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) { if (!IsRoutePSB2nhop(destp, sp, &rp->rs_rsvp_nhop)) continue; if (hop_addr_eq(&sp->ps_phop, &psbp->ps_phop)) return(1); } } return(0);} /* * common_resv_header(): Fill in common header fields for Resv msg */voidcommon_resv_header(struct packet *pkt, Session *destp) { static RSVP_HOP hop; packet_map *mapp = pkt->pkt_map; mapp->rsvp_msgtype = RSVP_RESV; mapp->rsvp_session = destp->d_session; mapp->rsvp_timev = &destp->d_timevalr; mapp->rsvp_hop = &hop; mapp->rsvp_dpolicy = NULL; pkt->rsvp_nflwd = 0; switch(Obj_CType(destp->d_session)) { case ctype_SESSION_ipv4: case ctype_SESSION_ipv4GPI: Init_Object(&hop,RSVP_HOP,RSVP_HOP_ipv4); break;#ifdef USE_IPV6 case ctype_SESSION_ipv6: case ctype_SESSION_ipv6GPI: Init_Object(&hop,RSVP_HOP,RSVP_HOP_ipv6); break;#endif /* USE_IPV6 */ default: Init_Object(&hop,NULL,NULL); break; }}/* * common_resv_tear_header(): Fill in common header fields for Resv_Tear */voidcommon_resv_tear_header(struct packet *pkt, Session *destp) { static RSVP_HOP hop; packet_map *mapp = pkt->pkt_map; mapp->rsvp_msgtype = RSVP_RESV_TEAR; mapp->rsvp_session = destp->d_session; mapp->rsvp_hop = &hop; mapp->rsvp_style = &Style_Obj; Init_Object(&Style_Obj,STYLE,STYLE_CTYPE); mapp->rsvp_nlist = 0; switch(Obj_CType(destp->d_session)) { case ctype_SESSION_ipv4: case ctype_SESSION_ipv4GPI: Init_Object(&hop,RSVP_HOP,RSVP_HOP_ipv4); break;#ifdef USE_IPV6 case ctype_SESSION_ipv6: case ctype_SESSION_ipv6GPI: Init_Object(&hop,RSVP_HOP,RSVP_HOP_ipv6); break;#endif /* USE_IPV6 */ default: Init_Object(&hop,NULL,NULL); break; }}/* * send_resv_out(): Send out Resv message to specified address. */static voidsend_resv_out( PSB *psbp, struct packet *pkt) { int outif = psbp->ps_in_if; FORCE_HOST_ORDER(pkt); if (outif == -1) { switch(Obj_CType(&psbp->ps_rsvp_phop)) { case ctype_RSVP_HOP_ipv4: outif = local_v4; break;#ifdef USE_IPV6 case ctype_RSVP_HOP_ipv6: outif = local_v6; break;#endif /* USE_IPV6 */ default: return; } } hop_if_assign(pkt->rsvp_nhop,&GET_IF(outif), hop_lih(&psbp->ps_rsvp_phop)); send_pkt_out_if(IF_UNICAST(outif), &psbp->ps_rsvp_phop, pkt);}intStyles_are_compat(style_t st1, style_t st2) { if (st1 == st2) return 1; else return 0;}/* Compute B_Police flag for given 'active' RSB. * * Scan all RSB's matching SESSION (and Filter spec list, if * distinct style) for all OI different from active RSB. * Return the TC_B_Police flag if RSB's flowspec is smaller * than, or incomparable to, any FLOWSPEC in those RSBs. */intIs_B_Police(Session *destp, RSB *rp) { RSB *trp; int rc; for (trp = destp->d_RSB_list; trp != NULL; trp = trp->rs_next) { if (trp->rs_OIf == rp->rs_OIf) continue; if ( !Style_is_Shared(rp->rs_style) && !match_filter(trp->rs_filter0, rp->rs_filter0)) continue; rc = Compare_Flowspecs(trp->rs_spec, rp->rs_spec); if (rc == SPEC1_GTR || rc == SPECS_INCOMPAT) return(TCF_B_POLICE); } return(0);}/* * Compute reservation properties from path state for reservation * for given NHOP, OI, and filter spec list. * * o Locate the set of PSBs (senders) that map to this NHOP and * FiltSpecList, and return count of these PSBs. * * o Compute Path_Te as the sum of the SENDER_TSPEC objects * * o Compute Path_Adspec. Note: we use the *first* adspec. * Since Guaranteed service only makes sense for distinct * style, this should be OK. * * o Set TC_E_Police flag if any of these PSBs have their * E-Police flag on. Set TC_M_Police flag on if it * is a shared style and there is more than one PSB * in the set. */intCompute_Path_Props(Session *destp, RSB *rp, FiltSpecStar *filtpp, SENDER_TSPEC *Path_Tep, ADSPEC **Path_Adspp, int *flagp) { PSB *sp; int sender_cnt = 0; Init_Object(Path_Tep, SENDER_TSPEC, SENDER_TSPEC_CTYPE); sender_cnt = 0; *Path_Adspp = NULL; for (sp = destp->d_PSB_list ; sp != NULL; sp = sp->ps_next) { if (!IsRoutePSB2nhop(destp,sp,&rp->rs_rsvp_nhop) || ( !Style_is_Wildcard(rp->rs_style) && !match_filt2star(sp->ps_templ, filtpp))) continue; sender_cnt++; addTspec2sum(sp->ps_tspec, Path_Tep); if (sp->ps_flags & PSBF_E_Police || (IF_FLAGS((int)sp->ps_in_if) & IF_FLAG_Police)) *flagp |= TCF_E_POLICE; if (*Path_Adspp == NULL) *Path_Adspp = copy_adspec(sp->ps_adspec); } if (sender_cnt > 1) *flagp |= TCF_M_POLICE; return(sender_cnt);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -