mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 09:52:27 +00:00
Merge pull request #6912 from GalaxyGorilla/ospf_ti_lfa_prep
ospfd: preparation for TI-LFA
This commit is contained in:
commit
4f4eed1cff
@ -995,7 +995,8 @@ void ospf_vl_delete(struct ospf *ospf, struct ospf_vl_data *vl_data)
|
|||||||
ospf_vl_data_free(vl_data);
|
ospf_vl_data_free(vl_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
|
static int ospf_vl_set_params(struct ospf_area *area,
|
||||||
|
struct ospf_vl_data *vl_data, struct vertex *v)
|
||||||
{
|
{
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
struct ospf_interface *voi;
|
struct ospf_interface *voi;
|
||||||
@ -1003,6 +1004,7 @@ static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
|
|||||||
struct vertex_parent *vp = NULL;
|
struct vertex_parent *vp = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct router_lsa *rl;
|
struct router_lsa *rl;
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
|
||||||
voi = vl_data->vl_oi;
|
voi = vl_data->vl_oi;
|
||||||
|
|
||||||
@ -1013,17 +1015,24 @@ static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
|
for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
|
||||||
vl_data->nexthop.oi = vp->nexthop->oi;
|
vl_data->nexthop.lsa_pos = vp->nexthop->lsa_pos;
|
||||||
vl_data->nexthop.router = vp->nexthop->router;
|
vl_data->nexthop.router = vp->nexthop->router;
|
||||||
|
|
||||||
if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
|
/*
|
||||||
&vl_data->nexthop.oi->address->u.prefix4))
|
* Only deal with interface data when the local
|
||||||
changed = 1;
|
* (calculating) node is the SPF root node
|
||||||
|
*/
|
||||||
|
if (!area->spf_dry_run) {
|
||||||
|
oi = ospf_if_lookup_by_lsa_pos(
|
||||||
|
area, vl_data->nexthop.lsa_pos);
|
||||||
|
|
||||||
voi->address->u.prefix4 =
|
if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
|
||||||
vl_data->nexthop.oi->address->u.prefix4;
|
&oi->address->u.prefix4))
|
||||||
voi->address->prefixlen =
|
changed = 1;
|
||||||
vl_data->nexthop.oi->address->prefixlen;
|
|
||||||
|
voi->address->u.prefix4 = oi->address->u.prefix4;
|
||||||
|
voi->address->prefixlen = oi->address->prefixlen;
|
||||||
|
}
|
||||||
|
|
||||||
break; /* We take the first interface. */
|
break; /* We take the first interface. */
|
||||||
}
|
}
|
||||||
@ -1114,7 +1123,7 @@ void ospf_vl_up_check(struct ospf_area *area, struct in_addr rid,
|
|||||||
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ospf_vl_set_params(vl_data, v)) {
|
if (ospf_vl_set_params(area, vl_data, v)) {
|
||||||
if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
|
if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"ospf_vl_up_check: VL cost change, scheduling router lsa refresh");
|
"ospf_vl_up_check: VL cost change, scheduling router lsa refresh");
|
||||||
|
@ -375,7 +375,7 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
|
|||||||
else
|
else
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
|
|
||||||
ospf_route_copy_nexthops_from_vertex(or, v);
|
ospf_route_copy_nexthops_from_vertex(area, or, v);
|
||||||
|
|
||||||
listnode_add(rn->info, or);
|
listnode_add(rn->info, or);
|
||||||
|
|
||||||
@ -438,7 +438,7 @@ void ospf_intra_add_transit(struct route_table *rt, struct vertex *v,
|
|||||||
or->type = OSPF_DESTINATION_NETWORK;
|
or->type = OSPF_DESTINATION_NETWORK;
|
||||||
or->u.std.origin = (struct lsa_header *)lsa;
|
or->u.std.origin = (struct lsa_header *)lsa;
|
||||||
|
|
||||||
ospf_route_copy_nexthops_from_vertex(or, v);
|
ospf_route_copy_nexthops_from_vertex(area, or, v);
|
||||||
|
|
||||||
rn->info = or ;
|
rn->info = or ;
|
||||||
}
|
}
|
||||||
@ -453,7 +453,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
|
|||||||
struct ospf_route * or ;
|
struct ospf_route * or ;
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p;
|
||||||
struct router_lsa *lsa;
|
struct router_lsa *lsa;
|
||||||
struct ospf_interface *oi;
|
struct ospf_interface *oi = NULL;
|
||||||
struct ospf_path *path;
|
struct ospf_path *path;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
@ -538,7 +538,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"ospf_intra_add_stub(): routes are equal, merge");
|
"ospf_intra_add_stub(): routes are equal, merge");
|
||||||
|
|
||||||
ospf_route_copy_nexthops_from_vertex(cur_or, v);
|
ospf_route_copy_nexthops_from_vertex(area, cur_or, v);
|
||||||
|
|
||||||
if (IPV4_ADDR_CMP(&cur_or->u.std.origin->id,
|
if (IPV4_ADDR_CMP(&cur_or->u.std.origin->id,
|
||||||
&lsa->header.id)
|
&lsa->header.id)
|
||||||
@ -563,7 +563,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
|
|||||||
|
|
||||||
list_delete_all_node(cur_or->paths);
|
list_delete_all_node(cur_or->paths);
|
||||||
|
|
||||||
ospf_route_copy_nexthops_from_vertex(cur_or, v);
|
ospf_route_copy_nexthops_from_vertex(area, cur_or, v);
|
||||||
|
|
||||||
cur_or->u.std.origin = (struct lsa_header *)lsa;
|
cur_or->u.std.origin = (struct lsa_header *)lsa;
|
||||||
return;
|
return;
|
||||||
@ -588,24 +588,35 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
|
|||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"ospf_intra_add_stub(): this network is on remote router");
|
"ospf_intra_add_stub(): this network is on remote router");
|
||||||
ospf_route_copy_nexthops_from_vertex(or, v);
|
ospf_route_copy_nexthops_from_vertex(area, or, v);
|
||||||
} else {
|
} else {
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"ospf_intra_add_stub(): this network is on this router");
|
"ospf_intra_add_stub(): this network is on this router");
|
||||||
|
|
||||||
if ((oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos))) {
|
/*
|
||||||
|
* Only deal with interface data when we
|
||||||
|
* don't do a dry run
|
||||||
|
*/
|
||||||
|
if (!area->spf_dry_run)
|
||||||
|
oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos);
|
||||||
|
|
||||||
|
if (oi || area->spf_dry_run) {
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"ospf_intra_add_stub(): the interface is %s",
|
"ospf_intra_add_stub(): the lsa pos is %d",
|
||||||
IF_NAME(oi));
|
lsa_pos);
|
||||||
|
|
||||||
path = ospf_path_new();
|
path = ospf_path_new();
|
||||||
path->nexthop.s_addr = INADDR_ANY;
|
path->nexthop.s_addr = INADDR_ANY;
|
||||||
path->ifindex = oi->ifp->ifindex;
|
|
||||||
if (CHECK_FLAG(oi->connected->flags,
|
if (oi) {
|
||||||
ZEBRA_IFA_UNNUMBERED))
|
path->ifindex = oi->ifp->ifindex;
|
||||||
path->unnumbered = 1;
|
if (CHECK_FLAG(oi->connected->flags,
|
||||||
|
ZEBRA_IFA_UNNUMBERED))
|
||||||
|
path->unnumbered = 1;
|
||||||
|
}
|
||||||
|
|
||||||
listnode_add(or->paths, path);
|
listnode_add(or->paths, path);
|
||||||
} else {
|
} else {
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
@ -654,6 +665,37 @@ void ospf_route_table_dump(struct route_table *rt)
|
|||||||
zlog_debug("========================================");
|
zlog_debug("========================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ospf_route_table_print(struct vty *vty, struct route_table *rt)
|
||||||
|
{
|
||||||
|
struct route_node *rn;
|
||||||
|
struct ospf_route * or ;
|
||||||
|
struct listnode *pnode;
|
||||||
|
struct ospf_path *path;
|
||||||
|
|
||||||
|
vty_out(vty, "========== OSPF routing table ==========\n");
|
||||||
|
for (rn = route_top(rt); rn; rn = route_next(rn))
|
||||||
|
if ((or = rn->info) != NULL) {
|
||||||
|
if (or->type == OSPF_DESTINATION_NETWORK) {
|
||||||
|
vty_out(vty, "N %-18pFX %-15pI4 %s %d\n",
|
||||||
|
&rn->p, & or->u.std.area_id,
|
||||||
|
ospf_path_type_str[or->path_type],
|
||||||
|
or->cost);
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(or->paths, pnode,
|
||||||
|
path))
|
||||||
|
vty_out(vty, " -> %s\n",
|
||||||
|
path->nexthop.s_addr != 0
|
||||||
|
? inet_ntoa(
|
||||||
|
path->nexthop)
|
||||||
|
: "directly connected");
|
||||||
|
} else
|
||||||
|
vty_out(vty, "R %-18pI4 %-15pI4 %s %d\n",
|
||||||
|
&rn->p.u.prefix4, & or->u.std.area_id,
|
||||||
|
ospf_path_type_str[or->path_type],
|
||||||
|
or->cost);
|
||||||
|
}
|
||||||
|
vty_out(vty, "========================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* This is 16.4.1 implementation.
|
/* This is 16.4.1 implementation.
|
||||||
o Intra-area paths using non-backbone areas are always the most preferred.
|
o Intra-area paths using non-backbone areas are always the most preferred.
|
||||||
o The other paths, intra-area backbone paths and inter-area paths,
|
o The other paths, intra-area backbone paths and inter-area paths,
|
||||||
@ -734,30 +776,41 @@ static int ospf_path_exist(struct list *plist, struct in_addr nexthop,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ospf_route_copy_nexthops_from_vertex(struct ospf_route *to,
|
void ospf_route_copy_nexthops_from_vertex(struct ospf_area *area,
|
||||||
|
struct ospf_route *to,
|
||||||
struct vertex *v)
|
struct vertex *v)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct ospf_path *path;
|
struct ospf_path *path;
|
||||||
struct vertex_nexthop *nexthop;
|
struct vertex_nexthop *nexthop;
|
||||||
struct vertex_parent *vp;
|
struct vertex_parent *vp;
|
||||||
|
struct ospf_interface *oi = NULL;
|
||||||
|
|
||||||
assert(to->paths);
|
assert(to->paths);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
|
for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
|
||||||
nexthop = vp->nexthop;
|
nexthop = vp->nexthop;
|
||||||
|
|
||||||
if (nexthop->oi != NULL) {
|
/*
|
||||||
if (!ospf_path_exist(to->paths, nexthop->router,
|
* Only deal with interface data when we
|
||||||
nexthop->oi)) {
|
* don't do a dry run
|
||||||
path = ospf_path_new();
|
*/
|
||||||
path->nexthop = nexthop->router;
|
if (!area->spf_dry_run)
|
||||||
path->ifindex = nexthop->oi->ifp->ifindex;
|
oi = ospf_if_lookup_by_lsa_pos(area, nexthop->lsa_pos);
|
||||||
if (CHECK_FLAG(nexthop->oi->connected->flags,
|
|
||||||
|
if ((oi && !ospf_path_exist(to->paths, nexthop->router, oi))
|
||||||
|
|| area->spf_dry_run) {
|
||||||
|
path = ospf_path_new();
|
||||||
|
path->nexthop = nexthop->router;
|
||||||
|
|
||||||
|
if (oi) {
|
||||||
|
path->ifindex = oi->ifp->ifindex;
|
||||||
|
if (CHECK_FLAG(oi->connected->flags,
|
||||||
ZEBRA_IFA_UNNUMBERED))
|
ZEBRA_IFA_UNNUMBERED))
|
||||||
path->unnumbered = 1;
|
path->unnumbered = 1;
|
||||||
listnode_add(to->paths, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listnode_add(to->paths, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,7 @@ extern void ospf_route_table_free(struct route_table *);
|
|||||||
|
|
||||||
extern void ospf_route_install(struct ospf *, struct route_table *);
|
extern void ospf_route_install(struct ospf *, struct route_table *);
|
||||||
extern void ospf_route_table_dump(struct route_table *);
|
extern void ospf_route_table_dump(struct route_table *);
|
||||||
|
extern void ospf_route_table_print(struct vty *vty, struct route_table *rt);
|
||||||
|
|
||||||
extern void ospf_intra_add_router(struct route_table *, struct vertex *,
|
extern void ospf_intra_add_router(struct route_table *, struct vertex *,
|
||||||
struct ospf_area *);
|
struct ospf_area *);
|
||||||
@ -146,7 +147,8 @@ extern void ospf_intra_add_stub(struct route_table *, struct router_lsa_link *,
|
|||||||
extern int ospf_route_cmp(struct ospf *, struct ospf_route *,
|
extern int ospf_route_cmp(struct ospf *, struct ospf_route *,
|
||||||
struct ospf_route *);
|
struct ospf_route *);
|
||||||
extern void ospf_route_copy_nexthops(struct ospf_route *, struct list *);
|
extern void ospf_route_copy_nexthops(struct ospf_route *, struct list *);
|
||||||
extern void ospf_route_copy_nexthops_from_vertex(struct ospf_route *,
|
extern void ospf_route_copy_nexthops_from_vertex(struct ospf_area *area,
|
||||||
|
struct ospf_route *,
|
||||||
struct vertex *);
|
struct vertex *);
|
||||||
|
|
||||||
extern void ospf_route_subst(struct route_node *, struct ospf_route *,
|
extern void ospf_route_subst(struct route_node *, struct ospf_route *,
|
||||||
|
783
ospfd/ospf_spf.c
783
ospfd/ospf_spf.c
File diff suppressed because it is too large
Load Diff
@ -49,15 +49,14 @@ struct vertex {
|
|||||||
|
|
||||||
/* A nexthop taken on the root node to get to this (parent) vertex */
|
/* A nexthop taken on the root node to get to this (parent) vertex */
|
||||||
struct vertex_nexthop {
|
struct vertex_nexthop {
|
||||||
struct ospf_interface *oi; /* output intf on root node */
|
|
||||||
struct in_addr router; /* router address to send to */
|
struct in_addr router; /* router address to send to */
|
||||||
|
int lsa_pos; /* LSA position for resolving the interface */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vertex_parent {
|
struct vertex_parent {
|
||||||
struct vertex_nexthop
|
struct vertex_nexthop *nexthop; /* nexthop address for this parent */
|
||||||
*nexthop; /* link to nexthop info for this parent */
|
struct vertex *parent; /* parent vertex */
|
||||||
struct vertex *parent; /* parent vertex */
|
int backlink; /* index back to parent for router-lsa's */
|
||||||
int backlink; /* index back to parent for router-lsa's */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* What triggered the SPF ? */
|
/* What triggered the SPF ? */
|
||||||
@ -73,7 +72,18 @@ typedef enum {
|
|||||||
} ospf_spf_reason_t;
|
} ospf_spf_reason_t;
|
||||||
|
|
||||||
extern void ospf_spf_calculate_schedule(struct ospf *, ospf_spf_reason_t);
|
extern void ospf_spf_calculate_schedule(struct ospf *, ospf_spf_reason_t);
|
||||||
|
extern void ospf_spf_calculate(struct ospf_area *area,
|
||||||
|
struct ospf_lsa *root_lsa,
|
||||||
|
struct route_table *new_table,
|
||||||
|
struct route_table *new_rtrs, bool is_dry_run,
|
||||||
|
bool is_root_node);
|
||||||
|
extern int ospf_spf_calculate_areas(struct ospf *ospf,
|
||||||
|
struct route_table *new_table,
|
||||||
|
struct route_table *new_rtrs,
|
||||||
|
bool is_dry_run, bool is_root_node);
|
||||||
extern void ospf_rtrs_free(struct route_table *);
|
extern void ospf_rtrs_free(struct route_table *);
|
||||||
|
|
||||||
|
extern void ospf_spf_print(struct vty *vty, struct vertex *v, int i);
|
||||||
|
|
||||||
/* void ospf_spf_calculate_timer_add (); */
|
/* void ospf_spf_calculate_timer_add (); */
|
||||||
#endif /* _QUAGGA_OSPF_SPF_H */
|
#endif /* _QUAGGA_OSPF_SPF_H */
|
||||||
|
@ -414,6 +414,10 @@ struct ospf_area {
|
|||||||
|
|
||||||
/* Shortest Path Tree. */
|
/* Shortest Path Tree. */
|
||||||
struct vertex *spf;
|
struct vertex *spf;
|
||||||
|
bool spf_dry_run; /* flag for checking if the SPF calculation is
|
||||||
|
intended for the local RIB */
|
||||||
|
bool spf_root_node; /* flag for checking if the calculating node is the
|
||||||
|
root node of the SPF tree */
|
||||||
|
|
||||||
/* Threads. */
|
/* Threads. */
|
||||||
struct thread *t_stub_router; /* Stub-router timer */
|
struct thread *t_stub_router; /* Stub-router timer */
|
||||||
|
Loading…
Reference in New Issue
Block a user