prune.c (mrouted-4.3) | : | prune.c (mrouted-4.4) | ||
---|---|---|---|---|
skipping to change at line 14 | skipping to change at line 14 | |||
* the terms and conditions listed in that file. | * the terms and conditions listed in that file. | |||
* | * | |||
* The mrouted program is COPYRIGHT 1989 by The Board of Trustees of | * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of | |||
* Leland Stanford Junior University. | * Leland Stanford Junior University. | |||
*/ | */ | |||
#include "defs.h" | #include "defs.h" | |||
extern int cache_lifetime; | extern int cache_lifetime; | |||
extern int prune_lifetime; | extern int prune_lifetime; | |||
extern struct rtentry *routing_table; | ||||
extern int phys_vif; | extern int phys_vif; | |||
extern int allow_black_holes; | extern int allow_black_holes; | |||
/* | /* | |||
* randomize value to obtain a value between .5x and 1.5x | * randomize value to obtain a value between .5x and 1.5x | |||
* in order to prevent synchronization | * in order to prevent synchronization | |||
*/ | */ | |||
#define JITTERED_VALUE(x) ((x) / 2 + ((int)random() % (x))) | #define JITTERED_VALUE(x) ((x) / 2 + ((int)random() % (x))) | |||
#define CACHE_LIFETIME(x) JITTERED_VALUE(x) /* XXX */ | #define CACHE_LIFETIME(x) JITTERED_VALUE(x) /* XXX */ | |||
skipping to change at line 623 | skipping to change at line 622 | |||
gt->gt_timer = CACHE_LIFETIME(cache_lifetime); | gt->gt_timer = CACHE_LIFETIME(cache_lifetime); | |||
time(>->gt_ctime); | time(>->gt_ctime); | |||
gt->gt_prsent_timer = 0; | gt->gt_prsent_timer = 0; | |||
gt->gt_grftsnt = 0; | gt->gt_grftsnt = 0; | |||
gt->gt_srctbl = NULL; | gt->gt_srctbl = NULL; | |||
gt->gt_pruntbl = NULL; | gt->gt_pruntbl = NULL; | |||
gt->gt_route = r; | gt->gt_route = r; | |||
gt->gt_rexmit_timer = 0; | gt->gt_rexmit_timer = 0; | |||
NBRM_CLRALL(gt->gt_prunes); | NBRM_CLRALL(gt->gt_prunes); | |||
gt->gt_prune_rexmit = PRUNE_REXMIT_VAL; | gt->gt_prune_rexmit = PRUNE_REXMIT_VAL; | |||
#ifdef RSRR | ||||
gt->gt_rsrr_cache = NULL; | ||||
#endif | ||||
/* Calculate forwarding vifs */ | /* Calculate forwarding vifs */ | |||
determine_forwvifs(gt); | determine_forwvifs(gt); | |||
/* update ttls */ | /* update ttls */ | |||
prun_add_ttls(gt); | prun_add_ttls(gt); | |||
gt->gt_next = *gtnp; | gt->gt_next = *gtnp; | |||
*gtnp = gt; | *gtnp = gt; | |||
if (gt->gt_next) | if (gt->gt_next) | |||
skipping to change at line 776 | skipping to change at line 772 | |||
/* | /* | |||
* And see if we want to forward again. | * And see if we want to forward again. | |||
*/ | */ | |||
if (!VIFM_ISSET(vifi, g->gt_grpmems)) { | if (!VIFM_ISSET(vifi, g->gt_grpmems)) { | |||
GET_MEMBERSHIP(g, vifi); | GET_MEMBERSHIP(g, vifi); | |||
APPLY_SCOPE(g); | APPLY_SCOPE(g); | |||
prun_add_ttls(g); | prun_add_ttls(g); | |||
/* Update kernel state */ | /* Update kernel state */ | |||
update_kernel(g); | update_kernel(g); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g,1); | ||||
#endif | ||||
/* | /* | |||
* If removing this prune causes us to start forwarding | * If removing this prune causes us to start forwarding | |||
* (e.g. the neighbor rebooted), and we sent a prune upstream, | * (e.g. the neighbor rebooted), and we sent a prune upstream, | |||
* send a graft to cancel the prune. | * send a graft to cancel the prune. | |||
*/ | */ | |||
if (!VIFM_ISEMPTY(g->gt_grpmems) && g->gt_prsent_timer) | if (!VIFM_ISEMPTY(g->gt_grpmems) && g->gt_prsent_timer) | |||
send_graft(g); | send_graft(g); | |||
IF_DEBUG(DEBUG_PEER) { | IF_DEBUG(DEBUG_PEER) { | |||
skipping to change at line 847 | skipping to change at line 839 | |||
} | } | |||
g->gt_pruntbl = NULL; | g->gt_pruntbl = NULL; | |||
if (g->gt_gnext) | if (g->gt_gnext) | |||
g->gt_gnext->gt_gprev = g->gt_gprev; | g->gt_gnext->gt_gprev = g->gt_gprev; | |||
if (g->gt_gprev) | if (g->gt_gprev) | |||
g->gt_gprev->gt_gnext = g->gt_gnext; | g->gt_gprev->gt_gnext = g->gt_gnext; | |||
else | else | |||
kernel_table = g->gt_gnext; | kernel_table = g->gt_gnext; | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g,0); | ||||
rsrr_cache_clean(g); | ||||
#endif | ||||
if (g->gt_rexmit_timer) | if (g->gt_rexmit_timer) | |||
timer_clear(g->gt_rexmit_timer); | timer_clear(g->gt_rexmit_timer); | |||
prev_g = g; | prev_g = g; | |||
g = g->gt_next; | g = g->gt_next; | |||
free(prev_g); | free(prev_g); | |||
} | } | |||
r->rt_groups = NULL; | r->rt_groups = NULL; | |||
} | } | |||
skipping to change at line 913 | skipping to change at line 900 | |||
kernel_table = g->gt_gnext; | kernel_table = g->gt_gnext; | |||
if (prev_g != (struct gtable *)&r->rt_groups) | if (prev_g != (struct gtable *)&r->rt_groups) | |||
g->gt_next->gt_prev = prev_g; | g->gt_next->gt_prev = prev_g; | |||
else | else | |||
g->gt_next->gt_prev = NULL; | g->gt_next->gt_prev = NULL; | |||
prev_g->gt_next = g->gt_next; | prev_g->gt_next = g->gt_next; | |||
if (g->gt_rexmit_timer) | if (g->gt_rexmit_timer) | |||
timer_clear(g->gt_rexmit_timer); | timer_clear(g->gt_rexmit_timer); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g,0); | ||||
rsrr_cache_clean(g); | ||||
#endif | ||||
free(g); | free(g); | |||
g = prev_g; | g = prev_g; | |||
} else { | } else { | |||
prev_g = g; | prev_g = g; | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
/* | /* | |||
skipping to change at line 995 | skipping to change at line 978 | |||
send_prune_or_graft(g); | send_prune_or_graft(g); | |||
IF_DEBUG(DEBUG_CACHE) { | IF_DEBUG(DEBUG_CACHE) { | |||
logit(LOG_DEBUG, 0, "Updating cache entries (%s %s) new gm:%lx", | logit(LOG_DEBUG, 0, "Updating cache entries (%s %s) new gm:%lx", | |||
RT_FMT(r, s1), inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), g->gt_ grpmems); | RT_FMT(r, s1), inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), g->gt_ grpmems); | |||
} | } | |||
/* update ttls and add entry into kernel */ | /* update ttls and add entry into kernel */ | |||
prun_add_ttls(g); | prun_add_ttls(g); | |||
update_kernel(g); | update_kernel(g); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g,1); | ||||
#endif | ||||
} | } | |||
} | } | |||
/* | /* | |||
* set the forwarding flag for all mcastgrps on this vifi | * set the forwarding flag for all mcastgrps on this vifi | |||
*/ | */ | |||
void update_lclgrp(vifi_t vifi, uint32_t mcastgrp) | void update_lclgrp(vifi_t vifi, uint32_t mcastgrp) | |||
{ | { | |||
struct rtentry *r; | struct rtentry *r; | |||
struct gtable *g; | struct gtable *g; | |||
skipping to change at line 1033 | skipping to change at line 1012 | |||
if (VIFM_ISEMPTY(g->gt_grpmems)) | if (VIFM_ISEMPTY(g->gt_grpmems)) | |||
continue; | continue; | |||
prun_add_ttls(g); | prun_add_ttls(g); | |||
IF_DEBUG(DEBUG_CACHE){ | IF_DEBUG(DEBUG_CACHE){ | |||
logit(LOG_DEBUG, 0, "Update lclgrp (%s %s) gm:%lx", RT_FMT(r, s1) , | logit(LOG_DEBUG, 0, "Update lclgrp (%s %s) gm:%lx", RT_FMT(r, s1) , | |||
inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), g->gt_grpmems); | inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), g->gt_grpmems); | |||
} | } | |||
update_kernel(g); | update_kernel(g); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g, 1); | ||||
#endif | ||||
} | } | |||
} | } | |||
} | } | |||
/* | /* | |||
* reset forwarding flag for all mcastgrps on this vifi | * reset forwarding flag for all mcastgrps on this vifi | |||
*/ | */ | |||
void delete_lclgrp(vifi_t vifi, uint32_t mcastgrp) | void delete_lclgrp(vifi_t vifi, uint32_t mcastgrp) | |||
{ | { | |||
struct gtable *g; | struct gtable *g; | |||
skipping to change at line 1072 | skipping to change at line 1047 | |||
if (g->gt_route) { | if (g->gt_route) { | |||
IF_DEBUG(DEBUG_CACHE) { | IF_DEBUG(DEBUG_CACHE) { | |||
logit(LOG_DEBUG, 0, "Delete lclgrp (%s %s) gm:%lx", | logit(LOG_DEBUG, 0, "Delete lclgrp (%s %s) gm:%lx", | |||
RT_FMT(g->gt_route, s1), | RT_FMT(g->gt_route, s1), | |||
inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), g->gt_grp mems); | inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), g->gt_grp mems); | |||
} | } | |||
} | } | |||
prun_add_ttls(g); | prun_add_ttls(g); | |||
update_kernel(g); | update_kernel(g); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g, 1); | ||||
#endif | ||||
/* | /* | |||
* If there are no more members of this particular group, | * If there are no more members of this particular group, | |||
* send prune upstream | * send prune upstream | |||
*/ | */ | |||
if (VIFM_ISEMPTY(g->gt_grpmems) && g->gt_route && g->gt_route->rt _gateway) | if (VIFM_ISEMPTY(g->gt_grpmems) && g->gt_route && g->gt_route->rt _gateway) | |||
send_prune(g); | send_prune(g); | |||
} | } | |||
} | } | |||
} | } | |||
skipping to change at line 1240 | skipping to change at line 1211 | |||
logit(LOG_WARNING, 0, "Subordinate error"); | logit(LOG_WARNING, 0, "Subordinate error"); | |||
/* XXX end debugging */ | /* XXX end debugging */ | |||
IF_DEBUG(DEBUG_PRUNE|DEBUG_CACHE) { | IF_DEBUG(DEBUG_PRUNE|DEBUG_CACHE) { | |||
logit(LOG_DEBUG, 0, "Prune (%s %s), stop sending on vif %u, gm:%l x", | logit(LOG_DEBUG, 0, "Prune (%s %s), stop sending on vif %u, gm:%l x", | |||
RT_FMT(r, s1), inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), vi fi, g->gt_grpmems); | RT_FMT(r, s1), inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), vi fi, g->gt_grpmems); | |||
} | } | |||
prun_add_ttls(g); | prun_add_ttls(g); | |||
update_kernel(g); | update_kernel(g); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g,1); | ||||
#endif | ||||
} | } | |||
/* | /* | |||
* check if all the child routers have expressed no interest | * check if all the child routers have expressed no interest | |||
* in this group and if this group does not exist in the | * in this group and if this group does not exist in the | |||
* interface | * interface | |||
* Send a prune message then upstream | * Send a prune message then upstream | |||
*/ | */ | |||
if (VIFM_ISEMPTY(g->gt_grpmems) && r->rt_gateway) | if (VIFM_ISEMPTY(g->gt_grpmems) && r->rt_gateway) | |||
send_prune(g); | send_prune(g); | |||
skipping to change at line 1308 | skipping to change at line 1275 | |||
/* update cache timer*/ | /* update cache timer*/ | |||
g->gt_timer = CACHE_LIFETIME(cache_lifetime); | g->gt_timer = CACHE_LIFETIME(cache_lifetime); | |||
IF_DEBUG(DEBUG_PRUNE|DEBUG_CACHE) { | IF_DEBUG(DEBUG_PRUNE|DEBUG_CACHE) { | |||
logit(LOG_DEBUG, 0, "chkgrp graft (%s %s) gm:%lx", | logit(LOG_DEBUG, 0, "chkgrp graft (%s %s) gm:%lx", | |||
RT_FMT(r, s1), inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)) , g->gt_grpmems); | RT_FMT(r, s1), inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)) , g->gt_grpmems); | |||
} | } | |||
prun_add_ttls(g); | prun_add_ttls(g); | |||
update_kernel(g); | update_kernel(g); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g, 1); | ||||
#endif | ||||
} | } | |||
} | } | |||
} | } | |||
/* determine the multicast group and src | /* determine the multicast group and src | |||
* | * | |||
* if it does, then determine if a prune was sent upstream. if prune | * if it does, then determine if a prune was sent upstream. if prune | |||
* sent upstream, send graft upstream and send ack downstream. | * sent upstream, send graft upstream and send ack downstream. | |||
* | * | |||
* if no prune sent upstream, change the forwarding bit for this | * if no prune sent upstream, change the forwarding bit for this | |||
skipping to change at line 1391 | skipping to change at line 1354 | |||
free(pt); | free(pt); | |||
VIFM_SET(vifi, g->gt_grpmems); | VIFM_SET(vifi, g->gt_grpmems); | |||
IF_DEBUG(DEBUG_PRUNE|DEBUG_CACHE) { | IF_DEBUG(DEBUG_PRUNE|DEBUG_CACHE) { | |||
logit(LOG_DEBUG, 0, "Accept graft (%s %s) gm:%lx", RT_FMT(r, s1), | logit(LOG_DEBUG, 0, "Accept graft (%s %s) gm:%lx", RT_FMT(r, s1), | |||
inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), g->gt_grpmems ); | inet_fmt(g->gt_mcastgrp, s2, sizeof(s2)), g->gt_grpmems ); | |||
} | } | |||
prun_add_ttls(g); | prun_add_ttls(g); | |||
update_kernel(g); | update_kernel(g); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(g,1); | ||||
#endif | ||||
break; | break; | |||
} else { | } else { | |||
ptnp = &pt->pt_next; | ptnp = &pt->pt_next; | |||
} | } | |||
} | } | |||
g->gt_timer = CACHE_LIFETIME(cache_lifetime); | g->gt_timer = CACHE_LIFETIME(cache_lifetime); | |||
if (g->gt_prsent_timer) | if (g->gt_prsent_timer) | |||
/* send graft upwards */ | /* send graft upwards */ | |||
send_graft(g); | send_graft(g); | |||
skipping to change at line 1478 | skipping to change at line 1437 | |||
} | } | |||
/* | /* | |||
* free all prune entries and kernel routes | * free all prune entries and kernel routes | |||
* normally, this should inform the kernel that all of its routes | * normally, this should inform the kernel that all of its routes | |||
* are going away, but this is only called by restart(), which is | * are going away, but this is only called by restart(), which is | |||
* about to call MRT_DONE which does that anyway. | * about to call MRT_DONE which does that anyway. | |||
*/ | */ | |||
void free_all_prunes(void) | void free_all_prunes(void) | |||
{ | { | |||
struct rtentry *r; | ||||
struct gtable *g, *prev_g; | struct gtable *g, *prev_g; | |||
struct stable *s, *prev_s; | struct stable *s, *prev_s; | |||
struct ptable *p, *prev_p; | struct ptable *p, *prev_p; | |||
struct rtentry *r = NULL; | ||||
for (r = routing_table; r; r = r->rt_next) { | while (route_iter(&r)) { | |||
g = r->rt_groups; | g = r->rt_groups; | |||
while (g) { | while (g) { | |||
s = g->gt_srctbl; | s = g->gt_srctbl; | |||
while (s) { | while (s) { | |||
prev_s = s; | prev_s = s; | |||
s = s->st_next; | s = s->st_next; | |||
free(prev_s); | free(prev_s); | |||
} | } | |||
p = g->gt_pruntbl; | p = g->gt_pruntbl; | |||
skipping to change at line 1535 | skipping to change at line 1494 | |||
* When a new route is created, search | * When a new route is created, search | |||
* a) The less-specific part of the routing table | * a) The less-specific part of the routing table | |||
* b) The route-less kernel table | * b) The route-less kernel table | |||
* for sources that the new route might want to handle. | * for sources that the new route might want to handle. | |||
* | * | |||
* "Inheriting" these sources might be cleanest, but simply deleting | * "Inheriting" these sources might be cleanest, but simply deleting | |||
* them is easier, and letting the kernel re-request them. | * them is easier, and letting the kernel re-request them. | |||
*/ | */ | |||
void steal_sources(struct rtentry *rt) | void steal_sources(struct rtentry *rt) | |||
{ | { | |||
struct rtentry *rp; | ||||
struct gtable *gt, **gtnp; | struct gtable *gt, **gtnp; | |||
struct stable *st, **stnp; | struct stable *st, **stnp; | |||
struct rtentry *rp = rt; | ||||
for (rp = rt->rt_next; rp; rp = rp->rt_next) { | while (route_iter(&rp)) { | |||
if (rp->rt_groups == NULL) | if (rp->rt_groups == NULL) | |||
continue; | continue; | |||
if ((rt->rt_origin & rp->rt_originmask) == rp->rt_origin) { | if ((rt->rt_origin & rp->rt_originmask) == rp->rt_origin) { | |||
IF_DEBUG(DEBUG_ROUTE) { | IF_DEBUG(DEBUG_ROUTE) { | |||
logit(LOG_DEBUG, 0, "Route for %s stealing sources from %s", | logit(LOG_DEBUG, 0, "Route for %s stealing sources from %s", | |||
RT_FMT(rt, s1), RT_FMT(rp, s2)); | RT_FMT(rt, s1), RT_FMT(rp, s2)); | |||
} | } | |||
for (gt = rp->rt_groups; gt; gt = gt->gt_next) { | for (gt = rp->rt_groups; gt; gt = gt->gt_next) { | |||
stnp = >->gt_srctbl; | stnp = >->gt_srctbl; | |||
skipping to change at line 1857 | skipping to change at line 1816 | |||
if (gt->gt_gprev) { | if (gt->gt_gprev) { | |||
gt->gt_gprev->gt_gnext = gt->gt_gnext; | gt->gt_gprev->gt_gnext = gt->gt_gnext; | |||
gtnptr = >->gt_gprev->gt_gnext; | gtnptr = >->gt_gprev->gt_gnext; | |||
} else { | } else { | |||
kernel_table = gt->gt_gnext; | kernel_table = gt->gt_gnext; | |||
gtnptr = &kernel_table; | gtnptr = &kernel_table; | |||
} | } | |||
if (gt->gt_gnext) | if (gt->gt_gnext) | |||
gt->gt_gnext->gt_gprev = gt->gt_gprev; | gt->gt_gnext->gt_gprev = gt->gt_gprev; | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(gt,0); | ||||
rsrr_cache_clean(gt); | ||||
#endif | ||||
if (gt->gt_rexmit_timer) | if (gt->gt_rexmit_timer) | |||
timer_clear(gt->gt_rexmit_timer); | timer_clear(gt->gt_rexmit_timer); | |||
free(gt); | free(gt); | |||
} else { | } else { | |||
if (gt->gt_prsent_timer == -1) { | if (gt->gt_prsent_timer == -1) { | |||
/* | /* | |||
* The upstream prune timed out. Remove any kernel | * The upstream prune timed out. Remove any kernel | |||
* state. | * state. | |||
*/ | */ | |||
skipping to change at line 1951 | skipping to change at line 1905 | |||
struct rtentry *rt = gt->gt_route; | struct rtentry *rt = gt->gt_route; | |||
VIFM_SET(vifi, gt->gt_grpmems); | VIFM_SET(vifi, gt->gt_grpmems); | |||
IF_DEBUG(DEBUG_CACHE) { | IF_DEBUG(DEBUG_CACHE) { | |||
logit(LOG_DEBUG, 0, "Forwarding again (%s %s) gm:%lx vif:%d", | logit(LOG_DEBUG, 0, "Forwarding again (%s %s) gm:%lx vif:%d", | |||
RT_FMT(rt, s1), inet_fmt(gt->gt_mcastgrp, s2, sizeof(s2)), gt-> gt_grpmems, vifi); | RT_FMT(rt, s1), inet_fmt(gt->gt_mcastgrp, s2, sizeof(s2)), gt-> gt_grpmems, vifi); | |||
} | } | |||
prun_add_ttls(gt); | prun_add_ttls(gt); | |||
update_kernel(gt); | update_kernel(gt); | |||
#ifdef RSRR | ||||
/* Send route change notification to reservation protocol. */ | ||||
rsrr_cache_send(gt,1); | ||||
#endif | ||||
} | } | |||
} | } | |||
/* | /* | |||
* Print the contents of the cache table on file 'fp'. | * Print the contents of the cache table on file 'fp'. | |||
*/ | */ | |||
void dump_cache(FILE *fp, int detail) | void dump_cache(FILE *fp, int detail) | |||
{ | { | |||
struct rtentry *r; | struct rtentry *r; | |||
struct gtable *gt; | struct gtable *gt; | |||
skipping to change at line 2412 | skipping to change at line 2362 | |||
resptype == IGMP_MTRACE_RESP ? "reply" : "request on", | resptype == IGMP_MTRACE_RESP ? "reply" : "request on", | |||
inet_fmt(dst, s1, sizeof(s1)), inet_fmt(src, s2, sizeof(s2))); | inet_fmt(dst, s1, sizeof(s1)), inet_fmt(src, s2, sizeof(s2))); | |||
} | } | |||
send_igmp(src, dst, resptype, no, group, datalen); | send_igmp(src, dst, resptype, no, group, datalen); | |||
} | } | |||
} | } | |||
/** | /** | |||
* Local Variables: | * Local Variables: | |||
* indent-tabs-mode: t | * indent-tabs-mode: t | |||
* c-file-style: "ellemtel" | * c-file-style: "cc-mode" | |||
* c-basic-offset: 4 | ||||
* End: | * End: | |||
*/ | */ | |||
End of changes. 20 change blocks. | ||||
57 lines changed or deleted | 6 lines changed or added |