📄 rsvp_llkern.c
字号:
if (rp->rs_flags & RSB_FLAG_MERGED) kp->tcs_flags |= TCF_MERGED; /* * If there are no matching RSBs now, simply kill the reservation */ if (!TC_specp) { if (IsDebug(DEBUG_ALL)) { log_K(LOGEV_TC_delflow, destp, kp); if (IsDebug(DEBUG_EVENTS)) log(LOG_DEBUG, 0, " flowspec= %s\n", fmt_flowspec(kp->tcs_spec)); }#ifdef SCHEDULE TC_DelFlowspec(kp->tcs_OIf, kp->tcs_rhandle);#endif kill_TCSB(destp, kp); if (TC_FiltSp) free(TC_FiltSp); return(LLDAL_RC_OK); } /* * Else recompute everything and update reservation */ return(KernTC_ModFlowspec(destp, rp));}/* * KernTC_Advertise(Session, PSB) * * Pass Adspec (pt'd to by PSB) to traffic control, to be updated. * */intKernTC_Advertise(int OI, Session *destp, PSB *psbp) { psbp->ps_newadspec = TC_Advertise(OI, psbp->ps_adspec, (int) psbp->ps_flags&PSBF_NonRSVP); return(LLDAL_RC_OK);}/* * KernTC_GetInfo(Session, RSB, item#) * * This is an exercise in information-hiding. Given (dummy) RSB defining * reservation, return pointers to objects containing useful effective * values as determined by the link layer: Tspec, flowspec, and filtspec*. * Flowspec and filtspecstar pointers are returned in the normal * places, while the Tspec is returned in rs_oldspec. * Also, the RSB_MERGED_FLAG is set 0/1. */intKernTC_GetInfo(Session *destp, RSB *rp) { TCSB *kp; Fobject *copy_obj2Fobj(Object_header *); kp = locate_TCSB(destp, rp->rs_OIf, rp->rs_filtstar, rp->rs_style); if (!kp || rp->rs_UnkObjList) return(LLDAL_RC_ERROR); rp->rs_spec = kp->tcs_spec; rp->rs_filtstar = kp->tcs_filtstar; rp->rs_oldspec = (FLOWSPEC *) kp->tcs_tspec; rp->rs_flags &= ~RSB_FLAG_MERGED; if (kp->tcs_flags & TCF_MERGED) rp->rs_flags |= RSB_FLAG_MERGED; return(LLDAL_RC_OK);}/* * KernTC_BugDump(OIf, session) */intKernTC_BugDump(int OIf, Session *destp) { TCSB *kp; void dump_filtstar(FiltSpecStar *, FLOWSPEC *); for (kp = (TCSB *) destp->d_LLB_listv[OIf]; kp != NULL; kp = kp->tcs_next) { if (IsNumAPI(OIf)) log(LOG_DEBUG, 0, " Kernel reservation: API Rhandle %x\n", kp->tcs_rhandle); else { log(LOG_DEBUG, 0, " Kernel reservation: Iface %d (%s) Rhandle %x \n", OIf, net_if_print(&GET_IF(OIf)), kp->tcs_rhandle); dump_filtstar(kp->tcs_filtstar, kp->tcs_spec); } } return(LLDAL_RC_OK);} /******************************************************************* * Auxiliary Routines * *******************************************************************//* * Kernel_SetFilters() * * Make FILTER_SPEC* in TCSB agree with given filter spec list * (empty for WF); call TC as necessary. If it fails, returns * -1; if there is a change, returns +1; else returns 0; */intKernel_SetFilters(Session *destp, TCSB *kp, FiltSpecStar *TC_FiltSp) { FiltSpecStar *filtssp; /* Empty filt* for WF */ int i, j, rc; /* Special case: insert "wildcard filter" for WF */ filtssp = kp->tcs_filtstar; if (TC_FiltSp->fst_count == 0) {#ifdef SCHEDULE rc = TC_AddFilter(kp->tcs_OIf, kp->tcs_rhandle, destp, NULL);#endif if (IsDebug(DEBUG_ALL)) { log_K(LOGEV_TC_addfilt, destp, kp); if (IsDebug(DEBUG_EVENTS)) log(LOG_DEBUG, 0, " WF Filter, Fhandle=%d\n", rc); } if (rc == TC_ERROR) return(LLDAL_RC_ERROR); } /* * 1. Delete any filter specs in TCSB that are not in *TC_FiltSp. */ for (i= 0; i < filtssp->fst_count; i++) { if (filtssp->fst_Filtp(i)&& find_fstar(filtssp->fst_Filtp(i), TC_FiltSp) < 0) {#ifdef SCHEDULE rc = TC_DelFilter(kp->tcs_OIf, filtssp->fst_p[i].Fhandle);#endif if (IsDebug(DEBUG_ALL)) { log_K(LOGEV_TC_delfilt, destp, kp); if (IsDebug(DEBUG_EVENTS)) log(LOG_DEBUG, 0, " Fhandle= %d\n", filtssp->fst_p[i].Fhandle); } if (rc == TC_ERROR) return(LLDAL_RC_ERROR); filtssp->fst_p[i].Fhandle = 0; free(filtssp->fst_Filtp(i)); filtssp->fst_Filtp(i) = NULL; } } /* * 2. Add to TCSB any filter specs in TC_Filtstar but not in TCSB. */ for (j= 0; j < TC_FiltSp->fst_count; j++) { FILTER_SPEC *filtp = TC_FiltSp->fst_Filtp(j); if (find_fstar(filtp, filtssp)<0) { i = find_fstar(NULL, filtssp); if (i < 0) { /* Damn... FiltSpecStar area needs to grow! */ kp = trade_TCSB(destp, kp, kp->tcs_filtstar->fst_size+16); if (!kp) goto Mem_setf_error; i = find_fstar(NULL, kp->tcs_filtstar); assert(i >= 0); filtssp = kp->tcs_filtstar; }#ifdef SCHEDULE rc = TC_AddFilter(kp->tcs_OIf, kp->tcs_rhandle, destp, filtp);#endif if (IsDebug(DEBUG_ALL)) { log_K(LOGEV_TC_addfilt, destp, kp); if (IsDebug(DEBUG_EVENTS)) log(LOG_DEBUG, 0, " Filter= %s Fhandle=%d\n", fmt_filtspec(filtp), rc); } if (rc == TC_ERROR) return(LLDAL_RC_ERROR); assert(filtssp->fst_count <= filtssp->fst_size); filtssp->fst_p[i].Fhandle = rc; filtssp->fst_Filtp(i) = copy_filter(filtp); } } return(LLDAL_RC_OK);Mem_setf_error: rsvp_errno = Set_Errno( RSVP_Err_RSVP_SYS_ERROR, RSVP_Erv_MEMORY); return(LLDAL_RC_ERROR);}/* Consider the set of RSB's matching SESSION and OI from the * active RSB. If the style is distinct, the Filterspec_list * in the RSB must also be matched. Merge them to compute * and return pointers to: * * o TC_spec, (copy of) effective TC flowspec to be installed * * o TC_FiltS, (copy of) union of FILTER_SPEC*'s in the set. * * It also sets MERGED flag on/off in active RSB, and returns * LLDAL_RC_OK or LLDAL_RC_ERROR. */intKernel_Merge(Session *destp, RSB *rp, FLOWSPEC **TC_specpp, FiltSpecStar **TC_FiltSpp) { RSB *trp; int cmp; FLOWSPEC *specp = NULL; int count = 0; *TC_specpp = NULL; *TC_FiltSpp = NULL; for (trp = destp->d_RSB_list; trp != NULL; trp = trp->rs_next) { if (!RSBs4_sameLL(trp, rp)) continue; count++; cmp = Compare_Flowspecs(trp->rs_spec, specp); switch (cmp) { case SPEC1_GTR: specp = trp->rs_spec; break; case SPECS_USELUB: specp = LUB_of_Flowspecs(trp->rs_spec, specp); break; case SPECS_INCOMPAT: rsvp_errno = Set_Errno( RSVP_Err_TC_ERROR, RSVP_Erv_Conflict_Serv); return(LLDAL_RC_ERROR); default: break; } if (union_filtstar(trp->rs_filtstar, TC_FiltSpp) < 0) goto Mem_merge_error; } *TC_specpp = copy_spec(specp); if ((!*TC_specpp) && specp) goto Mem_merge_error; rp->rs_flags &= ~RSB_FLAG_MERGED; if (count > 1) rp->rs_flags |= RSB_FLAG_MERGED; return(LLDAL_RC_OK);Mem_merge_error: rsvp_errno = Set_Errno( RSVP_Err_RSVP_SYS_ERROR, RSVP_Erv_MEMORY); return(LLDAL_RC_ERROR);}/* * TC_Newflow or TC_ModFlow returned a new flowspec, attach it to * the first matching RSB (same OI, filter spec). */intKernel_Return_Spec(Session *destp, RSB *rp, FLOWSPEC *Fwd_specp) { RSB *trp; int rc = LLDAL_RC_OK; for (trp = destp->d_RSB_list; trp != NULL; trp = trp->rs_next) { if (!RSBs4_sameLL(trp, rp)) continue; if (trp->rs_fwd_spec) free(trp->rs_fwd_spec); trp->rs_fwd_spec = copy_spec(Fwd_specp); if (!trp->rs_fwd_spec) rc = LLDAL_RC_ERROR; break; } free(Fwd_specp); return(rc);}/************************************************************************* * * Utility routines * *************************************************************************/TCSB *locate_TCSB( Session *destp, int out_if, FiltSpecStar *filtssp, style_t style) { TCSB *kp; if (Style_is_Shared(style)) return((TCSB *)destp->d_LLB_listv[out_if]); for (kp = (TCSB *)destp->d_LLB_listv[out_if]; kp != NULL; kp = kp->tcs_next) { if (match_filter(filtssp->fst_filtp0, kp->tcs_filtstar->fst_filtp0)) break; } return(kp);} /* Make TCSB control block with 'nhandles' empty filter * spec slots. */TCSB *make_TCSB(Session *destp, int out_if, int nhandles) { TCSB *kp; int size; /* Allocate TCSB with contiguous FiltSpecStar area. Clear all. */ size = SizeofFiltSpecStar(nhandles) + sizeof(TCSB); kp = (TCSB *) malloc(size); if (!kp) { Log_Mem_Full("TCresv1"); return(NULL); } memset((char *)kp, 0, size); kp->tcs_filtstar = (FiltSpecStar *)((char *) kp + sizeof(TCSB)); kp->tcs_next = (TCSB *)destp->d_LLB_listv[out_if]; destp->d_LLB_listv[out_if] = (void *)kp; /*** kp->tcs_OIf = if_vec[out_if].if_index; ***/ kp->tcs_OIf = out_if; kp->tcs_filtstar->fst_count = 0; kp->tcs_filtstar->fst_size = nhandles; return(kp);}/* Expand an existing TCSB control block with space for nhandle * filter handles. */TCSB *trade_TCSB(Session *destp, TCSB *kp, int nhandles) { TCSB *nkp; int n = kp->tcs_filtstar->fst_size; nkp = make_TCSB(destp, kp->tcs_OIf, nhandles); if (!nkp) { Log_Mem_Full("TCresv1"); return(NULL); } memcpy(nkp, kp, sizeof(TCSB)); nkp->tcs_filtstar = (FiltSpecStar *)((char *) nkp + sizeof(TCSB)); memcpy( (char *) nkp->tcs_filtstar, (char *) kp->tcs_filtstar, SizeofFiltSpecStar(n)); nkp->tcs_filtstar->fst_size = nhandles; free(kp); return(nkp);}/* * kill_TCSB(): Delete kernel reservation block */voidkill_TCSB(Session *destp, TCSB *kp) { TCSB **kpp; FiltSpecStar *filtssp; int i, OIf = kp->tcs_OIf; if (!kp) return; /* Unlink and delete kp */ for (kpp = (TCSB **)&destp->d_LLB_listv[OIf]; (*kpp) != NULL && (*kpp) != kp; kpp = &((*kpp)->tcs_next)); if (*kpp != NULL) *kpp = kp->tcs_next; free(kp->tcs_spec); if (kp->tcs_tspec) free(kp->tcs_tspec); filtssp = kp->tcs_filtstar; for (i=0; i < filtssp->fst_count; i++) if (filtssp->fst_Filtp(i)) free(filtssp->fst_Filtp(i)); free((char *)kp);}/**#define INIT_FST_COUNT 100 **/#define INIT_FST_COUNT 1 /* for testing XXX *//* Add new FiltSpecStar to union. Return -1 if error, else 0. */intunion_filtstar(FiltSpecStar *newfsp, FiltSpecStar **fspp) { FiltSpecStar *fsp = *fspp, *nfsp; int i, j; if (fsp == NULL) { /* First time... malloc an area. */ fsp = Get_FiltSpecStar(INIT_FST_COUNT); if (!fsp) return(-1); } for (i= 0; i < newfsp->fst_count; i++) { FILTER_SPEC *filtp = newfsp->fst_Filtp(i); for (j = 0; j < fsp->fst_count; j++) { if (match_filter(filtp, fsp->fst_Filtp(j))) break; } if (j == fsp->fst_count) { /* Add new filter to union */ if (fsp->fst_count >= fsp->fst_size) { nfsp = Get_FiltSpecStar(2*fsp->fst_count); if (!nfsp) return(-1); memcpy(nfsp, fsp, sizeof(FiltSpecStar) + (fsp->fst_count-1)*sizeof(FILTER_SPEC *)); nfsp->fst_size = 2*fsp->fst_count; free(fsp); fsp = nfsp; } fsp->fst_p[fsp->fst_count++].fst_filtp = filtp; } } *fspp = fsp; return(0);} voidlog_K(int evtype, Session *destp, TCSB *kp) { char *flgstr = cnv_flags("?????BME", kp->tcs_kflags); log_event(evtype, if_vec[kp->tcs_OIf].if_name, destp->d_session, " Flg=%s =>handle=%d\n", flgstr, kp->tcs_rhandle);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -