Fixes next hop handling.
This commit is contained in:
parent
9895502392
commit
b76aeb8234
1 changed files with 57 additions and 54 deletions
111
proto/ospf/rt.c
111
proto/ospf/rt.c
|
@ -11,9 +11,9 @@
|
||||||
static void add_cand(list * l, struct top_hash_entry *en,
|
static void add_cand(list * l, struct top_hash_entry *en,
|
||||||
struct top_hash_entry *par, u32 dist,
|
struct top_hash_entry *par, u32 dist,
|
||||||
struct ospf_area *oa);
|
struct ospf_area *oa);
|
||||||
static void calc_next_hop(struct ospf_area *oa,
|
static int calc_next_hop(struct ospf_area *oa,
|
||||||
struct top_hash_entry *en,
|
struct top_hash_entry *en,
|
||||||
struct top_hash_entry *par);
|
struct top_hash_entry *par);
|
||||||
static void ospf_ext_spf(struct proto_ospf *po);
|
static void ospf_ext_spf(struct proto_ospf *po);
|
||||||
static void rt_sync(struct proto_ospf *po);
|
static void rt_sync(struct proto_ospf *po);
|
||||||
|
|
||||||
|
@ -987,18 +987,23 @@ add_cand(list * l, struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* FIXME - fix link_back()
|
/* FIXME - fix link_back()
|
||||||
|
* NOTE - we should not change link_back when
|
||||||
|
* it is already computed with different way and calc_next_hop()
|
||||||
|
* for current would fail
|
||||||
if (!link_back(oa, en, par))
|
if (!link_back(oa, en, par))
|
||||||
return;
|
return;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (!calc_next_hop(oa, en, par))
|
||||||
|
{
|
||||||
|
log(L_WARN "Cannot find next hop for LSA (Type: %04x, Id: %R, Rt: %R)",
|
||||||
|
en->lsa.type, en->lsa.id, en->lsa.rt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DBG(" Adding candidate: rt: %R, id: %R, type: %u\n",
|
DBG(" Adding candidate: rt: %R, id: %R, type: %u\n",
|
||||||
en->lsa.rt, en->lsa.id, en->lsa.type);
|
en->lsa.rt, en->lsa.id, en->lsa.type);
|
||||||
|
|
||||||
calc_next_hop(oa, en, par);
|
|
||||||
|
|
||||||
if (!en->nhi)
|
|
||||||
return; /* We cannot find next hop, ignore it */
|
|
||||||
|
|
||||||
if (en->color == CANDIDATE)
|
if (en->color == CANDIDATE)
|
||||||
{ /* We found a shorter path */
|
{ /* We found a shorter path */
|
||||||
rem_node(&en->cn);
|
rem_node(&en->cn);
|
||||||
|
@ -1049,7 +1054,7 @@ match_dr(struct ospf_iface *ifa, struct top_hash_entry *en)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en,
|
calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en,
|
||||||
struct top_hash_entry *par)
|
struct top_hash_entry *par)
|
||||||
{
|
{
|
||||||
|
@ -1058,9 +1063,6 @@ calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en,
|
||||||
struct proto_ospf *po = oa->po;
|
struct proto_ospf *po = oa->po;
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
|
|
||||||
en->nhi = NULL;
|
|
||||||
en->nh = IPA_NONE;
|
|
||||||
|
|
||||||
/* 16.1.1. The next hop calculation */
|
/* 16.1.1. The next hop calculation */
|
||||||
DBG(" Next hop called.\n");
|
DBG(" Next hop called.\n");
|
||||||
if (ipa_equal(par->nh, IPA_NONE))
|
if (ipa_equal(par->nh, IPA_NONE))
|
||||||
|
@ -1068,57 +1070,58 @@ calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en,
|
||||||
DBG(" Next hop calculating for id: %R rt: %R type: %u\n",
|
DBG(" Next hop calculating for id: %R rt: %R type: %u\n",
|
||||||
en->lsa.id, en->lsa.rt, en->lsa.type);
|
en->lsa.id, en->lsa.rt, en->lsa.type);
|
||||||
|
|
||||||
/* The parent vertex is the root */
|
/*
|
||||||
if (par == oa->rt)
|
* There are three cases:
|
||||||
|
* 1) en is a local network (and par is root)
|
||||||
|
* 2) en is a ptp or ptmp neighbor (and par is root)
|
||||||
|
* 3) en is a bcast or nbma neighbor (and par is local network)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The first case - local network */
|
||||||
|
if ((en->lsa.type == LSA_T_NET) && (par == oa->rt))
|
||||||
{
|
{
|
||||||
if (en->lsa.type == LSA_T_NET)
|
WALK_LIST(ifa, po->iface_list)
|
||||||
{
|
if (match_dr(ifa, en))
|
||||||
WALK_LIST(ifa, po->iface_list)
|
|
||||||
if (match_dr(ifa, en))
|
|
||||||
{
|
{
|
||||||
en->nhi = ifa;
|
en->nh = IPA_NONE;
|
||||||
return;
|
en->nhi = ifa;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((neigh = find_neigh_noifa(po, en->lsa.rt)) == NULL)
|
|
||||||
return;
|
|
||||||
en->nhi = neigh->ifa;
|
|
||||||
en->nh = neigh->ip;
|
|
||||||
/* Yes, neighbor is it's own next hop */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The parent vertex is a network that directly connects the
|
/*
|
||||||
calculating router to the destination router. */
|
* Remaining cases - local neighbours.
|
||||||
if (par->lsa.type == LSA_T_NET)
|
* There are two problems with this code:
|
||||||
|
* 1) we use IP address from HELLO packet
|
||||||
|
* and not the one from LSA (router or link).
|
||||||
|
* This may break NBMA networks
|
||||||
|
* 2) we use find_neigh_noifa() and does not
|
||||||
|
* take into account associated iface.
|
||||||
|
* This breaks neighbors connected by more links.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((en->lsa.type == LSA_T_RT) &&
|
||||||
|
((par == oa->rt) || (par->lsa.type == LSA_T_NET)))
|
||||||
{
|
{
|
||||||
if (en->lsa.type == LSA_T_NET)
|
if ((neigh = find_neigh_noifa(po, en->lsa.rt)) != NULL)
|
||||||
bug("Parent for net is net?");
|
{
|
||||||
if ((en->nhi = par->nhi) == NULL)
|
en->nh = neigh->ip;
|
||||||
bug("Did not find next hop interface for INSPF lsa!");
|
en->nhi = neigh->ifa;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((neigh = find_neigh_noifa(po, en->lsa.rt)) == NULL)
|
/* Probably bug or some race condition, we log it */
|
||||||
return;
|
log(L_ERR "Unexpected case in next hop calculation");
|
||||||
en->nhi = neigh->ifa;
|
|
||||||
en->nh = neigh->ip;
|
return 0;
|
||||||
/* Yes, neighbor is it's own next hop */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ /* Parent is some RT neighbor */
|
|
||||||
log(L_ERR "Router's parent has no next hop. (EN=%R, PAR=%R)",
|
|
||||||
en->lsa.id, par->lsa.id);
|
|
||||||
/* I hope this would never happen */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
en->nhi = par->nhi;
|
|
||||||
en->nh = par->nh;
|
en->nh = par->nh;
|
||||||
DBG(" Next hop calculated: %I.\n", en->nh);
|
en->nhi = par->nhi;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue