diff options
-rw-r--r-- | proto/ospf/ospf.c | 3 | ||||
-rw-r--r-- | proto/ospf/topology.c | 32 | ||||
-rw-r--r-- | proto/ospf/topology.h | 1 |
3 files changed, 31 insertions, 5 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index ebea951..8229d09 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -391,11 +391,12 @@ ospf_rt_notify(struct proto *p, net *n, rte *new, rte *old, ea_list *attrs) u32 pr=ipa_to_u32(n->n.prefix); struct ospf_lsa_ext *ext; int i; + int max=max_ext_lsa(n->n.pxlen); /* Flush old external LSA */ WALK_LIST(oa, po->area_list) { - for(i=0;i<MAXNETS;i++,pr++) + for(i=0;i<max;i++,pr++) { if(en=ospf_hash_find(oa->gr, pr, rtid, LSA_T_EXT)) { diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 733719a..8750997 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -355,6 +355,28 @@ originate_ext_lsa_body(net *n, rte *e, struct proto_ospf *po, struct ea_list *at } /** + * max_ext_lsa - calculate the maximum amount of external networks + * possible for the given prefix length. + * + * This is a fix for the previous static use of MAXNETS which did + * only work correct if MAXNETS < possible IPs for given prefix. + * This solution is kind of a hack as there can now only be one + * route for /32 type entries but this is better than the crashes + * I did experience whith close together /32 routes originating + * on different hosts. + */ + +int +max_ext_lsa(unsigned pxlen) +{ + int i; + for(i=1;pxlen<BITS_PER_IP_ADDRESS;pxlen++,i<<=1) + if(i>=MAXNETS) + return MAXNETS; + return i; +} + +/** * originate_ext_lsa - new route received from nest and filters * @n: network prefix and mask * @e: rte @@ -380,6 +402,7 @@ originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs) struct ospf_area *oa; struct ospf_lsa_ext *ext1,*ext2; int i; + int max; OSPF_TRACE(D_EVENTS, "Originating Ext lsa for %I/%d.", n->n.prefix, n->n.pxlen); @@ -393,10 +416,11 @@ originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs) lsa.length=sizeof(struct ospf_lsa_ext)+sizeof(struct ospf_lsa_ext_tos)+ sizeof(struct ospf_lsa_header); ext1=body; + max=max_ext_lsa(n->n.pxlen); oa=HEAD(po->area_list); - for(i=0;i<MAXNETS;i++) + for(i=0;i<max;i++) { if((en=ospf_hash_find_header(oa->gr, &lsa))!=NULL) { @@ -407,10 +431,10 @@ originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs) else break; } - if(i==MAXNETS) + if(i==max) { - log("%s: got more routes for one network then %d, ignoring",p->name, - MAXNETS); + log("%s: got more routes for one /%d network then %d, ignoring",p->name, + n->n.pxlen,max); mb_free(body); return; } diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h index c4bbc9e..d85173f 100644 --- a/proto/ospf/topology.h +++ b/proto/ospf/topology.h @@ -54,6 +54,7 @@ void addifa_rtlsa(struct ospf_iface *ifa); void originate_rt_lsa(struct ospf_area *oa); void originate_net_lsa(struct ospf_iface *ifa); int can_flush_lsa(struct ospf_area *oa); +int max_ext_lsa(unsigned pxlen); void originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs); #endif /* _BIRD_OSPF_TOPOLOGY_H_ */ |