📄 rsvp_diag.c
字号:
/* Last hop... */ Init_Object(droute, ROUTE, ROUTE_ipv4); Obj_Length(droute) -= sizeof(d_resp->resp_in_addr); droute->R_pointer_ipv4 = -1; pkt->pkt_len += Obj_Length(droute); } else { /* Not last hop; copy save route obj to resp tail. */ assert(dr_old != NULL); droute = (ROUTE *)((char *)pkt->pkt_data + pkt->pkt_len); Move_Object(dr_old, droute); free(dr_old); } /* update the route object */ droute->R_pointer_ipv4++; route(droute,droute->R_pointer_ipv4) = d_resp->resp_in_addr; Obj_Length(droute) += sizeof(d_resp->resp_in_addr); /* Add the (new) route object (back) into the map */ pkt->pkt_len += sizeof(d_resp->resp_in_addr); pkt->pkt_map->rsvp_route = droute ; /* Set the ROUTEBIG error if the pkt_len has exceed ed * packet_MTU, but only after updating the route object. */ if ( !(flags & DREQ_TRIMFWD) && pkt->pkt_len > pkt->packet_MTU) d_resp->resp_Rerror |= (RSVP_Erv_Diag_ROUTEBIG << 4); } /* if no error bit is set, no flags are set, * forward the DREQ packet , else goto send_diag_reply */ if((DIAG_RESPONSE_RERROR(d_resp) == RSVP_Err_NONE) && !(flags & (DREQ_TRIMFWD | DREQ_MAXHOP)) && (map_if_addr(&saddr) < 0)) { mode = send_pkt_out_if(IF_UNICAST(fw_if),fwhop, pkt); if (mode< 0) return -1; return 0; } return(send_diag_reply(pkt,in_vif,flags,fwhop,fw_if,d_resp));}/* * accept_diag_reply() : Forwarding incoming diagnostic response messages * (DREP Forwarding) */intaccept_diag_reply(int in_vif, struct packet *pkt){ DIAGNOSTIC *diagnostic; u_char H ; int mode; RSVP_HOP hopp; net_addr laddr; net_addr toaddr; Init_Object(&hopp, RSVP_HOP, RSVP_HOP_ipv4); diagnostic = pkt->rsvp_diagnostic; H = DIAG_HBIT(diagnostic); NET_SET_ADDR_IPv4(&laddr,diagnostic->diag_laddr); NET_SET_ADDR3_UDP_IPv4(&toaddr,diagnostic->diag_raddr,diagnostic->diag_rport); /* Are we the LAST_HOP ? */ if (map_if_addr(&laddr) >=0) { if (IN_MULTICAST(ntoh32(diagnostic->diag_raddr.s_addr))) pkt->pkt_ttl = diagnostic->diag_ttl ; mode = send_pkt_to(-1, &toaddr, pkt); } else if(H == 1) { /* We are in the middle of a HBH DREP */ pkt->rsvp_droute->R_pointer_ipv4 --; hopp.hop4_addr = route(pkt->rsvp_droute, pkt->rsvp_droute->R_pointer_ipv4); mode = send_pkt_out_if(-1, &hopp, pkt); } else /* These two cases are exceptions, not included for * in the specification */ if (IN_MULTICAST(ntoh32(diagnostic->diag_raddr.s_addr))) { hopp.hop4_addr = diagnostic->diag_laddr ; mode = send_pkt_out_if(-1, &hopp, pkt); } else { mode = send_pkt_to(-1, &toaddr, pkt); } if (mode <0) return -1; return 0;}/* * send_diag_reply : Used primarily to send diagnostic replies. * In the fragmentation case, we will trim a DREP, * build and send a DREP, and forward a *new* DREQ * to the enclosed prev hop. */int send_diag_reply( struct packet *pkt, int in_vif, u_char flags, RSVP_HOP *fwhop, int fw_if, DIAG_RESPONSE *ldresp){ DIAG_RESPONSE *drespo, *dresp; RSVP_HOP hopp; int offset, old_off ,i ,mode; int outif; u_char H ; struct packet lpkt, *fwd_pkt = &lpkt; packet_map mapp, *fwd_map = &mapp; Session *destp; net_addr laddr; net_addr toaddr; bitmap bmp; int rv; bmp_rst(&bmp); H = DIAG_HBIT(pkt->rsvp_diagnostic); dresp = ldresp; destp = locate_session(pkt->rsvp_sess); NET_SET_ADDR_IPv4(&laddr,pkt->rsvp_diagnostic->diag_laddr); NET_SET_ADDR3_UDP_IPv4(&toaddr,pkt->rsvp_diagnostic->diag_raddr, pkt->rsvp_diagnostic->diag_rport); Init_Object(&hopp, RSVP_HOP, RSVP_HOP_ipv4); /* If there is no error and we need to trim and forward */ if ((flags & DREQ_TRIMFWD) && DIAG_RESPONSE_RERROR(dresp) == RSVP_Err_NONE) {/* XXX??? Currently the packet duplication code is a trick. * We use the current packet data buffer, and send out two packets, * with the appropriate map changes each time. For the DREQ forwarded * upstream, the packet and map data structues are created anew. * May need to revisit this section later. */ *fwd_pkt = *pkt ; *fwd_map = *pkt->pkt_map ; fwd_pkt->pkt_map = fwd_map ; assert(fwd_pkt->pkt_data->rsvp_type == RSVP_DREQ); assert(fwd_pkt->pkt_map->rsvp_msgtype == RSVP_DREQ);/* Compute the fragment offset, in terms of number of response * object bytes already, and update current offset. */ drespo = pkt->pkt_map->rsvp_diag_response; old_off = offset = pkt->rsvp_diagnostic->diag_frag_off ; for (i=0; i<pkt->pkt_map->rsvp_resplist; i++) { offset += Obj_Length(drespo); (char *)drespo += Obj_Length(drespo); } fwd_pkt->pkt_map->rsvp_diag_response = NULL; fwd_pkt->pkt_map->rsvp_resplist = 0; fwd_pkt->pkt_map->rsvp_diag->diag_frag_off = offset; /* Continue and forward the trimmed DREQ packet upstream */ mode = send_pkt_out_if(IF_UNICAST(fw_if),fwhop, fwd_pkt); if (mode < 0) return -1 ;/* Set the More Fragment bit on the original packet, indicating fragmentation * since this will be the first DREP, and restore the frag_off. */ pkt->pkt_map->rsvp_diag->diag_replymode |= 0x01; pkt->pkt_map->rsvp_diag->diag_frag_off = old_off; }/* Send the DREP after turning the packet to a DREP from a DREQ. */ pkt->pkt_data->rsvp_type = RSVP_DREP; pkt->pkt_map->rsvp_msgtype = RSVP_DREP;/* Current DREP : If any error bit is set, send the packet back to either last_hop * or response address. */ if (DIAG_RESPONSE_RERROR(dresp) != RSVP_Err_NONE) { if ( map_if_addr(&laddr) < 0 ) { if (H == 1 || IN_MULTICAST(ntoh32(pkt->rsvp_diagnostic->diag_raddr.s_addr))) { hopp.hop4_addr = pkt->rsvp_diagnostic->diag_laddr; /* outif = unicast_route(hop_addr(&hopp)); */ rv = rsrr_route_query((void *)0, (void *)0, (net_addr *)0, hop_addr(&hopp), 0, (int *)0, &bmp); if (rv == -1) { log(LOG_ERR,errno,"Unicast route lookup failure"); return -1; } outif = bmptoif(&bmp); mode = send_pkt_out_if(outif, &hopp, pkt); } } else /* last hop */ mode = send_pkt_to(-1, &toaddr, pkt); if (mode < 0) return (-1); return 0; } else { /* No errors, valid DREP to send, either because * of DREQ_MAXHOP, or the DREQ_TRIMFWD case, or * XXXX we reached the sender RSVP router XXXX */ if (H == 0 || ( map_if_addr(&laddr) >= 0)) { mode = send_pkt_to(-1, &toaddr, pkt); } else { assert(pkt->rsvp_droute != NULL); pkt->rsvp_droute->R_pointer_ipv4--; hopp.hop4_addr = route(pkt->rsvp_droute, pkt->rsvp_droute->R_pointer_ipv4); /* outif = unicast_route(hop_addr(&hopp)); */ rv = rsrr_route_query((void *)0, (void *)0, (net_addr *)0, hop_addr(&hopp), 0, (int *)0, &bmp); if (rv == -1) { log(LOG_ERR,errno,"Unicast route lookup failure"); return -1; } outif = bmptoif(&bmp); mode = send_pkt_out_if(outif ,&hopp, pkt); } if (mode <0) return -1; return 0; }}/* locate_RSB_diag(): * * This routine is similar to locate_RSB, but tailor made for Diagnostic * message support. It returns an RSB if a reservation exists, for the * given session, next hop, and sender (specified by filter) * * in_vif : this is the vif the diagnostic request came in on. */RSB * locate_RSB_diag(Session *destp, RSVP_HOP *nhopp, FILTER_SPEC *sfiltp, int in_vif) { RSB *rp = NULL ; RSB *cd_rp = NULL; /* cd_rp is used to save off a candidate RSB for the case detailed below */ for (rp = destp->d_RSB_list; rp != NULL; rp = rp->rs_next) { if (!hop_addr_eq(nhopp,&rp->rs_nhop)) {/* Kluge? for the case, where the diag request landed on a * broadcast multi-acess network (part of the reverse path). * There may be valid reservations on this router's BMA network interface, * but NHOPs may be different routers, not necessarily the router from * where the diag request got forwarded. But we still want to record the * LLB state for this OIF, so we just find some RSB for the same OIF * and call LL_GetInfo as usual. (OIF for the reservation is the incoming VIF * from the diagnostic request. * * Due to wierdness in unicast routing or the presence of tunnels, the diag request * may land up on the wrong interface. The definition of the diagnositc message header * has been changed to include for the HOP object with the LIH field, to handle this * problem. (version 3 of the specification). When this code is brought upto date, the * LIH value extracted from the HOP object (in a forwarded DIAG_REQ packet) will be used * instead of the in_vif value for correct behaviour. */ if(in_vif != rp->rs_OIf) continue; else if(!cd_rp) /* the rules to choose a candidate RSB are those that apply for * selecting a routine RSB */ if(Style_is_Shared(rp->rs_style) || match_filt2star(sfiltp, rp->rs_filtstar)) { cd_rp = rp; continue; } } if(Style_is_Shared(rp->rs_style) || match_filt2star(sfiltp, rp->rs_filtstar)) break; } if (rp) return(rp); else return(cd_rp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -