📄 rsvp_path.c
字号:
* For each expired PSB, forward PTear message to all * outgoing vifs and then kill PSB. */ for (psbp = destp->d_PSB_list; psbp; psbp = psbpx) { psbpx = psbp->ps_next; if (!LT(psbp->ps_ttd, time_now)) continue; killed = 1; Incr_ifstats(psbp->ps_in_if, rsvpstat_path_timeout); if (!pkt) pkt = new_packet_area(&data); rc = tear_PSB(destp, psbp, pkt, NULL); if (rc < 0) return -1; } return(killed);}/* * Delete a PSB: forward PTear message to all outgoing vifs and then kill * PSB. Common code for accept_path_tear() and cleanup_path_state(). * In the first case, specify list of unknown objects to be forwarded. */inttear_PSB(Session *destp, PSB *psbp, struct packet *pkt, Fobject *fobjp){ SenderDesc *newsdp; int vif; /* * Generate PathTear message */ pkt->pkt_map->rsvp_msgtype = RSVP_PATH_TEAR; common_path_header(destp, pkt); newsdp = SenderDesc_of(pkt); newsdp->rsvp_stempl = psbp->ps_templ; /* Omit Sender_Tspec and Adspec. */ pkt->pkt_map->rsvp_UnkObjList = fobjp; /* * Send PathTear message to each outgoing vif. */ if (psbp->ps_ip_ttl > 0) { pkt->pkt_ttl = psbp->ps_ip_ttl - 1; for (vif = 0; vif < if_num; vif++) { if (IsNumAPI(vif)) continue; if (IF_DOWN(vif)) continue; if (bmp_tst(&(psbp->ps_outif_list), vif)) send_path_out_vif(vif, destp, STempl_of(newsdp), pkt); } } return (kill_PSB(destp, psbp));}voidcommon_path_header(Session *destp, struct packet *pkt){ static RSVP_HOP hop; packet_map *mapp = pkt->pkt_map; mapp->rsvp_session = destp->d_session; if(pkt->pkt_map->rsvp_msgtype != RSVP_PATH_TEAR) { mapp->rsvp_timev = &destp->d_timevalp; } mapp->rsvp_hop = &hop; pkt->rsvp_nflwd = 1; /* Exactly one sender */ 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; }}voidsend_path_out_vif( int vif, Session *destp, SENDER_TEMPLATE *sdscp, struct packet *pkt){ assert(pkt->pkt_order == BO_HOST); /* * Previous-Hop address = addr of output interface. */ hop_if_assign(pkt->rsvp_phop,&GET_IF(vif),vif); send_pkt_out_vif(vif, destp, sdscp, pkt);}/* query_routing(): Initiate/perform route computation for sender. * Return 1 if asynchronous, else 0. * * If destination is multicast and mrouted is running (and raw I/O?? XXX) * then send RSRR message to mrouted requesting route for (S,G) and * return 1. For unicast routing, do synchronous lookup, set output * bitmap *bm, and return 0. For the API in a (possibly multihomed) * host, match S against our interfaces to generate *bm, and return 0. */static intquery_routing(Session *destp, PSB *psbp, int *in_vifp, bitmap *bmp, int note){ int i; u_char stype, ptype; int mcast; bmp_rst(bmp);#define TYPE_V4(x) ((x == ctype_SESSION_ipv4) || (x == ctype_SESSION_ipv4GPI))#ifdef USE_IPV6#define TYPE_V6(x) ((x == ctype_SESSION_ipv6) || (x == ctype_SESSION_ipv6GPI))#endif /* USE_IPV6 */ stype = Obj_CType(&(destp->d_session->sess_header)); if (TYPE_V4(stype)) { NET_SET_ADDR_IPv4(&dst, destp->d_session->sess4_addr); }#ifdef USE_IPV6 else if (TYPE_V6(stype)) { NET_SET_ADDR_IPv6(&dst, destp->d_session->sess6_addr); }#endif /* USE_IPV6 */ mcast = session_multicast(destp->d_session); /* Multicast session */ if (mcast) { ptype = Obj_CType(&(psbp->ps_templ->filt_header)); switch (ptype) { case ctype_SENDER_TEMPLATE_ipv4: NET_SET_ADDR_IPv4(&src, psbp->ps_templ->filt4_srcaddr); break; case ctype_SENDER_TEMPLATE_ipv4GPI: NET_SET_ADDR_IPv4(&src, psbp->ps_templ->filtgpi4_srcaddr); break;#ifdef USE_IPV6 case ctype_SENDER_TEMPLATE_ipv6: case ctype_SENDER_TEMPLATE_ipv6FL: NET_SET_ADDR_IPv6(&src, psbp->ps_templ->filt6_srcaddr); break; case ctype_SENDER_TEMPLATE_ipv6GPI: NET_SET_ADDR_IPv6(&src, psbp->ps_templ->filtgpi6_srcaddr); break;#endif /* USE_IPV6 */ default: /* shouldn't be here */ log(LOG_ERR,errno,"No such type"); break; } srcp = &src; } else srcp = 0; if (!mcast) { /* * Unicast case. */ if (session_if(destp->d_session) >= 0) { /* Unicast Path message destined to one of my * interfaces. That's it... */ return(0); } if ((TYPE_V4(stype) && !NoUnicast) #ifdef USE_IPV6 || (TYPE_V6(stype) && !NoUnicast)#endif /* USE_IPV6 */ ) { i = rsrr_route_query((void *)psbp, (void *)destp, srcp, &dst, note, in_vifp, bmp); if (i == -1) { log(LOG_ERR,errno,"Unicast route error"); return -1; } if (i > 0) /* (In case asynchronous) */ return(i); i = bmptoif(bmp); if (i == -1) { log(LOG_ERR,errno,"bmptoif failed"); return -1; } return(0); } } else if ((TYPE_V4(stype) && !NoV4Mroute)#ifdef USE_IPV6 || (TYPE_V6(stype) && !NoV6Mroute)#endif /* USE_IPV6 */ ) { /* * Multicast case: If there is an mrouted, send RSRR * route query and return 1 (asynch) unless route * notification is enabled for this PSB and PSB state * has not changed. */#ifdef HOST_ONLY assert(0);#else /* * If we only intend to remove this route from the route change * notification list in the multicast routing daemon */ if (!note) return rsrr_route_query((void *)psbp, (void *)destp, srcp, &dst, note, in_vifp, bmp); if ((!BIT_TST(psbp->ps_rsrr_flags, PSBF_RSRR_NOTIFY) || psbp->ps_flags & PSBF_Prefr_need)) { i = rsrr_route_query((void *)psbp, (void *)destp, srcp, &dst, note, in_vifp, bmp); if (i > 0) return(i); /* Is asynchronous */ if (i == -1) { log(LOG_ERR,errno,"Multicast route failed"); return -1; } return 0; } else { *bmp = psbp->ps_outif_list; *in_vifp = psbp->ps_in_if; return(0); }#endif /* HOST_ONLY */ } if (IsHopAPI(&psbp->ps_phop)) { /* If sender is local API, s_originvif is outgoing interface; * set this as the only route. */ bmp_set(bmp, psbp->ps_originvif); *in_vifp = psbp->ps_in_if; return(0); } /* Else... assume we are a host with one interface. */ /* Peserve the actual interface if we know it; else assume interface 0. */ if (*in_vifp < 0) *in_vifp = 0; return(0);}/* route_update(): Update state after route computation. * May be called synchronously (called from * path_refresh_common()) or asyncronously (called * from rsrr_update()). */voidroute_update(Session *destp, PSB *psbp, int in_vif, bitmap new_routes){ extern char s[]; int mcast = 0; PSB *fPSB = Find_fPSB(destp, psbp->ps_templ); if (!IsHopAPI(&psbp->ps_phop)) /* If it's from the network, send it to API, too */ bmp_set(&new_routes, api_num); /* Count Path messages. Note: Delayed until here * because may not have known incoming interface until * asynchronous return from RSRR told us. */ if (in_vif >= 0) Incr_ifstats(in_vif, rsvpstat_msgs_in[RSVP_PATH]); mcast = session_multicast(destp->d_session); if (IsHopAPI(&(psbp->ps_phop))) { /* If inc iface was unknown, assume routing result */ if (psbp->ps_in_if < 0) psbp->ps_in_if = in_vif; fPSB = psbp; } else if (mcast) { /* Multicast routing */ /* If inc iface was unknown, assume routing result */ if (psbp->ps_in_if < 0) psbp->ps_in_if = in_vif; /* If this Path msg arrived on an interface different from * what routing says but *psbp was the forwarding PSB, then * route has changed; make *psbp local-only. */ if (psbp->ps_in_if != in_vif && fPSB == psbp) { psbp->ps_flags |= PSBF_LocalOnly; bmp_rst(&(psbp->ps_outif_list)); fPSB = locate_PSB(destp, psbp->ps_templ, in_vif, NULL); } /* Else if Path msg arrived on correct routing interface but * this PSB is not forwarding PSB (it was local-only), swap * local-only designation with forwarding PSB. */ else if (psbp->ps_in_if == in_vif && fPSB != psbp) { if (fPSB) { psbp->ps_outif_list = fPSB->ps_outif_list; bmp_rst(&(fPSB->ps_outif_list)); fPSB->ps_flags |= PSBF_LocalOnly; } fPSB = psbp; psbp->ps_flags &= ~PSBF_LocalOnly; } } else { /* Unicast routing or no routing (end system) */ fPSB = psbp; } /* We know incoming interface and sender is not from API; if * pkt arrived with UDP encaps, mark incoming interface UDP. */ if (psbp->ps_flags & PSBF_UDP) { start_UDP_encap(in_vif); if_vec[IF_UNICAST(in_vif)].if_flags |= IF_FLAG_UseUDP; } /* If outgoing links have changed for existing PSB, set timer * to initiate local repair (=> path refresh). */ if (fPSB && !bmp_equ(&(fPSB->ps_outif_list), &new_routes)) { if (!bmp_zero(&(fPSB->ps_outif_list))){ if (IsDebug(DEBUG_RSRR)) { log(LOG_DEBUG, 0, "Outgoing vifs changed from %s\n", bm_expand(&(fPSB->ps_outif_list), s)); } add_to_timer((char *) destp, TIMEV_LocalRepair, LOCAL_REPAIR_W); } fPSB->ps_outif_list = new_routes; }}/* * Called when a PSB is going to be deleted, and it this PSB belongs to a * multicast session, while this PSB has the PSBF_RSRR_NOTIFY bit set. */static voidunnotify_rsrr(PSB *psbp, Session *ses){ int in_if = 0; bitmap bmp; if (BIT_TST(psbp->ps_rsrr_flags, PSBF_RSRR_NOTIFY)) query_routing(ses, psbp, &in_if, &bmp, 0); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -