Merge pull request #6912 from GalaxyGorilla/ospf_ti_lfa_prep

ospfd: preparation for TI-LFA
This commit is contained in:
Olivier Dugeon 2020-08-24 18:12:03 +02:00 committed by GitHub
commit 4f4eed1cff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 543 additions and 394 deletions

View File

@ -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");

View File

@ -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);
} }
} }
} }

View File

@ -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 *,

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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 */