📄 rsrr_rsrr.c
字号:
log(LOG_ERR, 0,"VIF config error\n"); return(-1); } break;#ifdef USE_IPV6 case RSRR_SOCK_V6UX: if (rsrr_use_v2_ipv6) { /* * Use RSRR v2 format */ struct rsrr_vif *vifs; /* * skip over RSRR header */ vifs = (struct rsrr_vif *)(rsrr_recv_buf+RSRR_HEADER_LEN); /* * loop through all the interfaces from the * interface reply */ for (vf = 0; vf < rsrr_in->num; vf++) { /* * loop through the if_vec[] table we kept */ for (i = 0; i < lnum; i++) { /* * Skip over API interface */ if (IsNumAPI(i)) continue; if (((vifs[vf].family == AF_INET) && (vifs[vf].addr_v4.s_addr == NET_GET_ADDR_IPv4(&NET_GET_IF_PHY_ADDR(&GET_IF(i))).s_addr)) || ((vifs[vf].family == AF_INET6) && (IN6_ARE_ADDR_EQUAL(&vifs[vf].addr_v6, &NET_GET_ADDR_IPv6(&NET_GET_IF_PHY_ADDR(&GET_IF(i))))))) { /* * fill out the table for doing conversion between * the interfaces used in gated and the ones used * in rsvpd */ gated_to_rsvpd[vifs[vf].id] = i; if (BIT_TST(vifs[vf].status,RSRR_M_DISABLED_BIT)) if_vec[i].if_flags &= ~IF_FLAG_IFF_UP; else if_vec[i].if_flags |= IF_FLAG_IFF_UP; break; } } } } else { /* * Gotta be an error */ log(LOG_ERR,0,"Only RSRRv2 supports IPv6",0); return(-1); } break;#endif /* USE_IPV6 */ default: return -1; } return 0;}/* * Send a Route Query to routing for a dest-source pair. */intrsrr_send_rq(pp, sp, af, src, dst, note) void *pp; /* PSB pointer */ void *sp; /* Session pointer */ u_char af; net_addr *src; net_addr *dst; int note;{ struct rsrr_header *rsrr; int sendlen; int rv; /* * Set up Route Query message */ rsrr = (struct rsrr_header *) rsrr_send_buf; rsrr->type = RSRR_ROUTE_QUERY; rsrr->flags = 0; rsrr->num = 0; if (note) BIT_SET(rsrr->flags,RSRR_NOTIFICATION_BIT); switch(af) { case AF_INET: if (rsrr_use_v1_ipv4) { /* * USE RSRR v1 */ struct rsrrv1_rq *route_query; rsrr->version = 1; route_query = (struct rsrrv1_rq *)(rsrr_send_buf + RSRR_HEADER_LEN); route_query->dest_addr = NET_GET_ADDR_IPv4(net_addr_ip(dst)); route_query->source_addr = NET_GET_ADDR_IPv4(net_addr_ip(src)); route_query->query_id = rsrr_qt_getid(pp); /* * Get the message size. */ sendlen = RSRRV1_RQ_LEN; if (IsDebug(DEBUG_RSRR)) { log(LOG_DEBUG, 0, "> Route Query (%s %s) Notify= %d\n", inet_fmt(route_query->source_addr.s_addr,s1), inet_fmt(route_query->dest_addr.s_addr,s2), BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)); } /* * Send it. */ if (rsrr_send(RSRR_SOCK_V4UX,sendlen) >= 0) { /* * Cache the query if note is not zero, otherwise it is * only used to remove the route from route change * notification list in the daemon. */ if (note) rsrr_qt_cache(route_query->query_id,pp,sp,src,dst); /* * asynchronous route query/reply * return the query ID */ return route_query->query_id; } else return -1; } else if (rsrr_use_v2_ipv4) { /* * USE RSRR v2 */ struct rsrr_rq *route_query; rsrr->version = 2; route_query = (struct rsrr_rq *)(rsrr_send_buf + RSRR_HEADER_LEN); route_query->family = (u_short) AF_INET; route_query->length = (u_short) sizeof (struct in_addr); route_query->dst_v4 = NET_GET_ADDR_IPv4(net_addr_ip(dst)); route_query->src_v4 = NET_GET_ADDR_IPv4(net_addr_ip(src)); route_query->query_id = rsrr_qt_getid(pp); /* * Get the message size. */ sendlen = RSRR_RQ_LEN; if (IsDebug(DEBUG_RSRR)) { log(LOG_DEBUG, 0, "> Route Query (%s %s) Notify= %d\n", inet_fmt(route_query->src_v4.s_addr,s1), inet_fmt(route_query->dst_v4.s_addr,s2), BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)); } /* * Send it. */ if (rsrr_send(RSRR_SOCK_V4UX,sendlen) >= 0) { /* * Cache the query if note is not zero, otherwise it is * only used to remove the route from route change * notification list in the daemon. */ if (note) rsrr_qt_cache(route_query->query_id,pp,sp,src,dst); /* * asynchronous route query/reply * return the query ID */ return route_query->query_id; } else return -1; } break;#ifdef USE_IPV6 case AF_INET6: if (rsrr_use_v2_ipv6) { /* * USE RSRR v2 */ struct rsrr_rq *route_query; rsrr->version = 2; route_query = (struct rsrr_rq *)(rsrr_send_buf + RSRR_HEADER_LEN); route_query->family = (u_short) AF_INET6; route_query->length = (u_short) sizeof (struct in6_addr); route_query->dst_v6 = NET_GET_ADDR_IPv6(net_addr_ip(dst)); route_query->src_v6 = NET_GET_ADDR_IPv6(net_addr_ip(src)); route_query->query_id = rsrr_qt_getid(pp); /* * Get the message size. */ sendlen = RSRR_RQ_LEN; if (IsDebug(DEBUG_RSRR)) { log(LOG_DEBUG, 0, "> Route Query (%s %s) Notify= %d\n", ip6_sprintf(&(route_query->src_v6)), ip6_sprintf(&(route_query->dst_v6)), BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)); } /* * Send it. */ if (rsrr_send(RSRR_SOCK_V6UX,sendlen) >= 0) { /* * Cache the query if note is not zero, otherwise it is * only used to remove the route from route change * notification list in the daemon. */ if (note) rsrr_qt_cache(route_query->query_id,pp,sp,src,dst); /* * asynchronous route query/reply * return the query ID */ return route_query->query_id; } else return -1; } else if (rsrr_use_v1_ipv6) { /* * IPv6 and RSRRv1? Not possible */ log(LOG_ERR,0,"Only RSRRv2 supports IPv6"); rv = -1; } break;#endif /* USE_IPV6 */ default: log(LOG_ERR,errno,"No support for AF = %d",af); rv = -1; break; } return rv;}/* * Accept a Route Reply from routing. Find the related session and sender * structures and issue a PATH refresh if needed. */intrsrr_accept_rr_ux(sock_type, rsrr) u_char sock_type; struct rsrr_header *rsrr;{ net_addr src; net_addr dst; int rv; int in_lih; bitmap out_bmp; bitmap y; int note = 0; u_char tree_type = RSRR_SENDER_TREE; memset(s,0,sizeof(s)); bmp_rst(&out_bmp); bmp_rst(&y); if (sock_type == RSRR_SOCK_V4UX) { /* * IPv4 */ if (rsrr_use_v1_ipv4) { /* * RSRR v1 */ struct rsrrv1_rr *route_reply; route_reply=(struct rsrrv1_rr *)(rsrr_recv_buf+RSRR_HEADER_LEN); /* * IPv4 mrouted uses virtual interfaces, so we need to * shift the replying incoming interface and the outgoing * bitmap */ in_lih = route_reply->in_vif + shift; bmp_create(route_reply->out_vif_bm, &y); bmp_shift(&y, &out_bmp, shift); /* * Reject errors. */ if (BIT_TST(rsrr->flags,RSRR_ERROR_BIT)) { /* * Delete any associated cache entry so that we * can re-use the query id. */ rsrr_qt_delete(route_reply->query_id); if (IsDebug(DEBUG_RSRR)) log(LOG_DEBUG,0, "Rejecting Route Reply because Error bit set.\n"); return -1; } if (IsDebug(DEBUG_RSRR)) { log(LOG_DEBUG, 0, "< Route Reply (%s %s) in vif %d out vifs %s Notify= %d\n", inet_fmt(route_reply->source_addr.s_addr,s1), inet_fmt(route_reply->dest_addr.s_addr,s2), (u_char)(in_lih), bm_expand(&out_bmp, s), BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)); } if (BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)) note = 1; if (RSRR_USE_SHARED(rsrr->flags)) tree_type = RSRR_HYBRID_UNIDIRECTIONAL_SHARED_TREE; else if (RSRR_USE_ALL_SHARED(rsrr->flags)) tree_type = RSRR_UNIDIRECTIONAL_SHARED_TREE; NET_SET_ADDR_IPv4(&src,route_reply->source_addr); NET_SET_ADDR_IPv4(&dst,route_reply->dest_addr); rv = rsrr_route_reply(route_reply->query_id,&src,&dst, in_lih,(bitmap*)&(out_bmp), note, tree_type); return rv; } else if (rsrr_use_v2_ipv4) { /* * RSRR v2 */ struct rsrr_rr *route_reply; route_reply = (struct rsrr_rr *)(rsrr_recv_buf + RSRR_HEADER_LEN); /* * IPv4 mrouted uses virtual interfaces, so we need to * shift the replying incoming interface and the outgoing * bitmap */ in_lih = route_reply->in_vif + shift; bmp_convert(&(route_reply->out_vif_bm), &y); bmp_shift(&y, &out_bmp, shift); /* * Reject errors. */ if (BIT_TST(rsrr->flags,RSRR_ERROR_BIT)) { /* * Delete any associated cache entry so that we * can re-use the query id. */ rsrr_qt_delete(route_reply->query_id); if (IsDebug(DEBUG_RSRR)) log(LOG_DEBUG,0, "Rejecting Route Reply because Error bit set.\n"); return -1; } if (IsDebug(DEBUG_RSRR)) { log(LOG_DEBUG, 0, "< Route Reply (%s %s) in vif %d out vifs %s Notify= %d\n", inet_fmt(route_reply->src_v4.s_addr,s1), inet_fmt(route_reply->dst_v4.s_addr,s2), (u_char)(in_lih), bm_expand(&out_bmp,s), BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)); } if (BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)) note = 1; NET_SET_ADDR_IPv4(&src,route_reply->src_v4); NET_SET_ADDR_IPv4(&dst,route_reply->dst_v4); tree_type = route_reply->tree_type; rv = rsrr_route_reply(route_reply->query_id,&src,&dst, in_lih, (bitmap *)&(out_bmp), note, tree_type); return rv; } }#ifdef USE_IPV6 else if (sock_type == RSRR_SOCK_V6UX) { /* * IPv6 */ if (rsrr_use_v2_ipv6) { /* * RSRR v2 */ struct rsrr_rr *route_reply; rsrr_bmp tmpbmp; route_reply = (struct rsrr_rr *)(rsrr_recv_buf + RSRR_HEADER_LEN); /* * For IPv6 mrouting daemon, no virtual interface used, * but we need to do conversion between the interface * used in gated and the one used in rsvpd. The * gated_to_rsvpd[] table was set up during the * interface reply phase */ in_lih = gated_to_rsvpd[route_reply->in_vif]; convert(&(route_reply->out_vif_bm), &tmpbmp); bmp_convert(&tmpbmp, &out_bmp); /* * Reject errors. */ if (BIT_TST(rsrr->flags,RSRR_ERROR_BIT)) { /* * Delete any associated cache entry so that we * can re-use the query id. */ rsrr_qt_delete(route_reply->query_id); if (IsDebug(DEBUG_RSRR)) log(LOG_DEBUG,0, "Rejecting Route Reply because Error bit set.\n"); return -1; } if (IsDebug(DEBUG_RSRR)) { log(LOG_DEBUG, 0, "< Route Reply (%s %s) in vif %d out vifs %s Notify= %d\n", ip6_sprintf(&(route_reply->src_v6)), ip6_sprintf(&(route_reply->dst_v6)), (u_char)(in_lih), bm_expand(&out_bmp,s), BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)); } if (BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)) note = 1; NET_SET_ADDR_IPv6(&src,route_reply->src_v6); NET_SET_ADDR_IPv6(&dst,route_reply->dst_v6); tree_type = route_reply->tree_type; rv = rsrr_route_reply(route_reply->query_id,&src,&dst, in_lih, (bitmap *)&(out_bmp), note, tree_type); return rv; } else if (rsrr_use_v1_ipv6) { /* * RSRRv1 and IPv6. Not possible */ log(LOG_ERR,0,"Only RSRRv2 supports IPv6"); return -1; } }#endif /* USE_IPV6 */ return 0;}/* * Initialize the query table. */voidrsrr_qt_init(){ int i; for (i=0; i<RSRR_QT_SIZE; i++) rsrr_qt[i] = (struct rsrr_query_table *) NULL;}u_longrsrr_qt_getid(pt) void *pt;{ return ((u_long)((u_long)pt & 0xffffffff));}/* * Cache a query id in the query table with its associated * source/destination combination. */voidrsrr_qt_cache(query_id,pp,sp,src,dst) u_long query_id; void *pp; /* PSB pointer */ void *sp; /* Session pointer */ net_addr *src; net_addr *dst;{ struct rsrr_query_table *qt; int hash = RSRR_QT_HASH(query_id); qt = rsrr_qt[hash]; while (qt) { if (qt->query_id == query_id) { /* * We somehow managed to duplicate a query id. * Amazing! Ditch the old one. */ qt->query_id = query_id; qt->ptrP = pp; qt->ptrS = sp; qt->src = *src; qt->dst = *dst; return; } qt = qt->next; } /* * Cache entry doesn't already exist. Create one and insert at * front of list. */ qt = (struct rsrr_query_table *) malloc(sizeof(struct rsrr_query_table)); if (qt == NULL) { Log_Mem_Full("RSRR cache"); return; } qt->query_id = query_id; qt->ptrP = pp; qt->ptrS = sp; qt->src = *src; qt->dst = *dst; qt->next = rsrr_qt[hash]; rsrr_qt[hash] = qt;}/* * Lookup a query id in the table. */struct rsrr_query_table *rsrr_qt_lookup(query_id) u_long query_id;{ struct rsrr_query_table *qt; int hash = RSRR_QT_HASH(query_id); qt = rsrr_qt[hash]; while(qt) { if (qt->query_id == query_id) return qt; qt = qt->next; } return qt;}/* * Delete a query id from the table. */voidrsrr_qt_delete(query_id) u_long query_id;{ struct rsrr_query_table *qt, *qt_prev; int hash = RSRR_QT_HASH(query_id); qt = rsrr_qt[hash]; while(qt) { if (qt->query_id == query_id) { if (qt == rsrr_qt[hash]) /* * Deleting first entry. */ rsrr_qt[hash] = qt->next; else qt_prev->next = qt->next; free(qt); return; } qt_prev = qt; qt = qt->next; }}voidSetNotifyBit(psbp, note) PSB *psbp; int note;{ if (note) /* * Routing can do route change notification. Set bit in * sender structure that indicates RSRR no longer needs to * send queries. */ BIT_SET(psbp->ps_rsrr_flags, PSBF_RSRR_NOTIFY); else /* * Clear the bit just in case it was set. */ BIT_CLR(psbp->ps_rsrr_flags, PSBF_RSRR_NOTIFY);}#endif /* ! HOST_ONLY *//* * The interface list in gated is different from the one being used in * rsvpd, thus we need to do some conversion for the bitmap returned * from gated to the one in rsvpd. For example, the interface table * in gated includes loop-back interfaces, and it has different ordering * for the interfaces of the same physical interface. We have built a * conversion table gated_to_rsvpd[] during interface reply, now we * use it to do the conversion. */rsrr_bmp *convert(rsrr_bmp *x, rsrr_bmp *y) { int i,j,d,m; for (i=0; i<(RSRR_MAX_VIFS_V2/NBBY); i++) y->bm[i]=0; for (i=0; i<RSRR_MAX_VIFS_V2; i++) { d = i/NBBY; m = i%NBBY; if ((x->bm[d]) & (1<<m)) { j = gated_to_rsvpd[i]; d = j/NBBY; m = j%NBBY; y->bm[d] |= (1 << m); } } return y;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -